Commit e0213ac4 authored by guozhiwei's avatar guozhiwei

feat: 工作码表组件封装

parent 60812710
<template>
<div class="jobs-wrap">
<div class="jobs-wrap-txt" :class="{ placeholder: !selectedTexts.length }" @click="show = true">
<span>{{ selectedTexts[1] || placeholder }}</span>
<svg-icon icon-class="triangle-right" slot="button" />
</div>
<cr-popup v-model="show" get-container="body" round closeable position="bottom" class="jobs">
<div class="jobs-head">
<div class="jobs-title">请选择</div>
<cr-divider :hairline="false" :style="{ color: '#F4F4F4', margin: 0 }" />
</div>
<!-- content -->
<div class="jobs-content">
<div class="job-list">
<div
class="jobs-item"
v-for="(item, index) in industry"
:key="index"
:class="{ active: columns[0].values.length > 0 && index === columns[0].selectedIndex }"
@click="changeIndustry(item, index)"
>
<div class="jobs-item-txt">
<span>{{ item.text }}</span>
<cr-icon type="arrow" />
</div>
<div
class="jobs-children"
v-if="columns[0].values.length > 0 && index === columns[0].selectedIndex"
>
<div
class="jobs-item"
v-for="(it, idx) in columns[1].values"
:key="idx"
@click="changeProfession(it, idx)"
>
<div class="jobs-item-txt">{{ it.text }}</div>
</div>
</div>
<cr-divider />
</div>
</div>
</div>
</cr-popup>
</div>
</template>
<script>
/**
* @description: 职业码表
* @param {type}
* @return:
*/
import popupPickerMixin from "../mixins/popupPicker.mixin.js";
import jobs from "@/api/jobs";
const CHANGE_EVENT = "input";
const INDUSTRY_INDEX = 0;
const PROFESSION_INDEX = 1;
export default {
name: "PopupCascade",
mixins: [popupPickerMixin],
props: {
value: null
},
watch: {
// value(val) {
// this.popupShow = val;
// },
popupShow(val) {
this.$emit(CHANGE_EVENT, val);
}
},
computed: {
industry() {
const list = this.jobs[this.industryKey];
return Object.keys(list).map(key => {
return {
code: key,
text: list[key]
};
});
},
profession() {
const list = this.jobs[this.professionKey];
return Object.keys(list).map(key => {
return {
code: key,
text: list[key]
};
});
}
},
data() {
return {
show: false,
jobs,
industryKey: "industry",
professionKey: "profession",
columns: [],
selectedCodes: [],
selectedTexts: []
};
},
created() {
if (this.value) {
const value = "" + this.value;
this.selectedCodes = [value.substring(0, 4), value];
}
for (let i = 0; i < 2; i++) {
this.columns[i] = {
values: [],
selectedIndex: ""
};
}
},
mounted() {
this.renderIndustry();
},
methods: {
changeIndustry(item, index) {
this.columns[INDUSTRY_INDEX].selectedIndex = index;
this.selectedCodes[INDUSTRY_INDEX] = item.code;
this.selectedTexts[INDUSTRY_INDEX] = item.text;
this.renderProfession(item.code);
},
changeProfession(item, index) {
this.columns[PROFESSION_INDEX].selectedIndex = index;
this.selectedCodes[PROFESSION_INDEX] = item.code;
this.selectedTexts[PROFESSION_INDEX] = item.text;
this.$emit("input", this.selectedCodes);
this.show = false;
},
renderIndustry() {
this.columns[INDUSTRY_INDEX].values = this.industry;
this.setDefaultIndexOfColumn(this.industry, INDUSTRY_INDEX);
const industry = this.industry[this.columns[INDUSTRY_INDEX].selectedIndex];
if (industry) {
this.selectedTexts[PROFESSION_INDEX] = industry.text;
this.renderProfession(industry?.code);
}
},
renderProfession(industryCode) {
const professionOfIndustry = this.quickFilter(this.profession, 5, industryCode);
this.columns[PROFESSION_INDEX].values = professionOfIndustry;
this.setDefaultIndexOfColumn(professionOfIndustry, PROFESSION_INDEX);
this.$forceUpdate();
},
quickFilter(list, slice, code) {
const prefix = code.substring(0, slice);
let start = false;
const filtered = [];
for (let i = 0, len = list.length; i < len; i++) {
if (list[i].code.substr(0, slice) === prefix) {
start = true;
filtered.push(list[i]);
} else {
if (start) {
break;
}
}
}
return filtered;
},
setDefaultIndexOfColumn(list, index) {
if (this.selectedCodes[index]) {
list.some((item, i) => {
if (item.code === this.selectedCodes[index]) {
this.columns[index].selectedIndex = i;
return true;
}
return false;
});
// clear after first render
this.selectedCodes[index] = "";
}
}
}
};
</script>
<style lang="less" scoped>
@import "../style/var.less";
.body-wrap-mixin {
overflow-x: hidden;
overflow-y: auto;
height: 80vh;
padding: @padding-lg;
}
.jobs {
z-index: 200;
height: 80vh;
overflow: hidden;
@{deep} .cr-icon {
position: absolute;
color: #d0cfcf;
font-size: @font-size-18;
top: 16px;
right: 14px;
z-index: 201;
}
&-wrap {
width: 100%;
&-txt {
height: 24px;
color: #333;
font-size: 14px;
display: flex;
justify-content: space-between;
align-items: center;
}
}
&-head {
width: 100%;
}
&-title {
font-weight: @font-weight-bold;
font-size: @font-size-18;
color: @black;
line-height: @line-height-lg + 1;
padding: 13px 0 10px;
text-align: center;
}
&-content {
.body-wrap-mixin();
font-size: @font-size-12;
color: @gray-5;
line-height: @line-height-md - 2;
}
&-list {
width: 100%;
}
&-item {
.cr-divider {
margin: 0;
}
&-txt {
display: flex;
justify-content: space-between;
align-items: center;
font-size: 15px;
color: #333;
padding: 12px 0;
.cr-icon {
font-size: 14px;
color: #333;
position: initial;
transition: tranform 0.2s linear;
}
}
&.active {
.jobs-children {
display: block;
}
.cr-icon {
transform: rotate(90deg);
}
}
}
&-children {
display: none;
margin: 0 0 10px;
padding: 2px 10px;
border-radius: 8px;
background-color: @gray-1;
.jobs-item-txt {
color: @gray-5;
padding: 0;
margin: 8px 0;
font-size: 14px;
}
}
}
.placeholder {
color: #ccc;
}
</style>
......@@ -2,7 +2,7 @@
* @Description: PopupPicker mixin
* @Date: 2020-07-28 19:46:31
* @LastEditors: gzw
* @LastEditTime: 2020-07-28 20:33:52
* @LastEditTime: 2020-08-16 21:21:05
*/
// TODO 默认值需要处理
......@@ -33,7 +33,7 @@ export default {
},
watch: {
show(val) {
if (val && !this.refreshed) {
if (val && !this.refreshed && this.$refs[this.refName]) {
this.refreshed = true;
this.$refs[this.refName].refreshColumns();
}
......
......@@ -82,11 +82,7 @@
:rules="[{ required: true, message: '请选择投保人职业' }]"
>
<template #input>
<popup-picker
:picker-data="['老师', '工人']"
v-model="formData.holderUserInfo.occupation"
placeholder="请选择投保人职业"
/>
<popup-cascade />
</template>
</cr-field>
<cr-field
......@@ -348,6 +344,7 @@ import PopupPicker from "@/components/PopupPicker";
import PopupAreaPicker from "@/components/PopupAreaPicker";
import PopupDatePicker from "@/components/PopupDatePicker";
import PopupWithIframe from "@/components/PopupWithIframe";
import PopupCascade from "@/components/PopupCascade";
import Stepper from "@/components/Stepper";
import GoInsureDialog from "@/views/Goods/Detail/modules/GoInsureDialog";
import detailPayMixin from "@/views/Goods/Detail/modules/detailPay.mixin";
......@@ -384,6 +381,7 @@ export default {
PopupAreaPicker,
PopupDatePicker,
PopupWithIframe,
PopupCascade,
Stepper
},
data() {
......
......@@ -886,7 +886,7 @@
resolved "http://npmprivate.quantgroups.com/@nodelib%2ffs.stat/-/fs.stat-1.1.3.tgz#2b5a3ab3f918cca48a8c754c08168e3f03eba61b"
integrity sha512-shAmDyaQC4H92APFoIaVDHCx5bStIocgvbwQyxPRrbUY20V1EYTbSDchWbuwlMG3V17cprZhA6+78JfB+3DTPw==
"@qg/cherry-ui@^1.1.2":
"@qg/cherry-ui@^1.2.1":
version "1.2.1"
resolved "http://npmprivate.quantgroups.com/@qg%2fcherry-ui/-/cherry-ui-1.2.1.tgz#5f59ebf0ed677c6d3f41dd04e3b9f6a43811936b"
integrity sha512-icj5WLUCJswPLF02YtCdppdfSDwQQrFoLxhRFCie2SFffIKVZSMEtSVVuEh2nZv2khPd/cvEISGpmzwDcBS7tw==
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment