12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238 |
- <template>
- <div>
- <div class="map-box">
- <!-- 地图 -->
- <div
- id="mapDiv"
- ></div>
- <!-- 企业查询 -->
- <div class="company-box">
- <!-- 企业名称 -->
- <div class="search-input-box">
- <a-select
- v-model:value="searchType"
- @change="searchTypeChange"
- >
- <a-select-option value="company">找企业</a-select-option>
- <a-select-option value="post">找岗位</a-select-option>
- </a-select>
- <a-input-search
- v-model:value="companySearchParam.companyName"
- :placeholder="searchType == 'company' ? '请输入企业名称' : '请输入岗位名称'"
- enter-button
- :loading="searchLoading"
- style="width: 75%"
- @search="onSearch"
- />
- </div>
- <!-- 查询多选框与数据列表 -->
- <div class="select-data-box">
- <!-- 多选框 -->
- <div class="select-box ">
- <span class="cursor-pointer" style="width: 46px;padding: 0 7px" @click="searchAll">全部</span>
- <a-select
- v-model:value="companySearchParam.maxDistance"
- placeholder="距离范围" style="width: 35%"
- :allow-clear="true" size="small"
- @change="onSearch"
- >
- <a-select-option :value="item.value" v-for="(item,index) in rangeList" :key="index">{{
- item.label
- }}
- </a-select-option>
- </a-select>
- <a-select
- v-model:value="companySearchParam.companyModel"
- :options="companyModelList"
- :field-names="{ label: 'name', value: 'value' }"
- placeholder="企业规模" style="width: 49%"
- :allow-clear="true" size="small"
- @change="onSearch"
- >
- </a-select>
- <a-select
- v-model:value="companySearchParam.regionCode"
- :allow-clear="true"
- :options="regionList"
- :field-names="{ label: 'name', value: 'code' }"
- placeholder="所属县区" size="small" style="width: 152px"
- @change="regionCodeChange"
- >
- </a-select>
- <a-select
- v-model:value="companySearchParam.siteID"
- :allow-clear="true"
- :options="siteList"
- :field-names="{ label: 'siteName', value: 'siteID' }"
- placeholder="所属驿站" size="small" style="width: 149px"
- @change="siteChange"
- >
- </a-select>
- <a-select
- v-model:value="companySearchParam.createTimeBy"
- :allow-clear="true"
- :options="createTimeByList"
- placeholder="创建时间" size="small" style="width: 50%"
- @change="onSearch"
- >
- </a-select>
- <a-select
- v-if="searchType == 'company'"
- v-model:value="companySearchParam.isPost"
- :allow-clear="true"
- :options="[
- {label:'有岗位', value: 1},
- {label:'无岗位', value: 0}
- ]"
- placeholder="是否有岗位" size="small" style="width: 50%"
- @change="onSearch"
- >
- </a-select>
- </div>
- <!-- 企业数据列表 -->
- <div class="list-box">
- <!-- 查询类型为企业,主要展示企业数据 -->
- <div class="company-data-box"
- :class="{
- 'check-company': (nowCheckCompany.companyID == company.companyID || nowMouseenterCompany.companyID == company.companyID) && company.creditRecordCount == null,
- 'check-company-red': (nowCheckCompany.companyID == company.companyID || nowMouseenterCompany.companyID == company.companyID) && company.creditRecordCount >= 1,
- }"
- v-if="companyList.length > 0 && searchType == 'company'" v-for="(company,index) in companyList"
- :key="index"
- @click="checkCompanyChange(company, true)"
- @mouseenter="companyMouseenter(company)"
- @mouseleave="companyMouseenter({companyID:-1})"
- >
- <p class="company-name">
- {{ company.companyName }}
- </p>
- <p class="label-text">
- 地点:{{ company.companyAddress }}
- </p>
- <!-- 岗位 -->
- <div class="company-post-box label-text">
- <span style="width: 65px; flex: 0 0 auto">招聘岗位:</span>
- <a-tag v-if="company.postList && company.postList.length > 0"
- v-for="(label, index) in company.postList.slice(0, 3)"
- :key="index">
- {{ label.professionName }}
- </a-tag>
- <span v-if="company.postList && company.postList.length > 3" class="all-post-btn"
- style="width: 25px;flex: 0 0 auto">
- 更多
- </span>
- <span v-if="!company.postList || company.postList.length == 0"
- style="width: 25px;flex: 0 0 auto">暂无</span>
- </div>
- <!-- 标签 -->
- <div class="company-label-box" v-if="company.companyLabelList && company.companyLabelList.length > 0"
- :ref="el => companyLabelBoxRef[index] = el" :class="{'label-box-max-height': company.labelExpanded}">
- <a-tag v-for="(label, labelIndex) in company.companyLabelList" :key="labelIndex">
- {{ label.labelName }}
- </a-tag>
- <div v-if="showLaunchBtnBox(companyLabelBoxRef,index,50)">
- <span class="launch-btn" v-if="company.labelExpanded"
- @click.stop="company.labelExpanded = false">展开</span>
- <span class="launch-btn" v-else @click.stop="company.labelExpanded = true">收起</span>
- </div>
- </div>
- </div>
- <!-- 查询类型为岗位时,主要展示岗位数据 -->
- <div v-if="companyList.length>0 && searchType == 'post'"
- v-for="(postCompany, postCompanyIndex) in companyList" :key="postCompanyIndex"
- class="company-data-box"
- :class="{'check-company':nowCheckCompany.postID == postCompany.postID || nowMouseenterCompany.postID == postCompany.postID}"
- @click="checkCompanyChange(postCompany, true)"
- @mouseenter="companyMouseenter(postCompany)"
- @mouseleave="companyMouseenter({postID:-1})"
- >
- <div class="post-title">
- <span>{{ postCompany.professionName }}({{ postCompany.recruitCount }}人)</span>
- <span class="post-salary">{{ showSalary(postCompany.minSalary, postCompany.maxSalary) }}</span>
- </div>
- <p class="label-text">
- 招聘企业:{{ postCompany.companyName }}
- </p>
- <p class="label-text">
- 工作地点:{{ postCompany.companyAddress }}
- </p>
- <!-- 标签 -->
- <div class="company-label-box"
- v-if="postCompany.postLabelList && postCompany.postLabelList.length > 0"
- :ref="el => companyPostLabelBoxRef[postCompanyIndex] = el"
- :class="{'label-box-max-height': postCompany.labelExpanded}">
- <a-tag v-for="(label, labelIndex) in postCompany.postLabelList" :key="labelIndex">
- {{ label.labelName }}
- </a-tag>
- <div v-if="showLaunchBtnBox(companyPostLabelBoxRef,postCompanyIndex,50)">
- <span class="launch-btn" v-if="postCompany.labelExpanded"
- @click.stop="postCompany.labelExpanded = false">展开</span>
- <span class="launch-btn" v-else @click.stop="postCompany.labelExpanded = true">收起</span>
- </div>
- </div>
- </div>
- <!-- 空数据状态 -->
- <div v-if="companyList.length == 0" class="empty-box">
- <a-empty/>
- </div>
- </div>
- </div>
- <!-- 分页区域 -->
- <div class="pagination-box">
- <span>共{{ companyTotal }}{{ searchType == 'company' ? '家' : '个' }}</span>
- <a-pagination v-model:current="companySearchParam.pageIndex" :total="companyTotal"
- v-model:pageSize="companySearchParam.pageSize" :disabled="searchLoading"
- show-less-items @change="companyPaginationChange" simple :show-size-changer="false"/>
- </div>
- </div>
- <!-- 岗位信息 -->
- <div class="post-box" v-if="nowCheckCompany.companyID">
- <div v-if="searchType == 'company'"
- style="width: 100%; height: 100%; background-color: #F8F8F8; border-radius: 10px; padding: 10px 10px 0 10px;">
- <!-- 企业信息 -->
- <div class="post-company-box margin-bottom-10">
- <p class="company-name">
- {{ nowCheckCompany.companyName }}
- </p>
- <p class="label-text">
- 所属行业:{{ nowCheckCompany.industryName }}
- </p>
- <p class="label-text flex-box justify-between">
- <span style="width: 50%">
- 企业规模:{{ nowCheckCompany.companyModelType }}
- </span>
- <span style="width: 50%">
- 企业状态:{{ nowCheckCompany.recordStatusName }}
- </span>
- </p>
- <p class="label-text flex-box justify-between">
- <span>
- 联系人:{{ nowCheckCompany.userName }}
- </span>
- <span>
- 联系电话:{{ nowCheckCompany.userMobile }}
- </span>
- </p>
- <p class="label-text">标签</p>
- <!-- 标签 -->
- <div class="company-label-box"
- v-if="nowCheckCompany.companyLabelList && nowCheckCompany.companyLabelList.length > 0"
- :ref="el => postBoxCompanyLabelBoxRef = el"
- :class="{'label-box-max-height': postBoxCompanyLabelExpanded}">
- <a-tag v-for="(label, index) in nowCheckCompany.companyLabelList" :key="index">
- {{ label.labelName }}
- </a-tag>
- <div v-if="showLaunchBtnBox(postBoxCompanyLabelBoxRef, null, 50)">
- <span class="launch-btn" v-if="postBoxCompanyLabelExpanded"
- @click.stop="postBoxCompanyLabelExpanded = false">展开</span>
- <span class="launch-btn" v-else @click.stop="postBoxCompanyLabelExpanded = true">收起</span>
- </div>
- </div>
- <div v-else class="label-text">
- 暂无标签
- </div>
- </div>
- <!-- 岗位列表 -->
- <div class="list-box">
- <div class="list-post-box margin-bottom-10" v-if="postList.length > 0"
- v-for="(post, postIndex) in postList"
- :key="postIndex">
- <div class="post-title">
- <span>{{ post.professionName }}</span>
- <span class="post-salary">{{ showSalary(post.minSalary, post.maxSalary) }}</span>
- </div>
- <p class="label-text">
- 招聘人数:{{ post.recruitCount }}
- </p>
- <p class="label-text">
- 招聘日期:
- {{ dayjs(post.startTime).format("YYYY-MM-DD") }}
- 至
- {{ dayjs(post.endTime).format("YYYY-MM-DD") }}
- </p>
- <!-- 岗位要求 -->
- <div class="post-desc-box">
- <div class="label-text post-desc" :ref="el => postDescBoxRef[postIndex] = el"
- :class="{'post-desc-max-height': post.descExpanded}">
- 岗位要求:{{ post.postDesc }}
- </div>
- <div v-if="showLaunchBtnBox(postDescBoxRef,postIndex,36)">
- <span class="launch-btn" v-if="post.descExpanded"
- @click.stop="post.descExpanded = false">展开</span>
- <span class="launch-btn " v-else @click.stop="post.descExpanded = true">收起</span>
- </div>
- </div>
- <!-- 标签 -->
- <div class="company-label-box" v-if="post.labelList && post.labelList.length > 0"
- :ref="el => postLabelBoxRef[postIndex] = el" :class="{'label-box-max-height': post.labelExpanded}">
- <a-tag v-for="(label, labelIndex) in post.labelList" :key="labelIndex">
- {{ label.labelName }}
- </a-tag>
- <div v-if="showLaunchBtnBox(postLabelBoxRef,postIndex,50)">
- <span class="launch-btn" v-if="post.labelExpanded"
- @click.stop="post.labelExpanded = false">展开</span>
- <span class="launch-btn" v-else @click.stop="post.labelExpanded = true">收起</span>
- </div>
- </div>
- </div>
- <div v-else class="empty-box">
- <a-empty/>
- </div>
- </div>
- <!-- 分页控件 -->
- <div class="pagination-box">
- <span>共{{ postTotal }}个</span>
- <a-pagination v-model:current="postSearchParams.pageIndex" :total="postTotal"
- v-model:pageSize="postSearchParams.pageSize"
- show-less-items @change="postPaginationChange" simple :show-size-changer="false"/>
- </div>
- </div>
- <div v-if="searchType == 'post'"
- style="width: 100%; height: 100%; background-color: #FFFFFF;border-radius: 10px;">
- <div class="post-company-box" style="max-height: 100%">
- <div class="post-title">
- <span class="font-weight-700">{{ nowCheckCompany.professionName }}</span>
- <span class="post-salary">{{ showSalary(nowCheckCompany.minSalary, nowCheckCompany.maxSalary) }}</span>
- </div>
- <!-- 标签 -->
- <div class="company-label-box"
- v-if="nowCheckCompany.postLabelList && nowCheckCompany.postLabelList.length > 0"
- >
- <a-tag v-for="(label, index) in nowCheckCompany.postLabelList" :key="index">
- {{ label.labelName }}
- </a-tag>
- </div>
- <!-- 联系人 -->
- <div class="company-contact-info">
- <p class="font-size-14 font-weight-700">{{ nowCheckCompany.companyName }}</p>
- <div class="avt-info margin-top-10">
- <img :src="avtO1" alt="">
- <div v-if="nowCheckCompany.contactName || nowCheckCompany.contactMobile">
- <p class="contact-name">
- {{ nowCheckCompany.contactName }}
- </p>
- <p class="contact-mobile">
- {{ nowCheckCompany.contactMobile }}
- </p>
- </div>
- <div v-else>
- <p class="contact-name">
- 未登记联系人
- </p>
- </div>
- </div>
- <p class="font-size-14 font-weight-700 margin-top-10">
- 登记人:{{ nowCheckCompany.postCreateUserName }}
- </p>
- </div>
- <div class="post-desc">
- <p class="font-size-16 font-weight-600 margin-bottom-10">职位描述:</p>
- <p class="font-size-12 font-weight-400 line-height-20">
- {{ nowCheckCompany.postDesc ? nowCheckCompany.postDesc : '暂无描述' }}</p>
- </div>
- <div class="post-company-address">
- <p class="font-size-16 font-weight-600 margin-bottom-10">工作地址:</p>
- <p class="font-size-12 font-weight-400 line-height-20">{{ nowCheckCompany.companyAddress }}</p>
- </div>
- </div>
- </div>
- </div>
- </div>
- </div>
- </template>
- <script setup lang="ts">
- import {onMounted, reactive, ref} from "vue";
- import huiZhouGeoJSON from "./geo";
- import {getPosition, setBoundary} from "@/utils/position";
- import redThIcon from "@/assets/images/redTh1.png";
- import redThIcon3 from "@/assets/images/redTh4.png";
- import blueThIcon from "@/assets/images/blueTh1.png";
- import {message, type SelectProps} from "ant-design-vue";
- import {getSysDictionaryList} from "@/api/system/dictionary";
- import {getSiteByID, getSiteList} from "@/api/baseSettings/siteInfo";
- import {getRegionCodeList} from "@/api/system/area/index";
- import {getDataMapList, getDataMapListByPostName} from "@/api/companyService/company";
- import {getCompanyMapPostList} from "@/api/companyService/post";
- import dayjs from "dayjs";
- import avtO1 from "@/assets/images/avt01.png";
- const T = (window as any).T;
- const zoom = 9;
- let map = null;
- // 天地图默认中心点坐标
- const centerLngLat = new T.LngLat(114.416110, 23.111582);
- // 地图标记点
- let userMarker = ref<any>(null)
- let markerList = ref<Array<any>>([]);
- let labelList = ref<Array<any>>([]);
- // 查询类型
- const searchType = ref("company")
- // 企业查询条件
- const companySearchParam = reactive({
- pageIndex: 1,
- pageSize: 100,
- companyName: "",
- maxDistance: null,
- companyModel: undefined,
- siteID: undefined,
- regionCode: undefined,
- createTimeBy: 'all',
- longitude: 114.411771,
- latitude: 23.113454,
- isPost: null
- })
- // 当前电脑的位置
- const defaultLonLat = reactive({
- longitude: 114.411771,
- latitude: 23.113454,
- })
- // 企业数据
- const companyList = ref<Array<any>>([])
- // 企业分页条数
- const companyTotal = ref(0);
- // 当前选中的企业
- const nowCheckCompany = ref<any>({})
- // 鼠标当前移入的企业
- const nowMouseenterCompany = ref<any>({})
- // 岗位查询条件
- const postSearchParams = reactive({
- pageIndex: 1,
- pageSize: 20,
- })
- // 当前选中的企业岗位列表
- const postList = ref<Array<any>>([]);
- // 岗位分页总条数
- const postTotal = ref(0);
- // 范围列表
- const rangeList = [
- {value: null, label: "--范围--"},
- {value: 5, label: "5KM"},
- {value: 3, label: "3KM"},
- {value: 1, label: "1KM"}
- ]
- // 创建时间
- const createTimeByList = [
- {label: '全部', value: 'all'},
- {label: '最近三天', value: '3Day'},
- {label: '最近一周', value: '1Week'},
- {label: '最近一月', value: '1Month'},
- {label: '最近三月', value: '3Month'},
- {label: '最近半年', value: 'Year'},
- ];
- // 企业规模
- const companyModelList = ref<SelectProps['options']>();
- // 所属驿站
- const siteList = ref<any>([]);
- // 所属县区
- const regionList = ref<SelectProps['options']>();
- // 查询按钮加载
- const searchLoading = ref(false);
- // 企业信息标签box ref
- const companyLabelBoxRef = ref<Array<any>>([]);
- // 企业信息-岗位标签box ref
- const companyPostLabelBoxRef = ref<Array<any>>([])
- // 岗位面板企业信息的标签盒子ref
- const postBoxCompanyLabelBoxRef = ref<any>(null);
- // 岗位面板企业信息的标签展开与收起开关
- const postBoxCompanyLabelExpanded = ref(true)
- // 岗位信息的标签box ref
- const postLabelBoxRef = ref<Array<any>>([]);
- // 岗位要求
- const postDescBoxRef = ref<Array<any>>([]);
- // 企业的岗位拼接HTML
- const companyPostWinHtml = ref({})
- // 查询企业规模
- const getCompanyModelList = async function () {
- companyModelList.value = await getSysDictionaryList("CompanyModel");
- }
- // 查询县区
- const getRegionList = async function () {
- regionList.value = await getRegionCodeList();
- }
- // 查询事件
- function onSearch() {
- searchLoading.value = true;
- companyList.value = [];
- // 按企业名称查询
- if (searchType.value == 'company') {
- getDataMapList(companySearchParam).then((result: any) => {
- findFuncThen(result);
- }).finally(() => {
- searchLoading.value = false;
- })
- }
- // 按岗位名称反向查询
- if (searchType.value == "post") {
- getDataMapListByPostName(companySearchParam).then((result: any) => {
- findFuncThen(result);
- }).finally(() => {
- searchLoading.value = false;
- })
- }
- }
- // 查询全部
- function searchAll() {
- companySearchParam.companyName = "";
- companySearchParam.companyModel = undefined;
- companySearchParam.siteID = undefined;
- companySearchParam.regionCode = undefined;
- companySearchParam.maxDistance = null;
- companySearchParam.pageIndex = 1;
- companySearchParam.pageSize = 50;
- onSearch();
- }
- // 查询处理
- function findFuncThen(result: any) {
- companyList.value = result.list;
- // 处理标签和岗位JSON数据
- companyList.value.forEach((item: any) => {
- item.postLabelList = JSON.parse(item.postLabelList || '[]')
- item.labelExpanded = true;
- });
- companyTotal.value = result.total;
- // 重置选中
- nowCheckCompany.value.companyID = "";
- setCompanyMarker(true);
- }
- // 地图初始化
- const initMap = () => {
- // 初始化容器
- map = new T.Map('mapDiv');
- if (map != null) {
- // 设置地图显示中心点为惠州市人民政府
- (map as any).centerAndZoom(centerLngLat, zoom);
- // 地图缩放监听事件
- (map as any).addEventListener("zoomend", function () {
- setCompanyMarker(false)
- });
- }
- // 设置城市边界
- setBoundary(map, T, huiZhouGeoJSON);
- // 设置登录用户的定位
- setLoginLocation();
- };
- // 设置中心点图标
- function setCenterIcon() {
- // 清除地图上的查询位置标记点
- (map as any).removeOverLay(userMarker);
- // 设置中心点
- (map as any).centerAndZoom(new T.LngLat(companySearchParam.longitude, companySearchParam.latitude), zoom);
- const icon = new T.Icon({
- iconUrl: redThIcon,
- iconSize: new T.Point(10, 10),
- iconAnchor: new T.Point(0, 5)
- })
- const point = new T.LngLat(companySearchParam.longitude, companySearchParam.latitude)
- // 创建标注
- userMarker = new T.Marker(point, {
- icon: icon
- });
- //向地图上标记
- (map as any).addOverLay(userMarker);
- }
- // 获取当前登录用户定位
- function setLoginLocation() {
- getPosition().then((data: any) => {
- if (data.longitude && data.latitude) {
- if (!companySearchParam.siteID) {
- companySearchParam.longitude = data.longitude;
- companySearchParam.latitude = data.latitude;
- }
- // 记录下来当前位置
- defaultLonLat.longitude = data.longitude;
- defaultLonLat.latitude = data.latitude;
- } else {
- // 如果没有获取到经纬度,设置默认为惠州市人民政府的位置
- if (!companySearchParam.siteID) {
- companySearchParam.longitude = 114.411771;
- companySearchParam.latitude = 23.113454;
- }
- message.info("获取定位失败,已使用默认定位");
- }
- }).finally(() => {
- setCenterIcon();
- onSearch();
- })
- }
- // 设置企业地图标点
- function setCompanyMarker(setCenter: boolean) {
- delMapInfo();
- if (setCenter) {
- // 设置中心点
- (map as any).centerAndZoom(new T.LngLat(companySearchParam.longitude, companySearchParam.latitude), zoom);
- }
- if (companyList.value.length > 0) {
- let zoomLevel = (map as any).getZoom();
- const sizeData = computeMarkerSize(zoomLevel);
- // 解析岗位数据,计算同一个企业标点的岗位信息
- let uniqueCompanyList = companyList.value;
- if (searchType.value == 'post') {
- // 岗位查询时,会出现多个岗位相同公司,按公司的ID去重
- const processedCompanyIDs = new Set();
- const companyIDCounts = {}; // 用于统计每个companyID的数量
- // 过滤出唯一的公司列表,并统计每个companyID的数量与岗位名称字段拼接
- uniqueCompanyList = companyList.value.filter((item: any) => {
- if (!processedCompanyIDs.has(item.companyID)) {
- processedCompanyIDs.add(item.companyID);
- companyIDCounts[item.companyID] = 1; // 初始化计数
- item.postNumber = 1; // 初始化postNumber
- companyPostWinHtml.value[item.companyID] = `
- <p style="margin: 5px 0;font-weight: 600">招聘岗位:</p>
- <div style="margin: 5px 0; cursor: pointer" onclick="checkCompanyChangeFun('${item.postID}', false)">${item.professionName}</div>
- `; // 初始化postName拼接
- return true;
- } else {
- companyIDCounts[item.companyID] += 1; // 增加计数
- companyPostWinHtml.value[item.companyID] += `
- <div style="margin: 5px 0; cursor: pointer" onclick="checkCompanyChangeFun('${item.postID}', false)">${item.professionName}</div>
- `; // 拼接postName
- return false;
- }
- });
- // 更新uniqueCompanyList中元素的postNumber
- uniqueCompanyList.forEach(item => {
- item.postNumber = companyIDCounts[item.companyID];
- item.postHtml = companyPostWinHtml.value[item.companyID];
- });
- }
- // 设置图标
- const icon_blue = new T.Icon({
- iconUrl: blueThIcon,
- iconSize: new T.Point(sizeData.iconSize, sizeData.iconSize),
- iconAnchor: sizeData.iconAnchor
- })
- const icon_red = new T.Icon({
- iconUrl: redThIcon3,
- iconSize: new T.Point(sizeData.iconSize, sizeData.iconSize),
- iconAnchor: sizeData.iconAnchor
- })
- // 解析企业数据,在地图中标记
- uniqueCompanyList.forEach((item: any) => {
- if (item.longitude && item.latitude) {
- const point = new T.LngLat(item.longitude, item.latitude)
- let marker = null;
- if (item.creditRecordCount == null) {
- marker = new T.Marker(point, {
- icon: icon_blue
- }); // 创建标注
- }
- if (item.creditRecordCount >= 1) {
- marker = new T.Marker(point, {
- icon: icon_red
- }); // 创建标注
- }
- let winHtml = "";
- if (searchType.value == 'company') {
- winHtml = `
- <div>
- <p style="font-size: 14px; font-weight: 600">${item.companyName}</p>
- <span style="line-height: 12px;">地址:${item.companyAddress}</span>
- <br>
- <span style="line-height: 12px;">岗位:${item.postList.length}个</span>
- </div>
- `;
- }
- if (searchType.value == 'post') {
- winHtml = `
- <div >
- <p style="font-size: 14px; font-weight: 600">${item.companyName}</p>
- ${item.postHtml}
- </div>
- `;
- }
- let markerInfoWin = new T.InfoWindow(winHtml, {
- autoPan: true,
- maxHeight: 300,
- maxWidth: 400,
- });
- // 添加鼠标经过事件
- marker.addEventListener('mouseover', () => {
- if (searchType.value == 'post') {
- (map as any).closeInfoWindow();
- }
- marker.openInfoWindow(markerInfoWin);
- });
- if (searchType.value == 'company') {
- // 给每个地图标点添加点击事件
- marker.addEventListener('click', () => {
- checkCompanyChange(item, true);
- });
- marker.addEventListener('mouseout', () => {
- marker.closeInfoWindow();
- });
- }
- (map as any).addOverLay(marker);// 将标注添加到地图中
- markerList.value.push(marker);
- }
- })
- // 如果是岗位,打上数量文本
- if (searchType.value == 'post') {
- uniqueCompanyList.forEach((item: any) => {
- if (item.longitude && item.latitude) {
- // 创建自定义的标签
- let label = new T.Label({
- text: item.postNumber + "", //文本标注的内容
- position: new T.LngLat(item.longitude, item.latitude), //文本标注的地理位置
- offset: sizeData.labelOffset, //文本标注的位置偏移值
- });
- label.setBackgroundColor("transparent");
- label.setBorderColor("transparent");
- label.setBorderLine(0);
- label.setFontSize(sizeData.fontSize);
- label.setFontColor("white");
- (map as any).addOverLay(label); // 将标注添加到地图中
- labelList.value.push(label);
- }
- })
- }
- }
- }
- // 天地图按缩放基本计算图标与文本的大小与锚点偏移值
- function computeMarkerSize(zoomLevel: any) {
- // 计算新的icon大小
- let newIconSize = Math.min(Math.max(zoomLevel * 2, 10), 15);
- // 计算新的icon锚点位置
- let iconAnchor = new T.Point(10 * (newIconSize / 15), 20 * (newIconSize / 15));
- // 计算新的偏移量,保持 label 居中且不超过初始值
- let offsetX = -15 + ((newIconSize - 15) / 2);
- let offsetY = 15 + ((newIconSize - 15) / 2);
- // 确保偏移量不超过初始值
- offsetX = Math.max(offsetX, -15);
- offsetY = Math.min(offsetY, 15);
- // 更新 label 的偏移量
- let newOffset = new T.Point(offsetX, offsetY);
- let fontSize = Math.min(12, Math.max(8, 12 - (15 - newIconSize) / 2))
- return {
- iconSize: newIconSize,
- iconAnchor,
- labelOffset: newOffset,
- fontSize
- }
- }
- // 企业分页器页码变更事件
- function companyPaginationChange() {
- onSearch()
- }
- // 企业信息点击事件
- const checkCompanyChange = async (company: any, funE: any) => {
- if (funE) {
- nowCheckCompany.value = JSON.parse(JSON.stringify(company));
- } else {
- const data = companyList.value.find(item => item.postID == company);
- if (data == null) {
- return;
- }
- nowCheckCompany.value = JSON.parse(JSON.stringify(data));
- }
- // 关闭地图上的其他信息弹窗
- (map as any).closeInfoWindow();
- // 设置中心点到企业位置
- if (company.longitude && company.latitude) {
- // 设置中心点
- (map as any).centerAndZoom(new T.LngLat(company.longitude, company.latitude), (map as any).getZoom());
- let winHtml = "";
- if (searchType.value == 'company') {
- winHtml = `
- <div>
- <p style="font-size: 14px; font-weight: 600">${company.companyName}</p>
- <span style="line-height: 12px;">地址:${company.companyAddress}</span>
- <br>
- <span style="line-height: 12px;">岗位:${company.postList.length}个</span>
- </div>
- `;
- }
- if (searchType.value == 'post') {
- winHtml = `
- <div >
- <p style="font-size: 14px; font-weight: 600">${company.companyName}</p>
- ${companyPostWinHtml.value[nowCheckCompany.value.companyID]}
- </div>
- `;
- }
- (map as any).openInfoWindow(winHtml, new T.LngLat(company.longitude, company.latitude), {
- autoPan: true,
- maxHeight: 300,
- maxWidth: 400,
- offset: new T.Point(-5, -15)
- });
- }
- await findPostList();
- }
- // 企业信息鼠标移入移出事件
- function companyMouseenter(company: any) {
- nowMouseenterCompany.value = JSON.parse(JSON.stringify(company));
- }
- // 查询岗位
- async function findPostList() {
- await getCompanyMapPostList({...postSearchParams, companyID: nowCheckCompany.value.companyID}).then((result: any) => {
- postList.value = result.list;
- // 处理标签JSON数据
- postList.value.forEach((item: any) => {
- item.labelList = JSON.parse(item.labelList || '[]');
- item.labelExpanded = true;
- item.descExpanded = true;
- })
- postTotal.value = result.total;
- })
- }
- // 企业分页器页码变更事件
- function postPaginationChange() {
- findPostList();
- }
- // 岗位薪酬优化显示
- const showSalary = (minSalary: any, maxSalary: any) => {
- if (minSalary != null) {
- if (maxSalary != null) {
- return (minSalary / 1000).toString() + "-" + (maxSalary / 1000).toString() + 'K';
- } else {
- return "≥" + (minSalary / 1000).toString() + "K";
- }
- } else {
- if (maxSalary != null) {
- return "≤" + (maxSalary / 1000).toString() + "K";
- } else {
- return "";
- }
- }
- }
- // 企业标签,岗位标签等的展开与收起按钮是否显示判断方法
- function showLaunchBtnBox(refValue: any, index: any, scrollHeight: any) {
- if (index != null) {
- if (refValue[index] && refValue[index].scrollHeight) {
- return refValue[index]?.scrollHeight > scrollHeight
- }
- return false;
- } else {
- if (refValue && refValue.scrollHeight) {
- return refValue?.scrollHeight > scrollHeight
- }
- return false;
- }
- }
- // 查询类型切换事件
- function searchTypeChange() {
- // 清空选中数据
- nowCheckCompany.value = {companyID: null};
- // 清空地图数据
- delMapInfo();
- onSearch();
- }
- // 清空地图标点
- function delMapInfo() {
- // 删除已有标点
- if (markerList.value.length > 0) {
- for (let i = 0; i < markerList.value.length; i++) {
- (map as any).removeOverLay(markerList.value[i]);
- }
- markerList.value = [];
- }
- if (labelList.value.length > 0) {
- for (let i = 0; i < labelList.value.length; i++) {
- (map as any).removeOverLay(labelList.value[i]);
- }
- labelList.value = [];
- }
- (map as any).closeInfoWindow();
- }
- function regionCodeChange() {
- if (companySearchParam.regionCode) {
- getSiteList({pageIndex: 1, pageSize: 9999, regionCode: companySearchParam.regionCode}).then((result: any) => {
- siteList.value = result.list;
- })
- } else {
- siteList.value = [];
- }
- onSearch();
- }
- function siteChange() {
- if (companySearchParam.siteID) {
- getSiteByID(companySearchParam.siteID).then((result: any) => {
- // 设置查询的中心点为驿站的经纬度
- if (result.siteLongitude && result.siteLatitude) {
- companySearchParam.longitude = result.siteLongitude;
- companySearchParam.latitude = result.siteLatitude;
- setCenterIcon();
- }
- }).finally(() => {
- onSearch();
- })
- } else {
- // 未选择驿站时恢复默认位置
- companySearchParam.longitude = defaultLonLat.longitude;
- companySearchParam.latitude = defaultLonLat.latitude;
- setCenterIcon();
- onSearch();
- }
- }
- onMounted(() => {
- initMap();
- getCompanyModelList();
- getRegionList();
- (window as any).checkCompanyChangeFun = checkCompanyChange;
- })
- </script>
- <script lang="ts">
- // 设置页面名称进行组件缓存
- export default {
- name: "CompanyDataMap"
- }
- </script>
- <style lang="less">
- .map-box {
- width: 100vw;
- height: 100vh;
- position: relative;
- border: 1px rgba(173, 173, 173, 0.8) solid;
- box-sizing: border-box;
- #mapDiv {
- position: absolute;
- width: 100%;
- height: 100%;
- z-index: 100;
- }
- .company-box, .post-box {
- position: absolute;
- top: 15px;
- bottom: 15px;
- z-index: 110;
- }
- .company-name, .post-title {
- font-size: 14px;
- font-weight: 600;
- margin-bottom: 8px;
- .post-salary {
- font-size: 12px;
- font-weight: normal;
- color: #DE4F3F;
- }
- }
- .label-text {
- font-size: 12px;
- color: #737373;
- margin-bottom: 3px;
- }
- .company-label-box {
- display: flex;
- align-items: center;
- flex-wrap: wrap;
- margin-top: 5px;
- overflow: hidden;
- position: relative;
- .ant-tag {
- margin-bottom: 3px;
- }
- }
- .label-box-max-height {
- max-height: 23px;
- }
- .ant-tag {
- text-align: center;
- overflow: hidden;
- text-overflow: ellipsis;
- white-space: nowrap;
- border: none;
- background-color: #F3F6F8;
- color: #899099
- }
- .search-box,
- .list-box,
- .pagination-box {
- width: 100%;
- }
- .list-box {
- margin-bottom: 10px;
- overflow-y: auto;
- }
- .pagination-box {
- display: flex;
- justify-content: center;
- align-items: center;
- }
- .launch-btn {
- font-size: 12px;
- color: #40a9ff;
- position: absolute;
- bottom: 4px;
- right: 0;
- cursor: pointer;
- }
- .empty-box {
- width: 100%;
- height: 450px;
- display: flex;
- justify-content: center;
- align-items: center;
- }
- .post-title {
- display: flex;
- justify-content: space-between;
- flex-wrap: wrap;
- }
- .search-input-box {
- margin-bottom: 10px;
- width: 100%;
- }
- .company-box {
- left: 15px;
- bottom: 5px;
- right: 300px;
- width: 330px;
- .select-data-box {
- width: 100%;
- height: calc(100% - 85px);
- background-color: #F8F8F8;
- padding: 10px 9px;
- border-radius: 10px 10px 0 0;
- .select-box {
- display: flex;
- flex-wrap: wrap;
- width: 100%;
- padding: 8px 5px;
- background-color: white;
- border-radius: 10px;
- }
- .list-box {
- max-height: calc(100% - 95px);
- margin-top: 10px;
- .company-data-box {
- background-color: white;
- border-radius: 10px;
- cursor: pointer;
- padding: 10px;
- margin-bottom: 10px;
- box-shadow: 0 5px 5px -5px rgba(0, 0, 0, 0.3);
- box-sizing: border-box;
- border: 1px solid white;
- .company-post-box {
- width: 100%;
- display: flex;
- flex-wrap: nowrap;
- align-items: center;
- .ant-tag {
- flex: 1 1 auto;
- min-width: 0;
- max-width: fit-content;
- }
- .all-post-btn {
- cursor: pointer;
- }
- }
- }
- .check-company {
- border: 1px solid #007EFF;
- }
- .check-company-red {
- border: 1px solid red;
- }
- }
- }
- .pagination-box {
- background-color: #F8F8F8;
- padding: 8px 0;
- border-radius: 0 0 12px 12px;
- }
- }
- .post-box {
- width: 330px;
- left: calc(100% - 345px);
- right: 0;
- border-radius: 10px;
- .company-info-post-list {
- width: 100%;
- height: 100%;
- background-color: #F8F8F8;
- border-radius: 10px;
- padding: 10px;
- }
- .title {
- text-align: center;
- margin-top: 8px;
- }
- .post-company-box {
- background-color: white;
- padding: 18px;
- width: 100%;
- max-height: 185px;
- overflow-y: auto;
- border-radius: 10px;
- .post-title {
- font-size: 18px;
- justify-content: normal;
- align-items: center;
- margin-bottom: 10px;
- .post-salary {
- font-size: 18px;
- margin-left: 20px;
- }
- }
- .company-contact-info {
- margin: 20px 0;
- border-top: 1px solid rgba(0, 0, 0, 0.1);
- border-bottom: 1px solid rgba(0, 0, 0, 0.1);
- padding: 18px 0;
- .avt-info {
- display: flex;
- align-items: center;
- img {
- width: 36px;
- height: 36px;
- margin-right: 10px;
- }
- .contact-name {
- font-size: 14px;
- color: #292934;
- }
- .contact-mobile {
- font-size: 12px;
- color: #6A6F75;
- }
- }
- }
- .post-desc {
- white-space: pre-wrap;
- margin-bottom: 14px;
- }
- }
- .list-box {
- height: calc(100% - 260px);
- .list-post-box {
- padding: 8px;
- background-color: white;
- border-radius: 10px;
- box-shadow: 0 5px 5px -5px rgba(0, 0, 0, 0.3);
- .post-desc-box {
- position: relative;
- .launch-btn {
- bottom: -1px;
- background-color: white;
- }
- .post-desc {
- overflow: hidden;
- width: 91%;
- }
- .post-desc-max-height {
- max-height: 35px;
- }
- }
- }
- .empty-box {
- height: 100%;
- }
- }
- .pagination-box {
- background-color: white;
- padding: 8px 0;
- border-radius: 12px;
- }
- }
- .ant-btn, .ant-input {
- border: none !important;
- }
- input {
- height: 32px;
- }
- .ant-select:not(.ant-select-customize-input) .ant-select-selector,
- .ant-select:not(.ant-select-customize-input) .ant-select-selector,
- .ant-input-affix-wrapper, .ant-select-selector {
- border: none !important;
- box-shadow: none !important;
- }
- .ant-select:not(.ant-select-disabled).ant-select:not(.ant-select-customize-input)
- .ant-select-selector {
- border-color: transparent;
- box-shadow: none;
- }
- }
- </style>
|