123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532 |
- <template>
- <div class="app-container jobDetail" >
- <el-row :gutter="20">
- <el-col :span="6">
- <div class="bd-f2">
- <p style="border-bottom: 1px solid #f2f2f2" class="pd10 f-333 f14">全部职业</p>
- <div class="tree-wrap">
- <el-tree
- ref="tree"
- :data="vocationList"
- node-key="code"
- :default-checked-keys="[code]"
- :default-expanded-keys="[code]"
- :props="defaultProps"
- :current-node-key="code"
- @node-click="handleNodeClick"
- :isLeaf="isLeaf"
- >
- <p class="custom-tree-node" :title="node.label" slot-scope="{node, data}">
- <span class="text-ellipsis">{{node.label }}</span>
- <span>{{data.children ? data.children.length : ''}}</span>
- </p>
- </el-tree>
- </div>
- </div>
- </el-col>
- <el-col :span="18">
- <el-card style="color: #5E5E5E;" ref="navBar">
- <el-breadcrumb separator-class="el-icon-arrow-right">
- <el-breadcrumb-item :to="{ path: '/index' }">首页</el-breadcrumb-item>
- <el-breadcrumb-item :to="{ path: '/new-gaokao/three/Vocation'}">职业库</el-breadcrumb-item>
- <el-breadcrumb-item>职业详情</el-breadcrumb-item>
- </el-breadcrumb>
- </el-card>
- <div class="mt20 header-content pd20" >
- <p class="f28 f-333">{{vocationDetail.name || ''}}</p>
- </div>
- <div class="tabs-wrap">
- <span class="tabs-item" @click="tabActive = 0" :class="{'bg-primary':tabActive == 0}">职业概况</span>
- <span class="tabs-item" @click="tabActive = 1":class="{'bg-primary':tabActive == 1}">就业岗位</span>
- </div>
- <p class="line"></p>
- <div
- v-show="loading"
- class="loading-div"
- v-loading="loading"
- :style="{height:windowHeight + 'px'}">
- </div>
- <div class="content-wrap mt20" >
- <!-- 职业概况 -->
- <div v-if="Object.keys(vocationDetail).length > 0">
- <div v-show="tabActive == 0">
- <div class="desc-item">
- <p class="format-tit">职业介绍</p>
- <div class="text-666" v-html="vocationDetail.description"></div>
- </div>
- <div class="desc-item">
- <p class="format-tit">就业岗位<span class="text-666 f14">({{vocationDetail.postJobs.length || 0}}个)</span></p>
- <div class="post-item mb20" v-for="post in vocationDetail.postJobs">
- <div class="post-title f16 mb10" style="cursor: pointer" @click="toJob(post)">{{post.name}}</div>
- <div class="pb10 text-666 post-text">
- <div>{{`${post.salaryMin}元-${post.salaryMax}元/月`}}</div>
- <div>热门地区:{{post.hotCity}}</div>
- </div>
- </div>
- </div>
- <div class="desc-item">
- <p class="format-tit">相关专业<span class="text-666 f14">({{vocationDetail.postMajors.length}}个)</span></p>
- <div class="post-item mb20" v-for="post in vocationDetail.postMajors">
- <div class="post-title f16 mb10" style="cursor: pointer" @click="toMajorDetail(post)">{{post.name}}</div>
- <div class="pb10 text-666 post-text">
- <div>国标代码:{{post.code}}</div>
- <div>学制:{{post.learnYear}}</div>
- <div>男女比例:{{`${post.maleRatio}/${post.femaleRatio}`}}</div>
- </div>
- </div>
- </div>
- </div>
- </div>
- <!-- 就业岗位-->
- <div v-if="vocationalPosts.length > 0">
- <div v-show="tabActive == 1">
- <el-row :gutter="20" type="flex" class="jobTabs">
- <el-col class="job-item-wrap" :span="4" v-for="item in vocationalPosts" :key="item.name">
- <div class="job-item f14 f-333" :class="{'bg-primary':jobActiveName == item.name}" @click="toActiveJob(item.name)">
- <p class="mb10">{{item.name}}</p>
- <p>{{`${item.salaryMin}-${item.salaryMax}`}}{{item.salaryUnit}}</p>
- </div>
- </el-col>
- </el-row>
- <!-- 岗位详情 -->
- <div v-if="Object.keys(jobDetail).length > 0">
- <!-- 图表 -->
- <div class="desc-item">
- <p class="format-tit">薪资情况</p>
- <el-row :gutter="10">
- <el-col :span="12">
- <p class="text-right f-333">按趋势</p>
- <mx-chart :options="chartExperience" height="300px"></mx-chart>
- </el-col>
- <el-col :span="12">
- <p class="text-right f-333">按分布</p>
- <mx-chart :options="chartSalary" height="300px"></mx-chart>
- </el-col>
- </el-row>
- </div>
- <div class="desc-item">
- <p class="format-tit">就业形势</p>
- <el-row :gutter="10">
- <el-col :span="12">
- <p class="text-right f-333">按学历</p>
- <mx-chart :options="chartEdu" height="300px"></mx-chart>
- </el-col>
- <el-col :span="12">
- <p class="text-right f-333">按经验</p>
- <mx-chart :options="chartExp" height="300px"></mx-chart>
- </el-col>
- </el-row>
- </div>
- <div class="desc-item">
- <p class="format-tit">招聘需求量</p>
- <el-row :gutter="40" type="flex" class="flex-wrap">
- <el-col :span="12" class="f16" v-for="(item,index) in jobDetail.demand">
- <el-row class="format-job-wrap">
- <el-col :span="3" class="f18 text-center f-666">{{index + 1}}</el-col>
- <el-col :span="15" class="f-333">{{item.city}}</el-col>
- <el-col :span="6" class="f-666 text-right f14">{{item.count}}职位</el-col>
- </el-row>
- </el-col>
- </el-row>
- </div>
- <div class="desc-item">
- <p class="format-tit">收入排行-按行业</p>
- <el-row :gutter="40" type="flex" class="flex-wrap">
- <el-col :span="12" class="f16" v-for="(item,index) in jobDetail.industrySalary">
- <el-row class="format-job-wrap">
- <el-col :span="3" class="f18 text-center f-666">{{index + 1}}</el-col>
- <el-col :span="15" class="f-333">{{item.name}}</el-col>
- <el-col :span="6" class="f-666 text-right f14">{{item.salary}}元 / 月</el-col>
- </el-row>
- </el-col>
- </el-row>
- </div>
- <div class="desc-item">
- <p class="format-tit">收入排行-按地区</p>
- <el-row :gutter="40" type="flex" class="flex-wrap">
- <el-col :span="12" class="f16" v-for="(item,index) in jobDetail.citySalary">
- <el-row class="format-job-wrap">
- <el-col :span="3" class="f18 text-center f-666">{{index + 1}}</el-col>
- <el-col :span="15" class="f-333">{{item.city}}</el-col>
- <el-col :span="6" class="f-666 text-right f14">{{item.salary}}元 / 月</el-col>
- </el-row>
- </el-col>
- </el-row>
- </div>
- </div>
- <div v-else>
- 暂无数据
- </div>
- </div>
- </div></div>
- </el-col>
- </el-row>
- </div>
- </template>
- <script>
- import MxChart from '@/components/MxChart/index'
- import { vocationalPostsDetail,vocationalPosts } from '@/api/webApi/vocation'
- import MxVocationTranslateMixin from '@/components/Cache/modules/mx-vocation-translate-mixin'
- export default {
- name: "Detail",
- components: {
- MxChart
- },
- mixins:[MxVocationTranslateMixin],
- data(){
- return {
- loading:false,
- code:'',
- defaultProps: {
- children: 'children',
- label: 'name'
- },
- tabActive: 0,
- vocationalPosts: [], // 就业岗位
- vocationDetail:{}, // 职业概况
- jobActiveName: '', // 激活状态的岗位
- jobDetail: {}, // 岗位详情
- windowHeight:document.documentElement.clientHeight,
- }
- },
- created() {
- this.code = this.$route.query.code
- this.getVocationalOverview();
- },
- computed:{
- // 按工资分布
- chartSalary() {
- if (!this.jobDetail.salary.length) return null
- const pieData = this.jobDetail.salary.map(item => {
- return {
- value: item.ratio,
- name: `${item.min}-${item.max}元/月 ${item.ratio}%`,
- }
- })
- const options = {
- toolbox: {
- show: true,
- },
- tooltip: {
- trigger: 'item'
- },
- series: [
- {
- type: 'pie',
- radius: [40, 60],
- label:{
- formatter: '{b}'
- },
- data: pieData
- }
- ]
- }
- return options
- },
- // 按经验
- chartExp() {
- if (!this.jobDetail.exp.length) return null
- const pieData = this.jobDetail.exp.map(item => {
- return {
- value: item.ratio,
- name: `${item.exp}${item.ratio}%`,
- }
- })
- const options = {
- toolbox: {
- show: true,
- },
- series: [
- {
- name: 'Nightingale Chart',
- type: 'pie',
- radius: [30, 60],
- label:{
- formatter: '{b}'
- },
- data: pieData
- }
- ]
- }
- return options
- },
- // 按教育程度
- chartEdu() {
- if (!this.jobDetail.edu.length) return null
- const pieData = this.jobDetail.edu.map(item => {
- return {
- value: item.ratio,
- name: `${item.edu}${item.ratio}%`,
- }
- })
- const options = {
- toolbox: {
- show: true,
- },
- series: [
- {
- name: 'Nightingale Chart',
- type: 'pie',
- radius: [30, 60],
- label:{
- formatter: '{b}'
- },
- data: pieData
- }
- ]
- }
- return options
- },
- // 按工资趋势
- chartExperience() {
- if (!this.jobDetail.experience.length) return null
- const col = this.jobDetail.experience.map(item => item.year)
- const row = this.jobDetail.experience.map(item => item.salary)
- const options = {
- xAxis: {
- data: col,
- axisLine: {
- lineStyle: {
- type: 'dashed'
- }
- },
- axisTick: {
- alignWithLabel: true
- },
- },
- yAxis: {
- type: 'value',
- },
- series: [
- {
- name: 'Email',
- type: 'line',
- color: '#47C6A2',
- stack: 'Total',
- label: {
- show: true,
- position: 'top',
- },
- smooth: false,
- data: row
- },
- ]
- }
- return options
- }
- },
- watch:{
- tabActive: {
- handler(newVal){
- // 1 岗位 0 概览
- if(newVal == 0) this.getVocationalOverview();
- if(newVal == 1) this.getVocationalPosts();
- }
- },
- },
- methods:{
- toMajorDetail(row) {
- console.log('跳转')
- console.log(row)
- // 跳转
- this.$router.push({path:'/career/plan/MajorDetail',query:{code:row.code}})
- },
- handleNodeClick(data,node) {
- if(!node.isLeaf || this.code == node.data.code) return
- this.code =node.data.code
- this.tabActive = 0
- this.getVocationalOverview()
- // 跳转
- // this.$router.replace({path:'/career/vocation/Detail',query:{code:node.data.code}})
- },
- toJob(post) {
- console.log(post)
- this.tabActive = 1
- this.toActiveJob(post.name)
- },
- isLeaf(data,node) {
- return node.childCount == 0
- },
- toActiveJob(name) {
- if(this.jobActiveName == name) return
- this.jobActiveName = name
- // 刷新数据
- this.getVocationalPostsDetail()
- },
- // 就业岗位
- getVocationalPosts() {
- this.loading = true
- const params={
- code:this.code
- };
- vocationalPosts(params).then(res => {
- this.vocationalPosts = res.data
- if(this.jobActiveName == '') {
- this.jobActiveName = res.data[0].name
- this.$nextTick(_ => {
- this.getVocationalPostsDetail()
- })
- }
- }).finally(_ => {
- this.loading = false
- })
- },
- // 就业岗位详情
- getVocationalPostsDetail() {
- this.loading = true
- vocationalPostsDetail({postName:this.jobActiveName }).then(res => {
- console.log(res)
- this.jobDetail = res.data || {}
- }).finally(res => {
- this.loading = false
- })
- },
- // 职业概况
- getVocationalOverview(){
- this.loading = true
- const params={
- code:this.code
- };
- vocationalOverview(params).then(res=>{
- console.log(res)
- this.vocationDetail = res.data || {}
- }).finally(_ => {
- this.loading = false
- })
- }
- }
- }
- </script>
- <style lang="scss" scoped>
- .jobDetail {
- .header-content{
- top: 0;
- left: 0;
- width: 100%;
- height: 100%;
- background: rgba(66, 185, 131, 0.1);
- }
- .custom-tree-node{
- display: flex;
- justify-content: space-between;
- align-items: center;
- width: 100%;
- overflow: hidden;
- }
- .tabs-wrap{
- margin-top: 20px;
- height: 40px;
- .tabs-item{
- cursor: pointer;
- padding: 0 33px;
- border-radius: 4px 4px 0 0;
- display: inline-block;
- line-height: 40px;
- &:hover{
- color:#47C6A2;
- }
- &.bg-primary{
- background: #47C6A2 ;
- color: white;
- }
- }
- }
- .bg-primary{
- background: #47C6A2 !important;
- color: white;
- }
- .format-job-wrap {
- display: flex;
- height: 44px;
- line-height: 44px;
- border-bottom: 1px solid #f2f2f2;
- }
- .line{
- background: #47C6A2;
- height: 1px;
- }
- .post-text{
- display: flex;
- div{
- min-width: 160px;
- &:not(:first-child):before{
- content: "";
- display: inline-block;
- width: 1px;
- height: 12px;
- background-color: #ccc;
- vertical-align: text-top;
- margin-right: 60px;
- margin-top: 4px;
- }
- }
- }
- .loading-div {
- width: 100%;
- position: absolute;
- background: transparent;
- left: 0;
- }
- .post-title{
- color: #333;
- }
- .post-item{
- border-bottom: 1px solid #f2f2f2;
- color: #333;
- }
- .format-tit{
- border-left: 4px solid #47C6A2;
- padding-left: 10px;
- margin-bottom: 20px;
- font-size: 20px;
- }
- .desc-item{
- margin-bottom: 40px;
- }
- .text-666{
- font-size: 14px;
- color: #666666 !important;
- }
- .flex-wrap{
- flex-wrap: wrap;
- }
- .jobTabs{
- flex-wrap: wrap;
- .job-item-wrap{
- padding: 10px;
- margin-bottom: 20px;
- .job-item{
- cursor: pointer;
- border-radius: 4px;
- padding: 10px;
- background: #f2f2f2;
- }
- }
- }
- .tree-wrap{
- padding: 10px;
- height: calc(100vh - 176px) ;
- overflow: hidden;
- overflow-y: auto;
- }
- ::v-deep .el-tree-node.is-current > .el-tree-node__content {
- background: rgba(22, 119, 255, 0.1);
- color: #47C6A2;
- ::v-deep .is-leaf {
- color: rgba(0, 0, 0, 0);
- }
- }
- }
- </style>
|