55 changed files with 15971 additions and 6533 deletions
File diff suppressed because it is too large
File diff suppressed because it is too large
File diff suppressed because it is too large
File diff suppressed because it is too large
@ -0,0 +1,40 @@ |
|||
// import { FormSchema } from "/@/components/Table";
|
|||
// import { BasicColumn } from "/@/components/Table";
|
|||
// import { formatToDateTime } from '/@/utils/dateUtil';
|
|||
// import { FilesServiceProxy, PagingFileInput } from "/@/services/ServiceProxies";
|
|||
// import { useI18n } from "/@/hooks/web/useI18n";
|
|||
|
|||
// const { t } = useI18n();
|
|||
// export const searchFormSchema: FormSchema[] = [
|
|||
// {
|
|||
// field: "filter",
|
|||
// label: t("routes.admin.fileName"),
|
|||
// component: "Input",
|
|||
// colProps: { span: 8 }
|
|||
// }
|
|||
// ];
|
|||
|
|||
// export const tableColumns: BasicColumn[] = [
|
|||
// {
|
|||
// title: t("routes.admin.fileName"),
|
|||
// dataIndex: "fileName"
|
|||
// },
|
|||
|
|||
// {
|
|||
// title: t("routes.admin.userManagement_createTime"),
|
|||
// dataIndex: "creationTime",
|
|||
// customRender: ({ text }) => {
|
|||
// return formatToDateTime(text);
|
|||
// }
|
|||
// }
|
|||
// ];
|
|||
|
|||
// /**
|
|||
// * 分页列表
|
|||
// * @param params
|
|||
// * @returns
|
|||
// */
|
|||
// export async function getTableListAsync(params: PagingFileInput) {
|
|||
// const _filesServiceProxy = new FilesServiceProxy();
|
|||
// return _filesServiceProxy.page(params);
|
|||
// }
|
|||
@ -0,0 +1,117 @@ |
|||
<template> |
|||
<div></div> |
|||
</template> |
|||
<!-- <template> |
|||
<div> |
|||
<BasicTable @register="registerTable" size="small"> |
|||
<template #toolbar> |
|||
<a-upload |
|||
v-model:file-list="fileList" |
|||
name="file" |
|||
:multiple="false" |
|||
:show-upload-list="false" |
|||
:customRequest="customRequest" |
|||
v-auth="'AbpIdentity.FileManagement.Upload'" |
|||
> |
|||
<a-button> |
|||
<upload-outlined></upload-outlined> |
|||
上传文件 |
|||
</a-button> |
|||
</a-upload> |
|||
</template> |
|||
<template #action="{ record }"> |
|||
<TableAction |
|||
:actions="[ |
|||
{ |
|||
icon: 'ant-design:arrow-down-outlined', |
|||
label: t('common.download'), |
|||
onClick: handleDownload.bind(null, record), |
|||
}, |
|||
]" |
|||
/> |
|||
</template> |
|||
</BasicTable> |
|||
</div> |
|||
</template> |
|||
|
|||
<script lang="ts"> |
|||
import { defineComponent, ref } from "vue"; |
|||
import { UploadOutlined } from "@ant-design/icons-vue"; |
|||
import { BasicTable, useTable, TableAction } from "/@/components/Table"; |
|||
import { tableColumns, searchFormSchema, getTableListAsync } from "/@/views/admin/files/File"; |
|||
import { Tag } from "ant-design-vue"; |
|||
import { useI18n } from "/@/hooks/web/useI18n"; |
|||
import { getOSSClient, importFileAsync, downLoadFile } from "./UploadOss"; |
|||
import { CreateFileInput } from "/@/services/ServiceProxies"; |
|||
import { dateUtil } from '/@/utils/dateUtil'; |
|||
|
|||
export default defineComponent({ |
|||
components: { |
|||
BasicTable, |
|||
TableAction, |
|||
Tag, |
|||
UploadOutlined |
|||
}, |
|||
setup() { |
|||
const { t } = useI18n(); |
|||
const fileList = ref([]); |
|||
// table配置 |
|||
const [registerTable, { reload }] = useTable({ |
|||
columns: tableColumns, |
|||
formConfig: { |
|||
labelWidth: 70, |
|||
schemas: searchFormSchema, |
|||
fieldMapToTime: [ |
|||
["time", ["executionBeginTime", "executionEndTime"], "YYYY-MM-DD HH:mm:ss"] |
|||
] |
|||
}, |
|||
api: getTableListAsync, |
|||
showTableSetting: true, |
|||
useSearchForm: true, |
|||
bordered: true, |
|||
canResize: true, |
|||
showIndexColumn: true, |
|||
actionColumn: { |
|||
width: 120, |
|||
title: t("common.action"), |
|||
dataIndex: "action", |
|||
slots: { |
|||
customRender: "action" |
|||
}, |
|||
fixed: "right" |
|||
} |
|||
}); |
|||
|
|||
async function customRequest(action) { |
|||
let fileName = action.file.name; |
|||
let index = fileName.lastIndexOf("."); |
|||
let type = fileName.slice(index + 1); |
|||
let name = fileName.slice(0, index); |
|||
const client = await getOSSClient(); |
|||
let fileFullName = `host/${dateUtil().format("YYYY-MM-DD")}/${name}_${dateUtil().format( |
|||
"X" |
|||
)}.${type}`; |
|||
|
|||
await client.put(fileFullName, action.file); |
|||
let request = new CreateFileInput(); |
|||
request.fileName = fileName; |
|||
request.filePath = fileFullName; |
|||
await importFileAsync({ request }); |
|||
await reload(); |
|||
} |
|||
|
|||
const handleDownload = async (record: Recordable) => { |
|||
await downLoadFile(record.filePath); |
|||
}; |
|||
return { |
|||
t, |
|||
fileList, |
|||
registerTable, |
|||
customRequest, |
|||
handleDownload |
|||
}; |
|||
} |
|||
}); |
|||
</script> |
|||
|
|||
<style lang="less" scoped></style> --> |
|||
@ -0,0 +1,66 @@ |
|||
// import { FilesServiceProxy, FileTokenOutput } from "/@/services/ServiceProxies";
|
|||
// import OSS from "ali-oss";
|
|||
// import { dateUtil } from '/@/utils/dateUtil';
|
|||
// export async function importFileAsync({ request }) {
|
|||
// const _filesServiceProxy = new FilesServiceProxy();
|
|||
// await _filesServiceProxy.create(request);
|
|||
// }
|
|||
|
|||
// async function getFileTokenAsync() {
|
|||
// const _filesServiceProxy = new FilesServiceProxy();
|
|||
// const result = await _filesServiceProxy.getFileToken();
|
|||
// sessionStorage.setItem("oss", JSON.stringify(result));
|
|||
// return result;
|
|||
// }
|
|||
|
|||
// export async function getOSSClient(): Promise<OSS> {
|
|||
// let fileToken = new FileTokenOutput();
|
|||
// try {
|
|||
// let oss = sessionStorage.getItem("oss");
|
|||
// if (!oss) {
|
|||
// fileToken = await getFileTokenAsync();
|
|||
// } else {
|
|||
// fileToken = JSON.parse(oss);
|
|||
// let expiration = dateUtil(fileToken.expiration).format("YYYY-MM-DD HH:mm:ss");
|
|||
// if (expiration < formatDate(dateUtil())) {
|
|||
// fileToken = await getFileTokenAsync();
|
|||
// }
|
|||
// }
|
|||
// let request = {
|
|||
// region: fileToken.region,
|
|||
// accessKeyId: fileToken.accessKeyId,
|
|||
// accessKeySecret: fileToken.accessKeySecret,
|
|||
// bucket: fileToken.bucket,
|
|||
// stsToken: fileToken.token as string
|
|||
// };
|
|||
|
|||
// return Promise.resolve<OSS>(new OSS(request));
|
|||
// } catch (error) {
|
|||
// console.error("获取oss Client失败");
|
|||
// }
|
|||
// }
|
|||
|
|||
// export async function downLoadFile(fileName) {
|
|||
// let oss = await getOSSClient();
|
|||
// const response = {
|
|||
// "content-disposition": `attachment; filename=${encodeURIComponent(fileName)}`
|
|||
// };
|
|||
// const url = (oss as OSS).signatureUrl(fileName, { response });
|
|||
// let link = document.createElement("a"); //创建a标签
|
|||
// link.style.display = "none"; //使其隐藏
|
|||
// link.href = url; //赋予文件下载地址
|
|||
// link.setAttribute("download", fileName); //设置下载属性 以及文件名
|
|||
// document.body.appendChild(link); //a标签插至页面中
|
|||
// link.click(); //强制触发a标签事件
|
|||
// }
|
|||
|
|||
// function formatDate(dateTime) {
|
|||
// const date = new Date(dateTime);
|
|||
// const YY = date.getFullYear() + "-";
|
|||
// const MM = (date.getMonth() + 1 < 10 ? "0" + (date.getMonth() + 1) : date.getMonth() + 1) + "-";
|
|||
// const DD = date.getDate() < 10 ? "0" + date.getDate() : date.getDate();
|
|||
// const hh = date.getHours() + ":";
|
|||
// const mm = date.getMinutes() + ":";
|
|||
// const ss = date.getSeconds();
|
|||
// return YY + MM + DD + " " + hh + mm + ss;
|
|||
// }
|
|||
@ -0,0 +1,19 @@ |
|||
import { FeaturesServiceProxy, GetFeatureListResultInput,UpdateFeatureInput,UpdateFeaturesDto} from '/@/services/ServiceProxies'; |
|||
|
|||
export async function getHostFeatureListAsync() { |
|||
const _featuresServiceProxy = new FeaturesServiceProxy(); |
|||
const request = new GetFeatureListResultInput(); |
|||
request.providerName = 'T'; |
|||
return await _featuresServiceProxy.list(request); |
|||
} |
|||
|
|||
export async function updateHostFeatureListAsync(params) { |
|||
const _featuresServiceProxy = new FeaturesServiceProxy(); |
|||
const request = new UpdateFeatureInput(); |
|||
|
|||
request.providerName = 'T'; |
|||
request.updateFeaturesDto= new UpdateFeaturesDto(); |
|||
request.updateFeaturesDto.features=params; |
|||
return await _featuresServiceProxy.update(request); |
|||
} |
|||
|
|||
@ -0,0 +1,137 @@ |
|||
<template> |
|||
<PageWrapper v-loading="loading"> |
|||
<div ref="wrapperRef" :class="prefixCls"> |
|||
<Tabs tab-position="left" :tabBarStyle="tabBarStyle" @change="change"> |
|||
<template v-for="item in featureList" :key="item.name"> |
|||
<TabPane :tab="item.displayName"> |
|||
<CollapseContainer :title="item.displayName" :canExpan="false"> |
|||
<a-form :label-col="labelCol" :wrapper-col="wrapperCol"> |
|||
<a-form-item v-for="feature in item.features" :label="feature.displayName"> |
|||
<div v-if="feature.valueType.name === 'FreeTextStringValueType'"> |
|||
<a-input v-model:value="feature.value" style="width: 80%" /> |
|||
</div> |
|||
|
|||
<div v-if="feature.valueType.name === 'ToggleStringValueType'"> |
|||
<a-checkbox :checked="!(feature.value == 'false' || feature.value == false)" |
|||
@update:checked="(val) => (feature.value = val)"> |
|||
</a-checkbox> |
|||
</div> |
|||
</a-form-item> |
|||
</a-form> |
|||
<a-button style="margin-left: 65%" type="primary" @click="update(item)">{{ |
|||
t('common.saveText') |
|||
}}</a-button> |
|||
</CollapseContainer> |
|||
</TabPane> |
|||
</template> |
|||
</Tabs> |
|||
</div> |
|||
</PageWrapper> |
|||
|
|||
</template> |
|||
|
|||
<script lang="ts"> |
|||
import { defineComponent, reactive, toRefs, onMounted } from 'vue'; |
|||
import { useI18n } from '/@/hooks/web/useI18n'; |
|||
import { Tabs } from 'ant-design-vue'; |
|||
import { CollapseContainer, ScrollContainer } from '/@/components/Container/index'; |
|||
import { PageWrapper } from '/@/components/Page'; |
|||
import { getHostFeatureListAsync, updateHostFeatureListAsync } from '/@/views/admin/manageFeatrue/index'; |
|||
import { FeatureGroupDto, UpdateFeatureDto } from '/@/services/ServiceProxies'; |
|||
import { message } from 'ant-design-vue'; |
|||
export default defineComponent({ |
|||
name: 'ManageHostFeatrue', |
|||
components: { |
|||
ScrollContainer, |
|||
CollapseContainer, |
|||
Tabs, |
|||
TabPane: Tabs.TabPane, |
|||
PageWrapper, |
|||
}, |
|||
setup() { |
|||
const { t } = useI18n(); |
|||
let featureList: FeatureGroupDto[] = []; |
|||
const state = reactive({ |
|||
featureList, |
|||
loading: true, |
|||
}); |
|||
onMounted(async () => { |
|||
state.loading = true; |
|||
const result = await getHostFeatureListAsync(); |
|||
state.featureList = result.groups as FeatureGroupDto[]; |
|||
state.loading = false; |
|||
}); |
|||
|
|||
const update = async (item) => { |
|||
console.log(item) |
|||
let features = item.features?.map(e => { |
|||
let item = new UpdateFeatureDto(); |
|||
item.name = e.name; |
|||
item.value = e.value?.toString(); |
|||
return item; |
|||
}) |
|||
|
|||
try { |
|||
state.loading = true; |
|||
await updateHostFeatureListAsync(features) |
|||
message.success(t('common.operationSuccess')); |
|||
} catch (error) { |
|||
message.success(t('common.operationFail')); |
|||
} finally { |
|||
state.loading = false; |
|||
} |
|||
} |
|||
const submit = async () => { |
|||
|
|||
if (currentFeature) { |
|||
let features = currentFeature.features?.map(e => { |
|||
let item = new UpdateFeatureDto(); |
|||
item.name = e.name; |
|||
item.value = e.value?.toString(); |
|||
return item; |
|||
}) |
|||
|
|||
try { |
|||
state.loading = true; |
|||
await updateHostFeatureListAsync(features) |
|||
message.success(t('common.operationSuccess')); |
|||
} catch (error) { |
|||
message.success(t('common.operationFail')); |
|||
} finally { |
|||
state.loading = false; |
|||
} |
|||
|
|||
} |
|||
}; |
|||
const cancel = () => { |
|||
}; |
|||
return { |
|||
t, |
|||
submit, |
|||
cancel, |
|||
...toRefs(state), |
|||
prefixCls: 'account-setting', |
|||
tabBarStyle: { |
|||
width: '220px', |
|||
}, |
|||
labelCol: { span: 4 }, |
|||
wrapperCol: { span: 14 }, |
|||
update |
|||
}; |
|||
}, |
|||
}); |
|||
</script> |
|||
<style lang="less"> |
|||
.account-setting { |
|||
margin: 12px; |
|||
background-color: @component-background; |
|||
|
|||
.base-title { |
|||
padding-left: 0; |
|||
} |
|||
|
|||
.ant-tabs-tab-active { |
|||
background-color: @item-active-bg; |
|||
} |
|||
} |
|||
</style> |
|||
@ -0,0 +1,65 @@ |
|||
<template> |
|||
<BasicModal |
|||
:title="t('common.createText')" |
|||
:canFullscreen="false" |
|||
@ok="submit" |
|||
@cancel="cancel" |
|||
@register="registerNotificationModal" |
|||
> |
|||
<BasicForm @register="registerNotificationForm" /> |
|||
</BasicModal> |
|||
</template> |
|||
|
|||
<script lang="ts"> |
|||
import { defineComponent } from 'vue'; |
|||
import { BasicModal, useModalInner } from '/@/components/Modal'; |
|||
import { BasicForm, useForm } from '/@/components/Form/index'; |
|||
import { createFormSchema, sendNotificationAsync } from './Index'; |
|||
import { useI18n } from '/@/hooks/web/useI18n'; |
|||
export default defineComponent({ |
|||
name: 'CreateSubscription', |
|||
components: { |
|||
BasicModal, |
|||
BasicForm, |
|||
}, |
|||
emits: ['reload', 'register'], |
|||
setup(_, { emit }) { |
|||
const { t } = useI18n(); |
|||
const [registerNotificationForm, { getFieldsValue, resetFields, validate }] = useForm({ |
|||
labelWidth: 120, |
|||
schemas: createFormSchema, |
|||
showActionButtonGroup: false, |
|||
}); |
|||
|
|||
const [registerNotificationModal, { changeOkLoading, closeModal }] = useModalInner(); |
|||
|
|||
const submit = async () => { |
|||
try { |
|||
const params = getFieldsValue(); |
|||
changeOkLoading(true); |
|||
await validate(); |
|||
await sendNotificationAsync({ params }); |
|||
await resetFields(); |
|||
emit('reload'); |
|||
closeModal(); |
|||
} finally { |
|||
changeOkLoading(false); |
|||
} |
|||
}; |
|||
|
|||
const cancel = () => { |
|||
resetFields(); |
|||
closeModal(); |
|||
}; |
|||
return { |
|||
registerNotificationModal, |
|||
registerNotificationForm, |
|||
submit, |
|||
cancel, |
|||
t |
|||
}; |
|||
}, |
|||
}); |
|||
</script> |
|||
|
|||
<style lang="less" scoped></style> |
|||
@ -0,0 +1,65 @@ |
|||
<template> |
|||
<BasicModal |
|||
:title="t('routes.admin.notificationManagement_sendNotificationSubscription')" |
|||
:canFullscreen="false" |
|||
@ok="submit" |
|||
@cancel="cancel" |
|||
@register="registerNotificationModal" |
|||
> |
|||
<BasicForm @register="registerNotificationForm" /> |
|||
</BasicModal> |
|||
</template> |
|||
|
|||
<script lang="ts"> |
|||
import { defineComponent } from 'vue'; |
|||
import { BasicModal, useModalInner } from '/@/components/Modal'; |
|||
import { BasicForm, useForm } from '/@/components/Form/index'; |
|||
import { createSubscriptionFormSchema, sendNotificationSubscriptionAsync } from './Index'; |
|||
import { useI18n } from '/@/hooks/web/useI18n'; |
|||
export default defineComponent({ |
|||
name: 'CreateNotification', |
|||
components: { |
|||
BasicModal, |
|||
BasicForm, |
|||
}, |
|||
emits: ['reload', 'register'], |
|||
setup(_, { emit }) { |
|||
const { t } = useI18n(); |
|||
const [registerNotificationForm, { getFieldsValue, resetFields, validate }] = useForm({ |
|||
labelWidth: 120, |
|||
schemas: createSubscriptionFormSchema, |
|||
showActionButtonGroup: false, |
|||
}); |
|||
|
|||
const [registerNotificationModal, { changeOkLoading, closeModal }] = useModalInner(); |
|||
|
|||
const submit = async () => { |
|||
try { |
|||
const params = getFieldsValue(); |
|||
changeOkLoading(true); |
|||
await validate(); |
|||
await sendNotificationSubscriptionAsync({ params }); |
|||
await resetFields(); |
|||
emit('reload'); |
|||
closeModal(); |
|||
} finally { |
|||
changeOkLoading(false); |
|||
} |
|||
}; |
|||
|
|||
const cancel = () => { |
|||
resetFields(); |
|||
closeModal(); |
|||
}; |
|||
return { |
|||
registerNotificationModal, |
|||
registerNotificationForm, |
|||
submit, |
|||
cancel, |
|||
t |
|||
}; |
|||
}, |
|||
}); |
|||
</script> |
|||
|
|||
<style lang="less" scoped></style> |
|||
@ -0,0 +1,396 @@ |
|||
import { FormSchema } from '/@/components/Table'; |
|||
import { BasicColumn } from '/@/components/Table'; |
|||
import { |
|||
NotificationServiceProxy, |
|||
PagingNotificationSubscriptionInput, |
|||
PagingNotificationInput, |
|||
PagingUserListInput, |
|||
UsersServiceProxy |
|||
} from '/@/services/ServiceProxies'; |
|||
import { useI18n } from '/@/hooks/web/useI18n'; |
|||
import { formatToDateTime, dateUtil } from '/@/utils/dateUtil'; |
|||
const { t } = useI18n(); |
|||
// 分页表格消息通知 BasicColumn
|
|||
export const tableColumns: BasicColumn[] = [ |
|||
{ |
|||
title: t('routes.admin.notificationManagement_title'), |
|||
dataIndex: 'title', |
|||
width: 200, |
|||
}, |
|||
{ |
|||
title: t('routes.admin.notificationManagement_content'), |
|||
dataIndex: 'content', |
|||
}, |
|||
// {
|
|||
// title: t('routes.admin.notificationManagement_messageType'),
|
|||
// dataIndex: 'messageTypeName',
|
|||
// width: 100,
|
|||
// },
|
|||
{ |
|||
title: t('routes.admin.notificationManagement_messageLevel'), |
|||
dataIndex: 'messageLevelName', |
|||
width: 100, |
|||
}, |
|||
|
|||
{ |
|||
title: t('routes.admin.notificationManagement_senderUserName'), |
|||
dataIndex: 'senderUserName', |
|||
width: 100, |
|||
}, |
|||
|
|||
{ |
|||
title: t('routes.admin.notificationManagement_receiveUserName'), |
|||
dataIndex: 'receiveUserName', |
|||
width: 100, |
|||
}, |
|||
{ |
|||
title: t('routes.admin.notificationManagement_read'), |
|||
dataIndex: 'read', |
|||
width: 100, |
|||
}, |
|||
{ |
|||
title: t('routes.admin.notificationManagement_readTime'), |
|||
dataIndex: 'readTime', |
|||
customRender: ({ text }) => { |
|||
return formatToDateTime(text); |
|||
}, |
|||
width: 250, |
|||
}, |
|||
]; |
|||
|
|||
// 分页查询消息通知 FormSchema
|
|||
export const searchFormSchema: FormSchema[] = [ |
|||
{ |
|||
field: 'title', |
|||
label: t('routes.admin.notificationManagement_title'), |
|||
component: "Input", |
|||
colProps: { span: 4 } |
|||
}, |
|||
{ |
|||
field: 'content', |
|||
label: t('routes.admin.notificationManagement_content'), |
|||
component: "Input", |
|||
colProps: { span: 6 } |
|||
}, |
|||
{ |
|||
field: 'messageType', |
|||
label: t('routes.admin.notificationManagement_messageType'), |
|||
component: "Input", |
|||
required: true, |
|||
defaultValue: 20, |
|||
show: false, |
|||
colProps: { span: 18 } |
|||
}, |
|||
{ |
|||
field: 'messageLevel', |
|||
component: 'Select', |
|||
label: t('routes.admin.notificationManagement_messageLevel'), |
|||
|
|||
colProps: { |
|||
span: 2, |
|||
}, |
|||
componentProps: { |
|||
options: [ |
|||
{ |
|||
label: '警告', |
|||
value: 10, |
|||
}, |
|||
{ |
|||
label: '正常', |
|||
value: 20, |
|||
}, |
|||
{ |
|||
label: '错误', |
|||
value: 30, |
|||
}, |
|||
], |
|||
}, |
|||
}, |
|||
{ |
|||
field: 'read', |
|||
component: 'Select', |
|||
label: t('routes.admin.notificationManagement_read'), |
|||
|
|||
colProps: { |
|||
span: 2, |
|||
}, |
|||
componentProps: { |
|||
options: [ |
|||
{ |
|||
label: '是', |
|||
value: true, |
|||
}, |
|||
{ |
|||
label: '否', |
|||
value: false, |
|||
} |
|||
], |
|||
}, |
|||
}, |
|||
|
|||
]; |
|||
|
|||
// 创建消息通知 FormSchema
|
|||
export const createFormSchema: FormSchema[] = [ |
|||
{ |
|||
field: 'title', |
|||
label: t('routes.admin.notificationManagement_title'), |
|||
component: "Input", |
|||
required: true, |
|||
colProps: { span: 18 } |
|||
}, |
|||
{ |
|||
field: 'content', |
|||
label: t('routes.admin.notificationManagement_content'), |
|||
component: "Input", |
|||
required: true, |
|||
colProps: { span: 18 } |
|||
}, |
|||
{ |
|||
field: 'messageLevel', |
|||
component: 'Select', |
|||
label: t('routes.admin.notificationManagement_messageLevel'), |
|||
defaultValue: 20, |
|||
colProps: { span: 18 }, |
|||
componentProps: { |
|||
options: [ |
|||
{ |
|||
label: '警告', |
|||
value: 10, |
|||
}, |
|||
{ |
|||
label: '正常', |
|||
value: 20, |
|||
}, |
|||
{ |
|||
label: '错误', |
|||
value: 30, |
|||
}, |
|||
], |
|||
}, |
|||
}, |
|||
{ |
|||
field: 'receiveUserId', |
|||
label: t('routes.admin.notificationManagement_receiveUserName'), |
|||
labelWidth: 120, |
|||
component: 'ApiSelect', |
|||
colProps: { span: 18 }, |
|||
componentProps: ({ formModel }) => { |
|||
return { |
|||
api: getUserListAsync, |
|||
labelField: 'userName', |
|||
valueField: 'id', |
|||
showSearch: true, |
|||
optionFilterProp: 'label', |
|||
onChange: async (e: any, options : any) => { |
|||
formModel.receiveUserName = options.name; |
|||
}, |
|||
}; |
|||
}, |
|||
}, |
|||
{ |
|||
field: 'receiveUserName', |
|||
label: 'ReceiveUserName', |
|||
component: "Input", |
|||
required: true, |
|||
show: false, |
|||
colProps: { span: 18 } |
|||
}, |
|||
]; |
|||
|
|||
// 创建消息通知 FormSchema
|
|||
export const createSubscriptionFormSchema: FormSchema[] = [ |
|||
{ |
|||
field: 'title', |
|||
label: t('routes.admin.notificationManagement_title'), |
|||
component: "Input", |
|||
required: true, |
|||
colProps: { span: 18 } |
|||
}, |
|||
{ |
|||
field: 'content', |
|||
label: t('routes.admin.notificationManagement_content'), |
|||
component: "Input", |
|||
required: true, |
|||
colProps: { span: 18 } |
|||
}, |
|||
{ |
|||
field: 'messageLevel', |
|||
component: 'Select', |
|||
label: t('routes.admin.notificationManagement_messageLevel'), |
|||
defaultValue: 20, |
|||
colProps: { span: 18 }, |
|||
componentProps: { |
|||
options: [ |
|||
{ |
|||
label: '警告', |
|||
value: 10, |
|||
}, |
|||
{ |
|||
label: '正常', |
|||
value: 20, |
|||
}, |
|||
{ |
|||
label: '错误', |
|||
value: 30, |
|||
}, |
|||
], |
|||
}, |
|||
} |
|||
]; |
|||
|
|||
|
|||
// 分页查询消息通知 FormSchema
|
|||
export const searchSubscriptionFormSchema: FormSchema[] = [ |
|||
{ |
|||
field: 'title', |
|||
label: t('routes.admin.notificationManagement_title'), |
|||
component: "Input", |
|||
colProps: { span: 4 } |
|||
}, |
|||
{ |
|||
field: 'content', |
|||
label: t('routes.admin.notificationManagement_content'), |
|||
component: "Input", |
|||
colProps: { span: 6 } |
|||
}, |
|||
{ |
|||
field: 'messageType', |
|||
label: t('routes.admin.notificationManagement_messageType'), |
|||
component: "Input", |
|||
required: true, |
|||
defaultValue: 10, |
|||
show: false, |
|||
colProps: { span: 18 } |
|||
}, |
|||
{ |
|||
field: 'messageLevel', |
|||
component: 'Select', |
|||
label: t('routes.admin.notificationManagement_messageLevel'), |
|||
|
|||
colProps: { |
|||
span: 2, |
|||
}, |
|||
componentProps: { |
|||
options: [ |
|||
{ |
|||
label: '警告', |
|||
value: 10, |
|||
}, |
|||
{ |
|||
label: '正常', |
|||
value: 20, |
|||
}, |
|||
{ |
|||
label: '错误', |
|||
value: 30, |
|||
}, |
|||
], |
|||
}, |
|||
}, |
|||
]; |
|||
// 分页表格消息通知 BasicColumn
|
|||
export const tableSubscriptionColumns: BasicColumn[] = [ |
|||
{ |
|||
title: t('routes.admin.notificationManagement_title'), |
|||
dataIndex: 'title', |
|||
width: 200, |
|||
}, |
|||
{ |
|||
title: t('routes.admin.notificationManagement_content'), |
|||
dataIndex: 'content', |
|||
}, |
|||
// {
|
|||
// title: t('routes.admin.notificationManagement_messageType'),
|
|||
// dataIndex: 'messageTypeName',
|
|||
// width: 100,
|
|||
// },
|
|||
{ |
|||
title: t('routes.admin.notificationManagement_messageLevel'), |
|||
dataIndex: 'messageLevelName', |
|||
width: 100, |
|||
}, |
|||
|
|||
{ |
|||
title: t('routes.admin.notificationManagement_senderUserName'), |
|||
dataIndex: 'senderUserName', |
|||
width: 100, |
|||
}, |
|||
{ |
|||
title: t('routes.admin.userManagement_createTime'), |
|||
dataIndex: 'creationTime', |
|||
customRender: ({ text }) => { |
|||
return dateUtil(text).format('YYYY-MM-DD HH:mm:ss'); |
|||
}, |
|||
width: 250, |
|||
}, |
|||
]; |
|||
|
|||
/** |
|||
* 分页查询消息通知 |
|||
*/ |
|||
export async function notificationPageAsync(params: PagingNotificationInput, |
|||
) { |
|||
const notificationServiceProxy = new NotificationServiceProxy(); |
|||
return notificationServiceProxy.notificationPage(params); |
|||
} |
|||
|
|||
/** |
|||
* 分页查询消息通知 |
|||
*/ |
|||
export async function notificationSubscriptionPageAsync(params: PagingNotificationSubscriptionInput, |
|||
) { |
|||
const notificationServiceProxy = new NotificationServiceProxy(); |
|||
return notificationServiceProxy.notificationSubscriptionPage(params); |
|||
} |
|||
|
|||
export async function setReadAsync(request) { |
|||
const _notificationServiceProxy = new NotificationServiceProxy(); |
|||
await _notificationServiceProxy.read(request); |
|||
} |
|||
|
|||
|
|||
/** |
|||
* 创建消息通知 |
|||
*/ |
|||
export async function sendNotificationAsync({ params }) { |
|||
const notificationServiceProxy = new NotificationServiceProxy(); |
|||
if (params.messageLevel == 10) { |
|||
await notificationServiceProxy.sendCommonWarningMessage(params); |
|||
} |
|||
if (params.messageLevel == 20) { |
|||
await notificationServiceProxy.sendCommonInformationMessage(params); |
|||
} |
|||
if (params.messageLevel == 30) { |
|||
await notificationServiceProxy.sendCommonErrorMessage(params); |
|||
} |
|||
} |
|||
|
|||
|
|||
/** |
|||
* 创建消息通知 |
|||
*/ |
|||
export async function sendNotificationSubscriptionAsync({ params }) { |
|||
const notificationServiceProxy = new NotificationServiceProxy(); |
|||
if (params.messageLevel == 10) { |
|||
await notificationServiceProxy.sendBroadCastWarningMessage(params); |
|||
} |
|||
if (params.messageLevel == 20) { |
|||
await notificationServiceProxy.sendBroadCastInformationMessage(params); |
|||
} |
|||
if (params.messageLevel == 30) { |
|||
await notificationServiceProxy.sendBroadCastErrorMessage(params); |
|||
} |
|||
} |
|||
|
|||
/** |
|||
* 获取用户列表 |
|||
* @param params |
|||
* @returns |
|||
*/ |
|||
export async function getUserListAsync( |
|||
params: PagingUserListInput, |
|||
) { |
|||
const _userServiceProxy = new UsersServiceProxy(); |
|||
return _userServiceProxy.list(params); |
|||
} |
|||
@ -0,0 +1,107 @@ |
|||
<template> |
|||
<div> |
|||
<BasicTable @register="registerTable" size="small"> |
|||
<template #toolbar> |
|||
<a-button |
|||
preIcon="ant-design:plus-circle-outlined" |
|||
type="primary" |
|||
@click="openCreateNotificationModal" |
|||
> |
|||
{{t('routes.admin.notificationManagement_sendNotification')}} |
|||
</a-button> |
|||
</template> |
|||
<template #bodyCell="{ column, record }"> |
|||
<template v-if="column.key === 'read'"> |
|||
<Tag color='green' v-if="record.read">{{ record.read? '已读' : '未读' }}</Tag> |
|||
<Tag v-if="!record.read">{{ record.read? '已读' : '未读' }}</Tag> |
|||
</template> |
|||
|
|||
<template v-if="column.key === 'messageLevelName'"> |
|||
<Tag color='yellow' v-if="record.messageLevel ===10">{{ record.messageLevelName}}</Tag> |
|||
<Tag color='green' v-if="record.messageLevel === 20">{{ record.messageLevelName}}</Tag> |
|||
<Tag color='red' v-if="record.messageLevel === 30">{{ record.messageLevelName}}</Tag> |
|||
</template> |
|||
|
|||
</template> |
|||
|
|||
<template #action="{ record }"> |
|||
<TableAction |
|||
:actions="[ |
|||
{ |
|||
icon: 'clarity:note-edit-line', |
|||
label: t('routes.admin.notificationManagement_setRead'), |
|||
onClick: handleSetRead.bind(null, record), |
|||
}, |
|||
]" |
|||
/> |
|||
</template> |
|||
</BasicTable> |
|||
<CreateNotification |
|||
@register="registerCreateNotificationModal" |
|||
@reload="reload" |
|||
:bodyStyle="{ 'padding-top': '0' }" |
|||
/> |
|||
</div> |
|||
</template> |
|||
|
|||
<script lang="ts"> |
|||
import { defineComponent } from 'vue'; |
|||
import { BasicTable, TableAction, useTable } from '/@/components/Table'; |
|||
import { Tag } from 'ant-design-vue'; |
|||
import { tableColumns, searchFormSchema, notificationPageAsync,setReadAsync } from './Index'; |
|||
import { useI18n } from '/@/hooks/web/useI18n'; |
|||
import { SetReadInput } from '/@/services/ServiceProxies'; |
|||
import CreateNotification from './CreateNotification.vue'; |
|||
import { useModal } from '/@/components/Modal'; |
|||
export default defineComponent({ |
|||
name: 'Notification', |
|||
components: { |
|||
BasicTable, |
|||
TableAction, |
|||
Tag, |
|||
CreateNotification |
|||
}, |
|||
setup() { |
|||
const { t } = useI18n(); |
|||
// table配置 |
|||
const [registerTable, { reload }] = useTable({ |
|||
columns: tableColumns, |
|||
formConfig: { |
|||
labelWidth: 70, |
|||
schemas: searchFormSchema, |
|||
}, |
|||
api: notificationPageAsync, |
|||
showTableSetting: true, |
|||
useSearchForm: true, |
|||
bordered: true, |
|||
canResize: true, |
|||
showIndexColumn: true, |
|||
immediate: true, |
|||
scroll: { x: true }, |
|||
actionColumn: { |
|||
width: 220, |
|||
title: '操作', |
|||
dataIndex: 'action', |
|||
slots: { customRender: 'action' }, |
|||
}, |
|||
}); |
|||
const [registerCreateNotificationModal, { openModal: openCreateNotificationModal }] = useModal(); |
|||
async function handleSetRead(record: Recordable) { |
|||
let request = new SetReadInput(); |
|||
request.id = record.id; |
|||
await setReadAsync(request); |
|||
await reload(); |
|||
} |
|||
|
|||
|
|||
return { |
|||
registerTable, |
|||
reload, |
|||
t, |
|||
handleSetRead, |
|||
registerCreateNotificationModal, |
|||
openCreateNotificationModal |
|||
}; |
|||
}, |
|||
}); |
|||
</script> |
|||
@ -0,0 +1,76 @@ |
|||
<template> |
|||
<div> |
|||
<BasicTable @register="registerTable" size="small"> |
|||
<template #toolbar> |
|||
<a-button |
|||
preIcon="ant-design:plus-circle-outlined" |
|||
type="primary" |
|||
@click="openCreateNotificationModal" |
|||
> |
|||
{{t('routes.admin.notificationManagement_sendNotificationSubscription')}} |
|||
</a-button> |
|||
</template> |
|||
<template #bodyCell="{ column, record }"> |
|||
|
|||
<template v-if="column.key === 'messageLevelName'"> |
|||
<Tag color='yellow' v-if="record.messageLevel ===10">{{ record.messageLevelName}}</Tag> |
|||
<Tag color='green' v-if="record.messageLevel === 20">{{ record.messageLevelName}}</Tag> |
|||
<Tag color='red' v-if="record.messageLevel === 30">{{ record.messageLevelName}}</Tag> |
|||
</template> |
|||
|
|||
</template> |
|||
|
|||
</BasicTable> |
|||
<CreateSubscription |
|||
@register="registerCreateNotificationModal" |
|||
@reload="reload" |
|||
:bodyStyle="{ 'padding-top': '0' }" |
|||
/> |
|||
</div> |
|||
</template> |
|||
|
|||
<script lang="ts"> |
|||
import { defineComponent } from 'vue'; |
|||
import { BasicTable, TableAction, useTable } from '/@/components/Table'; |
|||
import { Tag } from 'ant-design-vue'; |
|||
import { tableSubscriptionColumns, searchSubscriptionFormSchema, notificationPageAsync } from './Index'; |
|||
import { useI18n } from '/@/hooks/web/useI18n'; |
|||
import CreateSubscription from './CreateSubscription.vue'; |
|||
import { useModal } from '/@/components/Modal'; |
|||
export default defineComponent({ |
|||
name: 'Subscription', |
|||
components: { |
|||
BasicTable, |
|||
TableAction, |
|||
Tag, |
|||
CreateSubscription |
|||
}, |
|||
setup() { |
|||
const { t } = useI18n(); |
|||
// table配置 |
|||
const [registerTable, { reload }] = useTable({ |
|||
columns: tableSubscriptionColumns, |
|||
formConfig: { |
|||
labelWidth: 70, |
|||
schemas: searchSubscriptionFormSchema, |
|||
}, |
|||
api: notificationPageAsync, |
|||
showTableSetting: true, |
|||
useSearchForm: true, |
|||
bordered: true, |
|||
canResize: true, |
|||
showIndexColumn: true, |
|||
immediate: true, |
|||
scroll: { x: true }, |
|||
}); |
|||
const [registerCreateNotificationModal, { openModal: openCreateNotificationModal }] = useModal(); |
|||
return { |
|||
registerTable, |
|||
reload, |
|||
t, |
|||
registerCreateNotificationModal, |
|||
openCreateNotificationModal |
|||
}; |
|||
}, |
|||
}); |
|||
</script> |
|||
@ -0,0 +1,70 @@ |
|||
<template> |
|||
<BasicModal :title="t('common.createOrUpdateText')" :canFullscreen="false" @ok="submit" @cancel="cancel" |
|||
@register="registerModal"> |
|||
<BasicForm @register="registerTenantForm" /> |
|||
</BasicModal> |
|||
</template> |
|||
|
|||
<script lang="ts"> |
|||
import { defineComponent } from 'vue'; |
|||
import { BasicModal, useModalInner } from '/@/components/Modal'; |
|||
import { BasicForm, useForm } from '/@/components/Form/index'; |
|||
import { createConnectionStringFormSchema, addOrUpdateConnectionString } from '/@/views/tenants/Tenant'; |
|||
import { useI18n } from '/@/hooks/web/useI18n'; |
|||
|
|||
export default defineComponent({ |
|||
name: 'CreateConnectionString', |
|||
components: { |
|||
BasicModal, |
|||
BasicForm, |
|||
}, |
|||
emits: ['reload', 'register'], |
|||
setup(_, { emit }) { |
|||
const { t } = useI18n(); |
|||
const [registerTenantForm, { getFieldsValue, setFieldsValue }] = useForm({ |
|||
labelWidth: 120, |
|||
schemas: createConnectionStringFormSchema, |
|||
showActionButtonGroup: false, |
|||
}); |
|||
|
|||
const [registerModal, { closeModal }] = useModalInner((data) => { |
|||
setFieldsValue({ |
|||
id: data.id, |
|||
}) |
|||
}); |
|||
|
|||
const submit = async () => { |
|||
const request = getFieldsValue(); |
|||
await addOrUpdateConnectionString({ request }); |
|||
setFieldsValue({ |
|||
name: '', |
|||
}) |
|||
setFieldsValue({ |
|||
value: '', |
|||
}) |
|||
emit('reload'); |
|||
closeModal(); |
|||
|
|||
}; |
|||
|
|||
const cancel = () => { |
|||
setFieldsValue({ |
|||
name: '', |
|||
}) |
|||
setFieldsValue({ |
|||
value: '', |
|||
}) |
|||
closeModal(); |
|||
}; |
|||
return { |
|||
t, |
|||
registerModal, |
|||
registerTenantForm, |
|||
submit, |
|||
cancel, |
|||
}; |
|||
}, |
|||
}); |
|||
</script> |
|||
|
|||
<style lang="less" scoped></style> |
|||
@ -1,76 +1,124 @@ |
|||
<template> |
|||
<BasicModal |
|||
:title="t('common.editText')" |
|||
:canFullscreen="false" |
|||
@ok="submit" |
|||
@cancel="cancel" |
|||
@register="registerModal" |
|||
:minHeight="100" |
|||
> |
|||
<BasicForm @register="registerApiScopeForm" /> |
|||
<BasicModal :title="t('common.editText')" :canFullscreen="false" :showCancelBtn="false" @register="registerModal" |
|||
@ok="submit" :defaultFullscreen="true"> |
|||
|
|||
<BasicTable @register="registerTable" size="small"> |
|||
<template #toolbar> |
|||
<a-button type="primary" preIcon="ant-design:plus-circle-outlined" |
|||
@click="handlerOpenCreateConnectionStringModal"> |
|||
{{ t('common.createOrUpdateText') }} |
|||
</a-button> |
|||
</template> |
|||
|
|||
<template #action="{ record }"> |
|||
<TableAction :actions="[ |
|||
|
|||
{ |
|||
icon: 'ant-design:minus-outlined', |
|||
auth: 'AbpTenantManagement.Tenants.Delete', |
|||
label: t('common.delText'), |
|||
onClick: handleDelete.bind(null, record), |
|||
}, |
|||
]" /> |
|||
</template> |
|||
</BasicTable> |
|||
|
|||
<CreateConnectionString @register="registerCreateConnectionStringModal" @reload="reload" |
|||
:bodyStyle="{ 'padding-top': '0' }" /> |
|||
</BasicModal> |
|||
</template> |
|||
|
|||
<script lang="ts"> |
|||
import { defineComponent } from 'vue'; |
|||
import { BasicModal, useModalInner } from '/@/components/Modal'; |
|||
import { BasicForm, useForm } from '/@/components/Form/index'; |
|||
import { |
|||
updateConnectionStringFormSchema, |
|||
updateConnectionStringAsync, |
|||
getConnectionStringAsync, |
|||
} from '/@/views/tenants/Tenant'; |
|||
import { useI18n } from '/@/hooks/web/useI18n'; |
|||
|
|||
export default defineComponent({ |
|||
name: 'EditConnectionString', |
|||
components: { |
|||
BasicModal, |
|||
BasicForm, |
|||
}, |
|||
emits: ['reload', 'register'], |
|||
setup(_, { emit }) { |
|||
const { t } = useI18n(); |
|||
const [registerApiScopeForm, { getFieldsValue, resetFields, setFieldsValue }] = useForm({ |
|||
labelWidth: 120, |
|||
import { defineComponent } from 'vue'; |
|||
import { BasicModal, useModalInner } from '/@/components/Modal'; |
|||
import { updateConnectionStringFormSchema, editConnectionStringtableColumns, pageConnectionStringAsync, deleteConnectionString } from '/@/views/tenants/Tenant'; |
|||
import { useI18n } from '/@/hooks/web/useI18n'; |
|||
import { BasicTable, useTable, TableAction } from '/@/components/Table'; |
|||
import CreateConnectionString from './CreateConnectionString.vue'; |
|||
import { useModal } from '/@/components/Modal'; |
|||
import { useMessage } from '/@/hooks/web/useMessage'; |
|||
export default defineComponent({ |
|||
name: 'EditTenant', |
|||
components: { |
|||
BasicModal, |
|||
BasicTable, |
|||
TableAction, |
|||
CreateConnectionString |
|||
}, |
|||
setup() { |
|||
const { t } = useI18n(); |
|||
const [registerTable, { reload, getForm }] = useTable({ |
|||
columns: editConnectionStringtableColumns, |
|||
formConfig: { |
|||
labelWidth: 100, |
|||
schemas: updateConnectionStringFormSchema, |
|||
showActionButtonGroup: false, |
|||
}); |
|||
showResetButton: false |
|||
}, |
|||
api: pageConnectionStringAsync, |
|||
useSearchForm: true, |
|||
showTableSetting: true, |
|||
bordered: true, |
|||
canResize: true, |
|||
showIndexColumn: true, |
|||
actionColumn: { |
|||
title: t('common.action'), |
|||
dataIndex: 'action', |
|||
slots: { |
|||
customRender: 'action', |
|||
}, |
|||
width: 350, |
|||
fixed: 'right', |
|||
}, |
|||
}); |
|||
|
|||
const [registerModal, { changeOkLoading, closeModal }] = useModalInner(async (data) => { |
|||
const connectionString = await getConnectionStringAsync({ id: data.record.id }); |
|||
await setFieldsValue({ |
|||
id: data.record.id, |
|||
connectionString: connectionString, |
|||
}); |
|||
}); |
|||
|
|||
const submit = async () => { |
|||
try { |
|||
const request = getFieldsValue(); |
|||
changeOkLoading(true); |
|||
await updateConnectionStringAsync({ request }); |
|||
await resetFields(); |
|||
emit('reload'); |
|||
} finally { |
|||
changeOkLoading(false); |
|||
closeModal(); |
|||
} |
|||
}; |
|||
const [registerCreateConnectionStringModal, { openModal: openCreateConnectionStringModal }] = |
|||
useModal(); |
|||
|
|||
const cancel = () => { |
|||
resetFields(); |
|||
closeModal(); |
|||
}; |
|||
return { |
|||
t, |
|||
registerModal, |
|||
registerApiScopeForm, |
|||
submit, |
|||
cancel, |
|||
}; |
|||
}, |
|||
}); |
|||
|
|||
const [registerModal, { closeModal }] = useModalInner((data) => { |
|||
|
|||
getForm().setFieldsValue({ |
|||
id: data.record.id, |
|||
}) |
|||
}); |
|||
|
|||
// 编辑 |
|||
const handlerOpenCreateConnectionStringModal = () => { |
|||
openCreateConnectionStringModal(true, { id: getForm().getFieldsValue().id }); |
|||
}; |
|||
const submit = async () => { |
|||
closeModal(); |
|||
}; |
|||
|
|||
const { createConfirm } = useMessage(); |
|||
// 删除 |
|||
const handleDelete = async (record: Recordable) => { |
|||
console.log(record); |
|||
console.log(getForm().getFieldsValue().id); |
|||
let msg = t('common.askDelete'); |
|||
createConfirm({ |
|||
iconType: 'warning', |
|||
title: t('common.tip'), |
|||
content: msg, |
|||
onOk: async () => { |
|||
await deleteConnectionString(getForm().getFieldsValue().id, record.name); |
|||
await reload(); |
|||
}, |
|||
}); |
|||
}; |
|||
return { |
|||
t, |
|||
registerTable, |
|||
registerModal, |
|||
submit, |
|||
registerCreateConnectionStringModal, |
|||
reload, |
|||
handlerOpenCreateConnectionStringModal, |
|||
handleDelete |
|||
}; |
|||
}, |
|||
}); |
|||
</script> |
|||
|
|||
<style lang="less" scoped></style> |
|||
|
|||
@ -0,0 +1,137 @@ |
|||
<template> |
|||
<BasicModal :title="t('routes.tenant.manageFeatures')" :canFullscreen="false" :defaultFullscreen="true" @ok="submit" |
|||
@cancel="cancel" @register="registerModal"> |
|||
<PageWrapper v-loading="loading"> |
|||
<div ref="wrapperRef" :class="prefixCls"> |
|||
<Tabs tab-position="left" :tabBarStyle="tabBarStyle" @change="change"> |
|||
<template v-for="item in featureList" :key="item.name"> |
|||
<TabPane :tab="item.displayName"> |
|||
<CollapseContainer :title="item.displayName" :canExpan="false"> |
|||
<a-form :label-col="labelCol" :wrapper-col="wrapperCol"> |
|||
<a-form-item v-for="feature in item.features" :label="feature.displayName"> |
|||
<div v-if="feature.valueType.name === 'FreeTextStringValueType'"> |
|||
<a-input v-model:value="feature.value" style="width: 80%" /> |
|||
</div> |
|||
|
|||
<div v-if="feature.valueType.name === 'ToggleStringValueType'"> |
|||
<a-checkbox :checked="!(feature.value == 'false' || feature.value == false)" |
|||
@update:checked="(val) => (feature.value = val)"> |
|||
</a-checkbox> |
|||
</div> |
|||
</a-form-item> |
|||
</a-form> |
|||
</CollapseContainer> |
|||
</TabPane> |
|||
</template> |
|||
</Tabs> |
|||
</div> |
|||
</PageWrapper> |
|||
|
|||
</BasicModal> |
|||
</template> |
|||
|
|||
<script lang="ts"> |
|||
import { defineComponent, reactive, toRefs } from 'vue'; |
|||
import { BasicModal, useModalInner } from '/@/components/Modal'; |
|||
import { useI18n } from '/@/hooks/web/useI18n'; |
|||
import { Tabs } from 'ant-design-vue'; |
|||
import { CollapseContainer, ScrollContainer } from '/@/components/Container/index'; |
|||
import { PageWrapper } from '/@/components/Page'; |
|||
import { getTenantFeatureListAsync, updateTenantFeatureListAsync } from '/@/views/tenants/Tenant'; |
|||
import { FeatureGroupDto, UpdateFeatureDto } from '/@/services/ServiceProxies'; |
|||
import { message } from 'ant-design-vue'; |
|||
export default defineComponent({ |
|||
name: 'ManageFeatrue', |
|||
components: { |
|||
BasicModal, |
|||
ScrollContainer, |
|||
CollapseContainer, |
|||
Tabs, |
|||
TabPane: Tabs.TabPane, |
|||
PageWrapper, |
|||
}, |
|||
setup() { |
|||
const { t } = useI18n(); |
|||
let featureList: FeatureGroupDto[] = []; |
|||
|
|||
// 当前租户id |
|||
let tenantId = ''; |
|||
// 当前选中的tab页面数据 |
|||
let currentFeature: FeatureGroupDto | undefined; |
|||
const state = reactive({ |
|||
featureList, |
|||
loading: true, |
|||
}); |
|||
|
|||
|
|||
const [registerModal] = useModalInner(async (data) => { |
|||
state.loading = true; |
|||
tenantId = data.id; |
|||
const result = await getTenantFeatureListAsync(data.id); |
|||
state.featureList = result.groups as FeatureGroupDto[]; |
|||
if (state.featureList.length > 0) { |
|||
currentFeature = state.featureList[0] |
|||
} |
|||
state.loading = false; |
|||
}); |
|||
|
|||
|
|||
|
|||
const submit = async () => { |
|||
|
|||
if (currentFeature) { |
|||
let features = currentFeature.features?.map(e => { |
|||
let item = new UpdateFeatureDto(); |
|||
item.name = e.name; |
|||
item.value = e.value?.toString(); |
|||
return item; |
|||
}) |
|||
|
|||
try { |
|||
state.loading = true; |
|||
await updateTenantFeatureListAsync(tenantId, features) |
|||
message.success(t('common.operationSuccess')); |
|||
} catch (error) { |
|||
message.success(t('common.operationFail')); |
|||
}finally{ |
|||
state.loading = false; |
|||
} |
|||
|
|||
} |
|||
}; |
|||
const change = (key) => { |
|||
currentFeature = state.featureList.find(e => e.name == key); |
|||
}; |
|||
const cancel = () => { |
|||
}; |
|||
return { |
|||
t, |
|||
registerModal, |
|||
submit, |
|||
cancel, |
|||
...toRefs(state), |
|||
prefixCls: 'account-setting', |
|||
tabBarStyle: { |
|||
width: '220px', |
|||
}, |
|||
labelCol: { span: 4 }, |
|||
wrapperCol: { span: 14 }, |
|||
change |
|||
}; |
|||
}, |
|||
}); |
|||
</script> |
|||
<style lang="less"> |
|||
.account-setting { |
|||
margin: 12px; |
|||
background-color: @component-background; |
|||
|
|||
.base-title { |
|||
padding-left: 0; |
|||
} |
|||
|
|||
.ant-tabs-tab-active { |
|||
background-color: @item-active-bg; |
|||
} |
|||
} |
|||
</style> |
|||
File diff suppressed because it is too large
Loading…
Reference in new issue