32 changed files with 18878 additions and 77 deletions
@ -0,0 +1,12 @@ |
|||||
|
using System.ComponentModel.DataAnnotations; |
||||
|
|
||||
|
namespace CompanyName.ProjectName.IdentityServers.Clients |
||||
|
{ |
||||
|
public class EnabledInput |
||||
|
{ |
||||
|
[Required] |
||||
|
public string ClientId { get; set; } |
||||
|
|
||||
|
public bool Enabled { get; set; } |
||||
|
} |
||||
|
} |
||||
File diff suppressed because it is too large
@ -0,0 +1,61 @@ |
|||||
|
<template> |
||||
|
<BasicModal title="创建ApiResource" :canFullscreen="false" @ok="submit" @cancel="cancel" @register="registerModal"> |
||||
|
<BasicForm @register="registerApiResourceForm" /> |
||||
|
</BasicModal> |
||||
|
</template> |
||||
|
|
||||
|
<script lang="ts"> |
||||
|
import { defineComponent, useContext, defineEmit } from 'vue'; |
||||
|
import { BasicModal, useModalInner } from '/@/components/Modal'; |
||||
|
import { BasicForm, useForm } from '/@/components/Form/index'; |
||||
|
import { createFormSchema, createApiResourceAsync } from './ApiResources'; |
||||
|
import { useI18n } from '/@/hooks/web/useI18n'; |
||||
|
|
||||
|
export default defineComponent({ |
||||
|
name: 'CreateApiResource', |
||||
|
components: { |
||||
|
BasicModal, |
||||
|
BasicForm, |
||||
|
}, |
||||
|
setup() { |
||||
|
// 加载父组件方法 |
||||
|
defineEmit(['reload']); |
||||
|
const ctx = useContext(); |
||||
|
|
||||
|
const { t } = useI18n(); |
||||
|
const [registerApiResourceForm, { getFieldsValue, validate, resetFields }] = useForm({ |
||||
|
labelWidth: 120, |
||||
|
schemas: createFormSchema, |
||||
|
showActionButtonGroup: false, |
||||
|
}); |
||||
|
|
||||
|
const [registerModal, { changeOkLoading, closeModal }] = useModalInner(); |
||||
|
|
||||
|
// 保存角色 |
||||
|
const submit = async () => { |
||||
|
try { |
||||
|
const request = getFieldsValue(); |
||||
|
await createApiResourceAsync({ request, changeOkLoading, validate, closeModal }); |
||||
|
resetFields(); |
||||
|
ctx.emit('reload'); |
||||
|
} catch (error) { |
||||
|
changeOkLoading(false); |
||||
|
} |
||||
|
}; |
||||
|
|
||||
|
const cancel = () => { |
||||
|
resetFields(); |
||||
|
closeModal(); |
||||
|
}; |
||||
|
return { |
||||
|
t, |
||||
|
registerModal, |
||||
|
registerApiResourceForm, |
||||
|
submit, |
||||
|
cancel, |
||||
|
}; |
||||
|
}, |
||||
|
}); |
||||
|
</script> |
||||
|
|
||||
|
<style lang="less" scoped></style> |
||||
@ -0,0 +1,60 @@ |
|||||
|
<template> |
||||
|
<BasicModal title="创建ApiScope" :canFullscreen="false" @ok="submit" @cancel="cancel" @register="registerModal"> |
||||
|
<BasicForm @register="registerApiScopeForm" /> |
||||
|
</BasicModal> |
||||
|
</template> |
||||
|
|
||||
|
<script lang="ts"> |
||||
|
import { defineComponent, useContext, defineEmit } from 'vue'; |
||||
|
import { BasicModal, useModalInner } from '/@/components/Modal'; |
||||
|
import { BasicForm, useForm } from '/@/components/Form/index'; |
||||
|
import { createFormSchema, createApiScopeAsync } from './ApiScopes'; |
||||
|
import { useI18n } from '/@/hooks/web/useI18n'; |
||||
|
|
||||
|
export default defineComponent({ |
||||
|
name: 'CreateApiScope', |
||||
|
components: { |
||||
|
BasicModal, |
||||
|
BasicForm, |
||||
|
}, |
||||
|
setup() { |
||||
|
// 加载父组件方法 |
||||
|
defineEmit(['reload']); |
||||
|
const ctx = useContext(); |
||||
|
|
||||
|
const { t } = useI18n(); |
||||
|
const [registerApiScopeForm, { getFieldsValue, validate, resetFields }] = useForm({ |
||||
|
labelWidth: 120, |
||||
|
schemas: createFormSchema, |
||||
|
showActionButtonGroup: false, |
||||
|
}); |
||||
|
|
||||
|
const [registerModal, { changeOkLoading, closeModal }] = useModalInner(); |
||||
|
|
||||
|
const submit = async () => { |
||||
|
try { |
||||
|
const request = getFieldsValue(); |
||||
|
await createApiScopeAsync({ request, changeOkLoading, validate, closeModal }); |
||||
|
resetFields(); |
||||
|
ctx.emit('reload'); |
||||
|
} catch (error) { |
||||
|
changeOkLoading(false); |
||||
|
} |
||||
|
}; |
||||
|
|
||||
|
const cancel = () => { |
||||
|
resetFields(); |
||||
|
closeModal(); |
||||
|
}; |
||||
|
return { |
||||
|
t, |
||||
|
registerModal, |
||||
|
registerApiScopeForm, |
||||
|
submit, |
||||
|
cancel, |
||||
|
}; |
||||
|
}, |
||||
|
}); |
||||
|
</script> |
||||
|
|
||||
|
<style lang="less" scoped></style> |
||||
@ -0,0 +1,72 @@ |
|||||
|
<template> |
||||
|
<BasicModal title="创建ApiScope" :canFullscreen="false" @ok="submit" @cancel="cancel" @register="registerModal"> |
||||
|
<BasicForm @register="registerApiScopeForm" /> |
||||
|
</BasicModal> |
||||
|
</template> |
||||
|
|
||||
|
<script lang="ts"> |
||||
|
import { defineComponent, useContext, defineEmit } from 'vue'; |
||||
|
import { BasicModal, useModalInner } from '/@/components/Modal'; |
||||
|
import { BasicForm, useForm } from '/@/components/Form/index'; |
||||
|
import { editFormSchema, editApiScopeAsync } from './ApiScopes'; |
||||
|
import { useI18n } from '/@/hooks/web/useI18n'; |
||||
|
|
||||
|
export default defineComponent({ |
||||
|
name: 'EditApiScope', |
||||
|
components: { |
||||
|
BasicModal, |
||||
|
BasicForm, |
||||
|
}, |
||||
|
setup() { |
||||
|
// 加载父组件方法 |
||||
|
defineEmit(['reload']); |
||||
|
const ctx = useContext(); |
||||
|
|
||||
|
const { t } = useI18n(); |
||||
|
const [registerApiScopeForm, { getFieldsValue, validate, resetFields, setFieldsValue }] = useForm({ |
||||
|
labelWidth: 120, |
||||
|
schemas: editFormSchema, |
||||
|
showActionButtonGroup: false, |
||||
|
}); |
||||
|
|
||||
|
const [registerModal, { changeOkLoading, closeModal }] = useModalInner((data) => { |
||||
|
console.log(data.record); |
||||
|
setFieldsValue({ |
||||
|
name: data.record.name, |
||||
|
enabled: data.record.enabled, |
||||
|
displayName: data.record.displayName, |
||||
|
description: data.record.description, |
||||
|
required: data.record.required, |
||||
|
emphasize: data.record.emphasize, |
||||
|
showInDiscoveryDocument: data.record.showInDiscoveryDocument, |
||||
|
}); |
||||
|
}); |
||||
|
|
||||
|
// 保存角色 |
||||
|
const submit = async () => { |
||||
|
try { |
||||
|
const request = getFieldsValue(); |
||||
|
await editApiScopeAsync({ request, changeOkLoading, validate, closeModal }); |
||||
|
resetFields(); |
||||
|
ctx.emit('reload'); |
||||
|
} catch (error) { |
||||
|
changeOkLoading(false); |
||||
|
} |
||||
|
}; |
||||
|
|
||||
|
const cancel = () => { |
||||
|
resetFields(); |
||||
|
closeModal(); |
||||
|
}; |
||||
|
return { |
||||
|
t, |
||||
|
registerModal, |
||||
|
registerApiScopeForm, |
||||
|
submit, |
||||
|
cancel, |
||||
|
}; |
||||
|
}, |
||||
|
}); |
||||
|
</script> |
||||
|
|
||||
|
<style lang="less" scoped></style> |
||||
@ -0,0 +1,326 @@ |
|||||
|
import { FormSchema } from '/@/components/Table'; |
||||
|
import { BasicColumn } from '/@/components/Table'; |
||||
|
import { ClientServiceProxy, EnabledInput, IdInput, PagingClientListInput } from '/@/services/ServiceProxies'; |
||||
|
|
||||
|
export const searchFormSchema: FormSchema[] = [ |
||||
|
{ |
||||
|
field: 'filter', |
||||
|
label: '关键字', |
||||
|
component: 'Input', |
||||
|
colProps: { span: 8 }, |
||||
|
}, |
||||
|
]; |
||||
|
|
||||
|
export const tableColumns: BasicColumn[] = [ |
||||
|
{ |
||||
|
title: 'ClientId', |
||||
|
dataIndex: 'clientId', |
||||
|
}, |
||||
|
{ |
||||
|
title: 'ClientName', |
||||
|
dataIndex: 'clientName', |
||||
|
}, |
||||
|
{ |
||||
|
title: '是否启用', |
||||
|
dataIndex: 'enabled', |
||||
|
slots: { customRender: 'enabled' }, |
||||
|
}, |
||||
|
{ |
||||
|
title: 'AccessTokenLifetime', |
||||
|
dataIndex: 'accessTokenLifetime', |
||||
|
}, |
||||
|
{ |
||||
|
title: 'AbsoluteRefreshTokenLifetime', |
||||
|
dataIndex: 'absoluteRefreshTokenLifetime', |
||||
|
}, |
||||
|
{ |
||||
|
title: 'Description', |
||||
|
dataIndex: 'description', |
||||
|
}, |
||||
|
]; |
||||
|
|
||||
|
export const createFormSchema: FormSchema[] = [ |
||||
|
{ |
||||
|
field: 'clientId', |
||||
|
label: 'ClientId', |
||||
|
component: 'Input', |
||||
|
required: true, |
||||
|
colProps: { span: 20 }, |
||||
|
}, |
||||
|
{ |
||||
|
field: 'clientName', |
||||
|
label: 'ClientName', |
||||
|
component: 'Input', |
||||
|
required: true, |
||||
|
colProps: { span: 20 }, |
||||
|
}, |
||||
|
{ |
||||
|
field: 'description', |
||||
|
label: 'Description', |
||||
|
component: 'Input', |
||||
|
colProps: { span: 20 }, |
||||
|
}, |
||||
|
]; |
||||
|
|
||||
|
export const editBasicDetailSchema: FormSchema[] = [ |
||||
|
{ |
||||
|
field: 'clientId', |
||||
|
label: 'ClientId', |
||||
|
component: 'Input', |
||||
|
required: true, |
||||
|
labelWidth: 200, |
||||
|
componentProps: { |
||||
|
disabled: true, |
||||
|
}, |
||||
|
colProps: { span: 20 }, |
||||
|
}, |
||||
|
{ |
||||
|
field: 'clientName', |
||||
|
label: 'ClientName', |
||||
|
component: 'Input', |
||||
|
labelWidth: 200, |
||||
|
required: true, |
||||
|
colProps: { span: 20 }, |
||||
|
}, |
||||
|
{ |
||||
|
field: 'description', |
||||
|
label: 'Description', |
||||
|
component: 'Input', |
||||
|
labelWidth: 200, |
||||
|
colProps: { span: 20 }, |
||||
|
}, |
||||
|
{ |
||||
|
field: 'clientUri', |
||||
|
label: 'ClientUri', |
||||
|
component: 'Input', |
||||
|
labelWidth: 200, |
||||
|
colProps: { span: 20 }, |
||||
|
}, |
||||
|
{ |
||||
|
field: 'logoUri', |
||||
|
label: 'LogoUri', |
||||
|
component: 'Input', |
||||
|
labelWidth: 200, |
||||
|
colProps: { span: 20 }, |
||||
|
}, |
||||
|
{ |
||||
|
field: 'frontChannelLogoutUri', |
||||
|
label: 'FrontChannelLogoutUri', |
||||
|
component: 'Input', |
||||
|
labelWidth: 200, |
||||
|
colProps: { span: 20 }, |
||||
|
}, |
||||
|
{ |
||||
|
field: 'backChannelLogoutUri', |
||||
|
label: 'BackChannelLogoutUri', |
||||
|
component: 'Input', |
||||
|
labelWidth: 200, |
||||
|
colProps: { span: 20 }, |
||||
|
}, |
||||
|
]; |
||||
|
|
||||
|
export const editBasicOptionSchema: FormSchema[] = [ |
||||
|
{ |
||||
|
field: 'enabled', |
||||
|
label: 'enabled', |
||||
|
labelWidth: 250, |
||||
|
component: 'Switch', |
||||
|
colProps: { span: 10 }, |
||||
|
}, |
||||
|
{ |
||||
|
field: 'requireClientSecret', |
||||
|
label: 'requireClientSecret', |
||||
|
component: 'Switch', |
||||
|
labelWidth: 250, |
||||
|
colProps: { span: 10 }, |
||||
|
}, |
||||
|
{ |
||||
|
field: 'requireConsent', |
||||
|
label: 'requireConsent', |
||||
|
component: 'Switch', |
||||
|
labelWidth: 250, |
||||
|
colProps: { span: 10 }, |
||||
|
}, |
||||
|
{ |
||||
|
field: 'allowRememberConsent', |
||||
|
label: 'allowRememberConsent', |
||||
|
component: 'Switch', |
||||
|
labelWidth: 250, |
||||
|
colProps: { span: 10 }, |
||||
|
}, |
||||
|
|
||||
|
{ |
||||
|
field: 'requirePkce', |
||||
|
label: 'requirePkce', |
||||
|
labelWidth: 250, |
||||
|
component: 'Switch', |
||||
|
colProps: { span: 10 }, |
||||
|
}, |
||||
|
{ |
||||
|
field: 'allowOfflineAccess', |
||||
|
label: 'allowOfflineAccess', |
||||
|
component: 'Switch', |
||||
|
labelWidth: 250, |
||||
|
colProps: { span: 10 }, |
||||
|
}, |
||||
|
{ |
||||
|
field: 'enableLocalLogin', |
||||
|
label: 'enableLocalLogin', |
||||
|
component: 'Switch', |
||||
|
labelWidth: 250, |
||||
|
colProps: { span: 10 }, |
||||
|
}, |
||||
|
{ |
||||
|
field: 'includeJwtId', |
||||
|
label: 'includeJwtId', |
||||
|
component: 'Switch', |
||||
|
labelWidth: 250, |
||||
|
colProps: { span: 10 }, |
||||
|
}, |
||||
|
{ |
||||
|
field: 'allowAccessTokensViaBrowser', |
||||
|
label: 'allowAccessTokensViaBrowser', |
||||
|
component: 'Switch', |
||||
|
labelWidth: 250, |
||||
|
colProps: { span: 10 }, |
||||
|
}, |
||||
|
{ |
||||
|
field: 'alwaysIncludeUserClaimsInIdToken', |
||||
|
label: 'alwaysIncludeUserClaimsInIdToken', |
||||
|
component: 'Switch', |
||||
|
labelWidth: 250, |
||||
|
colProps: { span: 10 }, |
||||
|
}, |
||||
|
|
||||
|
{ |
||||
|
field: 'frontChannelLogoutSessionRequired', |
||||
|
label: 'frontChannelLogoutSessionRequired', |
||||
|
component: 'Switch', |
||||
|
labelWidth: 250, |
||||
|
colProps: { span: 10 }, |
||||
|
}, |
||||
|
{ |
||||
|
field: 'backChannelLogoutSessionRequired', |
||||
|
label: 'backChannelLogoutSessionRequired', |
||||
|
component: 'Switch', |
||||
|
labelWidth: 250, |
||||
|
colProps: { span: 10 }, |
||||
|
}, |
||||
|
]; |
||||
|
|
||||
|
export const editBasicTokenSchema: FormSchema[] = [ |
||||
|
{ |
||||
|
field: 'accessTokenLifetime', |
||||
|
label: 'accessTokenLifetime', |
||||
|
labelWidth: 200, |
||||
|
component: 'Input', |
||||
|
}, |
||||
|
{ |
||||
|
field: 'authorizationCodeLifetime', |
||||
|
label: 'authorizationCodeLifetime', |
||||
|
labelWidth: 200, |
||||
|
component: 'Input', |
||||
|
}, |
||||
|
{ |
||||
|
field: 'absoluteRefreshTokenLifetime', |
||||
|
label: 'absoluteRefreshTokenLifetime', |
||||
|
labelWidth: 200, |
||||
|
component: 'Input', |
||||
|
}, |
||||
|
{ |
||||
|
field: 'slidingRefreshTokenLifetime', |
||||
|
label: 'slidingRefreshTokenLifetime', |
||||
|
labelWidth: 200, |
||||
|
component: 'Input', |
||||
|
}, |
||||
|
{ |
||||
|
field: 'refreshTokenExpiration', |
||||
|
label: 'refreshTokenExpiration', |
||||
|
labelWidth: 200, |
||||
|
component: 'Input', |
||||
|
}, |
||||
|
{ |
||||
|
field: 'deviceCodeLifetime', |
||||
|
label: 'deviceCodeLifetime', |
||||
|
labelWidth: 200, |
||||
|
component: 'Input', |
||||
|
}, |
||||
|
]; |
||||
|
export const editBasicSecretSchema: FormSchema[] = [ |
||||
|
{ |
||||
|
field: 'secretType', |
||||
|
component: 'Select', |
||||
|
label: 'Secret', |
||||
|
labelWidth: 100, |
||||
|
colProps: { |
||||
|
span: 15, |
||||
|
}, |
||||
|
componentProps: { |
||||
|
options: [ |
||||
|
{ |
||||
|
label: 'SharedSecret', |
||||
|
value: 'SharedSecret', |
||||
|
key: '1', |
||||
|
}, |
||||
|
{ |
||||
|
label: 'X509Thumbprint', |
||||
|
value: 'X509Thumbprint', |
||||
|
key: '2', |
||||
|
}, |
||||
|
], |
||||
|
}, |
||||
|
}, |
||||
|
{ |
||||
|
field: 'secret', |
||||
|
label: 'secret', |
||||
|
labelWidth: 100, |
||||
|
component: 'InputPassword', |
||||
|
}, |
||||
|
]; |
||||
|
/** |
||||
|
* 分页列表 |
||||
|
* @param params |
||||
|
* @returns |
||||
|
*/ |
||||
|
export async function getTableListAsync(params: PagingClientListInput) { |
||||
|
const _clientServiceProxy = new ClientServiceProxy(); |
||||
|
return _clientServiceProxy.page(params); |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* 创建client |
||||
|
* @param params |
||||
|
* @returns |
||||
|
*/ |
||||
|
export async function createClientAsync({ request, changeOkLoading, validate, closeModal }) { |
||||
|
changeOkLoading(true); |
||||
|
await validate(); |
||||
|
const _clientServiceProxy = new ClientServiceProxy(); |
||||
|
await _clientServiceProxy.create(request); |
||||
|
changeOkLoading(false); |
||||
|
closeModal(); |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* 删除 |
||||
|
* @param param0 |
||||
|
*/ |
||||
|
export async function deleteClientAsync({ id, reload }) { |
||||
|
const _clientServiceProxy = new ClientServiceProxy(); |
||||
|
const request = new IdInput(); |
||||
|
request.id = id; |
||||
|
await _clientServiceProxy.delete(request); |
||||
|
reload(); |
||||
|
} |
||||
|
/** |
||||
|
* 删除 |
||||
|
* @param param0 |
||||
|
*/ |
||||
|
export async function enabledClientAsync({ clientId, enabled, reload }) { |
||||
|
const _clientServiceProxy = new ClientServiceProxy(); |
||||
|
const request = new EnabledInput(); |
||||
|
request.clientId = clientId; |
||||
|
request.enabled = enabled; |
||||
|
await _clientServiceProxy.enabled(request); |
||||
|
reload(); |
||||
|
} |
||||
@ -0,0 +1,116 @@ |
|||||
|
<template> |
||||
|
<div> |
||||
|
<BasicTable @register="registerTable" size="small"> |
||||
|
<template #toolbar> |
||||
|
<a-button type="primary" @click="openCreateClientModal"> |
||||
|
{{ t('common.createText') }} |
||||
|
</a-button> |
||||
|
</template> |
||||
|
|
||||
|
<template #enabled="{ record }"> |
||||
|
<Tag :color="record.enabled ? 'green' : 'red'"> |
||||
|
{{ record.enabled ? '是' : '否' }} |
||||
|
</Tag> |
||||
|
</template> |
||||
|
|
||||
|
<template #action="{ record }"> |
||||
|
<a-button type="link" size="small" @click="handleEdit(record)"> |
||||
|
{{ t('common.editText') }} |
||||
|
</a-button> |
||||
|
<a-button type="link" size="small" @click="handleEnabled(record)"> |
||||
|
{{ record.enabled ? '禁用' : '启用' }} |
||||
|
</a-button> |
||||
|
<a-button type="link" size="small" @click="handleDelete(record)"> |
||||
|
{{ t('common.delText') }} |
||||
|
</a-button> |
||||
|
</template> |
||||
|
</BasicTable> |
||||
|
<CreateClient @register="registerCreateClientModal" @reload="reload" :bodyStyle="{ 'padding-top': '0' }" /> |
||||
|
<EditClientBasic @register="registerEditClientModal" @reload="reload" :bodyStyle="{ 'padding-top': '0' }" /> |
||||
|
</div> |
||||
|
</template> |
||||
|
|
||||
|
<script lang="ts"> |
||||
|
import { defineComponent } from 'vue'; |
||||
|
import { BasicTable, useTable, TableAction } from '/@/components/Table'; |
||||
|
import { tableColumns, searchFormSchema, getTableListAsync, deleteClientAsync, enabledClientAsync } from './Clients'; |
||||
|
import { useI18n } from '/@/hooks/web/useI18n'; |
||||
|
import { Tag } from 'ant-design-vue'; |
||||
|
import CreateClient from './CreateClient.vue'; |
||||
|
import EditClientBasic from './EditClientBasic.vue'; |
||||
|
import { useModal } from '/@/components/Modal'; |
||||
|
import { useMessage } from '/@/hooks/web/useMessage'; |
||||
|
export default defineComponent({ |
||||
|
name: 'Clients', |
||||
|
components: { |
||||
|
BasicTable, |
||||
|
TableAction, |
||||
|
Tag, |
||||
|
CreateClient, |
||||
|
EditClientBasic, |
||||
|
}, |
||||
|
setup() { |
||||
|
const { t } = useI18n(); |
||||
|
const { createConfirm } = useMessage(); |
||||
|
// table配置 |
||||
|
const [registerTable, { reload }] = useTable({ |
||||
|
columns: tableColumns, |
||||
|
formConfig: { |
||||
|
labelWidth: 70, |
||||
|
schemas: searchFormSchema, |
||||
|
}, |
||||
|
api: getTableListAsync, |
||||
|
showTableSetting: true, |
||||
|
useSearchForm: true, |
||||
|
bordered: true, |
||||
|
canResize: true, |
||||
|
showIndexColumn: true, |
||||
|
actionColumn: { |
||||
|
width: 150, |
||||
|
title: t('common.action'), |
||||
|
dataIndex: 'action', |
||||
|
slots: { |
||||
|
customRender: 'action', |
||||
|
}, |
||||
|
fixed: 'right', |
||||
|
}, |
||||
|
}); |
||||
|
|
||||
|
const [registerCreateClientModal, { openModal: openCreateClientModal }] = useModal(); |
||||
|
const [registerEditClientModal, { openModal: openEditClientModal }] = useModal(); |
||||
|
const handleEdit = (record: Recordable) => { |
||||
|
openEditClientModal(true, { |
||||
|
record: record, |
||||
|
}); |
||||
|
}; |
||||
|
const handleDelete = (record: Recordable) => { |
||||
|
let msg = '是否确认删除'; |
||||
|
createConfirm({ |
||||
|
iconType: 'warning', |
||||
|
title: '提示', |
||||
|
content: msg, |
||||
|
onOk: async () => { |
||||
|
await deleteClientAsync({ id: record.id, reload }); |
||||
|
}, |
||||
|
}); |
||||
|
}; |
||||
|
const handleEnabled = async (record: Recordable) => { |
||||
|
await enabledClientAsync({ clientId: record.clientId, enabled: !record.enabled, reload }); |
||||
|
}; |
||||
|
return { |
||||
|
registerTable, |
||||
|
registerCreateClientModal, |
||||
|
openCreateClientModal, |
||||
|
registerEditClientModal, |
||||
|
openEditClientModal, |
||||
|
t, |
||||
|
reload, |
||||
|
handleEdit, |
||||
|
handleDelete, |
||||
|
handleEnabled, |
||||
|
}; |
||||
|
}, |
||||
|
}); |
||||
|
</script> |
||||
|
|
||||
|
<style lang="less" scoped></style> |
||||
@ -0,0 +1,61 @@ |
|||||
|
<template> |
||||
|
<BasicModal title="创建Client" :canFullscreen="false" @ok="submit" @cancel="cancel" @register="registerModal"> |
||||
|
<BasicForm @register="registerClientForm" /> |
||||
|
</BasicModal> |
||||
|
</template> |
||||
|
|
||||
|
<script lang="ts"> |
||||
|
import { defineComponent, useContext, defineEmit } from 'vue'; |
||||
|
import { BasicModal, useModalInner } from '/@/components/Modal'; |
||||
|
import { BasicForm, useForm } from '/@/components/Form/index'; |
||||
|
import { createFormSchema, createClientAsync } from './Clients'; |
||||
|
import { useI18n } from '/@/hooks/web/useI18n'; |
||||
|
|
||||
|
export default defineComponent({ |
||||
|
name: 'CreateAbpRole', |
||||
|
components: { |
||||
|
BasicModal, |
||||
|
BasicForm, |
||||
|
}, |
||||
|
setup() { |
||||
|
// 加载父组件方法 |
||||
|
defineEmit(['reload']); |
||||
|
const ctx = useContext(); |
||||
|
|
||||
|
const { t } = useI18n(); |
||||
|
const [registerClientForm, { getFieldsValue, validate, resetFields }] = useForm({ |
||||
|
labelWidth: 120, |
||||
|
schemas: createFormSchema, |
||||
|
showActionButtonGroup: false, |
||||
|
}); |
||||
|
|
||||
|
const [registerModal, { changeOkLoading, closeModal }] = useModalInner(); |
||||
|
|
||||
|
// 保存角色 |
||||
|
const submit = async () => { |
||||
|
try { |
||||
|
const request = getFieldsValue(); |
||||
|
await createClientAsync({ request, changeOkLoading, validate, closeModal }); |
||||
|
resetFields(); |
||||
|
ctx.emit('reload'); |
||||
|
} catch (error) { |
||||
|
changeOkLoading(false); |
||||
|
} |
||||
|
}; |
||||
|
|
||||
|
const cancel = () => { |
||||
|
resetFields(); |
||||
|
closeModal(); |
||||
|
}; |
||||
|
return { |
||||
|
t, |
||||
|
registerModal, |
||||
|
registerClientForm, |
||||
|
submit, |
||||
|
cancel, |
||||
|
}; |
||||
|
}, |
||||
|
}); |
||||
|
</script> |
||||
|
|
||||
|
<style lang="less" scoped></style> |
||||
@ -0,0 +1,156 @@ |
|||||
|
<template> |
||||
|
<BasicModal |
||||
|
title="编辑Client" |
||||
|
:width="700" |
||||
|
:canFullscreen="false" |
||||
|
@ok="submit" |
||||
|
@cancel="cancel" |
||||
|
@register="registerModal" |
||||
|
@visible-change="visibleChange" |
||||
|
:bodyStyle="{ 'padding-top': '0' }" |
||||
|
:destroyOnClose="true" |
||||
|
:maskClosable="false" |
||||
|
> |
||||
|
<div> |
||||
|
<Tabs> |
||||
|
<TabPane tab="基本信息" key="1"> |
||||
|
<BasicForm @register="registerDetailForm" /> |
||||
|
</TabPane> |
||||
|
<TabPane tab="Options" key="2"> |
||||
|
<BasicForm @register="registerOptionForm" /> |
||||
|
</TabPane> |
||||
|
<TabPane tab="Tokens" key="3"> |
||||
|
<BasicForm @register="registerTokenForm" /> |
||||
|
</TabPane> |
||||
|
<TabPane tab="Secret" key="4"> |
||||
|
<BasicForm @register="registerSecretForm" /> |
||||
|
</TabPane> |
||||
|
</Tabs> |
||||
|
</div> |
||||
|
</BasicModal> |
||||
|
</template> |
||||
|
|
||||
|
<script lang="ts"> |
||||
|
import { defineComponent, defineEmit } from 'vue'; |
||||
|
import { BasicModal, useModalInner } from '/@/components/Modal'; |
||||
|
import { BasicForm, useForm } from '/@/components/Form/index'; |
||||
|
import { Tabs } from 'ant-design-vue'; |
||||
|
import { editBasicDetailSchema, editBasicOptionSchema, editBasicTokenSchema, editBasicSecretSchema } from './Clients'; |
||||
|
|
||||
|
export default defineComponent({ |
||||
|
name: 'EditAbpUser', |
||||
|
components: { |
||||
|
BasicModal, |
||||
|
BasicForm, |
||||
|
Tabs, |
||||
|
TabPane: Tabs.TabPane, |
||||
|
}, |
||||
|
setup() { |
||||
|
// 加载父组件方法 |
||||
|
defineEmit(['reload']); |
||||
|
|
||||
|
const [registerDetailForm, { getFieldsValue: getFieldsDetailValue, validate: detailValidate, setFieldsValue: setDetailFieldsValue }] = useForm({ |
||||
|
labelWidth: 120, |
||||
|
schemas: editBasicDetailSchema, |
||||
|
showActionButtonGroup: false, |
||||
|
}); |
||||
|
const [registerOptionForm, { getFieldsValue: getFieldsOptionValue, validate: optionValidate, setFieldsValue: setOptionFieldsValue }] = useForm({ |
||||
|
labelWidth: 120, |
||||
|
schemas: editBasicOptionSchema, |
||||
|
showActionButtonGroup: false, |
||||
|
}); |
||||
|
const [registerTokenForm, { getFieldsValue: getFieldsTokenValue, validate: tokenValidate, setFieldsValue: setTokenFieldsValue }] = useForm({ |
||||
|
labelWidth: 120, |
||||
|
schemas: editBasicTokenSchema, |
||||
|
showActionButtonGroup: false, |
||||
|
}); |
||||
|
const [registerSecretForm, { getFieldsValue: getFieldsSecretnValue, validate: secretValidate, setFieldsValue: setSecretFieldsValue }] = useForm( |
||||
|
{ |
||||
|
labelWidth: 120, |
||||
|
schemas: editBasicSecretSchema, |
||||
|
showActionButtonGroup: false, |
||||
|
} |
||||
|
); |
||||
|
let currentClient: any; |
||||
|
const [registerModal, { changeOkLoading, closeModal }] = useModalInner((data) => { |
||||
|
currentClient = data.record; |
||||
|
console.log(currentClient); |
||||
|
|
||||
|
setDetailFieldsValue({ |
||||
|
clientId: data.record.clientId, |
||||
|
clientName: data.record.clientName, |
||||
|
description: data.record.description, |
||||
|
clientUri: data.record.clientUri, |
||||
|
logoUri: data.record.logoUri, |
||||
|
frontChannelLogoutUri: data.record.frontChannelLogoutUri, |
||||
|
backChannelLogoutUri: data.record.backChannelLogoutUri, |
||||
|
}); |
||||
|
setOptionFieldsValue({ |
||||
|
enabled: data.record.enabled, |
||||
|
requireClientSecret: data.record.requireClientSecret, |
||||
|
requireConsent: data.record.requireConsent, |
||||
|
allowRememberConsent: data.record.allowRememberConsent, |
||||
|
requirePkce: data.record.requirePkce, |
||||
|
allowOfflineAccess: data.record.allowOfflineAccess, |
||||
|
enableLocalLogin: data.record.enableLocalLogin, |
||||
|
includeJwtId: data.record.includeJwtId, |
||||
|
allowAccessTokensViaBrowser: data.record.allowAccessTokensViaBrowser, |
||||
|
alwaysIncludeUserClaimsInIdToken: data.record.alwaysIncludeUserClaimsInIdToken, |
||||
|
frontChannelLogoutSessionRequired: data.record.frontChannelLogoutSessionRequired, |
||||
|
backChannelLogoutSessionRequired: data.record.backChannelLogoutSessionRequired, |
||||
|
}); |
||||
|
setTokenFieldsValue({ |
||||
|
accessTokenLifetime: data.record.accessTokenLifetime, |
||||
|
authorizationCodeLifetime: data.record.authorizationCodeLifetime, |
||||
|
absoluteRefreshTokenLifetime: data.record.absoluteRefreshTokenLifetime, |
||||
|
slidingRefreshTokenLifetime: data.record.slidingRefreshTokenLifetime, |
||||
|
refreshTokenExpiration: data.record.refreshTokenExpiration, |
||||
|
deviceCodeLifetime: data.record.deviceCodeLifetime, |
||||
|
}); |
||||
|
|
||||
|
if (data.record.clientSecrets.length > 0) { |
||||
|
setSecretFieldsValue({ |
||||
|
secretType: data.record.clientSecrets[0].type, |
||||
|
secret: data.record.clientSecrets[0].value, |
||||
|
}); |
||||
|
} |
||||
|
}); |
||||
|
|
||||
|
const visibleChange = async (visible: boolean) => { |
||||
|
if (visible) { |
||||
|
detailValidate(); |
||||
|
optionValidate(); |
||||
|
tokenValidate(); |
||||
|
secretValidate(); |
||||
|
getFieldsTokenValue(); |
||||
|
getFieldsSecretnValue(); |
||||
|
getFieldsOptionValue(); |
||||
|
getFieldsDetailValue(); |
||||
|
changeOkLoading(true); |
||||
|
} else { |
||||
|
} |
||||
|
}; |
||||
|
|
||||
|
const submit = async () => {}; |
||||
|
const cancel = () => { |
||||
|
closeModal(); |
||||
|
}; |
||||
|
|
||||
|
return { |
||||
|
registerModal, |
||||
|
registerDetailForm, |
||||
|
registerOptionForm, |
||||
|
registerTokenForm, |
||||
|
registerSecretForm, |
||||
|
submit, |
||||
|
visibleChange, |
||||
|
cancel, |
||||
|
}; |
||||
|
}, |
||||
|
}); |
||||
|
</script> |
||||
|
<style lang="less" scoped> |
||||
|
.ant-checkbox-wrapper + .ant-checkbox-wrapper { |
||||
|
margin-left: 0px; |
||||
|
} |
||||
|
</style> |
||||
@ -0,0 +1,60 @@ |
|||||
|
<template> |
||||
|
<BasicModal title="创建IdentityResource" :canFullscreen="false" @ok="submit" @cancel="cancel" @register="registerModal"> |
||||
|
<BasicForm @register="registerApiScopeForm" /> |
||||
|
</BasicModal> |
||||
|
</template> |
||||
|
|
||||
|
<script lang="ts"> |
||||
|
import { defineComponent, useContext, defineEmit } from 'vue'; |
||||
|
import { BasicModal, useModalInner } from '/@/components/Modal'; |
||||
|
import { BasicForm, useForm } from '/@/components/Form/index'; |
||||
|
import { createFormSchema, createIdentityResourcesAsync } from './IdentityResources'; |
||||
|
import { useI18n } from '/@/hooks/web/useI18n'; |
||||
|
|
||||
|
export default defineComponent({ |
||||
|
name: 'CreateIdentityResource', |
||||
|
components: { |
||||
|
BasicModal, |
||||
|
BasicForm, |
||||
|
}, |
||||
|
setup() { |
||||
|
// 加载父组件方法 |
||||
|
defineEmit(['reload']); |
||||
|
const ctx = useContext(); |
||||
|
|
||||
|
const { t } = useI18n(); |
||||
|
const [registerApiScopeForm, { getFieldsValue, validate, resetFields }] = useForm({ |
||||
|
labelWidth: 120, |
||||
|
schemas: createFormSchema, |
||||
|
showActionButtonGroup: false, |
||||
|
}); |
||||
|
|
||||
|
const [registerModal, { changeOkLoading, closeModal }] = useModalInner(); |
||||
|
|
||||
|
const submit = async () => { |
||||
|
try { |
||||
|
const request = getFieldsValue(); |
||||
|
await createIdentityResourcesAsync({ request, changeOkLoading, validate, closeModal }); |
||||
|
resetFields(); |
||||
|
ctx.emit('reload'); |
||||
|
} catch (error) { |
||||
|
changeOkLoading(false); |
||||
|
} |
||||
|
}; |
||||
|
|
||||
|
const cancel = () => { |
||||
|
resetFields(); |
||||
|
closeModal(); |
||||
|
}; |
||||
|
return { |
||||
|
t, |
||||
|
registerModal, |
||||
|
registerApiScopeForm, |
||||
|
submit, |
||||
|
cancel, |
||||
|
}; |
||||
|
}, |
||||
|
}); |
||||
|
</script> |
||||
|
|
||||
|
<style lang="less" scoped></style> |
||||
@ -0,0 +1,13 @@ |
|||||
|
<template> </template> |
||||
|
|
||||
|
<script lang="ts"> |
||||
|
import { defineComponent } from 'vue'; |
||||
|
export default defineComponent({ |
||||
|
name: 'EditIdentityResources', |
||||
|
setup() { |
||||
|
return {}; |
||||
|
}, |
||||
|
}); |
||||
|
</script> |
||||
|
|
||||
|
<style lang="less" scoped></style> |
||||
Loading…
Reference in new issue