Browse Source

Merge remote-tracking branch 'origin/master'

# Conflicts:
#	h5app/src/views/pages/jobhunt/edit.vue
liao-sea 9 months ago
parent
commit
c9017b8337

+ 9 - 1
h5app/src/views/pages/jobUserInfo/userEdit.vue

@@ -334,6 +334,13 @@
                               placeholder="请输入个人技能" v-model="baseData.personalSkills"
                               style="border-bottom: 1px solid #fff2e8;"></ion-textarea>
               </div>
+              <div class="form-input">
+                <ion-label>
+                  图片上传
+                </ion-label>
+                <b-image v-if="baseData.jobUserID" :file-ref-id="baseData.jobUserID" :readonly="false"
+                         :is-single="false"></b-image>
+              </div>
             </div>
           </ion-list>
 
@@ -487,6 +494,7 @@ import dayjs from "dayjs";
 import CategorySelection from "@/components/ocCategorySelection.vue";
 import {getPosition} from "@/utils/position";
 import crtyptoHelp from "@/utils/crypto"
+import BImage from "@/components/bImage.vue";
 
 interface SelectProps {
   name: string,
@@ -498,7 +506,7 @@ interface StepParams{
 }
 export default defineComponent({
   name: "jobUserInfoEdit",
-  components:{CategorySelection},
+  components: {BImage, CategorySelection},
   setup() {
     const route = useRoute();
     const router = useRouter();

+ 9 - 2
h5app/src/views/pages/jobhunt/edit.vue

@@ -340,6 +340,13 @@
               </ion-col>
             </ion-row>
           </div>
+          <div class="form-input">
+            <ion-label>
+              图片上传
+            </ion-label>
+            <b-image v-if="baseData.jobUserID" :file-ref-id="baseData.jobUserID" :readonly="false"
+                     :is-single="false"></b-image>
+          </div>
         </div>
       </ion-list>
 
@@ -497,7 +504,7 @@ import CategorySelection from "@/components/ocCategorySelection.vue";
 import {getPosition} from "@/utils/position";
 import LabelSelection from "@/components/labelSelection.vue";
 import crtyptoHelp from "@/utils/crypto";
-import {Datetime} from "@ionic/core/dist/types/components/datetime/datetime";
+import BImage from "@/components/bImage.vue";
 
 interface SelectProps {
   name: string,
@@ -509,7 +516,7 @@ interface StepParams{
 }
 export default defineComponent({
   name: 'jobUserEdit',
-  components:{CategorySelection, LabelSelection},
+  components: {BImage, CategorySelection, LabelSelection},
   setup() {
     const router = useRouter();
     const route = useRoute();

+ 9 - 0
src/main/java/com/hz/employmentsite/controller/baseSettings/SiteInfoController.java

@@ -129,4 +129,13 @@ public class SiteInfoController {
         return RespGenerstor.success(result);
     }
 
+    @GetMapping("/dataMap")
+    public BaseResponse<PageInfo<SiteInfoVo>> getDataMapList(@RequestParam("pageIndex") int pageIndex, @RequestParam("pageSize") int pageSize,
+                                                             @RequestParam(required = false) String siteName, @RequestParam(required = false) String regionCode,
+                                                             @RequestParam(required = false) String streetCode) {
+
+        PageInfo<SiteInfoVo> result = siteInfoService.getDataMapList(pageIndex, pageSize, siteName, regionCode, streetCode);
+        return RespGenerstor.success(result);
+    }
+
 }

+ 3 - 0
src/main/java/com/hz/employmentsite/mapper/cquery/SiteInfoCQuery.java

@@ -17,4 +17,7 @@ public interface SiteInfoCQuery {
      * 查询驿站的登记企业、岗位、求职者数量
      */
     Map<String, Object> findSiteDataCount(@Param("siteID") String siteID);
+
+    List<SiteInfoVo> getDataMapList(@Param("siteName") String siteName, @Param("regionCode") String regionCode,
+                                    @Param("streetCode") String streetCode);
 }

+ 8 - 0
src/main/java/com/hz/employmentsite/services/impl/baseSettings/SiteInfoImpl.java

@@ -217,4 +217,12 @@ public class SiteInfoImpl implements SiteInfoService {
     public Map<String, Object> findSiteDataCount(String siteID) {
         return siteInfoCQuery.findSiteDataCount(siteID);
     }
+
+    @Override
+    public PageInfo<SiteInfoVo> getDataMapList(int pageIndex, int pageSize, String siteName, String regionCode, String streetCode) {
+        PageHelper.startPage(pageIndex, pageSize);
+        List<SiteInfoVo> dataList = siteInfoCQuery.getDataMapList(siteName, regionCode, streetCode);
+        PageInfo<SiteInfoVo> result = new PageInfo(dataList);
+        return result;
+    }
 }

+ 2 - 0
src/main/java/com/hz/employmentsite/services/service/baseSettings/SiteInfoService.java

@@ -30,4 +30,6 @@ public interface SiteInfoService {
     Integer delete(List<String> idList);
 
     Map<String, Object> findSiteDataCount(String siteID);
+
+    PageInfo<SiteInfoVo> getDataMapList(int pageIndex, int pageSize, String siteName, String regionCode, String streetCode);
 }

+ 6 - 0
src/main/java/com/hz/employmentsite/vo/dataMap/JobUserMapVo.java

@@ -16,6 +16,12 @@ public class JobUserMapVo {
 
     private String latitude;
 
+    private String siteName;
+
+    private int recommendedCount;
+
+    private Integer entryState;
+
     // JSON格式的列表数据
     private String labelList;
     private String jobHuntList;

+ 2 - 3
src/main/resources/mapping/cquery/CompanyCQuery.xml

@@ -138,7 +138,7 @@
             distance <![CDATA[ <= ]]> #{maxDistance}
         </if>
         ORDER BY
-        distance
+        Longitude DESC, Latitude DESC, distance DESC
     </select>
 
     <select id="getDataMapListByPostName" resultType="com.hz.employmentsite.vo.dataMap.CompanyPostMapVo">
@@ -206,7 +206,6 @@
             distance <![CDATA[ <= ]]> #{maxDistance}
         </if>
         ORDER BY
-        distance,
-        CompanyID
+        Longitude DESC, Latitude DESC, distance DESC, CompanyID
     </select>
 </mapper>

+ 41 - 7
src/main/resources/mapping/cquery/JobUserCQuery.xml

@@ -46,11 +46,16 @@
         left join pc_site_institution inSites on site.SiteID = inSites.SiteID
         left join pc_institution institution on inSites.institutionID = institution.InstitutionID
         left join sys_user modifyUser on jobuser.ModifyUserID = modifyUser.UserID
-        left join (SELECT job_user.JobUserID, count( 1 ) AS RecommendedCount
-                   FROM pc_recommend_mgt mgt
-                   LEFT JOIN pc_jobhunt hunt ON mgt.JobHuntID = hunt.JobHuntID
-                   LEFT JOIN pc_jobuser job_user ON job_user.JobUserID = job_user.JobuserID
-                   GROUP BY job_user.JobUserID
+        left join (
+            SELECT
+                job_user.JobUserID,
+                COUNT(mgt.JobHuntID) AS RecommendedCount
+            FROM
+                pc_jobuser job_user
+                LEFT JOIN pc_jobhunt hunt ON job_user.JobUserID = hunt.JobUserID
+                LEFT JOIN pc_recommend_mgt mgt ON hunt.JobHuntID = mgt.JobHuntID
+            GROUP BY
+                job_user.JobUserID
         ) recommendCountData on recommendCountData.JobUserID = jobuser.JobUserID
         left join (select JobUserID, count(1) as jobHuntCount from pc_jobhunt jobhunt group by JobUserID) jobhuntCountData on jobhuntCountData.JobUserID = jobuser.JobUserID
         where 1=1
@@ -119,6 +124,9 @@
                     CURRENT_DATE ()) AS age,
             jobuser.Longitude,
             jobuser.Latitude,
+            site.SiteName,
+            recommendCountData.RecommendedCount,
+            mgtEntryState.EntryState,
             (
                 SELECT
                     JSON_ARRAYAGG( JSON_OBJECT( 'professionID', jobHuntTemp.ProfessionID, 'professionName', jobHuntTemp.ProfessionName ) )
@@ -152,8 +160,32 @@
             ) AS labelList
         FROM
             pc_jobuser jobuser
-                LEFT JOIN sys_dictionary_item keytype ON jobuser.KeyPersonTypeID = keytype.`Value`
-                AND keytype.DictionaryCode = 'KeyPersonType'
+            LEFT JOIN sys_dictionary_item keytype ON jobuser.KeyPersonTypeID = keytype.`Value`
+            AND keytype.DictionaryCode = 'KeyPersonType'
+            LEFT JOIN pc_site site ON jobuser.SiteID = site.SiteID
+            LEFT JOIN (
+                SELECT
+                    job_user.JobUserID,
+                    COUNT( mgt.JobHuntID ) AS RecommendedCount
+                FROM
+                    pc_jobuser job_user
+                LEFT JOIN pc_jobhunt hunt ON job_user.JobUserID = hunt.JobUserID
+                LEFT JOIN pc_recommend_mgt mgt ON hunt.JobHuntID = mgt.JobHuntID
+                GROUP BY
+                    job_user.JobUserID
+            ) recommendCountData ON recommendCountData.JobUserID = jobuser.JobUserID
+            LEFT JOIN (
+                SELECT
+                    job_user.JobUserID,
+                    mgt.EntryState
+                FROM
+                    pc_jobuser job_user
+                LEFT JOIN pc_jobhunt hunt ON job_user.JobUserID = hunt.JobUserID
+                LEFT JOIN pc_recommend_mgt mgt ON hunt.JobHuntID = mgt.JobHuntID
+                AND mgt.EntryState = 1
+                GROUP BY
+                    job_user.JobUserID
+            ) mgtEntryState ON mgtEntryState.JobUserID = jobuser.JobUserID
         WHERE 1=1
         <if test="keyTypeValue != null">
             and keytype.`Value` = #{keyTypeValue}
@@ -204,6 +236,8 @@
             jobuser.BirthDay,
             CURRENT_DATE ()) <![CDATA[ <= ]]> #{maxAge}
         </if>
+        ORDER BY
+        Longitude DESC, Latitude DESC
     </select>
     <select id="getJobUserDataList" resultType="com.hz.employmentsite.vo.jobUserManager.JobUserVo">
         select  jobUserID,name,userMobile  from pc_jobuser jobuser

+ 58 - 2
src/main/resources/mapping/cquery/SiteInfoCQuery.xml

@@ -4,8 +4,7 @@
     <select id="getList" resultType="com.hz.employmentsite.vo.baseSettings.SiteInfoVo">
         select site.*,inSites.InstitutionID as InstitutionID,inSites.SiteInstitutionID,institution.companyName as
         InstitutionName,
-        (select GROUP_CONCAT(SiteUserName SEPARATOR ',') from pc_site_user siteUser where SiteID = site.siteID ) AS
-        siteUsers,
+        siteUserStr.siteUsers,
         ModifyUser.Name as modifyUserName,
         region.name as RegionName,street.name as StreetName from pc_site site
         left join pc_site_institution inSites on site.SiteID = inSites.SiteID
@@ -13,6 +12,19 @@
         left join area_code region on site.RegionCode = region.code
         left join area_code street on site.StreetCode = street.code
         left join sys_user ModifyUser on site.ModifyUserID = ModifyUser.UserID
+        LEFT JOIN (
+            SELECT
+                siteTemp.siteID,
+                GROUP_CONCAT( SiteUserName SEPARATOR ',' ) AS siteUsers
+            FROM
+                pc_site_user siteUser
+            LEFT JOIN sys_user sysUser ON siteUser.UserID = sysUser.UserID
+            LEFT JOIN pc_site siteTemp ON siteTemp.SiteID = siteUser.SiteID
+            WHERE
+                sysUser.RecordStatus = 1
+            GROUP BY
+                siteTemp.SiteID
+        ) siteUserStr ON siteUserStr.SiteID = site.SiteID
         where 1=1
         <if test="siteIDList!='' and siteIDList!=null">
             and site.siteID in (${siteIDList})
@@ -49,4 +61,48 @@
             (SELECT COUNT(1) FROM pc_post post LEFT JOIN pc_company company ON post.CompanyID = company.CompanyID WHERE SiteID = #{siteID}) AS postCount,
             (SELECT COUNT(1) FROM pc_jobuser WHERE SiteID = #{siteID}) AS jobUserCount;
     </select>
+
+    <select id="getDataMapList" resultType="com.hz.employmentsite.vo.baseSettings.SiteInfoVo">
+        SELECT
+            site.SiteID,
+            site.SiteCode,
+            site.SiteName,
+            site.DetailAddress,
+            site.FzrName,
+            site.FzrMobile,
+            site.SiteLongitude,
+            site.SiteLatitude,
+            region.`name` AS RegionName,
+            street.`name` AS StreetName,
+            siteUserStr.siteUsers
+        FROM
+            pc_site site
+                LEFT JOIN pc_site_institution inSites ON site.SiteID = inSites.SiteID
+                LEFT JOIN area_code region ON site.RegionCode = region.`CODE`
+                LEFT JOIN area_code street ON site.StreetCode = street.`CODE`
+                LEFT JOIN (
+                SELECT
+                    siteTemp.siteID,
+                    GROUP_CONCAT( SiteUserName SEPARATOR ',' ) AS siteUsers
+                FROM
+                    pc_site_user siteUser
+                        LEFT JOIN sys_user sysUser ON siteUser.UserID = sysUser.UserID
+                        LEFT JOIN pc_site siteTemp ON siteTemp.SiteID = siteUser.SiteID
+                WHERE
+                    sysUser.RecordStatus = 1
+                GROUP BY
+                    siteTemp.SiteID
+            ) siteUserStr ON siteUserStr.SiteID = site.SiteID
+        where 1=1
+        <if test="siteName!='' and siteName!=null">
+            and siteName like Concat('%',#{siteName},'%')
+        </if>
+        <if test="regionCode!='' and regionCode!=null">
+            and regionCode like Concat('%',#{regionCode},'%')
+        </if>
+        <if test="streetCode!='' and streetCode!=null">
+            and streetCode like Concat('%',#{streetCode},'%')
+        </if>
+        order by site.SiteLongitude desc, site.SiteLatitude DESC
+    </select>
 </mapper>

+ 2 - 0
src/main/resources/mapping/cquery/SiteUserCQuery.xml

@@ -130,6 +130,8 @@
         <if test="streetCode!='' and streetCode!=null">
             and site.streetCode = #{streetCode}
         </if>
+        ORDER BY
+        Longitude DESC, Latitude DESC, SiteLongitude DESC, SiteLatitude DESC
     </select>
 
     <select id="findUserDataCount" resultType="Map">

+ 13 - 0
vue/src/api/baseSettings/siteInfo.ts

@@ -113,3 +113,16 @@ export function findSiteDataCount(siteID: string) {
     },
   );
 }
+
+export function getDataMapList(params: any) {
+  return request<object>(
+    {
+      url: "siteInfo/dataMap",
+      method: 'get',
+      params: params,
+    },
+    {
+      isNew: true,
+    },
+  );
+}

+ 5 - 4
vue/src/views/dataMap/companyDataMap.vue

@@ -158,7 +158,7 @@
         <div class="pagination-box">
           <span>共{{ companyTotal }}{{ searchType == 'company' ? '家' : '个' }}</span>
           <a-pagination v-model:current="companySearchParam.pageIndex" :total="companyTotal"
-                        v-model:pageSize="companySearchParam.pageSize"
+                        v-model:pageSize="companySearchParam.pageSize" :disabled="searchLoading"
                         show-less-items @change="companyPaginationChange" simple :show-size-changer="false"/>
         </div>
       </div>
@@ -670,7 +670,6 @@ function companyPaginationChange() {
 
 // 企业信息点击事件
 const checkCompanyChange = async (company: any, funE: any) => {
-  console.log(company)
   if (funE) {
     nowCheckCompany.value = JSON.parse(JSON.stringify(company));
   } else {
@@ -680,10 +679,12 @@ const checkCompanyChange = async (company: any, funE: any) => {
     }
     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), 14);
+    (map as any).centerAndZoom(new T.LngLat(company.longitude, company.latitude), (map as any).getZoom());
     let winHtml = "";
     if (searchType.value == 'company') {
       winHtml = `
@@ -707,7 +708,7 @@ const checkCompanyChange = async (company: any, funE: any) => {
       autoPan: true,
       maxHeight: 300,
       maxWidth: 400,
-      offset: new T.Point(10, -10)
+      offset: new T.Point(10, 0)
     });
   }
   await findPostList();

+ 290 - 127
vue/src/views/dataMap/jobUserDataMap.vue

@@ -86,9 +86,11 @@
               <div class="label-box" v-if="jobUser.labelList.length > 0"
                    :ref="el => jobUserLabelBoxRef[jobUserIndex] = el"
                    :class="{'label-box-max-height': jobUser.labelExpanded}">
-                <a-tag v-for="(label, labelIndex) in jobUser.labelList" :key="labelIndex">
-                  {{ label.labelName }}
-                </a-tag>
+                <div class="tag-box">
+                  <a-tag v-for="(label, labelIndex) in jobUser.labelList" :key="labelIndex">
+                    {{ label.labelName }}
+                  </a-tag>
+                </div>
                 <div v-if="showLaunchBtnBox(jobUserLabelBoxRef,jobUserIndex,40)">
                 <span class="launch-btn" v-if="jobUser.labelExpanded"
                       @click.stop="jobUser.labelExpanded = false">展开</span>
@@ -98,17 +100,66 @@
             </div>
           </div>
           <div v-else class="empty-box">
-            <a-empty/>
+            <a-empty description="暂无求职人员"/>
           </div>
         </div>
         <!-- 分页控件 -->
         <div class="pagination-box">
           <span>共{{ jobUserTotal }}人</span>
           <a-pagination v-model:current="searchParams.pageIndex" :total="jobUserTotal"
-                        v-model:pageSize="searchParams.pageSize"
+                        v-model:pageSize="searchParams.pageSize" :disabled="searchLoading"
                         show-less-items @change="onSearch" simple :show-size-changer="false"/>
         </div>
       </div>
+      <!-- 右侧数据详情内容 -->
+      <div v-if="nowCheckJobUser.jobUserID" class="right-data-box">
+        <!-- 求助人员信息 -->
+        <div class="jobUser-data-box margin-bottom-10">
+          <p class="font-size-14 font-weight-600 margin-bottom-8">
+            {{ nowCheckJobUser.name }}
+          </p>
+          <p class="label-text">年龄:{{ nowCheckJobUser.age }}岁</p>
+          <p class="label-text">重点人员类别:{{ nowCheckJobUser.keyTypeName }}</p>
+          <p class="label-text">已推荐岗位数量:{{ nowCheckJobUser.recommendedCount }}个</p>
+          <p class="label-text">入职情况:{{ nowCheckJobUser.entryState == 1 ? '已入职' : '未入职' }}</p>
+          <!-- 标签 -->
+          <div class="label-box" v-if="nowCheckJobUser.labelList.length > 0"
+               :ref="el => nowCheckJobUserLabelBoxRef = el"
+               :class="{'label-box-max-height': nowCheckJobUserLabelExpanded}">
+            <div class="tag-box">
+              <a-tag v-for="(label, labelIndex) in nowCheckJobUser.labelList" :key="labelIndex">
+                {{ label.labelName }}
+              </a-tag>
+            </div>
+            <div v-if="showLaunchBtnBox(nowCheckJobUserLabelBoxRef,null,40)">
+                <span class="launch-btn" v-if="nowCheckJobUserLabelExpanded"
+                      @click.stop="nowCheckJobUserLabelExpanded = false">展开</span>
+              <span class="launch-btn" v-else @click.stop="nowCheckJobUserLabelExpanded = true">收起</span>
+            </div>
+          </div>
+        </div>
+        <!-- 求助意向列表 -->
+        <div v-if="jobHuntList.length > 0" class="jobHunt-list-box">
+          <div class="jobHunt-box" v-for="(jobHunt, jobHuntIndex) in jobHuntList" :key="jobHuntIndex">
+            <div class="jobHunt-title">
+              <span class="font-weight-700">{{ jobHunt.professionName }}</span>
+              <span class="jobHunt-salary">{{ showSalary(jobHunt.minSalary, jobHunt.maxSalary) }}</span>
+            </div>
+            <p class="label-text">求职类型:{{ jobHunt.jobHuntTypeStr }}</p>
+            <p class="label-text">可到职日期:{{ dayjs(jobHunt.inDate).format("YYYY-MM-DD") }}</p>
+          </div>
+        </div>
+        <div v-else class="empty-box">
+          <a-empty description="暂无求职意向"/>
+        </div>
+        <!-- 分页控件 -->
+        <div class="pagination-box">
+          <span>共{{ jobHuntTotal }}个</span>
+          <a-pagination v-model:current="jobHuntSearchParams.pageIndex" :total="jobHuntTotal"
+                        v-model:pageSize="jobHuntSearchParams.pageSize"
+                        show-less-items @change="jobHuntPaginationChange" simple :show-size-changer="false"/>
+        </div>
+      </div>
     </div>
   </div>
 </template>
@@ -123,6 +174,8 @@ import {getRegionCodeList} from "@/api/system/area/index";
 import {getSysDictionaryList} from "@/api/system/dictionary";
 import {getDataMapList} from "@/api/jobUserManager/jobuser";
 import thIcon from "@/assets/images/blueTh.png"
+import {getJobHuntList} from "@/api/jobUserManager/jobhunt";
+import dayjs from "dayjs";
 
 const T = (window as any).T;
 const zoom = 9;
@@ -132,9 +185,6 @@ const centerLngLat = new T.LngLat(114.416110, 23.111582);
 // 地图标记点
 let markerList = ref<Array<any>>([]);
 let labelList = ref<Array<any>>([]);
-let labelNumberCount = ref(0);
-const jobUserCountMarker = ref<any>(null)
-const jobUserCountLabel = ref<any>(null)
 
 const searchParams = reactive({
   pageIndex: 1,
@@ -145,10 +195,19 @@ const searchParams = reactive({
   regionCode: null,
   labelID: null
 })
+const jobHuntSearchParams = reactive({
+  pageIndex: 1,
+  pageSize: 100,
+  jobUserID: "",
+})
 // 求职人员数据
 const jobUserList = ref<Array<any>>([])
 // 求职人员数据总条数
 const jobUserTotal = ref(0)
+// 选择的求职人员的求助意向
+const jobHuntList = ref<Array<any>>([])
+// 求助意向数据总条数
+const jobHuntTotal = ref(0)
 
 // 求职人员标签
 const jobUserLabelDicList = ref<Array<any>>([]);
@@ -164,6 +223,10 @@ const nowCheckJobUser = ref<any>({})
 const nowMouseenterJobUser = ref<any>({});
 // 求职人员标签div ref
 const jobUserLabelBoxRef = ref<Array<any>>([]);
+// 右侧求职人员详情的标签盒子ref
+const nowCheckJobUserLabelBoxRef = ref<any>(null);
+// 右侧求职人员详情的标签展开与收起开关
+const nowCheckJobUserLabelExpanded = ref(true)
 
 // 查询求职人员标签字典
 function getJobUserLabelDicList() {
@@ -186,6 +249,9 @@ const getKeyPersonTypeList = () => {
 
 // 求职人员查询
 function onSearch() {
+  // 清空选择数据
+  nowCheckJobUser.value.jobUserID = false;
+
   searchLoading.value = true;
   getDataMapList(searchParams).then((result: any) => {
     jobUserList.value = result.list;
@@ -197,7 +263,7 @@ function onSearch() {
       item.labelExpanded = true;
     })
 
-    setMapMarker();
+    setMapMarker(true);
   }).finally(() => {
     searchLoading.value = false;
   })
@@ -210,85 +276,44 @@ const initMap = () => {
   if (map != null) {
     // 设置地图显示中心点为惠州市人民政府
     (map as any).centerAndZoom(centerLngLat, zoom);
-    (map as any).setMinZoom(7);
+    (map as any).setMinZoom(5);
     (map as any).setMaxZoom(14);
 
     // 地图缩放监听事件
     (map as any).addEventListener("zoomend", function () {
-      let zoomLevel = (map as any).getZoom();
-      console.log(zoomLevel);
-      const sizeData = computeMarkerSize(zoomLevel);
-      console.log(sizeData)
-
-      if (zoomLevel <= 9) {
-        // 删除小标点
-        markerList.value.forEach((item: any) => {
-          (map as any).removeOverLay(item);
-        });
-        labelList.value.forEach((item: any) => {
-          (map as any).removeOverLay(item);
-        });
-        if (jobUserCountMarker.value != null) {
-          // 显示总数标点
-          jobUserCountMarker.value.getIcon().setIconSize(new T.Point(sizeData.iconSize, sizeData.iconSize));
-          jobUserCountMarker.value.getIcon().setIconAnchor(sizeData.iconAnchor);
-          (map as any).addOverLay(jobUserCountMarker.value);
-          jobUserCountLabel.value.setOffset(sizeData.labelOffset);
-          jobUserCountLabel.value.setFontSize(sizeData.fontSize);
-          (map as any).addOverLay(jobUserCountLabel.value);
-        }
-      } else {
-        // 删除总数标点
-        (map as any).removeOverLay(jobUserCountMarker.value);
-        (map as any).removeOverLay(jobUserCountLabel.value);
-
-        markerList.value.forEach((item: any) => {
-          (map as any).removeOverLay(item);
-          item.getIcon().setIconSize(new T.Point(sizeData.iconSize, sizeData.iconSize));
-          item.getIcon().setIconAnchor(sizeData.iconAnchor);
-          (map as any).addOverLay(item);
-        })
-        labelList.value.forEach((item: any) => {
-          (map as any).removeOverLay(item);
-          item.setOffset(sizeData.labelOffset);
-          item.setFontSize(sizeData.fontSize);
-          (map as any).addOverLay(item);
-        })
-      }
+      setMapMarker(false);
     });
   }
   // 设置城市边界
   setBoundary(map, T, huiZhouGeoJSON);
 };
 
-// 设置标点
-function setMapMarker() {
+// 清空地图标点
+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 = []
+    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 = []
-  }
-  if (jobUserCountMarker.value) {
-    (map as any).removeOverLay(jobUserCountMarker.value);
+    labelList.value = [];
   }
-  if (jobUserCountLabel.value) {
-    (map as any).removeOverLay(jobUserCountLabel.value);
-  }
-  jobUserCountMarker.value = null;
-  jobUserCountLabel.value = null;
-  // 重置总数
-  labelNumberCount.value = 0;
+  (map as any).closeInfoWindow();
+}
+
+// 设置标点
+function setMapMarker(setCenter: boolean) {
+  delMapInfo();
 
   // 设置中心点
-  (map as any).centerAndZoom(centerLngLat, zoom);
+  if (setCenter) {
+    (map as any).centerAndZoom(centerLngLat, zoom);
+  }
 
   if (jobUserList.value.length > 0) {
     let zoomLevel = (map as any).getZoom();
@@ -308,37 +333,20 @@ function setMapMarker() {
       if (item.longitude && item.latitude) {
         const key = `${item.longitude},${item.latitude}`;
         if (!pointCountMap.has(key)) {
-          pointCountMap.set(key, {count: 0, data: item});
+          pointCountMap.set(key, {count: 0, data: item, jobUserHtml: ""});
         }
         pointCountMap.get(key).count++;
+        pointCountMap.get(key).jobUserHtml += `
+          <div style="margin: 5px 0; cursor: pointer" onclick="checkJobUserById('${item.jobUserID}')">${item.name}</div>
+        `;
       }
     });
     // 转换为数组
     pointCountMap.forEach((value) => {
-      filteredJobUserList.push({...value.data, count: value.count});
-      labelNumberCount.value += value.count;
-    });
-
-    // 设置总数标点
-    const marker = new T.Marker(centerLngLat, {icon: icon}); // 创建标注
-    let label = new T.Label({
-      text: labelNumberCount.value + "", //文本标注的内容
-      position: centerLngLat, //文本标注的地理位置
-      offset: sizeData.labelOffset, //文本标注的位置偏移值
+      filteredJobUserList.push({...value.data, count: value.count, jobUserHtml: value.jobUserHtml});
     });
-    label.setBackgroundColor("transparent");
-    label.setBorderColor("transparent");
-    label.setBorderLine(0);
-    label.setFontSize(sizeData.fontSize);
-    label.setFontColor("white");
-    if (zoomLevel <= 9) {
-      (map as any).addOverLay(marker);// 将标注添加到地图中
-      (map as any).addOverLay(label);// 将标注添加到地图中
-    }
-    jobUserCountMarker.value = marker;
-    jobUserCountLabel.value = label;
 
-    // 解析站点数据,在地图中标记
+    // 解析求职人员数据,在地图中标记
     filteredJobUserList.forEach((item: any) => {
       if (item.longitude && item.latitude) {
         const point = new T.LngLat(item.longitude, item.latitude)
@@ -353,10 +361,28 @@ function setMapMarker() {
         label.setBorderLine(0);
         label.setFontSize(sizeData.fontSize);
         label.setFontColor("white");
-        if (zoomLevel >= 10) {
-          (map as any).addOverLay(marker);// 将标注添加到地图中
-          (map as any).addOverLay(label);// 将标注添加到地图中
-        }
+
+        let winHtml = `
+            <div >
+                <p style="font-size: 14px; font-weight: 600;">求职人员:</p>
+                ${item.jobUserHtml}
+            </div>
+          `;
+        let markerInfoWin = new T.InfoWindow(winHtml, {
+          autoPan: true,
+          maxHeight: 300,
+          maxWidth: 400,
+        });
+        // 添加鼠标经过事件
+        marker.addEventListener('mouseover', () => {
+          marker.openInfoWindow(markerInfoWin);
+        });
+        marker.addEventListener('click', () => {
+          marker.openInfoWindow(markerInfoWin);
+        });
+
+        (map as any).addOverLay(marker);// 将标注添加到地图中
+        (map as any).addOverLay(label);// 将标注添加到地图中
         markerList.value.push(marker);
         labelList.value.push(label);
       }
@@ -388,12 +414,47 @@ function computeMarkerSize(zoomLevel: any) {
   }
 }
 
-// 选择站点
+// 选择求职人员
 function checkJobUser(jobUser: any) {
   nowCheckJobUser.value = JSON.parse(JSON.stringify(jobUser))
+  // 查询求职意向
+  jobHuntList.value = [];
+  jobHuntTotal.value = 0;
+  getJobHunt();
+  // 关闭地图上的其他信息弹窗
+  (map as any).closeInfoWindow();
   if (jobUser.longitude && jobUser.latitude) {
     // 设置地图中心点
-    (map as any).centerAndZoom(new T.LngLat(jobUser.longitude, jobUser.latitude), 14);
+    (map as any).centerAndZoom(new T.LngLat(jobUser.longitude, jobUser.latitude), (map as any).getZoom());
+    // 地图打开弹窗
+    let winHtml = `
+      <div>
+        <span style="font-size: 14px; font-weight: 600;margin-bottom: 5px;">${jobUser.name}(${jobUser.siteName})</span><br><br>
+        <span>年龄:${jobUser.age}岁</span><br>
+        <span>重点人员类别:${jobUser.keyTypeName}</span><br>
+        <span>推荐岗位次数:${jobUser.recommendedCount}次</span><br>
+        <span>入职情况:${jobUser.entryState == 1 ? '已入职' : '未入职'}</span>
+      </div>
+    `;
+    (map as any).openInfoWindow(winHtml, new T.LngLat(jobUser.longitude, jobUser.latitude), {
+      autoPan: true,
+      maxHeight: 300,
+      maxWidth: 400,
+      offset: new T.Point(10, 0)
+    });
+  }
+}
+
+// 选择求职人员
+function checkJobUserById(jobUserID: any) {
+  nowCheckJobUser.value = jobUserList.value.find(item => item.jobUserID == jobUserID);
+  // 查询求职意向
+  jobHuntList.value = [];
+  jobHuntTotal.value = 0;
+  getJobHunt();
+  if (nowCheckJobUser.value.longitude && nowCheckJobUser.value.latitude) {
+    // 设置地图中心点
+    (map as any).centerAndZoom(new T.LngLat(nowCheckJobUser.value.longitude, nowCheckJobUser.value.latitude), (map as any).getZoom());
   }
 }
 
@@ -427,6 +488,37 @@ function ageBlur() {
   }
 }
 
+// 查询求职意向
+async function getJobHunt() {
+  jobHuntSearchParams.jobUserID = nowCheckJobUser.value.jobUserID;
+  await getJobHuntList(jobHuntSearchParams).then((result: any) => {
+    jobHuntList.value = result.list;
+    jobHuntTotal.value = result.total;
+  })
+}
+
+// 求助意向分页变更事件
+function jobHuntPaginationChange() {
+  getJobHunt();
+}
+
+// 岗位薪酬优化显示
+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 searchAll() {
   searchParams.pageIndex = 1
@@ -443,6 +535,7 @@ onMounted(() => {
   getRegionList();
   getKeyPersonTypeList();
   onSearch();
+  (window as any).checkJobUserById = checkJobUserById;
 })
 </script>
 
@@ -478,6 +571,42 @@ export default {
     color: #899099
   }
 
+  .label-text {
+    font-size: 12px;
+    color: #737373;
+    margin-bottom: 3px;
+  }
+
+  .label-box {
+    display: flex;
+    align-items: center;
+    flex-wrap: wrap;
+    margin-top: 5px;
+    overflow: hidden;
+    position: relative;
+
+    .tag-box {
+      width: 91%;
+    }
+
+    .ant-tag {
+      margin-top: 3px;
+    }
+
+    .launch-btn {
+      font-size: 12px;
+      color: #40a9ff;
+      position: absolute;
+      bottom: 0;
+      right: 0;
+      cursor: pointer;
+    }
+  }
+
+  .label-box-max-height {
+    max-height: 23px;
+  }
+
   .jobUser-search-data-box {
     position: absolute;
     width: 330px;
@@ -489,7 +618,6 @@ export default {
 
     .search-box, .data-box, .pagination-box {
       padding: 8px;
-      border-radius: 10px;
       background-color: #F8F8F8;
     }
 
@@ -503,6 +631,7 @@ export default {
     .data-box {
       height: calc(100% - 135px);
       padding: 10px;
+      border-radius: 0;
 
       .list-box {
         width: 100%;
@@ -518,12 +647,6 @@ export default {
           box-sizing: border-box;
           border: 1px solid white;
 
-          .label-text {
-            font-size: 12px;
-            color: #737373;
-            margin-bottom: 3px;
-          }
-
           .jobHunt-box {
             width: 100%;
             display: flex;
@@ -540,32 +663,6 @@ export default {
               cursor: pointer;
             }
           }
-
-          .label-box {
-            display: flex;
-            align-items: center;
-            flex-wrap: wrap;
-            margin-top: 5px;
-            overflow: hidden;
-            position: relative;
-
-            .ant-tag {
-              margin-top: 3px;
-            }
-
-            .launch-btn {
-              font-size: 12px;
-              color: #40a9ff;
-              position: absolute;
-              bottom: 0;
-              right: 0;
-              cursor: pointer;
-            }
-          }
-
-          .label-box-max-height {
-            max-height: 23px;
-          }
         }
 
         .check-jobUser {
@@ -583,10 +680,76 @@ export default {
     }
 
     .pagination-box {
+      border-radius: 0 0 10px 10px;
       display: flex;
       justify-content: center;
       align-items: center;
     }
   }
+
+  .right-data-box {
+    position: absolute;
+    top: 15px;
+    left: calc(100% - 360px);
+    right: 15px;
+    bottom: 15px;
+    z-index: 110;
+    background-color: #F8F8F8;
+    border-radius: 10px;
+    padding: 10px;
+
+    .jobUser-data-box {
+      background-color: white;
+      padding: 10px;
+      width: 100%;
+      max-height: 165px;
+      overflow-y: auto;
+      border-radius: 10px;
+    }
+
+    .jobHunt-list-box {
+      width: 100%;
+      height: calc(100% - 210px);
+      overflow: hidden;
+      overflow-y: auto;
+
+      .jobHunt-box {
+        border-radius: 10px;
+        background-color: white;
+        padding: 8px 10px;
+        margin-bottom: 10px;
+
+        .jobHunt-title {
+          display: flex;
+          justify-content: space-between;
+          flex-wrap: wrap;
+          font-size: 14px;
+          font-weight: normal;
+          margin-bottom: 8px;
+
+          .jobHunt-salary {
+            color: #DE4F3F;
+          }
+        }
+      }
+    }
+
+    .empty-box {
+      width: 100%;
+      height: calc(100% - 210px);
+      display: flex;
+      justify-content: center;
+      align-items: center;
+    }
+
+    .pagination-box {
+      display: flex;
+      justify-content: center;
+      align-items: center;
+      background-color: white;
+      padding: 8px 0;
+      border-radius: 10px;
+    }
+  }
 }
 </style>

+ 26 - 21
vue/src/views/dataMap/siteDataMap.vue

@@ -74,7 +74,7 @@
                  :key="siteIndex"
                  @click="checkSite(site)"
                  @mouseenter="siteMouseenter(site)"
-                 @mouseleave="siteMouseenter({siteID:-1})"
+                 @mouseleave="siteMouseenter({siteID:null})"
             >
               <p class="site-name">
                 {{ site.siteName }}
@@ -93,7 +93,7 @@
                  :key="siteIndex"
                  @click="checkSiteUser(siteUser)"
                  @mouseenter="siteUserMouseenter(siteUser)"
-                 @mouseleave="siteUserMouseenter({siteUserID:-1})"
+                 @mouseleave="siteUserMouseenter({siteUserID:null})"
             >
               <p class="site-name">
                 {{ siteUser.siteUserName }}
@@ -119,12 +119,12 @@
         <div class="pagination-box">
           <span>共{{ paginationTotal }}{{ searchType == 'site' ? '个' : '人' }}</span>
           <a-pagination v-model:current="siteSearchParam.pageIndex" :total="paginationTotal"
-                        v-model:pageSize="siteSearchParam.pageSize"
+                        v-model:pageSize="siteSearchParam.pageSize" :disabled="searchLoading"
                         show-less-items @change="onSearch" simple :show-size-changer="false"/>
         </div>
       </div>
       <!-- 驿站详情 -->
-      <div class="site-info-box" v-if="searchType == 'site' && nowCheckSite.siteID != -1">
+      <div class="site-info-box" v-if="searchType == 'site' && nowCheckSite.siteID != null">
         <p class="font-size-16 font-weight-600 margin-bottom-10">{{ nowCheckSite.siteName }}</p>
         <p class="margin-bottom-3">驿站编号:{{ nowCheckSite.siteCode }}</p>
         <p class="margin-bottom-3">地点:{{ nowCheckSite.detailAddress }}</p>
@@ -136,7 +136,7 @@
         <p class="margin-bottom-3">站点工作人员:{{ nowCheckSite.siteUsers.length }}人</p>
       </div>
       <!-- 驿站人员信息详情 -->
-      <div class="site-user-info-box" v-if="searchType == 'siteUser' && nowCheckSiteUser.siteUserID != -1">
+      <div class="site-user-info-box" v-if="searchType == 'siteUser' && nowCheckSiteUser.siteUserID != null">
         <div class="user-info-box margin-bottom-10">
           <p class="font-size-18 margin-bottom-8" style="font-weight: 600">
             {{ nowCheckSiteUser.siteUserName }}
@@ -176,7 +176,7 @@ import {setBoundary} from "@/utils/position";
 import {onMounted, reactive, ref} from "vue";
 import type {SelectProps} from "ant-design-vue";
 import {getRegionCodeList, getStreetCodeList} from "@/api/system/area/index";
-import {findSiteDataCount, getSiteList} from "@/api/baseSettings/siteInfo";
+import {findSiteDataCount, getDataMapList, getSiteList} from "@/api/baseSettings/siteInfo";
 import thIcon from "@/assets/images/blueTh.png"
 import {findUserDataCount, getSiteUserDataMapList} from "@/api/baseSettings/userInfo";
 
@@ -215,15 +215,15 @@ const streetList = ref<SelectProps['options']>();
 // 驿站下拉框数据
 const siteDicList = ref<any>([]);
 // 选中的站点
-const nowCheckSite = ref<any>({siteID: -1})
+const nowCheckSite = ref<any>({siteID: null})
 // 鼠标经过的站点
-const nowMouseenterSite = ref<any>({siteID: -1});
+const nowMouseenterSite = ref<any>({siteID: null});
 // 驿站的业务数据
 const siteDataCount = ref<any>({})
 // 选中的站点
-const nowCheckSiteUser = ref<any>({siteUserID: -1})
+const nowCheckSiteUser = ref<any>({siteUserID: null})
 // 鼠标经过的站点
-const nowMouseenterSiteUser = ref<any>({siteUserID: -1});
+const nowMouseenterSiteUser = ref<any>({siteUserID: null});
 // 驿站人员的业务数据
 const siteUserDataCount = ref<any>({})
 
@@ -250,7 +250,7 @@ const initMap = () => {
 function onSearch() {
   searchLoading.value = true;
   if (searchType.value == "site") {
-    getSiteList(siteSearchParam).then((result: any) => {
+    getDataMapList(siteSearchParam).then((result: any) => {
       siteList.value = result.list;
       siteList.value.forEach((site: any) => {
         if (site.siteUsers) {
@@ -300,6 +300,8 @@ function searchAll() {
 // 查询类型切换事件
 function searchTypeChange() {
   // 清空数据
+  nowCheckSite.value = {siteID: null};
+  nowCheckSiteUser.value = {siteUserID: null};
   onSearch();
   delMapInfo();
 }
@@ -415,6 +417,7 @@ function delMapInfo() {
     }
     labelList.value = [];
   }
+  (map as any).closeInfoWindow();
 }
 
 // 天地图按缩放基本计算图标与文本的大小与锚点偏移值
@@ -422,13 +425,13 @@ function computeMarkerSize(zoomLevel: any) {
   // 计算新的icon大小
   let newIconSize = Math.min(Math.max(zoomLevel * 3, 15), 45);
   // 计算新的icon锚点位置
-  let iconAnchor = new T.Point(15 * (newIconSize / 45), 30 * (newIconSize / 45));
+  let iconAnchor = new T.Point(10 * (newIconSize / 45), 20 * (newIconSize / 45));
   // 计算新的偏移量,保持 label 居中且不超过初始值
-  let offsetX = -30 + ((newIconSize - 45) / 3);
-  let offsetY = 30 + ((newIconSize - 45) / 3);
+  let offsetX = -20 + ((newIconSize - 45) / 3);
+  let offsetY = 28 + ((newIconSize - 45) / 3);
   // 确保偏移量不超过初始值
-  offsetX = Math.max(offsetX, -30);
-  offsetY = Math.min(offsetY, 30);
+  offsetX = Math.max(offsetX, -20);
+  offsetY = Math.min(offsetY, 28);
   // 更新 label 的偏移量
   let newOffset = new T.Point(offsetX, offsetY);
   let fontSize = Math.min(12, Math.max(8, 12 - (45 - newIconSize) / 3))
@@ -447,10 +450,12 @@ function checkSite(site: any) {
   findSiteDataCount(site.siteID).then((result: any) => {
     siteDataCount.value = result;
   })
-  nowCheckSite.value = JSON.parse(JSON.stringify(site))
+  nowCheckSite.value = JSON.parse(JSON.stringify(site));
+  // 关闭地图上的其他信息弹窗
+  (map as any).closeInfoWindow();
   if (site.siteLongitude && site.siteLatitude) {
     // 设置地图中心点
-    (map as any).centerAndZoom(new T.LngLat(site.siteLongitude, site.siteLatitude), 14);
+    (map as any).centerAndZoom(new T.LngLat(site.siteLongitude, site.siteLatitude), (map as any).getZoom());
     if (searchType.value == 'site') {
       let winHtml = `
             <div >
@@ -466,7 +471,7 @@ function checkSite(site: any) {
         autoPan: true,
         maxHeight: 300,
         maxWidth: 400,
-        offset: new T.Point(5, -20)
+        offset: new T.Point(5, 0)
       });
     }
   }
@@ -485,10 +490,10 @@ async function checkSiteUser(siteUser: any) {
   nowCheckSiteUser.value = JSON.parse(JSON.stringify(siteUser))
   if (siteUser.longitude && siteUser.latitude) {
     // 设置地图中心点
-    (map as any).centerAndZoom(new T.LngLat(siteUser.longitude, siteUser.latitude), 14);
+    (map as any).centerAndZoom(new T.LngLat(siteUser.longitude, siteUser.latitude), (map as any).getZoom());
   } else if (siteUser.siteLongitude && siteUser.siteLatitude) {
     // 设置地图中心点
-    (map as any).centerAndZoom(new T.LngLat(siteUser.siteLongitude, siteUser.siteLatitude), 14);
+    (map as any).centerAndZoom(new T.LngLat(siteUser.siteLongitude, siteUser.siteLatitude), (map as any).getZoom());
   }
 }
 

+ 3 - 0
vue/src/views/jobUserManager/jobuser/edit.vue

@@ -533,6 +533,9 @@
           </a-table>
         </a-col>
       </a-row>
+      <a-divider orientation="left">附件上传</a-divider>
+      <b-upload-file :fileRefId="dataModel.jobUserID" :readonly="false" :multiple="true" style="width: 100%;"
+                     :setFileList="setFileList" :accept="'.pdf,.png,.jpg'"></b-upload-file>
       <a-form-item class="buttom-btns">
         <a-button @click="onClose">取消</a-button>
         <a-button type="primary" html-type="submit">提交</a-button>

+ 10 - 0
vue/src/views/jobUserManager/jobuser/vitae.vue

@@ -106,6 +106,9 @@
             <p>{{ item.duties }}</p>
           </a-timeline-item>
         </a-timeline>
+        <a-divider orientation="left">附件</a-divider>
+        <b-upload-file :fileRefId="jobUserInfo.jobUserID" :readonly="true" :multiple="true" style="width: 100%;"
+                       :setFileList="setFileList" :accept="'.pdf,.png,.jpg'"></b-upload-file>
       </div>
     </div>
   </div>
@@ -121,12 +124,14 @@ import {getSysDictionaryList} from "@/api/system/dictionary";
 import {getJobHuntList} from "@/api/jobUserManager/jobhunt";
 import {useUserStore} from "@/store/modules/user";
 import crtyptoHelp from "@/utils/crypto";
+import BUploadFile from "@/components/file/uploadFile.vue";
 
 const userStore = useUserStore();
 const userInfo = ref(userStore.getUserInfo)
 
 // 求职人员信息
 const jobUserInfo = reactive({
+  jobUserID: "",
   name: "",
   genderName: "",
   age: null,
@@ -311,6 +316,11 @@ function getCultureName(value: any) {
   return "";
 }
 
+const fileList = ref();
+const setFileList = (files) => {
+  fileList.value = files;
+};
+
 // 页面初始化
 onMounted(() => {
   const id = history.state.params?.id;