Compare commits

...

46 Commits

Author SHA1 Message Date
fit2bot
3717089c4c feat: Update v3.0.1 2023-02-27 18:45:21 +08:00
Aaron3S
c2706bbafa fix: 修复 term 组件上的按钮被覆盖的问题 2023-02-27 18:35:22 +08:00
老广
d65f5326ae Merge pull request #2816 from jumpserver/pr@v3.0@fix_platform_create
perf: 修改 assetMeta 调用
2023-02-27 17:56:09 +08:00
ibuler
5e048b5537 perf: 修改 assetMeta 调用 2023-02-27 09:46:31 +00:00
老广
5199bfb144 Merge pull request #2814 from jumpserver/pr@v3.0@fix_platform_create
fix: 修复平台创建
2023-02-27 17:44:10 +08:00
ibuler
415e01984a fix: 修复平台创建 2023-02-27 09:40:18 +00:00
feng
bca21fb11e perf: lina 提示优化 2023-02-27 16:27:54 +08:00
Aaron3S
f1d4bbe23c fix: 暂时隐藏参数设置字段 2023-02-27 16:11:51 +08:00
feng626
c425d3842a Merge pull request #2807 from jumpserver/revert-2799-pr@v3.0@lina_point_out
Revert "perf: lina 提示优化"
2023-02-27 16:01:45 +08:00
feng626
86147dc48e Revert "perf: lina 提示优化" 2023-02-27 16:00:03 +08:00
ibuler
656a76dae9 perf: 平台允许修改 2023-02-27 15:51:11 +08:00
ibuler
bad88b1543 perf: 添加accounts 搜索建议 2023-02-27 15:21:00 +08:00
feng626
71c58dcf8f Merge pull request #2799 from jumpserver/pr@v3.0@lina_point_out
perf: lina 提示优化
2023-02-27 13:28:55 +08:00
feng
7e953296c5 perf: lina 提示优化 2023-02-27 13:25:07 +08:00
Bai
e381a32954 perf: 优化 applet host 请求引起的 error 2023-02-26 12:37:50 +08:00
feng626
a4c239a79f Merge pull request #2793 from jumpserver/pr@v3.0@add_account_asset_required
perf: add account asset required
2023-02-24 16:26:41 +08:00
feng
645b3d96c4 perf: add account asset required 2023-02-24 16:25:31 +08:00
Jiangjie.Bai
36aea652d6 Merge pull request #2788 from jumpserver/dev
v3.0.0
2023-02-23 20:16:41 +08:00
Jiangjie.Bai
1a42ce90ab Merge pull request #2760 from jumpserver/dev
v3.0.0-rc-latest
2023-02-22 22:21:54 +08:00
Jiangjie.Bai
31a401b55d Merge pull request #2463 from jumpserver/dev
v3.0.0-rc4
2023-01-31 18:55:34 +08:00
Jiangjie.Bai
582a84178d Merge pull request #2187 from jumpserver/dev
v2.28.0
2022-11-17 17:44:19 +08:00
Jiangjie.Bai
9b9f7c936c Merge pull request #2184 from jumpserver/dev
v2.28.0-rc5
2022-11-17 14:18:15 +08:00
Jiangjie.Bai
2a6100957f Merge pull request #2182 from jumpserver/dev
v2.28.0-rc4
2022-11-16 21:08:55 +08:00
Jiangjie.Bai
16606d6a27 Merge pull request #2176 from jumpserver/dev
v2.28.0-rc2
2022-11-14 10:01:05 +08:00
Jiangjie.Bai
0a612f50e6 Merge pull request #2164 from jumpserver/dev
v2.28.0-rc1
2022-11-10 17:45:47 +08:00
Jiangjie.Bai
fe36fa9390 Merge pull request #2117 from jumpserver/dev
v2.27.0-rc4
2022-10-18 21:02:10 +08:00
Jiangjie.Bai
ba109900ec Merge pull request #2113 from jumpserver/dev
v2.27.0-rc3
2022-10-18 11:20:57 +08:00
Jiangjie.Bai
ec7768267f Merge pull request #2105 from jumpserver/dev
v2.27.0-rc2
2022-10-14 11:01:32 +08:00
Jiangjie.Bai
cc58b374ab Merge pull request #2101 from jumpserver/dev
v2.27.0-rc1
2022-10-13 17:44:53 +08:00
Jiangjie.Bai
04ffbb8fd6 Merge pull request #2097 from jumpserver/dev
v2.27.0-rc1
2022-10-13 15:14:40 +08:00
Jiangjie.Bai
49880f6739 Merge pull request #2059 from jumpserver/dev
v2.26.0
2022-09-15 17:49:44 +08:00
Jiangjie.Bai
e6f98d58c4 Merge pull request #2057 from jumpserver/dev
v2.26.0-rc4
2022-09-15 16:18:03 +08:00
Jiangjie.Bai
fd1f16d43c Merge pull request #2050 from jumpserver/dev
v2.26.0-rc2
2022-09-13 17:41:39 +08:00
Jiangjie.Bai
968b2415b1 Merge pull request #2043 from jumpserver/dev
v2.26.0-rc1
2022-09-08 15:46:44 +08:00
Jiangjie.Bai
776090d6ba Merge pull request #2001 from jumpserver/dev
v2.25.0
2022-08-18 16:12:45 +08:00
Jiangjie.Bai
3a37952288 Merge pull request #1996 from jumpserver/dev
v2.25.0-rc4
2022-08-17 16:53:23 +08:00
Jiangjie.Bai
62b8fc0e3b Merge pull request #1994 from jumpserver/dev
v2.25.0-rc3
2022-08-16 19:08:23 +08:00
Jiangjie.Bai
b2028869cb Merge pull request #1986 from jumpserver/dev
v2.25.0-rc2
2022-08-12 18:06:56 +08:00
Jiangjie.Bai
5277a725f8 Merge pull request #1973 from jumpserver/dev
v2.25.0-rc1
2022-08-11 14:11:59 +08:00
Jiangjie.Bai
f137788c1a Merge pull request #1957 from jumpserver/dev
v2.24.0-rc5
2022-07-20 19:06:03 +08:00
Jiangjie.Bai
f7d17c8de7 Merge pull request #1954 from jumpserver/dev
v2.24.0-rc4
2022-07-19 16:18:13 +08:00
Jiangjie.Bai
feea70b0be Merge pull request #1944 from jumpserver/dev
v2.24.0-rc3
2022-07-18 12:05:42 +08:00
Jiangjie.Bai
04696ef3d6 Merge pull request #1940 from jumpserver/dev
v2.24.0-rc2
2022-07-15 18:07:37 +08:00
Jiangjie.Bai
1731f4f788 Merge pull request #1934 from jumpserver/dev
v2.24.0-rc1
2022-07-14 18:27:51 +08:00
Jiangjie.Bai
6f25d93909 Merge pull request #1931 from jumpserver/dev
v2.24.0-rc1
2022-07-14 17:51:58 +08:00
Jiangjie.Bai
46461ec324 Merge pull request #1925 from jumpserver/dev
v2.24.0-rc1
2022-07-14 15:12:15 +08:00
16 changed files with 87 additions and 47 deletions

