bxs-tools-ui 3.3.2 → 3.4.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (63) hide show
  1. package/es/add-and-take/index.js +1 -7969
  2. package/es/adjust-baoe/index.js +196 -8195
  3. package/es/index.css +1 -1
  4. package/es/index.js +8788 -43744
  5. package/es/insure-calculate/index.css +1 -1
  6. package/es/insure-calculate/index.js +1046 -36665
  7. package/es/person-info/index.css +1 -1
  8. package/es/person-info/index.js +83 -8042
  9. package/es/product-info/index.css +1 -1
  10. package/es/product-info/index.js +3005 -10614
  11. package/es/share-sheet/index.js +69 -8040
  12. package/es/utils/index.js +1250 -9334
  13. package/lib/add-and-take/index.js +4 -7973
  14. package/lib/adjust-baoe/index.js +195 -8195
  15. package/lib/index.css +1 -1
  16. package/lib/index.js +8717 -43678
  17. package/lib/insure-calculate/index.css +1 -1
  18. package/lib/insure-calculate/index.js +1034 -36662
  19. package/lib/person-info/index.css +1 -1
  20. package/lib/person-info/index.js +86 -8046
  21. package/lib/product-info/index.css +1 -1
  22. package/lib/product-info/index.js +2807 -10417
  23. package/lib/share-sheet/index.js +72 -8044
  24. package/lib/utils/index.js +1252 -9337
  25. package/package.json +5 -3
  26. package/packages/add-and-take/demo/index.vue +3 -6
  27. package/packages/adjust-baoe/index.vue +21 -34
  28. package/packages/adjust-baoe/readme.md +0 -1
  29. package/packages/bxs-utils/planbook/common.ts +5 -0
  30. package/packages/bxs-utils/planbook/insurance.ts +19 -0
  31. package/packages/bxs-utils/planbook/person.ts +3 -2
  32. package/packages/bxs-utils/planbook/product.ts +57 -164
  33. package/packages/bxs-utils/readme.md +3 -1
  34. package/packages/index.ts +1 -1
  35. package/packages/insure-calculate/demo/index.vue +1 -1
  36. package/packages/insure-calculate/index.vue +18 -17
  37. package/packages/person-info/demo/index.vue +2 -4
  38. package/packages/planbook-input/components/product-table.vue +3 -14
  39. package/packages/planbook-input/helper.js +16 -53
  40. package/packages/planbook-input/index.vue +20 -28
  41. package/packages/planbook-input/readme.md +3 -3
  42. package/packages/product-info/components/product-insurance-form.md +46 -0
  43. package/packages/product-info/components/product-insurance-form.vue +360 -0
  44. package/packages/product-info/demo/index.vue +4 -5
  45. package/packages/product-info/handler.js +307 -0
  46. package/packages/product-info/handler.md +26 -0
  47. package/packages/product-info/index.less +33 -0
  48. package/packages/product-info/index.vue +306 -534
  49. package/packages/product-info/readme.md +7 -2
  50. package/packages/share-sheet/constant.js +1 -2
  51. package/src/api/adjust-baoe.js +2 -2
  52. package/src/api/planbook.js +4 -20
  53. package/src/api/trade.js +31 -0
  54. package/src/components/common/common-group-title.less +54 -0
  55. package/src/components/common/common-group-title.md +34 -0
  56. package/src/components/common/common-group-title.vue +72 -0
  57. package/src/components/common/common-title.less +4 -0
  58. package/src/components/common/common-title.vue +8 -2
  59. package/src/components/profession-list/README.md +114 -0
  60. package/src/components/profession-list/constant.js +4 -0
  61. package/src/components/profession-list/handler.js +155 -0
  62. package/src/components/profession-list/index.less +182 -0
  63. package/src/components/profession-list/index.vue +443 -0
@@ -9,6 +9,8 @@
9
9
  > - `groupKey`:`inputData → productGroupList → key`
10
10
  > - `productKey`:`inputData → productGroupList → prodOrderList → key`
11
11
 
12
+ **组合险**:子险带 `groupKey` / `groupName`(可选 `isCheckbox`)。组头用 `CommonGroupTitle`(Switch);UI 状态见 `handler.js`(`Map`:`active` + `selectedIds` + `locked`),**不写入产品数据**;试算只认子险 `title`。有子险 title 锁定勾选时 `locked=true`:组开关开启且不可关,其他子险不可点。展示:**普通险在前**,组合险在后。单险种表单:`components/product-insurance-form`。
13
+
12
14
  ---
13
15
 
14
16
  ### 模块引用(import)
@@ -40,6 +42,7 @@ export default {
40
42
  </template>
41
43
 
42
44
  <script>
45
+ import { Toast } from 'vant';
43
46
  import { ProductInfo } from 'bxs-tools-ui';
44
47
 
45
48
  export default {
@@ -48,7 +51,7 @@ export default {
48
51
  cgProduct(product, options, inst) {
49
52
  if (options.type === 'change' && options.errorMsg) {
50
53
  this.$nextTick(() => {
51
- this.$toast(options.errorMsg);
54
+ Toast(options.errorMsg);
52
55
  });
53
56
  }
54
57
  },
@@ -88,7 +91,6 @@ export default {
88
91
  | 参数 | 说明 | 类型 |
89
92
  | --------------------- | ------------------------------------------------------------------------- | ------- |
90
93
  | `planbookId` | 计划书 ID,用于产品联动逻辑 | Number |
91
- | `publicPbUuid` | 公开计划书 uuid,传入后使用 public 接口重算 | String |
92
94
  | `allowCustomResult` | 是否显示「自定义保费/保额」开关 | Boolean |
93
95
  | `insuranceSaleStatus` | 险种停售状态映射:`{ [insuranceKey]: number }`;值为 `2` 时展示「停」标签 | Object |
94
96
 
@@ -107,6 +109,9 @@ export default {
107
109
  | `eleOrderList` | 必传,险种内元素列表,见 EleOrderList 数组 | Array |
108
110
  | `code` | 险种 code | String |
109
111
  | `isFollowing` | 是否去除与上一险种之间的间距 | Boolean |
112
+ | `groupKey` | 组合险分组 key;有值则为组合子险 | String |
113
+ | `groupName` | 组合险组标题 | String |
114
+ | `isCheckbox` | 组合内是否多选;默认单选互斥 | Boolean |
110
115
 
111
116
  #### EleOrderList 数组(单项)
112
117
 
@@ -1,5 +1,4 @@
1
- import Jax from '@bxs/jax'
2
- export const { isIos, isAndroid } = Jax.parseUaString()
1
+ import { isIos } from 'src/js/variables.js'
3
2
  const oneDayMillisecond = 24 * 3600 * 1000
4
3
 
5
4
  export const EXPIRE_ENUM = [
@@ -1,9 +1,9 @@
1
1
  import QS from 'qs'
2
2
  import request from './request'
3
3
 
4
- export function validateAdjustBaoe(params, options = {}) {
4
+ export function validateAdjustBaoe(params) {
5
5
  return request({
6
- url: `/planBook/${options.publicPbUuid ? 'public' : 'V2'}/validateAccount/-1/low`,
6
+ url: '/planBook/V2/validateAccount/-1/low',
7
7
  method: 'post',
8
8
  data: QS.stringify({
9
9
  jd: JSON.stringify(params)
@@ -1,4 +1,3 @@
1
- import QS from 'qs'
2
1
  import request from './request'
3
2
  import { APP_HOSTNAME } from '../js/variables.js'
4
3
 
@@ -10,28 +9,13 @@ export function getPlanbookInitData(params) {
10
9
  })
11
10
  }
12
11
 
13
- export function getPublicPlanbookInitData(params) {
14
- return request({
15
- url: '/planBook/public/init',
16
- method: 'post',
17
- data: QS.stringify(params),
18
- headers: {
19
- Accept: 'application/json, text/plain, */*',
20
- 'Content-Type': 'application/x-www-form-urlencoded'
21
- }
22
- })
23
- }
24
-
25
12
  export function getPlanbookData(params) {
26
- if (params && params.publicPbUuid) {
27
- return getPublicPlanbookInitData(params)
28
- }
29
13
  return getPlanbookInitData(params)
30
14
  }
31
15
 
32
- export function calcPlanbookProduct(params, options = {}) {
16
+ export function calcPlanbookProduct(params) {
33
17
  return request({
34
- url: `/planBook/${options.publicPbUuid ? 'public' : 'V2'}/calculate`,
18
+ url: '/planBook/V2/calculate',
35
19
  method: 'post',
36
20
  data: params,
37
21
  headers: {
@@ -43,9 +27,9 @@ export function calcPlanbookProduct(params, options = {}) {
43
27
  })
44
28
  }
45
29
 
46
- export function uploadPlanBookResult(params, options = {}) {
30
+ export function uploadPlanBookResult(params) {
47
31
  return request({
48
- url: `/planBook/${options.publicPbUuid ? 'public/createPb' : 'V2/uploadResult'}`,
32
+ url: '/planBook/V2/uploadResult',
49
33
  method: 'post',
50
34
  data: params,
51
35
  headers: {
package/src/api/trade.js CHANGED
@@ -28,6 +28,37 @@ export function getAddress(data, userUuid) {
28
28
  })
29
29
  }
30
30
 
31
+ /**
32
+ * 职业类别(POST `…/api/product/data/getProfession`)
33
+ * @param {object} urlParams query 参数,如 `{ userUuid }`
34
+ * @param {object} postParams body,如 `{ productId, parentId?, searchKey? }`
35
+ * @param {boolean} [isDev] 可选,覆盖默认环境域名(true → .cn,false → 生产)
36
+ */
37
+ export function getProfession(urlParams, postParams, isDev) {
38
+ const host = typeof isDev === 'boolean' ? `https://insurance2a-api.wyins.net${isDev ? '.cn' : ''}` : INSURANCE2A_API_HOSTNAME
39
+ let url = `${host}/api/product/data/getProfession`
40
+ if (urlParams && typeof urlParams === 'object') {
41
+ const query = Object.keys(urlParams)
42
+ .filter(key => urlParams[key] !== undefined && urlParams[key] !== null)
43
+ .map(key => `${encodeURIComponent(key)}=${encodeURIComponent(urlParams[key])}`)
44
+ .join('&')
45
+ if (query) {
46
+ url += `?${query}`
47
+ }
48
+ }
49
+ return request({
50
+ url,
51
+ method: 'post',
52
+ data: postParams,
53
+ headers: {
54
+ Accept: 'application/json, text/plain, */*',
55
+ 'Content-Type': 'application/json'
56
+ },
57
+ isIgnoreLoading: false,
58
+ returnFullResponse: true
59
+ })
60
+ }
61
+
31
62
  /**
32
63
  * 险种保费试算 `/api/product/data/calculate`
33
64
  */
@@ -0,0 +1,54 @@
1
+ .bxt-group-title-wrapper {
2
+ width: 100%;
3
+ }
4
+
5
+ .bxt-group-title {
6
+ position: relative;
7
+ text-align: left;
8
+
9
+ &::before {
10
+ position: absolute;
11
+ left: -15px;
12
+ top: 9px;
13
+ display: block;
14
+ width: 4px;
15
+ height: 15px;
16
+ content: '';
17
+ background: var(--bxt-primary);
18
+ }
19
+
20
+ & .bxt-group-title-label {
21
+ display: flex;
22
+ align-items: center;
23
+ padding: 5px 0;
24
+ line-height: normal;
25
+ font-size: 17px;
26
+ font-weight: bold;
27
+ vertical-align: middle;
28
+ white-space: nowrap;
29
+
30
+ & .bxt-group-title-label-name {
31
+ flex: 1;
32
+ min-width: 0;
33
+
34
+ & .bxt-group-title-content {
35
+ display: inline-block;
36
+ vertical-align: middle;
37
+ white-space: normal;
38
+
39
+ &--disabled {
40
+ color: var(--bxt-text-assist);
41
+ }
42
+ }
43
+ }
44
+
45
+ & .bxt-group-title-label-switch {
46
+ flex: 0 0 auto;
47
+ margin-left: 12px;
48
+
49
+ & .van-switch--on {
50
+ background-color: var(--bxt-primary);
51
+ }
52
+ }
53
+ }
54
+ }
@@ -0,0 +1,34 @@
1
+ # CommonGroupTitle
2
+
3
+ 组合险组标题:在 `common-title` 布局基础上,右侧用 **Switch** 控制组展开/收起(非 Checkbox)。
4
+
5
+ ## 用法
6
+
7
+ ```html
8
+ <CommonGroupTitle
9
+ v-model="active"
10
+ :label="groupName"
11
+ :disabled="disabled"
12
+ data-stat-id="product_insurance_group_xxx"
13
+ @change="onGroupActiveChange"
14
+ />
15
+ ```
16
+
17
+ ## Props
18
+
19
+ | 属性 | 说明 | 类型 | 默认 |
20
+ |------|------|------|------|
21
+ | `value` / `v-model` | 是否展开 | Boolean | — |
22
+ | `label` | 组名 | String | `''` |
23
+ | `disabled` | 禁用开关 | Boolean | `null` |
24
+ | `dataStatId` | 声明式埋点 id(挂在 switch 上) | String | `''` |
25
+ | `size` | Switch 尺寸 | String / Number | `24` |
26
+
27
+ 打开态 Switch 使用主题色 `var(--bxt-primary)`(与 `common-title` Checkbox 一致)。
28
+
29
+ ## Events
30
+
31
+ | 事件 | 说明 | 参数 |
32
+ |------|------|------|
33
+ | `input` | v-model | `boolean` |
34
+ | `change` | 切换后 | `boolean` |
@@ -0,0 +1,72 @@
1
+ <template>
2
+ <div class="bxt-group-title-wrapper">
3
+ <div class="bxt-group-title">
4
+ <div class="bxt-group-title-label">
5
+ <div class="bxt-group-title-label-name">
6
+ <span
7
+ :class="{
8
+ 'bxt-group-title-content': true,
9
+ 'bxt-group-title-content--disabled': !!disabled && !value
10
+ }"
11
+ >{{ label }}</span
12
+ >
13
+ </div>
14
+ <div class="bxt-group-title-label-switch">
15
+ <van-switch
16
+ :value="currentValue"
17
+ :disabled="disabled"
18
+ :size="size"
19
+ active-color="var(--bxt-primary)"
20
+ :data-stat-id="dataStatId"
21
+ @input="onSwitchInput"
22
+ />
23
+ </div>
24
+ </div>
25
+ </div>
26
+ </div>
27
+ </template>
28
+ <script lang="ts">
29
+ import Vue from 'vue'
30
+ import { Component, Model, Prop, Watch } from 'vue-property-decorator'
31
+ import './common-group-title.less'
32
+
33
+ @Component({
34
+ name: 'BxtGroupTitle'
35
+ })
36
+ export default class BxtGroupTitle extends Vue {
37
+ currentValue: boolean = false
38
+
39
+ @Model('input', {})
40
+ value!: boolean
41
+
42
+ @Prop({ default: '' })
43
+ label!: string
44
+
45
+ @Prop({ default: null })
46
+ disabled!: boolean
47
+
48
+ @Prop({ default: '' })
49
+ dataStatId!: string
50
+
51
+ @Prop({ default: 20 })
52
+ size!: string | number
53
+
54
+ @Watch('value', { immediate: true })
55
+ watchValue(val: boolean) {
56
+ this.currentValue = val
57
+ }
58
+
59
+ created() {
60
+ this.currentValue = this.value
61
+ }
62
+
63
+ onSwitchInput(val: boolean) {
64
+ if (this.disabled) {
65
+ return
66
+ }
67
+ this.currentValue = val
68
+ this.$emit('input', val)
69
+ this.$emit('change', val)
70
+ }
71
+ }
72
+ </script>
@@ -22,6 +22,10 @@
22
22
  border-color: var(--bxt-primary);
23
23
  }
24
24
 
25
+ & .van-checkbox--disabled .van-checkbox__icon--checked .van-icon {
26
+ opacity: 0.4;
27
+ }
28
+
25
29
  & .bxt-item-title-label {
26
30
  display: flex;
27
31
  padding: 5px 0;
@@ -9,7 +9,7 @@
9
9
  <span
10
10
  :class="{
11
11
  'bxt-titile-content': true,
12
- 'bxt-titile-content--disabled': !!disabled && !value
12
+ 'bxt-title-content--disabled': !!disabled && !value
13
13
  }"
14
14
  :style="{
15
15
  maxWidth: huomianTag || statusTag ? '78%' : '100%'
@@ -27,7 +27,7 @@
27
27
  {{ huomianTag }}
28
28
  </span>
29
29
  </div>
30
- <div v-if="!(currentValue && disabled)" class="bxt-item-title-label-item">
30
+ <div v-if="alwaysShowCheckbox || !(currentValue && disabled)" class="bxt-item-title-label-item">
31
31
  <van-checkbox class="bxt-item-title-checkbox" :value="currentValue" :disabled="disabled" @click.native="onchange" />
32
32
  </div>
33
33
  </div>
@@ -94,6 +94,12 @@ export default class BxtTitleItem extends Vue {
94
94
  })
95
95
  dataStatId!: string
96
96
 
97
+ /** 锁定勾选时仍展示 checkbox(组合子险必选) */
98
+ @Prop({
99
+ default: false
100
+ })
101
+ alwaysShowCheckbox!: boolean
102
+
97
103
  @Watch('value', {
98
104
  immediate: true,
99
105
  deep: true
@@ -0,0 +1,114 @@
1
+ # ProfessionList(职业类别)
2
+
3
+ ## 说明
4
+
5
+ 保险试算等场景下的职业类别选择 / 查询面板。支持异步接口拉取与本地树形 `columns` 两种数据源,可只读查询或选择后回传。
6
+
7
+ 非目标:不做投保规则引擎;校验由外部传入的 `verifyProfess` 决定。
8
+
9
+ ## 引用
10
+
11
+ ```js
12
+ import ProfessionList from 'src/components/profession-list'
13
+ // 或相对路径
14
+ import ProfessionList from '../../src/components/profession-list'
15
+ ```
16
+
17
+ ```html
18
+ <bxt-profession-list
19
+ v-model="isShowProfession"
20
+ :async-columns-params="asyncColumnsParams"
21
+ readonly
22
+ @select="onSelectProfession"
23
+ />
24
+ ```
25
+
26
+ ## Props
27
+
28
+ | 参数 | 说明 | 类型 | 默认值 |
29
+ |------|------|------|--------|
30
+ | value | 控制面板显隐(`v-model`) | Boolean | `false` |
31
+ | async-columns-params | 异步模式必传;含 `urlParams.userUuid`、`postParams.productId`,可选 `isDev` | Object | - |
32
+ | columns | 同步树形数据 | Array | `[]` |
33
+ | children-key-name | 子集字段名 | String | `'children'` |
34
+ | initial-selection | 同步模式默认选中(`{ code, des, val }`) | Object | `null` |
35
+ | verify-profess | 校验函数,返回 `true` / `false` | Function | `() => true` |
36
+ | readonly | 只读:选中叶子不关闭,仅展示是否符合条件 | Boolean | `false` |
37
+
38
+ ### asyncColumnsParams
39
+
40
+ | 字段 | 说明 |
41
+ |------|------|
42
+ | urlParams.userUuid | 拼到请求 query |
43
+ | postParams.productId | 请求 body |
44
+ | isDev | 可选,覆盖环境域名(`true` → `.cn`) |
45
+
46
+ ## Events
47
+
48
+ | 事件 | 说明 | 参数 |
49
+ |------|------|------|
50
+ | input | 显隐变更 | `Boolean` |
51
+ | select | 选中末级职业(搜索符合条件或非只读点选叶子) | 当前职业对象 |
52
+
53
+ ## Slots
54
+
55
+
56
+
57
+ ## Demo
58
+
59
+ ```html
60
+ <template>
61
+ <div>
62
+ <button @click="isShow = true">查询职业</button>
63
+ <bxt-profession-list
64
+ v-model="isShow"
65
+ :async-columns-params="asyncColumnsParams"
66
+ :verify-profess="verifyProfess"
67
+ @select="onSelect"
68
+ />
69
+ </div>
70
+ </template>
71
+
72
+ <script>
73
+ import ProfessionList from 'src/components/profession-list'
74
+
75
+ export default {
76
+ components: { BxtProfessionList: ProfessionList },
77
+ data() {
78
+ return {
79
+ isShow: false,
80
+ asyncColumnsParams: {
81
+ urlParams: { userUuid: 'xxx' },
82
+ postParams: { productId: '102163' },
83
+ isDev: true
84
+ }
85
+ }
86
+ },
87
+ methods: {
88
+ verifyProfess() {
89
+ return true
90
+ },
91
+ onSelect(item) {
92
+ console.log(item)
93
+ }
94
+ }
95
+ }
96
+ </script>
97
+ ```
98
+
99
+ ## 依赖
100
+
101
+ | 依赖 | 说明 |
102
+ |------|------|
103
+ | Vue 2 Options API | 组件实现 |
104
+ | vant ^2 | `Popup` / `Search` / `Icon` / `Empty` / `Toast` |
105
+ | `src/api` → `getProfession` | 异步职业接口 |
106
+ | 原生 App 桥接 | 无(不适用 use-wy-appbridge) |
107
+
108
+ ## 埋点清单
109
+
110
+ 本组件为通用选择面板,**当前无独立埋点**。若业务页需要,请在挂载入口的触发按钮上声明式埋点。
111
+
112
+ | 事件类型 | 触发位置 | statId | ep | 备注 |
113
+ |----------|----------|--------|----|------|
114
+ | - | - | - | - | 无 programmatic / 声明式埋点 |
@@ -0,0 +1,4 @@
1
+ /** 职业层级菜单文案 */
2
+ export const PROFESSION_LEVEL_DIGIT = ['一级', '二级', '三级', '四级', '五级', '六级', '七级', '八级', '九级', '十级']
3
+
4
+ export const DEFAULT_MENU_LIST = [{ des: '一级' }]
@@ -0,0 +1,155 @@
1
+ /**
2
+ * asyncColumnsParams 校验:异步模式下需 productId + userUuid
3
+ * null/undefined 表示未启用异步;不完整对象不告警(兼容父组件渐进赋值)
4
+ * @param {object|null|undefined} ov
5
+ * @returns {boolean}
6
+ */
7
+ export function asyncColumnsParamsValidator(ov) {
8
+ if (!ov || typeof ov !== 'object') {
9
+ return true
10
+ }
11
+ const { postParams, urlParams } = ov
12
+ // 尚未填入请求参数时跳过(避免 init 中间态告警)
13
+ if (!postParams && !urlParams) {
14
+ return true
15
+ }
16
+ return !!(postParams && postParams.productId && urlParams && urlParams.userUuid)
17
+ }
18
+
19
+ /**
20
+ * 是否已带职业类别(含 0 类;无 category 的为中间层级)
21
+ * @param {object} item
22
+ * @returns {boolean}
23
+ */
24
+ export function hasProfessionCategory(item) {
25
+ return item != null && item.category != null && item.category !== ''
26
+ }
27
+
28
+ /**
29
+ * 异步接口数据格式化:补齐 des / val
30
+ * @param {Array} data
31
+ * @returns {Array}
32
+ */
33
+ export function formatColumn(data) {
34
+ if (!data || data.length === 0) {
35
+ return []
36
+ }
37
+ return data.map(item => {
38
+ if (hasProfessionCategory(item)) {
39
+ return { ...item, des: item.name, val: item.category }
40
+ }
41
+ return { ...item, des: item.name }
42
+ })
43
+ }
44
+
45
+ /**
46
+ * 沿 parent 链拼出完整路径节点(搜索结果用)
47
+ * @param {object} item
48
+ * @param {Array} arr
49
+ * @returns {Array}
50
+ */
51
+ export function getAllNames(item, arr) {
52
+ if (!item.parent) {
53
+ arr.unshift(item)
54
+ return arr
55
+ }
56
+ arr.unshift(item)
57
+ return getAllNames(item.parent, arr)
58
+ }
59
+
60
+ /**
61
+ * 树转扁平数组(同步搜索用)
62
+ * @param {Array} list
63
+ * @param {string} des
64
+ * @param {Array} params
65
+ * @param {string} childrenKeyName
66
+ * @returns {Array}
67
+ */
68
+ export function treeTranArray(list, des, params, childrenKeyName) {
69
+ const res = params
70
+ for (let index = 0; index < list.length; index += 1) {
71
+ const item = list[index]
72
+ if (item[childrenKeyName]) {
73
+ const tempDes = `${des}-${item.des}`
74
+ treeTranArray(item[childrenKeyName], tempDes, res, childrenKeyName)
75
+ } else {
76
+ const tempDes = `${des}-${item.des}`
77
+ res.push({ ...item, des: tempDes.slice(1) })
78
+ }
79
+ }
80
+ return res
81
+ }
82
+
83
+ /**
84
+ * 按 code/des/val 查找职业路径
85
+ * @returns {{ nodes: Array }|null}
86
+ */
87
+ export function findProfessionByCode(list, code, des, val, childrenKeyName, params) {
88
+ for (let index = 0; index < list.length; index += 1) {
89
+ const item = list[index]
90
+ let data = JSON.parse(JSON.stringify(params || { nodes: [] }))
91
+ if (String(item.code) === String(code) && item.des === des && item.val === val) {
92
+ data.nodes.push(item)
93
+ return data
94
+ }
95
+ if (item[childrenKeyName]) {
96
+ data.nodes.push(item)
97
+ const result = findProfessionByCode(item[childrenKeyName], code, des, val, childrenKeyName, data)
98
+ if (result) {
99
+ return result
100
+ }
101
+ } else {
102
+ data = null
103
+ }
104
+ }
105
+ return null
106
+ }
107
+
108
+ /**
109
+ * 已选文案
110
+ * @param {Array} selected
111
+ * @param {boolean} asyncColumns
112
+ * @returns {string}
113
+ */
114
+ export function buildSelectedStr(selected, asyncColumns) {
115
+ if (!selected || !selected.length) {
116
+ return ''
117
+ }
118
+ if (asyncColumns) {
119
+ return selected.reduce((preVal, currVal, idx) => `${preVal}${currVal.name && idx > 0 ? '-' : ''}${currVal.name || ''}`, '')
120
+ }
121
+ return selected.reduce((preVal, currVal, idx) => `${preVal}${currVal.des && idx > 0 ? '-' : ''}${currVal.des || ''}`, '')
122
+ }
123
+
124
+ /**
125
+ * 根据已选生成层级菜单
126
+ * @param {Array} selected
127
+ * @param {boolean} asyncColumns
128
+ * @param {number} totalLevels
129
+ * @param {string[]} digit
130
+ * @returns {{ menuList: Array, totalLevels: number }}
131
+ */
132
+ export function buildMenuFromSelected(selected, asyncColumns, totalLevels, digit) {
133
+ const menuList = JSON.parse(JSON.stringify(selected || []))
134
+ let nextTotalLevels = totalLevels
135
+ if (asyncColumns) {
136
+ if (selected && selected.length) {
137
+ const lastItem = selected[selected.length - 1]
138
+ if (!hasProfessionCategory(lastItem)) {
139
+ menuList.push({
140
+ des: digit[menuList.length]
141
+ })
142
+ }
143
+ } else {
144
+ menuList.push({
145
+ des: digit[menuList.length]
146
+ })
147
+ }
148
+ nextTotalLevels = menuList.length
149
+ } else if (menuList.length < totalLevels) {
150
+ menuList.push({
151
+ des: digit[menuList.length]
152
+ })
153
+ }
154
+ return { menuList, totalLevels: nextTotalLevels }
155
+ }