12 changed files with 367 additions and 3 deletions
@ -0,0 +1,50 @@ |
|||||
|
import { defAbpHttp } from '/@/utils/http/abp'; |
||||
|
import { |
||||
|
Edition, |
||||
|
EditionCreate, |
||||
|
EditionUpdate, |
||||
|
EditionGetListInput, |
||||
|
} from './model/editionsModel'; |
||||
|
import { format } from '/@/utils/strings'; |
||||
|
import { PagedResultDto } from '../model/baseModel'; |
||||
|
|
||||
|
enum Api { |
||||
|
Create = '/api/saas/editions', |
||||
|
DeleteById = '/api/saas/editions/{id}', |
||||
|
GetById = '/api/saas/editions/{id}', |
||||
|
GetList = '/api/saas/editions', |
||||
|
Update = '/api/saas/editions/{id}', |
||||
|
} |
||||
|
|
||||
|
export const getById = (id: string) => { |
||||
|
return defAbpHttp.get<Edition>({ |
||||
|
url: format(Api.GetById, { id: id }), |
||||
|
}); |
||||
|
}; |
||||
|
|
||||
|
export const getList = (input: EditionGetListInput) => { |
||||
|
return defAbpHttp.get<PagedResultDto<Edition>>({ |
||||
|
url: Api.GetList, |
||||
|
params: input, |
||||
|
}); |
||||
|
}; |
||||
|
|
||||
|
export const create = (input: EditionCreate) => { |
||||
|
return defAbpHttp.post<Edition>({ |
||||
|
url: Api.Create, |
||||
|
data: input, |
||||
|
}); |
||||
|
}; |
||||
|
|
||||
|
export const deleteById = (id: string) => { |
||||
|
return defAbpHttp.delete<void>({ |
||||
|
url: format(Api.GetById, { id: id }), |
||||
|
}); |
||||
|
}; |
||||
|
|
||||
|
export const update = (id: string, input: EditionUpdate) => { |
||||
|
return defAbpHttp.put<Edition>({ |
||||
|
url: format(Api.Update, { id: id }), |
||||
|
data: input, |
||||
|
}); |
||||
|
}; |
||||
@ -0,0 +1,23 @@ |
|||||
|
import { |
||||
|
IHasConcurrencyStamp, |
||||
|
AuditedEntityDto, |
||||
|
PagedAndSortedResultRequestDto, |
||||
|
} from '../../model/baseModel'; |
||||
|
|
||||
|
export interface Edition extends AuditedEntityDto { |
||||
|
id: string; |
||||
|
displayName: string; |
||||
|
} |
||||
|
|
||||
|
interface EditionCreateOrUpdate { |
||||
|
displayName: string; |
||||
|
} |
||||
|
|
||||
|
export type EditionCreate = EditionCreateOrUpdate; |
||||
|
|
||||
|
export interface EditionUpdate extends EditionCreateOrUpdate, IHasConcurrencyStamp { |
||||
|
} |
||||
|
|
||||
|
export interface EditionGetListInput extends PagedAndSortedResultRequestDto { |
||||
|
filter?: string; |
||||
|
} |
||||
@ -0,0 +1,70 @@ |
|||||
|
<template> |
||||
|
<BasicModal |
||||
|
v-bind="$attrs" |
||||
|
:title="modalTitle" |
||||
|
:loading="loading" |
||||
|
:showOkBtn="!loading" |
||||
|
:showCancelBtn="!loading" |
||||
|
:maskClosable="!loading" |
||||
|
:closable="!loading" |
||||
|
:width="500" |
||||
|
:height="300" |
||||
|
@register="registerModal" |
||||
|
@ok="handleSubmit" |
||||
|
> |
||||
|
<BasicForm @register="registerForm" /> |
||||
|
</BasicModal> |
||||
|
</template> |
||||
|
|
||||
|
<script lang="ts" setup> |
||||
|
import { computed, ref, unref, nextTick } from 'vue'; |
||||
|
import { useLocalization } from '/@/hooks/abp/useLocalization'; |
||||
|
import { BasicForm, useForm } from '/@/components/Form'; |
||||
|
import { BasicModal, useModalInner } from '/@/components/Modal'; |
||||
|
import { getModalFormSchemas } from '../datas//ModalData'; |
||||
|
import { getById, create, update } from '/@/api/saas/editions'; |
||||
|
|
||||
|
const emits = defineEmits(['change', 'register']); |
||||
|
const { L } = useLocalization('AbpSaas'); |
||||
|
const loading = ref(false); |
||||
|
const editionIdRef = ref(''); |
||||
|
const [registerModal, { closeModal, changeOkLoading }] = useModalInner((data) => { |
||||
|
editionIdRef.value = data.id; |
||||
|
fetchEdition(); |
||||
|
}); |
||||
|
const [registerForm, { setFieldsValue, resetFields, validate }] = useForm({ |
||||
|
schemas: getModalFormSchemas(), |
||||
|
showActionButtonGroup: false, |
||||
|
}); |
||||
|
const modalTitle = computed(() => { |
||||
|
return unref(editionIdRef) ? L('Edit') : L('NewEdition'); |
||||
|
}); |
||||
|
|
||||
|
function fetchEdition() { |
||||
|
const editionId = unref(editionIdRef); |
||||
|
if (!editionId) { |
||||
|
nextTick(() => { |
||||
|
resetFields(); |
||||
|
}); |
||||
|
return; |
||||
|
} |
||||
|
getById(editionId).then((edition) => { |
||||
|
nextTick(() => { |
||||
|
setFieldsValue(edition); |
||||
|
}); |
||||
|
}); |
||||
|
} |
||||
|
|
||||
|
function handleSubmit() { |
||||
|
validate().then((input) => { |
||||
|
changeOkLoading(true); |
||||
|
const api = input.id ? update(input.id, input) : create(input); |
||||
|
api.then((edition) => { |
||||
|
emits('change', edition); |
||||
|
closeModal(); |
||||
|
}).finally(() => { |
||||
|
changeOkLoading(false); |
||||
|
}); |
||||
|
}); |
||||
|
} |
||||
|
</script> |
||||
@ -0,0 +1,108 @@ |
|||||
|
<template> |
||||
|
<div> |
||||
|
<BasicTable @register="registerTable"> |
||||
|
<template #toolbar> |
||||
|
<a-button |
||||
|
v-if="hasPermission('AbpSaas.Editions.Create')" |
||||
|
type="primary" |
||||
|
@click="handleAddNew" |
||||
|
>{{ L('NewEdition') }}</a-button |
||||
|
> |
||||
|
</template> |
||||
|
<template #action="{ record }"> |
||||
|
<TableAction |
||||
|
:actions="[ |
||||
|
{ |
||||
|
auth: 'AbpSaas.Editions.Update', |
||||
|
label: L('Edit'), |
||||
|
icon: 'ant-design:edit-outlined', |
||||
|
onClick: handleEdit.bind(null, record), |
||||
|
}, |
||||
|
{ |
||||
|
auth: 'AbpSaas.Editions.Delete', |
||||
|
color: 'error', |
||||
|
label: L('Delete'), |
||||
|
icon: 'ant-design:delete-outlined', |
||||
|
onClick: handleDelete.bind(null, record), |
||||
|
}, |
||||
|
]" |
||||
|
:dropDownActions="[ |
||||
|
{ |
||||
|
auth: 'AbpSaas.Editions.ManageFeatures', |
||||
|
label: L('ManageFeatures'), |
||||
|
onClick: handleManageFeature.bind(null, record), |
||||
|
}, |
||||
|
]" |
||||
|
/> |
||||
|
</template> |
||||
|
</BasicTable> |
||||
|
<EditionModal @register="registerModal" @change="reload" /> |
||||
|
<FeatureModal @register="registerFeatureModal" /> |
||||
|
</div> |
||||
|
</template> |
||||
|
|
||||
|
<script lang="ts" setup> |
||||
|
import { useLocalization } from '/@/hooks/abp/useLocalization'; |
||||
|
import { usePermission } from '/@/hooks/web/usePermission'; |
||||
|
import { useMessage } from '/@/hooks/web/useMessage'; |
||||
|
import { useModal } from '/@/components/Modal'; |
||||
|
import { BasicTable, TableAction, useTable } from '/@/components/Table'; |
||||
|
import { useFeatureModal } from '../hooks/useFeatureModal'; |
||||
|
import { FeatureModal } from '../../../feature'; |
||||
|
import { deleteById, getList } from '../../../../api/saas/editions'; |
||||
|
import { getDataColumns } from '../datas/TableData'; |
||||
|
import { getSearchFormSchemas } from '../datas//ModalData'; |
||||
|
import { formatPagedRequest } from '/@/utils/http/abp/helper'; |
||||
|
import EditionModal from './EditionModal.vue'; |
||||
|
|
||||
|
const { L } = useLocalization('AbpSaas', 'AbpFeatureManagement'); |
||||
|
const { createConfirm } = useMessage(); |
||||
|
const { hasPermission } = usePermission(); |
||||
|
const [registerModal, { openModal }] = useModal(); |
||||
|
const { registerModal: registerFeatureModal, handleManageFeature } = useFeatureModal(); |
||||
|
const [registerTable, { reload }] = useTable({ |
||||
|
rowKey: 'id', |
||||
|
title: L('Tenants'), |
||||
|
columns: getDataColumns(), |
||||
|
api: getList, |
||||
|
beforeFetch: formatPagedRequest, |
||||
|
pagination: true, |
||||
|
striped: false, |
||||
|
useSearchForm: true, |
||||
|
showTableSetting: true, |
||||
|
bordered: true, |
||||
|
showIndexColumn: false, |
||||
|
canResize: true, |
||||
|
immediate: true, |
||||
|
canColDrag: true, |
||||
|
formConfig: getSearchFormSchemas(), |
||||
|
actionColumn: { |
||||
|
width: 200, |
||||
|
title: L('Actions'), |
||||
|
dataIndex: 'action', |
||||
|
slots: { customRender: 'action' }, |
||||
|
}, |
||||
|
}); |
||||
|
|
||||
|
function handleAddNew() { |
||||
|
openModal(true, {}); |
||||
|
} |
||||
|
|
||||
|
function handleEdit(record) { |
||||
|
openModal(true, record); |
||||
|
} |
||||
|
|
||||
|
function handleDelete(record) { |
||||
|
createConfirm({ |
||||
|
iconType: 'warning', |
||||
|
title: L('AreYouSure'), |
||||
|
content: L('ItemWillBeDeletedMessageWithFormat', record.displayName), |
||||
|
okCancel: true, |
||||
|
onOk: () => { |
||||
|
deleteById(record.id).then(() => { |
||||
|
reload(); |
||||
|
}); |
||||
|
}, |
||||
|
}); |
||||
|
} |
||||
|
</script> |
||||
@ -0,0 +1,44 @@ |
|||||
|
import { useLocalization } from '/@/hooks/abp/useLocalization'; |
||||
|
import { FormProps, FormSchema } from '/@/components/Form'; |
||||
|
|
||||
|
const { L } = useLocalization('AbpSaas'); |
||||
|
|
||||
|
export function getSearchFormSchemas(): Partial<FormProps> { |
||||
|
return { |
||||
|
labelWidth: 120, |
||||
|
schemas: [ |
||||
|
{ |
||||
|
field: 'filter', |
||||
|
component: 'Input', |
||||
|
label: L('Search'), |
||||
|
colProps: { span: 24 }, |
||||
|
}, |
||||
|
], |
||||
|
}; |
||||
|
} |
||||
|
|
||||
|
export function getModalFormSchemas(): FormSchema[] { |
||||
|
return [ |
||||
|
{ |
||||
|
field: 'id', |
||||
|
component: 'Input', |
||||
|
label: 'id', |
||||
|
show: false, |
||||
|
dynamicDisabled: true, |
||||
|
}, |
||||
|
{ |
||||
|
field: 'concurrencyStamp', |
||||
|
component: 'Input', |
||||
|
label: 'concurrencyStamp', |
||||
|
show: false, |
||||
|
dynamicDisabled: true, |
||||
|
}, |
||||
|
{ |
||||
|
field: 'displayName', |
||||
|
component: 'Input', |
||||
|
label: L('DisplayName:EditionName'), |
||||
|
colProps: { span: 24 }, |
||||
|
required: true, |
||||
|
}, |
||||
|
]; |
||||
|
} |
||||
@ -0,0 +1,22 @@ |
|||||
|
import { useLocalization } from '/@/hooks/abp/useLocalization'; |
||||
|
import { BasicColumn } from '/@/components/Table'; |
||||
|
|
||||
|
const { L } = useLocalization('AbpSaas'); |
||||
|
|
||||
|
export function getDataColumns(): BasicColumn[] { |
||||
|
return [ |
||||
|
{ |
||||
|
title: 'id', |
||||
|
dataIndex: 'id', |
||||
|
width: 1, |
||||
|
ifShow: false, |
||||
|
}, |
||||
|
{ |
||||
|
title: L('DisplayName:EditionName'), |
||||
|
dataIndex: 'displayName', |
||||
|
align: 'left', |
||||
|
width: 'auto', |
||||
|
sorter: true, |
||||
|
}, |
||||
|
]; |
||||
|
} |
||||
@ -0,0 +1,14 @@ |
|||||
|
import { useModal } from '/@/components/Modal'; |
||||
|
|
||||
|
export function useFeatureModal() { |
||||
|
const [registerModal, { openModal }] = useModal(); |
||||
|
|
||||
|
function handleManageFeature(record) { |
||||
|
openModal(true, { providerName: 'E', providerKey: record.id }); |
||||
|
} |
||||
|
|
||||
|
return { |
||||
|
registerModal, |
||||
|
handleManageFeature, |
||||
|
}; |
||||
|
} |
||||
@ -0,0 +1,13 @@ |
|||||
|
<template> |
||||
|
<EditionTable /> |
||||
|
</template> |
||||
|
|
||||
|
<script lang="ts"> |
||||
|
import { defineComponent } from 'vue'; |
||||
|
import EditionTable from './components/EditionTable.vue'; |
||||
|
export default defineComponent({ |
||||
|
name: 'Editions', |
||||
|
components: { EditionTable }, |
||||
|
setup() {}, |
||||
|
}); |
||||
|
</script> |
||||
@ -1,9 +1,11 @@ |
|||||
using System; |
using System; |
||||
using Volo.Abp.Application.Dtos; |
using Volo.Abp.Application.Dtos; |
||||
|
using Volo.Abp.Domain.Entities; |
||||
|
|
||||
namespace LINGYUN.Abp.Saas.Editions; |
namespace LINGYUN.Abp.Saas.Editions; |
||||
|
|
||||
public class EditionDto : ExtensibleFullAuditedEntityDto<Guid> |
public class EditionDto : ExtensibleAuditedEntityDto<Guid>, IHasConcurrencyStamp |
||||
{ |
{ |
||||
public string DisplayName { get; set; } |
public string DisplayName { get; set; } |
||||
|
public string ConcurrencyStamp { get; set; } |
||||
} |
} |
||||
|
|||||
Loading…
Reference in new issue