1
GITSHA Normal file
View File

@@ -0,0 +1 @@
c2706bbafa15a6d64fd19df3cc4eaf196b8d9482

View File

@@ -13,7 +13,7 @@ import { UpdateToken } from '@/components/FormFields'
import Select2 from '@/components/FormFields/Select2' import Select2 from '@/components/FormFields/Select2'
import AssetSelect from '@/components/AssetSelect' import AssetSelect from '@/components/AssetSelect'
import { encryptPassword } from '@/utils/crypto' import { encryptPassword } from '@/utils/crypto'
import { RequiredChange } from '@/components/DataForm/rules' import { RequiredChange, Required } from '@/components/DataForm/rules'
export default { export default {
name: 'AccountCreateForm', name: 'AccountCreateForm',
@@ -67,6 +67,7 @@ export default {
], ],
fieldsMeta: { fieldsMeta: {
assets: { assets: {
rules: [Required],
component: AssetSelect, component: AssetSelect,
label: this.$t('assets.Asset'), label: this.$t('assets.Asset'),
el: { el: {

View File

@@ -12,14 +12,17 @@
> >
{{ v }} {{ v }}
</el-tag> </el-tag>
<el-input <component
:is="component"
ref="SearchInput" ref="SearchInput"
v-model.trim="filterValue" v-model.trim="filterValue"
:fetch-suggestions="autocomplete"
:placeholder="this.$t('common.EnterToContinue')" :placeholder="this.$t('common.EnterToContinue')"
class="search-input" class="search-input"
@blur="focus = false" @blur="focus = false"
@change="handleConfirm" @change="handleConfirm"
@focus="focus = true" @focus="focus = true"
@select="handleSelect"
@keyup.enter.native="handleConfirm" @keyup.enter.native="handleConfirm"
/> />
</div> </div>
@@ -41,13 +44,18 @@ export default {
placeholder: { placeholder: {
type: String, type: String,
default: () => i18n.t('perms.Input') default: () => i18n.t('perms.Input')
},
autocomplete: {
type: Function,
default: null
} }
}, },
data() { data() {
return { return {
filterTags: this.value, filterTags: this.value,
focus: false, focus: false,
filterValue: '' filterValue: '',
component: this.autocomplete ? 'el-autocomplete' : 'el-input'
} }
}, },
methods: { methods: {
@@ -55,6 +63,10 @@ export default {
this.filterTags.splice(this.filterTags.indexOf(tag), 1) this.filterTags.splice(this.filterTags.indexOf(tag), 1)
this.$emit('change', this.filterTags) this.$emit('change', this.filterTags)
}, },
handleSelect(item) {
this.filterValue = item.value
this.handleConfirm()
},
handleConfirm() { handleConfirm() {
if (this.filterValue === '') return if (this.filterValue === '') return
if (!this.filterTags.includes(this.filterValue)) { if (!this.filterTags.includes(this.filterValue)) {

View File

@@ -55,14 +55,14 @@ export default {
toolbar: [ toolbar: [
{ {
tip: this.$tc('ops.ScrollToTop'), tip: this.$tc('ops.ScrollToTop'),
icon: 'fa fa-upload', icon: 'fa fa-arrow-up',
callback: () => { callback: () => {
this.xterm.scrollToTop() this.xterm.scrollToTop()
} }
}, },
{ {
tip: this.$tc('ops.ScrollToBottom'), tip: this.$tc('ops.ScrollToBottom'),
icon: 'fa fa-download', icon: 'fa fa-arrow-down',
callback: () => { callback: () => {
this.xterm.scrollToBottom() this.xterm.scrollToBottom()
} }
@@ -108,10 +108,10 @@ export default {
} }
.actions { .actions {
position: absolute; text-align: right;
right: 4px; background-color: #FFF;
z-index: 2; padding-right: 5px;
margin-top: 4px; padding-top: 2px;
} }
.el-button { .el-button {

View File

@@ -290,6 +290,7 @@
"Domain": "Domain", "Domain": "Domain",
"DomainDetail": "Domain detail", "DomainDetail": "Domain detail",
"DomainHelpMessage": "The domain function is added to address the fact that some environments (such as the hybrid cloud) cannot be connected directly by jumping on the gateway server.\nJMS => Domain gateway => Target assets", "DomainHelpMessage": "The domain function is added to address the fact that some environments (such as the hybrid cloud) cannot be connected directly by jumping on the gateway server.\nJMS => Domain gateway => Target assets",
"WebHelpMessage": "Web type assets depend on remote applications. Please go to System Settings to configure the publisher in the remote application.",
"FullName": "Full name", "FullName": "Full name",
"Gateway": "Gateway", "Gateway": "Gateway",
"GatewayList": "Gateway", "GatewayList": "Gateway",
@@ -999,7 +1000,7 @@
"ManualInput": "Manual input", "ManualInput": "Manual input",
"SameAccount": "Same account", "SameAccount": "Same account",
"SpecifyAccounts": "Specify accounts", "SpecifyAccounts": "Specify accounts",
"AccountsHelp": "All accounts: accounts exists on the asset; Specify accounts: specify accounts by usernameManual input: username/password; Same account: The account username name same with login user", "AccountsHelp": "All accounts: accounts exists on the asset; Specify accounts: specify the user name of the account under the assetManual input: username/password; Same account: The account username name same with login user",
"Input": "Input", "Input": "Input",
"permAccount": "Accounts", "permAccount": "Accounts",
"Actions": "Actions", "Actions": "Actions",

View File

@@ -283,6 +283,7 @@
"Domain": "ドメイン", "Domain": "ドメイン",
"DomainDetail": "ドメインの詳細", "DomainDetail": "ドメインの詳細",
"DomainHelpMessage": "ドメイン機能は、一部の環境 (ハイブリッドクラウドなど) が直接接続できないことを解決するために追加された機能で、ゲートウェイサーバを介してジャンプ登録を行うのが原理です。JMS => ドメインゲートウェイ => ターゲット資産", "DomainHelpMessage": "ドメイン機能は、一部の環境 (ハイブリッドクラウドなど) が直接接続できないことを解決するために追加された機能で、ゲートウェイサーバを介してジャンプ登録を行うのが原理です。JMS => ドメインゲートウェイ => ターゲット資産",
"WebHelpMessage": "Web タイプ資産はリモートアプリケーションに依存しており、システム設定のリモートアプリケーションでパブリッシャを構成してください。",
"FullName": "フルネーム", "FullName": "フルネーム",
"Gateway": "ゲートウェイ", "Gateway": "ゲートウェイ",
"GatewayProtocolHelpText": "SSHゲートウェイ、プロキシSSH、RDP、VNCをサポート", "GatewayProtocolHelpText": "SSHゲートウェイ、プロキシSSH、RDP、VNCをサポート",
@@ -997,7 +998,7 @@
"ManualInput": "手動入力", "ManualInput": "手動入力",
"SameAccount": "同じ名前のアカウント", "SameAccount": "同じ名前のアカウント",
"SpecifyAccounts": "入力の指定", "SpecifyAccounts": "入力の指定",
"AccountsHelp": "すべてのアカウント: アカウントはアセットに存在します。 アカウントの指定: ユーザー名でアカウントを指定します。手入力: ユーザー名/パスワード; 同一アカウント:ログインユーザーと同じアカウントのユーザー名", "AccountsHelp": "すべてのアカウント: アカウントはアセットに存在します。 アカウントの指定: 資産の下のアカウントのユーザー名を指定します。手入力: ユーザー名/パスワード; 同一アカウント:ログインユーザーと同じアカウントのユーザー名",
"Input": "入力", "Input": "入力",
"permAccount": "認定アカウント", "permAccount": "認定アカウント",
"Actions": "アクション", "Actions": "アクション",

View File

@@ -297,6 +297,7 @@
"Domain": "网域", "Domain": "网域",
"DomainDetail": "网域详情", "DomainDetail": "网域详情",
"DomainHelpMessage": "网域功能是为了解决部分环境混合云无法直接连接而新增的功能原理是通过网关服务器进行跳转登录。JMS => 网域网关 => 目标资产", "DomainHelpMessage": "网域功能是为了解决部分环境混合云无法直接连接而新增的功能原理是通过网关服务器进行跳转登录。JMS => 网域网关 => 目标资产",
"WebHelpMessage": "Web 类型资产依赖于远程应用,请前往系统设置在远程应用中配置发布机。",
"FullName": "全称", "FullName": "全称",
"Gateway": "网关", "Gateway": "网关",
"GatewayProtocolHelpText": "SSH网关支持代理SSH,RDP和VNC", "GatewayProtocolHelpText": "SSH网关支持代理SSH,RDP和VNC",
@@ -989,7 +990,7 @@
}, },
"perms": { "perms": {
"": "", "": "",
"AccountsHelp": "所有账号: 资产上添加的账号; 指定账号:指定账号的用户名;手动输入: 用户名/密码 手动输入; 同名账号: 与被授权人用户名相同的账号;", "AccountsHelp": "所有账号: 资产上添加的账号; 指定账号:指定资产下账号的用户名;手动输入: 用户名/密码 手动输入; 同名账号: 与被授权人用户名相同的账号;",
"AllAccounts": "所有账号", "AllAccounts": "所有账号",
"ManualInput": "手动输入", "ManualInput": "手动输入",
"SameAccount": "同名账号", "SameAccount": "同名账号",

View File

@@ -10,7 +10,7 @@ function getPropOrg() {
if (defaultOrg) { if (defaultOrg) {
return defaultOrg return defaultOrg
} }
return orgs.filter(item => !item['is_root'])[0] return orgs.filter(item => !item['is_root'] && item.id !== SYSTEM_ORG_ID)[0]
} }
async function change2PropOrg() { async function change2PropOrg() {

View File

@@ -8,7 +8,7 @@ import { Message } from '@/utils/Message'
import store from '@/store' import store from '@/store'
import axiosRetry from 'axios-retry' import axiosRetry from 'axios-retry'
import router from '@/router' import router from '@/router'
import { DEFAULT_ORG_ID } from '@/utils/org' import { DEFAULT_ORG_ID, SYSTEM_ORG_ID } from '@/utils/org'
// create an axios instance // create an axios instance
const service = axios.create({ const service = axios.create({
@@ -25,7 +25,7 @@ function beforeRequestAddToken(config) {
const queryOrgId = router.currentRoute.query?.oid const queryOrgId = router.currentRoute.query?.oid
const storeOrgId = store.getters.currentOrg?.id const storeOrgId = store.getters.currentOrg?.id
let orgId = queryOrgId || storeOrgId let orgId = queryOrgId || storeOrgId
if (!store.getters.publicSettings?.XPACK_ENABLED) { if (!store.getters.publicSettings?.XPACK_ENABLED && orgId !== SYSTEM_ORG_ID) {
orgId = DEFAULT_ORG_ID orgId = DEFAULT_ORG_ID
} }
if (orgId) { if (orgId) {

View File

@@ -27,7 +27,8 @@ export default {
width: '100px' width: '100px'
} }
} }
} },
helpMessage: this.$t('assets.DomainHelpMessage')
} }
} }
} }

View File

@@ -1,5 +1,8 @@
<template> <template>
<div> <div>
<el-alert v-if="helpMessage" type="success">
<span class="announcement-main" v-html="helpMessage" />
</el-alert>
<ListTable ref="ListTable" :header-actions="iHeaderActions" :table-config="iTableConfig" /> <ListTable ref="ListTable" :header-actions="iHeaderActions" :table-config="iTableConfig" />
<PlatformDialog :category="category" :visible.sync="showPlatform" /> <PlatformDialog :category="category" :visible.sync="showPlatform" />
<AssetBulkUpdateDialog <AssetBulkUpdateDialog
@@ -52,6 +55,10 @@ export default {
addExtraMoreActions: { addExtraMoreActions: {
type: Array, type: Array,
default: () => [] default: () => []
},
helpMessage: {
type: String,
default: ''
} }
}, },
data() { data() {

View File

@@ -3,9 +3,8 @@ import rules from '@/components/DataForm/rules'
import { JsonEditor } from '@/components/FormFields' import { JsonEditor } from '@/components/FormFields'
import { assetFieldsMeta } from '@/views/assets/const' import { assetFieldsMeta } from '@/views/assets/const'
const assetMeta = assetFieldsMeta()
export const platformFieldsMeta = (vm) => { export const platformFieldsMeta = (vm) => {
const assetMeta = assetFieldsMeta(vm)
return { return {
automation: { automation: {
initial: { initial: {

View File

@@ -29,6 +29,7 @@ export const filterSelectValues = (values) => {
export const assetFieldsMeta = (vm) => { export const assetFieldsMeta = (vm) => {
const platformProtocols = [] const platformProtocols = []
const secretTypes = [] const secretTypes = []
const platformType = vm?.$route.query.platform_type
return { return {
address: { address: {
rules: [rules.IpCheck, rules.specialEmojiCheck] rules: [rules.IpCheck, rules.specialEmojiCheck]
@@ -58,9 +59,8 @@ export const assetFieldsMeta = (vm) => {
platform: { platform: {
el: { el: {
multiple: false, multiple: false,
disabled: true,
ajax: { ajax: {
url: '/api/v1/assets/platforms/', url: `/api/v1/assets/platforms/?type=${platformType}`,
transformOption: (item) => { transformOption: (item) => {
return { label: item.name, value: item.id } return { label: item.name, value: item.id }
} }

View File

@@ -8,7 +8,6 @@
<script> <script>
import { GenericCreateUpdatePage } from '@/layout/components' import { GenericCreateUpdatePage } from '@/layout/components'
import AssetSelect from '@/components/AssetSelect' import AssetSelect from '@/components/AssetSelect'
import { JsonEditor } from '@/components/FormFields'
import CodeEditor from '@/components/FormFields/CodeEditor' import CodeEditor from '@/components/FormFields/CodeEditor'
import { CronTab } from '@/components' import { CronTab } from '@/components'
import i18n from '@/i18n/i18n' import i18n from '@/i18n/i18n'
@@ -30,7 +29,6 @@ export default {
[this.$t('common.Basic'), ['name', 'type', 'instant']], [this.$t('common.Basic'), ['name', 'type', 'instant']],
[this.$t('common.Task'), ['module', 'args', 'playbook', 'chdir', 'timeout']], [this.$t('common.Task'), ['module', 'args', 'playbook', 'chdir', 'timeout']],
[this.$t('ops.Asset'), ['assets', 'runas', 'runas_policy']], [this.$t('ops.Asset'), ['assets', 'runas', 'runas_policy']],
[this.$t('ops.Parameter'), ['use_parameter_define', 'parameters_define']],
[this.$t('ops.Plan'), ['run_after_save', 'is_periodic', 'crontab']], [this.$t('ops.Plan'), ['run_after_save', 'is_periodic', 'crontab']],
[this.$t('common.Other'), ['comment']] [this.$t('common.Other'), ['comment']]
], ],
@@ -134,13 +132,6 @@ export default {
return true return true
} }
}, },
parameters_define: {
label: '',
component: JsonEditor,
hidden: (formValue) => {
return !formValue.use_parameter_define
}
},
chdir: { chdir: {
helpText: i18n.t('ops.ChdirHelpText'), helpText: i18n.t('ops.ChdirHelpText'),
hidden: (formValue) => { hidden: (formValue) => {
@@ -153,13 +144,6 @@ export default {
return this.instantTask return this.instantTask
} }
}, },
use_parameter_define: {
label: this.$t('ops.UseParameterDefine'),
type: 'switch',
hidden: () => {
return this.instantTask
}
},
is_periodic: { is_periodic: {
type: 'switch', type: 'switch',
hidden: () => { hidden: () => {

View File

@@ -91,7 +91,15 @@ export default {
type: 'input', type: 'input',
label: this.$t('perms.Account'), label: this.$t('perms.Account'),
component: AccountFormatter, component: AccountFormatter,
helpText: this.$t('perms.AccountsHelp') helpText: this.$t('perms.AccountsHelp'),
el: {
assets: [],
nodes: []
},
hidden: (formValue) => {
this.fieldsMeta.accounts.el.assets = formValue.assets
this.fieldsMeta.accounts.el.nodes = formValue.nodes
}
}, },
actions: { actions: {
label: this.$t('perms.Actions'), label: this.$t('perms.Actions'),

View File

@@ -12,6 +12,7 @@
</el-checkbox-group> </el-checkbox-group>
<TagInput <TagInput
v-if="showSpecAccounts" v-if="showSpecAccounts"
:autocomplete="autocomplete"
:value="specAccountsInput" :value="specAccountsInput"
@change="handleTagChange" @change="handleTagChange"
/> />
@@ -20,13 +21,7 @@
<script> <script>
import { TagInput } from '@/components/FormFields' import { TagInput } from '@/components/FormFields'
import { import { AccountLabelMapper, AllAccount, ManualINPUT, SameUSER, SPECAccount } from '@/views/perms/const'
AllAccount,
SPECAccount,
SameUSER,
ManualINPUT,
AccountLabelMapper
} from '@/views/perms/const'
export default { export default {
components: { components: {
@@ -36,9 +31,18 @@ export default {
value: { value: {
type: [Array], type: [Array],
default: () => [] default: () => []
},
assets: {
type: [Array],
default: () => []
},
nodes: {
type: [Array],
default: () => []
} }
}, },
data() { data() {
const vm = this
const choices = [ const choices = [
{ {
label: AccountLabelMapper[AllAccount], label: AccountLabelMapper[AllAccount],
@@ -64,7 +68,27 @@ export default {
choicesSelected: [], choicesSelected: [],
defaultChoices: [this.ALL], defaultChoices: [this.ALL],
specAccountsInput: [], specAccountsInput: [],
showSpecAccounts: false showSpecAccounts: false,
autocomplete: (query, cb) => {
this.$axios.get('/api/v1/accounts/accounts/username-suggestions/', {
params: {
username: query,
assets: this.assets.slice(0, 20).join(','),
nodes: this.nodes.slice(0, 20).map(item => {
if (typeof item === 'object') {
return item.pk
} else {
return item.pk
}
}).join(',')
}
}).then(res => {
const data = res
.filter(item => vm.value.indexOf(item) === -1)
.map(v => ({ value: v, label: v }))
cb(data)
})
}
} }
}, },
mounted() { mounted() {