这是基于vue-vben-admin 模板适用于abp vNext的前端管理项目
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

375 lines
15 KiB

<template>
<BasicModal
v-bind="$attrs"
@register="registerModal"
:title="formTitle"
:width="1000"
:min-height="500"
:mask-closable="false"
@ok="handleOk"
@visible-change="handleVisibleModal"
>
<Form
ref="formElRef"
:model="modelRef"
:rules="formRules"
:label-col="{ span: 6 }"
:wrapper-col="{ span: 18 }"
>
<Tabs
v-model:activeKey="tabActivedKey"
:style="tabsStyle.style"
:tabBarStyle="tabsStyle.tabBarStyle"
@change="handleChangeTab"
>
<!-- 基本信息 -->
<TabPane key="basic" :tab="L('Basics')">
<FormItem name="enabled" :label="L('Enabled')">
<Checkbox v-model:checked="modelRef.enabled">{{ L('Enabled') }}</Checkbox>
</FormItem>
<FormItem name="requireRequestObject" :label="L('Client:RequireRequestObject')">
<Checkbox v-model:checked="modelRef.requireRequestObject">{{
L('Client:RequireRequestObject')
}}</Checkbox>
</FormItem>
<FormItem name="clientId" required :label="L('Client:Id')">
<BInput v-model:value="modelRef.clientId" :disabled="isEdit" />
</FormItem>
<FormItem name="clientName" required :label="L('Name')">
<BInput v-model:value="modelRef.clientName" />
</FormItem>
<FormItem name="description" :label="L('Description')">
<TextArea v-model:value="modelRef.description" />
</FormItem>
<FormItem name="protocolType" :label="L('Client:ProtocolType')">
<Select v-model:value="modelRef.protocolType">
<Option value="oidc">OpenID Connect</Option>
</Select>
</FormItem>
<FormItem
name="allowedIdentityTokenSigningAlgorithms"
:label="L('Client:AllowedIdentityTokenSigningAlgorithms')"
>
<BInput v-model:value="modelRef.allowedIdentityTokenSigningAlgorithms" />
</FormItem>
<FormItem name="requirePkce" :label="L('Client:RequiredPkce')">
<Checkbox v-model:checked="modelRef.requirePkce">{{
L('Client:RequiredPkce')
}}</Checkbox>
</FormItem>
<FormItem name="allowPlainTextPkce" :label="L('Client:AllowedPlainTextPkce')">
<Checkbox v-model:checked="modelRef.allowPlainTextPkce">{{
L('Client:AllowedPlainTextPkce')
}}</Checkbox>
</FormItem>
</TabPane>
<!-- Urls -->
<TabPane key="urls">
<template #tab>
<Dropdown>
<span
>{{ L('Client:ApplicationUrls') }}
<DownOutlined />
</span>
<template #overlay>
<Menu @click="handleClickUrlsMenu">
<MenuItem key="ClientCallback">{{ L('Client:CallbackUrl') }}</MenuItem>
<MenuItem key="ClientCorsOrigins">{{
L('Client:AllowedCorsOrigins')
}}</MenuItem>
<MenuItem key="ClientLogoutRedirectUris">{{
L('Client:PostLogoutRedirectUri')
}}</MenuItem>
</Menu>
</template>
</Dropdown>
</template>
<component :is="componentsRef[urlsComponent]" :modelRef="modelRef" />
</TabPane>
<!-- 资源 -->
<TabPane key="resources">
<template #tab>
<Dropdown>
<span
>{{ L('Client:Resources') }}
<DownOutlined />
</span>
<template #overlay>
<Menu @click="handleClickResourcesMenu">
<MenuItem key="ClientApiResource">{{ L('Resource:Api') }}</MenuItem>
<MenuItem key="ClientIdentityResource">{{ L('Resource:Identity') }}</MenuItem>
</Menu>
</template>
</Dropdown>
</template>
<component :is="componentsRef[resourcesComponent]" :modelRef="modelRef" />
</TabPane>
<!-- 认证/注销 -->
<TabPane key="authentication" :tab="L('Authentication')">
<FormItem
name="frontChannelLogoutSessionRequired"
:label="L('Client:FrontChannelLogoutSessionRequired')"
>
<Checkbox v-model:checked="modelRef.frontChannelLogoutSessionRequired">{{
L('Client:FrontChannelLogoutSessionRequired')
}}</Checkbox>
</FormItem>
<!-- :required="modelRef.frontChannelLogoutSessionRequired" -->
<FormItem name="frontChannelLogoutUri" :label="L('Client:FrontChannelLogoutUri')">
<BInput v-model:value="modelRef.frontChannelLogoutUri" />
</FormItem>
<FormItem name="enabled" :label="L('Client:BackChannelLogoutSessionRequired')">
<Checkbox v-model:checked="modelRef.backChannelLogoutSessionRequired">{{
L('Client:BackChannelLogoutSessionRequired')
}}</Checkbox>
</FormItem>
<!-- :required="modelRef.backChannelLogoutSessionRequired" -->
<FormItem name="backChannelLogoutUri" :label="L('Client:BackChannelLogoutUri')">
<BInput v-model:value="modelRef.backChannelLogoutUri" />
</FormItem>
</TabPane>
<!-- 令牌 -->
<TabPane key="token" :tab="L('Token')">
<FormItem name="identityTokenLifetime" :label="L('Client:IdentityTokenLifetime')">
<InputNumber class="input-number" v-model:value="modelRef.identityTokenLifetime" />
</FormItem>
<FormItem name="accessTokenLifetime" :label="L('Client:AccessTokenLifetime')">
<InputNumber class="input-number" v-model:value="modelRef.accessTokenLifetime" />
</FormItem>
<FormItem name="accessTokenType" :label="L('Client:AccessTokenType')">
<Select v-model:value="modelRef.accessTokenType">
<Option :value="0">Jwt</Option>
<Option :value="1">Reference</Option>
</Select>
</FormItem>
<FormItem name="authorizationCodeLifetime" :label="L('Client:AuthorizationCodeLifetime')">
<InputNumber class="input-number" v-model:value="modelRef.authorizationCodeLifetime" />
</FormItem>
<FormItem
name="absoluteRefreshTokenLifetime"
:label="L('Client:AbsoluteRefreshTokenLifetime')"
>
<InputNumber
class="input-number"
v-model:value="modelRef.absoluteRefreshTokenLifetime"
/>
</FormItem>
<FormItem
name="slidingRefreshTokenLifetime"
:label="L('Client:SlidingRefreshTokenLifetime')"
>
<InputNumber
class="input-number"
v-model:value="modelRef.slidingRefreshTokenLifetime"
/>
</FormItem>
<FormItem name="refreshTokenUsage" :label="L('Client:RefreshTokenUsage')">
<Select v-model:value="modelRef.refreshTokenUsage">
<Option :value="0">ReUse</Option>
<Option :value="1">OneTimeOnly</Option>
</Select>
</FormItem>
<FormItem name="refreshTokenExpiration" :label="L('Client:RefreshTokenExpiration')">
<Select v-model:value="modelRef.refreshTokenExpiration">
<Option :value="0">Sliding</Option>
<Option :value="1">Absolute</Option>
</Select>
</FormItem>
<FormItem name="userSsoLifetime" :label="L('Client:UserSsoLifetime')">
<InputNumber class="input-number" v-model:value="modelRef.userSsoLifetime" />
</FormItem>
<FormItem name="allowOfflineAccess" :label="L('Client:AllowedOfflineAccess')">
<Checkbox v-model:checked="modelRef.allowOfflineAccess">{{
L('Client:AllowedOfflineAccess')
}}</Checkbox>
</FormItem>
<FormItem
name="allowAccessTokensViaBrowser"
:label="L('Client:AllowedAccessTokensViaBrowser')"
>
<Checkbox v-model:checked="modelRef.allowAccessTokensViaBrowser">{{
L('Client:AllowedAccessTokensViaBrowser')
}}</Checkbox>
</FormItem>
<FormItem
name="updateAccessTokenClaimsOnRefresh"
:label="L('Client:UpdateAccessTokenClaimsOnRefresh')"
>
<Checkbox v-model:checked="modelRef.updateAccessTokenClaimsOnRefresh">{{
L('Client:UpdateAccessTokenClaimsOnRefresh')
}}</Checkbox>
</FormItem>
<FormItem name="includeJwtId" :label="L('Client:IncludeJwtId')">
<Checkbox v-model:checked="modelRef.includeJwtId">{{
L('Client:IncludeJwtId')
}}</Checkbox>
</FormItem>
<FormItem name="clientClaimsPrefix" :label="L('Client:ClientClaimsPrefix')">
<BInput v-model:value="modelRef.clientClaimsPrefix" />
</FormItem>
<FormItem name="pairWiseSubjectSalt" :label="L('Client:PairWiseSubjectSalt')">
<BInput v-model:value="modelRef.pairWiseSubjectSalt" />
</FormItem>
</TabPane>
<!-- 同意屏幕 -->
<TabPane key="consent" :tab="L('Consent')">
<FormItem name="requireConsent" :label="L('Client:RequireConsent')">
<Checkbox v-model:checked="modelRef.requireConsent">{{
L('Client:RequireConsent')
}}</Checkbox>
</FormItem>
<FormItem name="allowRememberConsent" :label="L('Client:AllowRememberConsent')">
<Checkbox v-model:checked="modelRef.allowRememberConsent">{{
L('Client:AllowRememberConsent')
}}</Checkbox>
</FormItem>
<FormItem name="clientUri" :label="L('Client:ClientUri')">
<BInput v-model:value="modelRef.clientUri" />
</FormItem>
<FormItem name="logoUri" :label="L('Client:LogoUri')">
<BInput v-model:value="modelRef.logoUri" />
</FormItem>
</TabPane>
<!-- 设备流程 -->
<TabPane key="deviceFlow" :tab="L('DeviceFlow')">
<FormItem name="userCodeType" :label="L('Client:UserCodeType')">
<BInput v-model:value="modelRef.userCodeType" />
</FormItem>
<FormItem name="deviceCodeLifetime" :label="L('Client:DeviceCodeLifetime')">
<InputNumber class="input-number" v-model:value="modelRef.deviceCodeLifetime" />
</FormItem>
</TabPane>
<!-- 高级 -->
<TabPane key="advanced">
<template #tab>
<Dropdown>
<span
>{{ L('Advanced') }}
<DownOutlined />
</span>
<template #overlay>
<Menu @click="handleClickAdvancedMenu">
<MenuItem key="ClientSecret">{{ L('Secret') }}</MenuItem>
<MenuItem key="ClientClaim">{{ L('Claims') }}</MenuItem>
<MenuItem key="ClientProperties">{{ L('Propertites') }}</MenuItem>
<MenuItem key="ClientGrantType">{{ L('Client:AllowedGrantTypes') }}</MenuItem>
<MenuItem key="ClientIdentityProvider">{{
L('Client:IdentityProviderRestrictions')
}}</MenuItem>
</Menu>
</template>
</Dropdown>
</template>
<component :is="componentsRef[advancedComponent]" :modelRef="modelRef" />
</TabPane>
</Tabs>
</Form>
</BasicModal>
</template>
<script lang="ts" setup>
import { ref, shallowRef } from 'vue';
import { useTabsStyle } from '/@/hooks/component/useStyles';
import { useMessage } from '/@/hooks/web/useMessage';
import { useLocalization } from '/@/hooks/abp/useLocalization';
import { DownOutlined } from '@ant-design/icons-vue';
import { Checkbox, Dropdown, Menu, Tabs, Form, Input, InputNumber, Select } from 'ant-design-vue';
import { Input as BInput } from '/@/components/Input';
import { BasicModal, useModalInner } from '/@/components/Modal';
import { useModal } from '../hooks/useModal';
import ClientCallback from './ClientCallback.vue';
import ClientCorsOrigins from './ClientCorsOrigins.vue';
import ClientLogoutRedirectUris from './ClientLogoutRedirectUris.vue';
import ClientApiResource from './ClientApiResource.vue';
import ClientIdentityResource from './ClientIdentityResource.vue';
import ClientSecret from './ClientSecret.vue';
import ClientClaim from './ClientClaim.vue';
import ClientProperties from './ClientProperties.vue';
import ClientGrantType from './ClientGrantType.vue';
import ClientIdentityProvider from './ClientIdentityProvider.vue';
const FormItem = Form.Item;
const MenuItem = Menu.Item;
const TabPane = Tabs.TabPane;
const TextArea = Input.TextArea;
const Option = Select.Option;
const componentsRef = shallowRef({
'ClientCallback': ClientCallback,
'ClientCorsOrigins': ClientCorsOrigins,
'ClientLogoutRedirectUris': ClientLogoutRedirectUris,
'ClientApiResource': ClientApiResource,
'ClientIdentityResource': ClientIdentityResource,
'ClientSecret': ClientSecret,
'ClientClaim': ClientClaim,
'ClientProperties': ClientProperties,
'ClientGrantType': ClientGrantType,
'ClientIdentityProvider': ClientIdentityProvider,
});
const emits = defineEmits(['change', 'register']);
const { createMessage } = useMessage();
const { L } = useLocalization('AbpIdentityServer');
const formElRef = ref<any>(null);
const modelIdRef = ref('');
const tabActivedKey = ref('basic');
const advancedComponent = ref('ClientSecret');
const urlsComponent = ref('ClientCallback');
const resourcesComponent = ref('ClientApiResource');
const [registerModal, { changeOkLoading }] = useModalInner((val) => {
modelIdRef.value = val.id;
});
const {
isEdit,
modelRef,
formRules,
formTitle,
handleChangeTab,
handleVisibleModal,
handleSubmit,
} = useModal({
modelIdRef,
formElRef,
tabActivedKey,
});
const tabsStyle = useTabsStyle();
function handleClickAdvancedMenu(e) {
tabActivedKey.value = 'advanced';
advancedComponent.value = e.key;
}
function handleClickUrlsMenu(e) {
tabActivedKey.value = 'urls';
urlsComponent.value = e.key;
}
function handleClickResourcesMenu(e) {
tabActivedKey.value = 'resources';
resourcesComponent.value = e.key;
}
function handleOk() {
changeOkLoading(true);
handleSubmit().then(() => {
createMessage.success(L('Successful'));
emits('change');
}).finally(() => {
changeOkLoading(false);
});
}
</script>
<style lang="less" scoped>
.input-number {
width: 100%;
}
</style>