Browse Source

feat: 调整模板项目

production 8.3.0.4
hanpaopao 2 years ago
parent
commit
f26547f9bc
  1. 17
      Readme.md
  2. 1991
      templates/abp-vnext-pro-nuget-all/aspnet-core/src/MyCompanyName.MyProjectName.EntityFrameworkCore/Migrations/20231220045138_Init.Designer.cs
  3. 1311
      templates/abp-vnext-pro-nuget-all/aspnet-core/src/MyCompanyName.MyProjectName.EntityFrameworkCore/Migrations/20231220045138_Init.cs
  4. 1988
      templates/abp-vnext-pro-nuget-all/aspnet-core/src/MyCompanyName.MyProjectName.EntityFrameworkCore/Migrations/MyProjectNameDbContextModelSnapshot.cs
  5. 4
      templates/abp-vnext-pro-nuget-all/vben28/.env
  6. 5
      templates/abp-vnext-pro-nuget-all/vben28/.env.development
  7. 6
      templates/abp-vnext-pro-nuget-all/vben28/.env.production
  8. 1
      templates/abp-vnext-pro-nuget-all/vben28/.eslintignore
  9. 6
      templates/abp-vnext-pro-nuget-all/vben28/Dockerfile
  10. 8
      templates/abp-vnext-pro-nuget-all/vben28/build/vite/plugin/imagemin.ts
  11. 4
      templates/abp-vnext-pro-nuget-all/vben28/build/vite/plugin/index.ts
  12. 6
      templates/abp-vnext-pro-nuget-all/vben28/build/vite/plugin/styleImport.ts
  13. 2
      templates/abp-vnext-pro-nuget-all/vben28/nswag/nswag.json
  14. 2
      templates/abp-vnext-pro-nuget-all/vben28/src/api/sys/user.ts
  15. 7
      templates/abp-vnext-pro-nuget-all/vben28/src/hooks/component/useFormItem.ts
  16. 90
      templates/abp-vnext-pro-nuget-all/vben28/src/hooks/web/useSignalR.ts
  17. 182
      templates/abp-vnext-pro-nuget-all/vben28/src/layouts/default/header/components/notify/NoticeList.vue
  18. 29
      templates/abp-vnext-pro-nuget-all/vben28/src/layouts/default/header/components/notify/data.ts
  19. 6
      templates/abp-vnext-pro-nuget-all/vben28/src/layouts/default/header/components/notify/index.vue
  20. 10
      templates/abp-vnext-pro-nuget-all/vben28/src/layouts/default/header/index.vue
  21. 1
      templates/abp-vnext-pro-nuget-all/vben28/src/locales/lang/en/common.ts
  22. 14
      templates/abp-vnext-pro-nuget-all/vben28/src/locales/lang/en/routes/admin.ts
  23. 1
      templates/abp-vnext-pro-nuget-all/vben28/src/locales/lang/en/routes/tenant.ts
  24. 1
      templates/abp-vnext-pro-nuget-all/vben28/src/locales/lang/zh-CN/common.ts
  25. 14
      templates/abp-vnext-pro-nuget-all/vben28/src/locales/lang/zh-CN/routes/admin.ts
  26. 1
      templates/abp-vnext-pro-nuget-all/vben28/src/locales/lang/zh-CN/routes/tenant.ts
  27. 6
      templates/abp-vnext-pro-nuget-all/vben28/src/main.ts
  28. 32
      templates/abp-vnext-pro-nuget-all/vben28/src/router/routes/modules/admin.ts
  29. 2058
      templates/abp-vnext-pro-nuget-all/vben28/src/services/ServiceProxies.ts
  30. 5
      templates/abp-vnext-pro-nuget-all/vben28/src/views/admin/dictionary/AbpDictionary.ts
  31. 367
      templates/abp-vnext-pro-nuget-all/vben28/src/views/admin/dictionary/AbpDictionary.vue
  32. 40
      templates/abp-vnext-pro-nuget-all/vben28/src/views/admin/files/File.ts
  33. 117
      templates/abp-vnext-pro-nuget-all/vben28/src/views/admin/files/File.vue
  34. 66
      templates/abp-vnext-pro-nuget-all/vben28/src/views/admin/files/UploadOss.ts
  35. 19
      templates/abp-vnext-pro-nuget-all/vben28/src/views/admin/manageFeatrue/index.ts
  36. 137
      templates/abp-vnext-pro-nuget-all/vben28/src/views/admin/manageFeatrue/index.vue
  37. 65
      templates/abp-vnext-pro-nuget-all/vben28/src/views/admin/notification/CreateNotification.vue
  38. 65
      templates/abp-vnext-pro-nuget-all/vben28/src/views/admin/notification/CreateSubscription.vue
  39. 396
      templates/abp-vnext-pro-nuget-all/vben28/src/views/admin/notification/Index.ts
  40. 107
      templates/abp-vnext-pro-nuget-all/vben28/src/views/admin/notification/Index.vue
  41. 76
      templates/abp-vnext-pro-nuget-all/vben28/src/views/admin/notification/Subscription.vue
  42. 18
      templates/abp-vnext-pro-nuget-all/vben28/src/views/admin/organizationUnits/OrganizationUnit.vue
  43. 201
      templates/abp-vnext-pro-nuget-all/vben28/src/views/admin/roles/PermissionAbpRole.vue
  44. 151
      templates/abp-vnext-pro-nuget-all/vben28/src/views/admin/settings/Setting.vue
  45. 216
      templates/abp-vnext-pro-nuget-all/vben28/src/views/admin/users/AbpUser.ts
  46. 224
      templates/abp-vnext-pro-nuget-all/vben28/src/views/admin/users/AbpUser.vue
  47. 162
      templates/abp-vnext-pro-nuget-all/vben28/src/views/admin/users/CreateAbpUser.vue
  48. 70
      templates/abp-vnext-pro-nuget-all/vben28/src/views/tenants/CreateConnectionString.vue
  49. 176
      templates/abp-vnext-pro-nuget-all/vben28/src/views/tenants/EditConnectionString.vue
  50. 137
      templates/abp-vnext-pro-nuget-all/vben28/src/views/tenants/ManageFeatrue.vue
  51. 96
      templates/abp-vnext-pro-nuget-all/vben28/src/views/tenants/Tenant.ts
  52. 38
      templates/abp-vnext-pro-nuget-all/vben28/src/views/tenants/Tenant.vue
  53. 8
      templates/abp-vnext-pro-nuget-all/vben28/tsconfig.json
  54. 5
      templates/abp-vnext-pro-nuget-all/vben28/vite.config.ts
  55. 11739
      templates/abp-vnext-pro-nuget-all/vben28/yarn.lock

17
Readme.md

@ -23,27 +23,26 @@
```bash
dotnet tool install Lion.AbpPro.Cli -g
```
### 三个项目模板
- 生成源码版本
- 更新Cli
```bash
lion.abp new -t pro -c 公司名称 -p 项目名称 -v 版本(默认LastRelease) -o 默认当前控制台执行目录
dotnet tool update Lion.AbpPro.Cli -g
```
- nuget包形式的网关基础版本
- abp自带的所有模块,pro的通知模块,数据字典模块 以及ocelot网关。
### 三个项目模板
- 源码版本
```bash
lion.abp new -t pro.all -c 公司名称 -p 项目名称 -v 版本(默认LastRelease) -o 默认当前控制台执行目录
lion.abp new -t pro -c 公司名称 -p 项目名称 -v 版本(默认LastRelease) -o 默认当前控制台执行目录
```
- nuget包形式的基础版本
- abp自带的所有模块,pro的通知模块,数据字典模块 无ocelot网关
- nuget版本
```bash
lion.abp new -t pro.simplify -c 公司名称 -p 项目名称 -v 版本(默认LastRelease) -o 默认当前控制台执行目录
lion.abp new -t pro.all -c 公司名称 -p 项目名称 -v 版本(默认LastRelease) -o 默认当前控制台执行目录
```
- 模块
```bash

1991
templates/abp-vnext-pro-nuget-all/aspnet-core/src/MyCompanyName.MyProjectName.EntityFrameworkCore/Migrations/20231220045138_Init.Designer.cs

File diff suppressed because it is too large

1311
templates/abp-vnext-pro-nuget-all/aspnet-core/src/MyCompanyName.MyProjectName.EntityFrameworkCore/Migrations/20231220045138_Init.cs

File diff suppressed because it is too large

1988
templates/abp-vnext-pro-nuget-all/aspnet-core/src/MyCompanyName.MyProjectName.EntityFrameworkCore/Migrations/MyProjectNameDbContextModelSnapshot.cs

File diff suppressed because it is too large

4
templates/abp-vnext-pro-nuget-all/vben28/.env

@ -2,7 +2,7 @@
VITE_PORT = 4200
# spa-title
VITE_GLOB_APP_TITLE = MyProjectName
VITE_GLOB_APP_TITLE = Abp Pro
# spa shortname
VITE_GLOB_APP_SHORT_NAME = MyProjectName
VITE_GLOB_APP_SHORT_NAME = vue_abp_pro

5
templates/abp-vnext-pro-nuget-all/vben28/.env.development

@ -22,7 +22,8 @@ VITE_GLOB_UPLOAD_URL=/upload
VITE_GLOB_API_URL_PREFIX=
# 接口地址
VITE_API_URL= http://localhost:44314/gateway
VITE_API_URL= http://localhost:44315/
# WEBSOCKE 地址
VITE_WEBSOCKE_URL= http://localhost:44314/ws
VITE_WEBSOCKE_URL= http://localhost:44315/signalr/notification

6
templates/abp-vnext-pro-nuget-all/vben28/.env.production

@ -34,8 +34,10 @@ VITE_USE_PWA = false
# Is it compatible with older browsers
VITE_LEGACY = false
# 接口地址
VITE_API_URL= http://localhost:8081/gateway
VITE_API_URL= http://43.139.143.143:8080
# WEBSOCKE 地址
VITE_WEBSOCKE_URL= http://localhost:8081/ws
VITE_WEBSOCKE_URL= http://43.139.143.143:8080/signalr/notification

1
templates/abp-vnext-pro-nuget-all/vben28/.eslintignore

@ -13,3 +13,4 @@ dist
.local
/bin
Dockerfile
/src/services/ServiceProxies.ts

6
templates/abp-vnext-pro-nuget-all/vben28/Dockerfile

@ -1,9 +1,11 @@
FROM node:16-alpine as build-stage
FROM node:18-alpine as build-stage
WORKDIR /app
COPY . ./
ENV NODE_OPTIONS=--max-old-space-size=16384
RUN npm install pnpm -g
# 切换淘宝镜像源
# RUN npm config set registry https://registry.npmmirror.com/
# RUN pnpm config set registry https://registry.npmmirror.com/
RUN pnpm i
RUN npm run build

8
templates/abp-vnext-pro-nuget-all/vben28/build/vite/plugin/imagemin.ts

@ -4,10 +4,10 @@
// export function configImageminPlugin() {
// const plugin = viteImagemin({
// gifsicle: {
// optimizationLevel: 7,
// interlaced: false,
// },
// // gifsicle: {
// // optimizationLevel: 7,
// // interlaced: false,
// // },
// optipng: {
// optimizationLevel: 7,
// },

4
templates/abp-vnext-pro-nuget-all/vben28/build/vite/plugin/index.ts

@ -5,7 +5,7 @@ import legacy from '@vitejs/plugin-legacy';
import purgeIcons from 'vite-plugin-purge-icons';
import windiCSS from 'vite-plugin-windicss';
import VitePluginCertificate from 'vite-plugin-mkcert';
import vueSetupExtend from 'vite-plugin-vue-setup-extend';
//import vueSetupExtend from 'vite-plugin-vue-setup-extend';
import { configHtmlPlugin } from './html';
import { configPwaConfig } from './pwa';
import { configMockPlugin } from './mock';
@ -31,7 +31,7 @@ export function createVitePlugins(viteEnv: ViteEnv, isBuild: boolean) {
// have to
vueJsx(),
// support name
vueSetupExtend(),
//vueSetupExtend(),
VitePluginCertificate({
source: 'coding',
}),

6
templates/abp-vnext-pro-nuget-all/vben28/build/vite/plugin/styleImport.ts

@ -5,9 +5,9 @@
import { createStyleImportPlugin } from 'vite-plugin-style-import';
export function configStyleImportPlugin(_isBuild: boolean) {
// if (!isBuild) {
// return [];
// }
if (!_isBuild) {
return [];
}
const styleImportPlugin = createStyleImportPlugin({
libs: [
{

2
templates/abp-vnext-pro-nuget-all/vben28/nswag/nswag.json

@ -3,7 +3,7 @@
"defaultVariables": null,
"documentGenerator": {
"fromDocument": {
"url": "http://localhost:44315/swagger/MyProjectName/swagger.json",
"url": "http://localhost:44315/swagger/AbpPro/swagger.json",
"output": null,
"newLineBehavior": "Auto"
}

2
templates/abp-vnext-pro-nuget-all/vben28/src/api/sys/user.ts

@ -58,7 +58,7 @@ export function login(input: LoginInput): Promise<LoginOutput> {
*/
export function getAbpApplicationConfiguration() {
const _abpApplicationConfigurationServiceProxy = new AbpApplicationConfigurationServiceProxy();
return _abpApplicationConfigurationServiceProxy.applicationConfiguration();
return _abpApplicationConfigurationServiceProxy.applicationConfiguration(false);
}

7
templates/abp-vnext-pro-nuget-all/vben28/src/hooks/component/useFormItem.ts

@ -50,9 +50,12 @@ export function useRuleFormItem<T extends Recordable>(
if (isEqual(value, defaultState.value)) return;
innerState.value = value as T[keyof T];
nextTick(() => {
// nextTick(() => {
// emit?.(changeEvent, value, ...(toRaw(unref(emitData)) || []));
// });
setTimeout(() => {
emit?.(changeEvent, value, ...(toRaw(unref(emitData)) || []));
});
}, 0);
},
});

90
templates/abp-vnext-pro-nuget-all/vben28/src/hooks/web/useSignalR.ts

@ -1,17 +1,16 @@
import * as signalR from '@microsoft/signalr';
import { useMessage } from '/@/hooks/web/useMessage';
import { useUserStoreWithOut } from '/@/store/modules/user';
let connection:signalR.HubConnection;
let connection: signalR.HubConnection;
export function useSignalR() {
/**
* 开始连接SignalR
*/
async function startConnect() {
try {
try {
connectionsignalR();
await connection.start();
} catch (err) {
} catch (err) {
console.log(err);
setTimeout(() => startConnect(), 5000);
}
@ -20,49 +19,45 @@ export function useSignalR() {
/**
* 关闭SignalR连接
*/
function closeConnect(): void {8
function closeConnect(): void {
8;
if (connection) {
connection.stop();
}
}
async function connectionsignalR(){
async function connectionsignalR() {
const userStore = useUserStoreWithOut();
const token = userStore.getToken;
const url = (import.meta.env.VITE_WEBSOCKE_URL as string) + '/signalr/notification';
connection = new signalR.HubConnectionBuilder()
.withUrl(url, {
accessTokenFactory: () => token,
skipNegotiation: true,
transport: signalR.HttpTransportType.WebSockets,
})
.withAutomaticReconnect({
nextRetryDelayInMilliseconds: retryContext => {
//重连规则:重连次数<300:间隔1s;重试次数<3000:间隔3s;重试次数>3000:间隔30s
let count = retryContext.previousRetryCount / 300;
if (count < 1)//重试次数<300,间隔1s
{
return 1000;
}
else if (count < 10) //重试次数>300:间隔5s
{
return 1000 * 5;
}
else //重试次数>3000:间隔30s
{
return 1000 * 30;
}
}
})
.configureLogging(signalR.LogLevel.Debug)
.build();
.withUrl(import.meta.env.VITE_WEBSOCKE_URL, {
accessTokenFactory: () => token,
skipNegotiation: true,
transport: signalR.HttpTransportType.WebSockets,
})
.withAutomaticReconnect({
nextRetryDelayInMilliseconds: (retryContext) => {
//重连规则:重连次数<300:间隔1s;重试次数<3000:间隔3s;重试次数>3000:间隔30s
const count = retryContext.previousRetryCount / 300;
if (count < 1) {
//重试次数<300,间隔1s
return 1000;
} else if (count < 10) {
//重试次数>300:间隔5s
return 1000 * 5;
} //重试次数>3000:间隔30s
else {
return 1000 * 30;
}
},
})
.configureLogging(signalR.LogLevel.Debug)
.build();
//接收普通文本消息
connection.on('ReceiveTextMessageAsync', ReceiveTextMessageHandlerAsync);
//接收广播消息
connection.on('ReceiveBroadCastMessageAsync', ReceiveBroadCastMessageHandlerAsync);
//接收普通文本消息
connection.on('ReceiveTextMessageAsync', ReceiveTextMessageHandlerAsync);
//接收广播消息
connection.on('ReceiveBroadCastMessageAsync', ReceiveBroadCastMessageHandlerAsync);
}
/**
@ -77,21 +72,16 @@ export function useSignalR() {
message: message.title,
description: message.content,
});
} else if (message.messageLevel == 20) {
} if (message.messageLevel == 20) {
notification.info({
message: message.title,
description: message.content,
});
} else if (message.messageLevel == 30) {
} if (message.messageLevel == 30) {
notification.error({
message: message.title,
description: message.content,
});
} else {
notification.info({
message: message.title,
description: message.content,
});
}
}
@ -100,28 +90,22 @@ export function useSignalR() {
* @param message 消息体
*/
function ReceiveBroadCastMessageHandlerAsync(message: any) {
const { notification } = useMessage();
if (message.messageLevel == 10) {
notification.warn({
message: message.title,
description: message.content,
});
} else if (message.messageLevel == 20) {
} if (message.messageLevel == 20) {
notification.info({
message: message.title,
description: message.content,
});
} else if (message.messageLevel == 30) {
} if (message.messageLevel == 30) {
notification.error({
message: message.title,
description: message.content,
});
} else {
notification.info({
message: message.title,
description: message.content,
});
}
}

182
templates/abp-vnext-pro-nuget-all/vben28/src/layouts/default/header/components/notify/NoticeList.vue

@ -5,33 +5,28 @@
<a-list-item-meta>
<template #title>
<div class="title">
<a-typography-paragraph
style="width: 100%; margin-bottom: 0 !important"
:ellipsis="titleRows > 0 ? { rows: titleRows, tooltip: item.title } : false"
:content="item.title"
/>
<div>
<a-typography-paragraph @click="handleTitleClick(item)" style="width: 100%; margin-bottom: 0 !important"
:ellipsis="titleRows > 0 ? { rows: titleRows, tooltip: item.title } : false" :content="item.title" />
<!-- <div>
<a-tag class="tag" :color="item.read ? 'green' : 'red'">
{{ item.read ? '已读' : '未读' }}
</a-tag>
<a-tag v-if="!item.read" class="tag" color="green" @click="onSetRead(item)">
{{ '标记为已读' }}
</a-tag>
</div>
</div> -->
</div>
</template>
<template #description>
<div>
<div class="description">
<a-typography-paragraph
style="width: 100%; margin-bottom: 0 !important"
:ellipsis="descRows > 0 ? { rows: descRows, tooltip: item.content } : false"
:content="item.content"
/>
<a-typography-paragraph style="width: 100%; margin-bottom: 0 !important"
:ellipsis="descRows > 0 ? { rows: descRows, tooltip: item.content } : false" :content="item.content"
@click="handleTitleClick(item)" />
</div>
<div class="datetime">
{{ formatToDateTime(item.creationTime) }}
{{ formatToDateTime(item.creationTime) }}
</div>
</div>
</template>
@ -41,95 +36,110 @@
</a-list>
</template>
<script lang="ts">
import { defineComponent, PropType } from 'vue';
import { setReadAsync } from './data';
import { useDesign } from '/@/hooks/web/useDesign';
import { List, Tag, Typography } from 'ant-design-vue';
import { PagingNotificationListOutput, SetReadInput } from '/@/services/ServiceProxies';
import { formatToDateTime } from '/@/utils/dateUtil';
export default defineComponent({
components: {
[List.name]: List,
[List.Item.name]: List.Item,
AListItemMeta: List.Item.Meta,
ATypographyParagraph: Typography.Paragraph,
[Tag.name]: Tag,
import { defineComponent, PropType } from 'vue';
import { setReadAsync } from './data';
import { useDesign } from '/@/hooks/web/useDesign';
import { List, Tag, Typography } from 'ant-design-vue';
import { PagingNotificationOutput, SetReadInput } from '/@/services/ServiceProxies';
import { formatToDateTime } from '/@/utils/dateUtil';
import { Modal } from 'ant-design-vue';
export default defineComponent({
components: {
[List.name]: List,
[List.Item.name]: List.Item,
AListItemMeta: List.Item.Meta,
ATypographyParagraph: Typography.Paragraph,
[Tag.name]: Tag,
},
props: {
list: {
type: Array as PropType<PagingNotificationOutput[]>,
default: () => [],
},
props: {
list: {
type: Array as PropType<PagingNotificationListOutput[]>,
default: () => [],
},
titleRows: {
type: Number,
default: 1,
},
descRows: {
type: Number,
default: 1,
},
titleRows: {
type: Number,
default: 1,
},
setup() {
const onSetRead = async (record: PagingNotificationListOutput) => {
let request = new SetReadInput();
request.id = record.id;
await setReadAsync(request);
record.read = true;
console.log(record);
};
const { prefixCls } = useDesign('header-notify-list');
return { prefixCls, onSetRead,formatToDateTime };
descRows: {
type: Number,
default: 1,
},
});
},
setup() {
const onSetRead = async (record: PagingNotificationOutput) => {
let request = new SetReadInput();
request.id = record.id;
await setReadAsync(request);
record.read = true;
};
const { prefixCls } = useDesign('header-notify-list');
async function readMessageAsync(item) {
let request = new SetReadInput();
request.id = item.id;
await setReadAsync(request);
}
async function handleTitleClick(item) {
console.log(item)
Modal.success({
okText: '朕已阅',
title: item.title,
content: item.content,
onOk: await readMessageAsync(item)
});
}
return { prefixCls, onSetRead, formatToDateTime, handleTitleClick };
},
});
</script>
<style lang="less" scoped>
@prefix-cls: ~'@{namespace}-header-notify-list';
@prefix-cls: ~'@{namespace}-header-notify-list';
.@{prefix-cls} {
&::-webkit-scrollbar {
display: none;
}
.@{prefix-cls} {
&::-webkit-scrollbar {
display: none;
}
::v-deep(.ant-pagination-disabled) {
display: inline-block !important;
}
::v-deep(.ant-pagination-disabled) {
display: inline-block !important;
}
&-item {
padding: 6px;
overflow: hidden;
cursor: pointer;
transition: all 0.3s;
&-item {
padding: 6px;
overflow: hidden;
cursor: pointer;
transition: all 0.3s;
.title {
margin-bottom: 8px;
.title {
margin-bottom: 8px;
font-weight: normal;
.extra {
float: right;
margin-top: -1.5px;
margin-right: 0;
font-weight: normal;
.extra {
float: right;
margin-top: -1.5px;
margin-right: 0;
.tag {
font-weight: normal;
.tag {
font-weight: normal;
}
}
.avatar {
margin-top: 4px;
}
}
.description {
font-size: 12px;
line-height: 18px;
}
.avatar {
margin-top: 4px;
}
.datetime {
margin-top: 4px;
font-size: 12px;
line-height: 18px;
}
.description {
font-size: 12px;
line-height: 18px;
}
.datetime {
margin-top: 4px;
font-size: 12px;
line-height: 18px;
}
}
}
}
</style>

29
templates/abp-vnext-pro-nuget-all/vben28/src/layouts/default/header/components/notify/data.ts

@ -1,9 +1,12 @@
import {
NotificationServiceProxy,
PagingNotificationListOutput,
PagingNotificationListInput,
PagingNotificationListOutputPagedResultDto,
PagingNotificationOutput,
PagingNotificationInput,
PagingNotificationSubscriptionInput,
PagingNotificationOutputPagedResultDto,
} from '/@/services/ServiceProxies';
import { useUserStoreWithOut } from '/@/store/modules/user';
const userStore = useUserStoreWithOut();
export interface ListItem {
id: string;
avatar: string;
@ -23,7 +26,7 @@ export interface ListItem {
export interface TabItem {
key: string;
name: string;
list?: PagingNotificationListOutput[];
list?: PagingNotificationOutput[];
unreadlist?: ListItem[];
}
@ -40,21 +43,27 @@ export const tabListData: TabItem[] = [
},
];
export async function getTextAsync(): Promise<PagingNotificationListOutputPagedResultDto> {
let request = new PagingNotificationListInput();
export async function getTextAsync(): Promise<PagingNotificationOutputPagedResultDto> {
let request = new PagingNotificationInput();
request.pageSize = 5;
request.pageIndex = 1;
request.receiverUserId = userStore.getUserInfo.userId as string;
request.messageType = 20;
const _notificationServiceProxy = new NotificationServiceProxy();
return await _notificationServiceProxy.common(request);
return await _notificationServiceProxy.notificationPage(request);
}
export async function getBroadCastAsync(): Promise<PagingNotificationListOutputPagedResultDto> {
let request = new PagingNotificationListInput();
export async function getBroadCastAsync(): Promise<PagingNotificationOutputPagedResultDto> {
let request = new PagingNotificationInput();
request.pageSize = 5;
request.pageIndex = 1;
request.messageType = 10;
const _notificationServiceProxy = new NotificationServiceProxy();
return await _notificationServiceProxy.broadCast(request);
return await _notificationServiceProxy.notificationPage(request);
}
export async function setReadAsync(request) {
const _notificationServiceProxy = new NotificationServiceProxy();
await _notificationServiceProxy.read(request);
}

6
templates/abp-vnext-pro-nuget-all/vben28/src/layouts/default/header/components/notify/index.vue

@ -25,7 +25,7 @@
import { defineComponent, computed } from 'vue';
import { Popover, Tabs, Badge } from 'ant-design-vue';
import { BellOutlined } from '@ant-design/icons-vue';
import { PagingNotificationListOutput } from '/@/services/ServiceProxies';
import { PagingNotificationOutput } from '/@/services/ServiceProxies';
import { tabListData } from './data';
import NoticeList from './NoticeList.vue';
import { useDesign } from '/@/hooks/web/useDesign';
@ -34,8 +34,8 @@
export default defineComponent({
components: { Popover, BellOutlined, Tabs, TabPane: Tabs.TabPane, Badge, NoticeList },
props: {
textMessage: Array as PropType<PagingNotificationListOutput[]>,
broadCastMessage: Array as PropType<PagingNotificationListOutput[]>,
textMessage: Array as PropType<PagingNotificationOutput[]>,
broadCastMessage: Array as PropType<PagingNotificationOutput[]>,
ff: string,
},
setup(props) {

10
templates/abp-vnext-pro-nuget-all/vben28/src/layouts/default/header/index.vue

@ -84,7 +84,7 @@
import { createAsyncComponent } from '/@/utils/factory/createAsyncComponent';
import { useLocale } from '/@/locales/useLocale';
import { useSignalR } from '/@/hooks/web/useSignalR';
import { PagingNotificationListOutput } from '/@/services/ServiceProxies';
import { PagingNotificationOutput } from '/@/services/ServiceProxies';
import {
getTextAsync,
getBroadCastAsync,
@ -181,8 +181,8 @@
onMounted(() => {
startConnect();
});
let textMessage: PagingNotificationListOutput[] = [];
let broadCastMessage: PagingNotificationListOutput[] = [];
let textMessage: PagingNotificationOutput[] = [];
let broadCastMessage: PagingNotificationOutput[] = [];
const notifiData = reactive({
textMessage,
broadCastMessage,
@ -190,10 +190,10 @@
const clickNotify = async () => {
notifiData.textMessage = (await (
await getTextAsync()
).items) as PagingNotificationListOutput[];
).items) as PagingNotificationOutput[];
notifiData.broadCastMessage = (await (
await getBroadCastAsync()
).items) as PagingNotificationListOutput[];
).items) as PagingNotificationOutput[];
console.log(notifiData);
};
return {

1
templates/abp-vnext-pro-nuget-all/vben28/src/locales/lang/en/common.ts

@ -20,6 +20,7 @@ export default {
locked: 'Locked',
unLocked: 'UnLocked',
createText: 'Create',
createOrUpdateText: 'Create Or Update',
tip: 'Tip',
askDelete: 'Are you sure you want to delete',
operationSuccess: 'Operation Success',

14
templates/abp-vnext-pro-nuget-all/vben28/src/locales/lang/en/routes/admin.ts

@ -65,6 +65,7 @@ export default {
logLevel: 'Level',
logContent: 'Content',
settingManagement: 'SettingManagement',
featureManagement: 'FeatureManagement',
dictionaryManagement: 'DataDictionary',
dictionaryTypeName: 'Type',
dictionaryCode: 'Code',
@ -96,4 +97,17 @@ export default {
identitySecurityLog_CorrelationId: 'CorrelationId',
identitySecurityLog_ClientIpAddress: 'ClientIpAddress',
identitySecurityLog_CreationTime: 'LoginTime',
notificationManagement: 'NotificationManagement',
notificationSubscriptionManagement: 'NotificationSubscriptionManagement',
notificationManagement_title : 'Title',
notificationManagement_content : 'Content',
notificationManagement_read : 'Read',
notificationManagement_readTime : 'ReadTime',
notificationManagement_messageType : 'Type',
notificationManagement_messageLevel : 'Level',
notificationManagement_senderUserName : 'SenderUserName ',
notificationManagement_receiveUserName : 'ReceiveUserName',
notificationManagement_setRead : 'SetRead',
notificationManagement_sendNotification : 'SendNotification',
notificationManagement_sendNotificationSubscription : 'SendNotificationSubscription',
};

1
templates/abp-vnext-pro-nuget-all/vben28/src/locales/lang/en/routes/tenant.ts

@ -1,6 +1,7 @@
export default {
name: 'Name',
connectionString: 'ConnectionString',
manageFeatures : 'Manage Features',
tenantManagement: 'TenantManagement',
tenantList: 'TenantList',
adminPassword: 'AdminPassword',

1
templates/abp-vnext-pro-nuget-all/vben28/src/locales/lang/zh-CN/common.ts

@ -27,6 +27,7 @@ export default {
locked: '已锁定',
unLocked: '未锁定',
createText: '新增',
createOrUpdateText: '新增或编辑',
tip: '提示',
askDelete: '确认删除吗',
disEnabledSelf: '不能禁用自己',

14
templates/abp-vnext-pro-nuget-all/vben28/src/locales/lang/zh-CN/routes/admin.ts

@ -64,6 +64,7 @@ export default {
logContent: '内容',
detail: '详情',
settingManagement: '设置管理',
featureManagement: '功能管理',
dictionaryManagement: '数据字典',
dictionaryTypeName: '字典类型',
dictionaryCode: '编码',
@ -96,4 +97,17 @@ export default {
identitySecurityLog_CorrelationId: 'CorrelationId',
identitySecurityLog_ClientIpAddress: '客户端IP',
identitySecurityLog_CreationTime: '登录时间',
notificationManagement: '消息管理',
notificationSubscriptionManagement: '通告管理',
notificationManagement_title : '标题',
notificationManagement_content : '内容',
notificationManagement_read : '已读',
notificationManagement_readTime : '已读时间',
notificationManagement_messageType : '类型',
notificationManagement_messageLevel : '级别',
notificationManagement_senderUserName : '发送人',
notificationManagement_receiveUserName : '接收人',
notificationManagement_setRead : '设置已读',
notificationManagement_sendNotification : '发送消息',
notificationManagement_sendNotificationSubscription : '发送公告',
};

1
templates/abp-vnext-pro-nuget-all/vben28/src/locales/lang/zh-CN/routes/tenant.ts

@ -1,6 +1,7 @@
export default {
name: '名称',
connectionString: '连接字符串',
manageFeatures : '功能管理',
tenantManagement: '租户管理',
tenantList: '租户列表',
adminPassword: '管理员密码',

6
templates/abp-vnext-pro-nuget-all/vben28/src/main.ts

@ -15,6 +15,12 @@ import { setupGlobDirectives } from '/@/directives';
import { setupI18n } from '/@/locales/setupI18n';
import { registerGlobComp } from '/@/components/registerGlobComp';
import Antd from 'ant-design-vue';
import { isDevMode } from './utils/env';
if (isDevMode()) {
import('ant-design-vue/es/style');
}
async function bootstrap() {
const app = createApp(App);
app.use(Antd);

32
templates/abp-vnext-pro-nuget-all/vben28/src/router/routes/modules/admin.ts

@ -21,7 +21,7 @@ const admin: AppRouteModule = {
meta: {
title: t('routes.admin.userManagement'),
policy: 'AbpIdentity.Users',
icon: 'ant-design:skin-outlined',
icon: 'ant-design:user-outlined',
},
},
{
@ -54,6 +54,16 @@ const admin: AppRouteModule = {
icon: 'ant-design:unordered-list-outlined',
},
},
{
path: 'manageFeatrue',
name: 'manageFeatrue',
component: () => import('/@/views/admin/manageFeatrue/index.vue'),
meta: {
title: t('routes.admin.featureManagement'),
policy: 'AbpIdentity.FeatureManagement',
icon: 'ant-design:tool-outlined',
},
},
{
path: 'abpAuditLogs',
name: 'AuditLogs',
@ -104,6 +114,26 @@ const admin: AppRouteModule = {
policy: 'AbpIdentity.LanguageTexts',
},
},
{
path: 'notification',
name: 'notification',
component: () => import('/@/views/admin/notification/Index.vue'),
meta: {
title: t('routes.admin.notificationManagement'),
icon: 'ant-design:comment-outlined',
policy: 'AbpIdentity.NotificationManagement',
},
},
{
path: 'subscription',
name: 'subscription',
component: () => import('/@/views/admin/notification/Subscription.vue'),
meta: {
title: t('routes.admin.notificationSubscriptionManagement'),
icon: 'ant-design:customer-service-twotone',
policy: 'AbpIdentity.NotificationSubscriptionManagement',
},
},
],
};

2058
templates/abp-vnext-pro-nuget-all/vben28/src/services/ServiceProxies.ts

File diff suppressed because it is too large

5
templates/abp-vnext-pro-nuget-all/vben28/src/views/admin/dictionary/AbpDictionary.ts

@ -42,11 +42,8 @@ export const tableColumns: BasicColumn[] = [
enableDictionaryAsync(request)
.then(() => {
record.isEnabled = checked;
message.success(t('common.operationSuccess'));
})
.catch(() => {
message.error(t('common.operationFail'));
});
.catch(() => {});
},
});
},

367
templates/abp-vnext-pro-nuget-all/vben28/src/views/admin/dictionary/AbpDictionary.vue

@ -8,13 +8,12 @@
@selection-change="onSelectChange"
:clickToRowSelect="false"
>
<template #bodyCell="{ column, record }">
<template v-if="column.key === 'text'">
{{ record.code }}|
{{ record.displayText }}
</template>
</template>
<template #bodyCell="{ column, record }">
<template v-if="column.key === 'text'">
{{ record.code }}|
{{ record.displayText }}
</template>
</template>
<template #toolbar>
<a-button
@ -23,21 +22,20 @@
preIcon="ant-design:plus-circle-outlined"
@click="handleCreateType"
>
{{ t("common.createText") }}
</a-button
>
{{ t('common.createText') }}
</a-button>
</template>
<template #action="{ record }">
<TableAction
:dropDownActions="[
{
label: t('common.editText'),
auth:'AbpIdentity.DataDictionaryManagement.Update',
auth: 'AbpIdentity.DataDictionaryManagement.Update',
onClick: handleEditType.bind(null, record),
},
{
label: t('common.delText'),
auth:'AbpIdentity.DataDictionaryManagement.Delete',
auth: 'AbpIdentity.DataDictionaryManagement.Delete',
onClick: handleDeleteDictionaryType.bind(null, record),
},
]"
@ -53,9 +51,8 @@
type="primary"
@click="handleCreate"
>
{{ t("common.createText") }}
</a-button
>
{{ t('common.createText') }}
</a-button>
</template>
<template #action="{ record }">
@ -86,187 +83,187 @@
</template>
<script lang="ts">
import { defineComponent, ref } from "vue";
import { BasicTable, useTable, TableAction } from "/@/components/Table";
import { PageWrapper } from '/@/components/Page';
import { useModal } from "/@/components/Modal";
import CreateAbpDictionary from "./CreateAbpDictionary.vue";
import EditAbpDictionary from "./EditAbpDictionary.vue";
import EditAbpDictionaryType from "./EditAbpDictionaryType.vue";
import CreateAbpDictionaryType from "./CreateAbpDictionaryType.vue";
import { defineComponent, ref } from 'vue';
import { BasicTable, useTable, TableAction } from '/@/components/Table';
import { PageWrapper } from '/@/components/Page';
import { useModal } from '/@/components/Modal';
import CreateAbpDictionary from './CreateAbpDictionary.vue';
import EditAbpDictionary from './EditAbpDictionary.vue';
import EditAbpDictionaryType from './EditAbpDictionaryType.vue';
import CreateAbpDictionaryType from './CreateAbpDictionaryType.vue';
import { useI18n } from "/@/hooks/web/useI18n";
import {
tableColumns,
searchFormSchema,
getDictionaryTypeAsync,
dictionaryTypeTableColumns,
searchDictionaryFormSchema,
getDictionaryDetailsAsync,
deleteDetailAsync,
deleteDictionaryTypeAsync
} from "/@/views/admin/dictionary/AbpDictionary";
import { useMessage } from "/@/hooks/web/useMessage";
import { Tag, message } from "ant-design-vue";
import { useI18n } from '/@/hooks/web/useI18n';
import {
tableColumns,
searchFormSchema,
getDictionaryTypeAsync,
dictionaryTypeTableColumns,
searchDictionaryFormSchema,
getDictionaryDetailsAsync,
deleteDetailAsync,
deleteDictionaryTypeAsync,
} from '/@/views/admin/dictionary/AbpDictionary';
import { useMessage } from '/@/hooks/web/useMessage';
import { Tag, message } from 'ant-design-vue';
export default defineComponent({
name: "AbpDictionary",
components: {
BasicTable,
PageWrapper,
TableAction,
Tag,
CreateAbpDictionaryType,
CreateAbpDictionary,
EditAbpDictionary,
EditAbpDictionaryType
},
setup() {
const { t } = useI18n();
export default defineComponent({
name: 'AbpDictionary',
components: {
BasicTable,
PageWrapper,
TableAction,
Tag,
CreateAbpDictionaryType,
CreateAbpDictionary,
EditAbpDictionary,
EditAbpDictionaryType,
},
setup() {
const { t } = useI18n();
const [registerCreateModal, { openModal: createModal }] = useModal();
const [registerEditModal, { openModal: editModal }] = useModal();
const [registerEditTypeModal, { openModal: editTypeModal }] = useModal();
const [registerCreateType, { openModal: createTypeModal }] = useModal();
const selectedDataDictionaryIdRef = ref("");
const selectedDataDictionaryDisplayTextRef = ref("");
const [registerCreateModal, { openModal: createModal }] = useModal();
const [registerEditModal, { openModal: editModal }] = useModal();
const [registerEditTypeModal, { openModal: editTypeModal }] = useModal();
const [registerCreateType, { openModal: createTypeModal }] = useModal();
const selectedDataDictionaryIdRef = ref('');
const selectedDataDictionaryDisplayTextRef = ref('');
//左边表格
const [registerTypeTable, { reload: reloadType, clearSelectedRowKeys }] = useTable({
columns: dictionaryTypeTableColumns,
formConfig: {
labelWidth: 0,
schemas: searchDictionaryFormSchema,
showResetButton: false
},
api: getDictionaryTypeAsync,
useSearchForm: true,
showTableSetting: false,
showIndexColumn: false,
bordered: true,
canResize: true,
rowSelection: { type: "radio" },
pagination: false,
actionColumn: {
width: 50,
title: t("common.action"),
dataIndex: "action",
slots: { customRender: "action" }
}
});
//左边表格
const [registerTypeTable, { reload: reloadType, clearSelectedRowKeys }] = useTable({
columns: dictionaryTypeTableColumns,
formConfig: {
labelWidth: 0,
schemas: searchDictionaryFormSchema,
showResetButton: false,
},
api: getDictionaryTypeAsync,
useSearchForm: true,
showTableSetting: false,
showIndexColumn: false,
bordered: true,
canResize: true,
rowSelection: { type: 'radio' },
maxHeight: 600,
actionColumn: {
width: 50,
title: t('common.action'),
dataIndex: 'action',
slots: { customRender: 'action' },
},
});
//勾选事件
const onSelectChange = ({ rows }) => {
selectedDataDictionaryIdRef.value = rows[0].id;
selectedDataDictionaryDisplayTextRef.value = rows[0].displayText;
reload();
};
//勾选事件
const onSelectChange = ({ rows }) => {
selectedDataDictionaryIdRef.value = rows[0].id;
selectedDataDictionaryDisplayTextRef.value = rows[0].displayText;
reload();
};
const handleCreate = () => {
if (selectedDataDictionaryIdRef.value == "") {
message.error(t("routes.admin.chooseDictionary"));
return;
} else {
let dictionaryCreate = {
id: selectedDataDictionaryIdRef.value,
displayText: selectedDataDictionaryDisplayTextRef.value
};
createModal(true, { dictionaryCreate: dictionaryCreate });
}
};
const handleEditType = (record: Recordable) => {
editTypeModal(true, {
record: record
});
};
const handleDeleteDictionaryType = async (record: Recordable) => {
let msg = t("common.askDelete");
createConfirm({
iconType: "warning",
title: t("common.tip"),
content: msg,
onOk: async () => {
await deleteDictionaryTypeAsync({
id: record.id,
reloadType
});
await reload();
const handleCreate = () => {
if (selectedDataDictionaryIdRef.value == '') {
message.error(t('routes.admin.chooseDictionary'));
return;
} else {
let dictionaryCreate = {
id: selectedDataDictionaryIdRef.value,
displayText: selectedDataDictionaryDisplayTextRef.value,
};
createModal(true, { dictionaryCreate: dictionaryCreate });
}
};
const handleEditType = (record: Recordable) => {
editTypeModal(true, {
record: record,
});
};
const handleDeleteDictionaryType = async (record: Recordable) => {
let msg = t('common.askDelete');
createConfirm({
iconType: 'warning',
title: t('common.tip'),
content: msg,
onOk: async () => {
await deleteDictionaryTypeAsync({
id: record.id,
reloadType,
});
await reload();
},
});
};
const [registerTable, { reload }] = useTable({
columns: tableColumns,
formConfig: {
labelWidth: 120,
schemas: searchFormSchema,
},
api: getDictionaryPageDetailsAsync,
useSearchForm: true,
showTableSetting: true,
showIndexColumn: true,
bordered: true,
canResize: true,
actionColumn: {
width: 150,
title: t('common.action'),
dataIndex: 'action',
slots: { customRender: 'action' },
},
});
};
const [registerTable, { reload }] = useTable({
columns: tableColumns,
formConfig: {
labelWidth: 120,
schemas: searchFormSchema
},
api: getDictionaryPageDetailsAsync,
useSearchForm: true,
showTableSetting: true,
showIndexColumn: true,
bordered: true,
canResize: true,
actionColumn: {
width: 150,
title: t("common.action"),
dataIndex: "action",
slots: { customRender: "action" }
}
});
async function getDictionaryPageDetailsAsync(params) {
if (selectedDataDictionaryIdRef.value == "") {
return [];
async function getDictionaryPageDetailsAsync(params) {
if (selectedDataDictionaryIdRef.value == '') {
return [];
}
params.dataDictionaryId = selectedDataDictionaryIdRef.value;
return await getDictionaryDetailsAsync({ params });
}
params.dataDictionaryId = selectedDataDictionaryIdRef.value;
return await getDictionaryDetailsAsync({ params });
}
const handleEdit = (record: Recordable) => {
editModal(true, {
record: record
});
};
const handleCreateType = () => {
createTypeModal(true);
};
const { createConfirm } = useMessage();
const handleDelete = async (record: Recordable) => {
let msg = t("common.askDelete");
createConfirm({
iconType: "warning",
title: t("common.tip"),
content: msg,
onOk: async () => {
await deleteDetailAsync({
dataDictionaryId: record.dataDictionaryId,
dataDictionaryDetailId: record.id,
reload
});
}
});
};
return {
registerTable,
registerCreateModal,
registerEditModal,
registerEditTypeModal,
handleCreate,
handleEdit,
handleEditType,
reload,
registerTypeTable,
registerCreateType,
handleCreateType,
reloadType,
onSelectChange,
clearSelectedRowKeys,
t,
handleDelete,
handleDeleteDictionaryType
};
}
});
const handleEdit = (record: Recordable) => {
editModal(true, {
record: record,
});
};
const handleCreateType = () => {
createTypeModal(true);
};
const { createConfirm } = useMessage();
const handleDelete = async (record: Recordable) => {
let msg = t('common.askDelete');
createConfirm({
iconType: 'warning',
title: t('common.tip'),
content: msg,
onOk: async () => {
await deleteDetailAsync({
dataDictionaryId: record.dataDictionaryId,
dataDictionaryDetailId: record.id,
reload,
});
},
});
};
return {
registerTable,
registerCreateModal,
registerEditModal,
registerEditTypeModal,
handleCreate,
handleEdit,
handleEditType,
reload,
registerTypeTable,
registerCreateType,
handleCreateType,
reloadType,
onSelectChange,
clearSelectedRowKeys,
t,
handleDelete,
handleDeleteDictionaryType,
};
},
});
</script>
<style lang="less" scoped></style>

40
templates/abp-vnext-pro-nuget-all/vben28/src/views/admin/files/File.ts

@ -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);
// }

117
templates/abp-vnext-pro-nuget-all/vben28/src/views/admin/files/File.vue

@ -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> -->

66
templates/abp-vnext-pro-nuget-all/vben28/src/views/admin/files/UploadOss.ts

@ -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;
// }

19
templates/abp-vnext-pro-nuget-all/vben28/src/views/admin/manageFeatrue/index.ts

@ -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);
}

137
templates/abp-vnext-pro-nuget-all/vben28/src/views/admin/manageFeatrue/index.vue

@ -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>

65
templates/abp-vnext-pro-nuget-all/vben28/src/views/admin/notification/CreateNotification.vue

@ -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>

65
templates/abp-vnext-pro-nuget-all/vben28/src/views/admin/notification/CreateSubscription.vue

@ -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>

396
templates/abp-vnext-pro-nuget-all/vben28/src/views/admin/notification/Index.ts

@ -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);
}

107
templates/abp-vnext-pro-nuget-all/vben28/src/views/admin/notification/Index.vue

@ -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>

76
templates/abp-vnext-pro-nuget-all/vben28/src/views/admin/notification/Subscription.vue

@ -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>

18
templates/abp-vnext-pro-nuget-all/vben28/src/views/admin/organizationUnits/OrganizationUnit.vue

@ -124,6 +124,8 @@ import { usePermission } from '/@/hooks/web/usePermission';
import { useModal } from "/@/components/Modal";
import { useMessage } from "/@/hooks/web/useMessage";
import { useI18n } from "/@/hooks/web/useI18n";
export default defineComponent({
name: "OrganizationUnit",
components: {
@ -167,6 +169,7 @@ export default defineComponent({
onMounted(async () => {
await initOrganizationUnit();
});
// 新增根节点
function createRootOrganizationUnit() {
let record = {
@ -175,6 +178,7 @@ export default defineComponent({
};
CreateOrganizationUnitModal(true, { record });
}
function getRightMenuList(node: any): ContextMenuItem[] {
let create = hasPermission('AbpIdentity.OrganizationUnitManagement.Create');
let update = hasPermission('AbpIdentity.OrganizationUnitManagement.Update');
@ -223,6 +227,7 @@ export default defineComponent({
}
];
}
async function handleSelect(keys) {
if (keys.length > 0) {
organizationUnitId = keys[0];
@ -234,7 +239,9 @@ export default defineComponent({
} else {
organizationUnitId = "";
}
}
const getUserAsync = async () => {
if (organizationUnitId) {
let request = new GetOrganizationUnitUserInput();
@ -242,13 +249,16 @@ export default defineComponent({
request.organizationUnitId = organizationUnitId;
return await getUserTableListAsync(request);
}
};
const getRoleAsync = async () => {
if (organizationUnitId) {
let request = new GetOrganizationUnitRoleInput();
request.organizationUnitId = organizationUnitId;
return await getRoleTableListAsync(request);
}
};
const [registerUserTable, { reload: reloadUser, getForm: getUserForm }] = useTable({
columns: userTableColumns,
@ -272,6 +282,7 @@ export default defineComponent({
fixed: "right"
}
});
const [registerRoleTable, { reload: reloadRole }] = useTable({
columns: roleTableColumns,
api: getRoleAsync,
@ -291,6 +302,7 @@ export default defineComponent({
}
});
const activeKeyChange = async (activeKey) => {
if (organizationUnitId) {
if (activeKey == 1) {
await reloadUser();
@ -298,7 +310,10 @@ export default defineComponent({
await reloadRole();
}
}
};
const handleUserDelete = async (record: Recordable) => {
let msg = t("common.askDelete");
createConfirm({
@ -314,6 +329,7 @@ export default defineComponent({
}
});
};
const handleRoleDelete = async (record: Recordable) => {
let msg = t("common.askDelete");
createConfirm({
@ -360,4 +376,4 @@ export default defineComponent({
/*.ant-tabs-tabpane {*/
/* background: #F0F2F5;*/
/*}*/
</style>
</style>

201
templates/abp-vnext-pro-nuget-all/vben28/src/views/admin/roles/PermissionAbpRole.vue

@ -1,18 +1,6 @@
<template>
<BasicDrawer
@register="registerDrawer"
:maskClosable="false"
:title="t('routes.admin.roleManagement_permission')"
width="20%"
>
<BasicTree
:treeData="allPermissionsRef"
@check="handleCheck"
:checkStrictly="'false'"
checkable
ref="treeRef"
style="margin-bottom: 50px"
/>
<BasicDrawer @register="registerDrawer" :maskClosable="false" :title="t('routes.admin.roleManagement_permission')" width="20%">
<BasicTree :treeData="allPermissionsRef" @check="handleCheck" :checkStrictly="'false'" checkable ref="treeRef" style="margin-bottom: 50px" />
<div
:style="{
position: 'absolute',
@ -26,9 +14,7 @@
zIndex: 1,
}"
>
<a-button :style="{ marginRight: '8px' }" @click="closeDrawer"
>{{ t('common.cancelText') }}
</a-button>
<a-button :style="{ marginRight: '8px' }" @click="closeDrawer">{{ t('common.cancelText') }} </a-button>
<a-button type="primary" @click="submitRolePermisstionAsync">
{{ t('common.saveText') }}
</a-button>
@ -37,108 +23,103 @@
</template>
<script lang="ts">
import { defineComponent, reactive, ref, unref } from 'vue';
import { BasicDrawer, useDrawerInner } from '/@/components/Drawer';
import { getRolePermissionAsync, updateRolePermissionAsync } from './AbpRole';
import { useI18n } from '/@/hooks/web/useI18n';
import { BasicTree, TreeActionType } from '/@/components/Tree/index';
import { useUserStoreWithOut } from '/@/store/modules/user';
import {
UpdateRolePermissionsInput,
UpdatePermissionDto,
UpdatePermissionsDto,
} from '/@/services/ServiceProxies';
import { message } from 'ant-design-vue';
export default defineComponent({
name: 'PermissionAbpRole',
components: { BasicDrawer, BasicTree },
setup() {
let roleName: string = '';
const { t } = useI18n();
const [registerDrawer, { closeDrawer, setDrawerProps }] = useDrawerInner(async (data) => {
roleName = data.record.name;
await getRolePermissions(data.record.name);
//loading.value = false;
});
const treeRef = ref<Nullable<TreeActionType>>(null);
import { defineComponent, reactive, ref, unref } from 'vue';
import { BasicDrawer, useDrawerInner } from '/@/components/Drawer';
import { getRolePermissionAsync, updateRolePermissionAsync } from './AbpRole';
import { useI18n } from '/@/hooks/web/useI18n';
import { BasicTree, TreeActionType } from '/@/components/Tree/index';
import { useUserStoreWithOut } from '/@/store/modules/user';
import { UpdateRolePermissionsInput, UpdatePermissionDto, UpdatePermissionsDto } from '/@/services/ServiceProxies';
import { message } from 'ant-design-vue';
export default defineComponent({
name: 'PermissionAbpRole',
components: { BasicDrawer, BasicTree },
setup() {
let roleName: string = '';
const { t } = useI18n();
const [registerDrawer, { closeDrawer, setDrawerProps }] = useDrawerInner(async (data) => {
roleName = data.record.name;
await getRolePermissions(data.record.name);
//loading.value = false;
});
const treeRef = ref<Nullable<TreeActionType>>(null);
const totalRolePermissionsRef = reactive([]);
let allPermissionsRef = reactive([]);
const getTree = () => {
const tree = unref(treeRef);
if (!tree) {
throw new Error('tree is null!');
}
return tree;
};
/**
* 获取权限信息并且构造权限树
*/
const getRolePermissions = async (roleName: string) => {
setDrawerProps({ loading: true });
totalRolePermissionsRef.splice(0, totalRolePermissionsRef.length);
allPermissionsRef.splice(0, allPermissionsRef.length);
const permissions = await getRolePermissionAsync(roleName);
totalRolePermissionsRef.push(...(permissions.allGrants as []));
allPermissionsRef.push(...(permissions.permissions as []));
const totalRolePermissionsRef = reactive([]);
let allPermissionsRef = reactive([]);
const getTree = () => {
const tree = unref(treeRef);
if (!tree) {
throw new Error('tree is null!');
}
return tree;
};
/**
* 获取权限信息并且构造权限树
*/
const getRolePermissions = async (roleName: string) => {
setDrawerProps({ loading: true });
totalRolePermissionsRef.splice(0, totalRolePermissionsRef.length);
allPermissionsRef.splice(0, allPermissionsRef.length);
const permissions = await getRolePermissionAsync(roleName);
totalRolePermissionsRef.push(...(permissions.allGrants as []));
allPermissionsRef.push(...(permissions.permissions as []));
getTree().setCheckedKeys(permissions.grants as []);
setDrawerProps({ loading: false });
};
getTree().setCheckedKeys(permissions.grants as []);
setDrawerProps({ loading: false });
};
const submitRolePermisstionAsync = async () => {
let request: UpdateRolePermissionsInput = new UpdateRolePermissionsInput();
request.updatePermissionsDto = new UpdatePermissionsDto();
const keys = getTree().getCheckedKeys();
let permisstions: UpdatePermissionDto[] = [];
request.providerName = 'R';
request.providerKey = roleName;
totalRolePermissionsRef.forEach((item: string) => {
let permisstion = new UpdatePermissionDto();
permisstion.name = item;
if ((keys.checked as []).some((e) => e == item)) {
const submitRolePermisstionAsync = async () => {
let request: UpdateRolePermissionsInput = new UpdateRolePermissionsInput();
request.updatePermissionsDto = new UpdatePermissionsDto();
const keys = getTree().getCheckedKeys();
let permisstions: UpdatePermissionDto[] = [];
request.providerName = 'R';
request.providerKey = roleName;
totalRolePermissionsRef.forEach((item:string)=>{
let permisstion = new UpdatePermissionDto();
permisstion.name = item;
if (((keys.checked ? keys.checked : keys) as []).some((e) => e == item)) {
permisstion.isGranted = true;
permisstions.push(permisstion);
} else {
}else{
permisstion.isGranted = false;
permisstions.push(permisstion);
}
});
request.updatePermissionsDto.permissions = permisstions;
await updateRolePermissionAsync({ request, closeDrawer, setDrawerProps });
const userStore = useUserStoreWithOut();
if (userStore.getUserInfo.roles.some((e) => e == roleName)) {
message.success(t('routes.admin.grantedMessage'));
await userStore.logout(true);
} else {
message.success(t('common.operationSuccess'));
}
};
})
request.updatePermissionsDto.permissions = permisstions;
await updateRolePermissionAsync({ request, closeDrawer, setDrawerProps });
const userStore = useUserStoreWithOut();
if (userStore.getUserInfo.roles.some(e=>e==roleName)) {
message.success(t('routes.admin.grantedMessage'));
await userStore.logout(true);
} else {
message.success(t('common.operationSuccess'));
}
};
// 自定义级联选中
const handleCheck = (checkedKeys, e) => {
if (e.checked === true) {
// 新增权限时,向下级联选中
var filteredKeys = totalRolePermissionsRef.filter((key) => key.startsWith(e.node.key));
checkedKeys.checked = checkedKeys.checked.concat(
filteredKeys.filter((key) => checkedKeys.checked.indexOf(key) === -1),
);
} else {
// 取消权限时,向下级联反选
checkedKeys.checked = checkedKeys.checked.filter((key) => !key.startsWith(e.node.key));
}
};
// 自定义级联选中
const handleCheck = (checkedKeys, e) => {
if (e.checked === true) {
// 新增权限时,向下级联选中
var filteredKeys = totalRolePermissionsRef.filter(key => key.startsWith(e.node.key));
checkedKeys.checked = checkedKeys.checked.concat(filteredKeys.filter(key => checkedKeys.checked.indexOf(key) === -1));
} else {
// 取消权限时,向下级联反选
checkedKeys.checked = checkedKeys.checked.filter(key => !key.startsWith(e.node.key));
}
}
return {
t,
registerDrawer,
allPermissionsRef,
submitRolePermisstionAsync,
closeDrawer,
treeRef,
handleCheck,
};
},
});
return {
t,
registerDrawer,
allPermissionsRef,
submitRolePermisstionAsync,
closeDrawer,
treeRef,
handleCheck,
};
},
});
</script>
<style lang="less" scoped></style>

151
templates/abp-vnext-pro-nuget-all/vben28/src/views/admin/settings/Setting.vue

@ -14,21 +14,15 @@
<a-input-number v-model:value="setting.value" :min="1" :max="99999" />
</div>
<div v-if="setting.type === 'CheckBox'">
<a-checkbox
:checked="!(setting.value == 'false' || setting.value == false)"
@update:checked="(val) => (setting.value = val)"
>
{{ setting.description }}
<a-checkbox :checked="!(setting.value == 'false' || setting.value == false)"
@update:checked="(val) => (setting.value = val)">
</a-checkbox>
{{ setting.description }}
</div>
</a-form-item>
<a-button
style="margin-left: 65%"
type="primary"
@click="updateSettingValues(item.settingItemOutput)"
>{{ t('common.saveText') }}</a-button
>
<a-button style="margin-left: 65%" type="primary" :loading="loading"
@click="updateSettingValues(item.settingItemOutput)">{{ t('common.saveText') }}</a-button>
</a-form>
</CollapseContainer>
</TabPane>
@ -39,78 +33,79 @@
</template>
<script lang="ts">
import { defineComponent, reactive, toRefs, onMounted } from 'vue';
import { Tabs } from 'ant-design-vue';
import { CollapseContainer,ScrollContainer } from '/@/components/Container/index';
import { SettingOutput, UpdateSettingInput } from '/@/services/ServiceProxies';
import { getAllSettingsAsync, updateSettingsAsync } from "/@/views/admin/settings/Setting";
import { useI18n } from '/@/hooks/web/useI18n';
import { PageWrapper } from '/@/components/Page';
import { message } from 'ant-design-vue';
export default defineComponent({
components: {
ScrollContainer,
CollapseContainer,
Tabs,
TabPane: Tabs.TabPane,
PageWrapper,
},
setup() {
let settingList: SettingOutput[] = [];
const { t } = useI18n();
const state = reactive({
settingList,
loading: true,
});
onMounted(async () => {
import { defineComponent, reactive, toRefs, onMounted } from 'vue';
import { Tabs } from 'ant-design-vue';
import { CollapseContainer, ScrollContainer } from '/@/components/Container/index';
import { SettingOutput, UpdateSettingInput } from '/@/services/ServiceProxies';
import { getAllSettingsAsync, updateSettingsAsync } from '/@/views/admin/settings/Setting';
import { useI18n } from '/@/hooks/web/useI18n';
import { PageWrapper } from '/@/components/Page';
import { message } from 'ant-design-vue';
export default defineComponent({
components: {
ScrollContainer,
CollapseContainer,
Tabs,
TabPane: Tabs.TabPane,
PageWrapper,
},
setup() {
let settingList: SettingOutput[] = [];
const { t } = useI18n();
const state = reactive({
settingList,
loading: true,
});
onMounted(async () => {
state.loading = true;
const result = await getAllSettingsAsync();
state.settingList = result;
state.loading = false;
});
const updateSettingValues = async (item: any) => {
try {
const prefix = 'setting_';
const request = new UpdateSettingInput();
request.values as {};
let items: { [key: string]: string } = {};
item.forEach((e) => {
items[prefix + e.name] = String(e.value);
});
request.values = items;
state.loading = true;
const result = await getAllSettingsAsync();
state.settingList = result;
await updateSettingsAsync({ request });
state.loading = false;
});
const updateSettingValues = async (item: any) => {
try {
const prefix = 'setting_';
const request = new UpdateSettingInput();
request.values as {};
let items: { [key: string]: string } = {};
item.forEach((e) => {
items[prefix + e.name] = String(e.value);
});
request.values = items;
await updateSettingsAsync({ request });
message.success(t('common.operationSuccess'));
} catch (error) {
message.success(t('common.operationFail'));
}
};
return {
prefixCls: 'account-setting',
tabBarStyle: {
width: '220px',
},
labelCol: { span: 4 },
wrapperCol: { span: 14 },
...toRefs(state),
t,
updateSettingValues,
};
},
});
message.success(t('common.operationSuccess'));
} catch (error) {
message.success(t('common.operationFail'));
}
};
return {
prefixCls: 'account-setting',
tabBarStyle: {
width: '220px',
},
labelCol: { span: 4 },
wrapperCol: { span: 14 },
...toRefs(state),
t,
updateSettingValues,
};
},
});
</script>
<style lang="less">
.account-setting {
margin: 12px;
background-color: @component-background;
.account-setting {
margin: 12px;
background-color: @component-background;
.base-title {
padding-left: 0;
}
.base-title {
padding-left: 0;
}
.ant-tabs-tab-active {
background-color: @item-active-bg;
}
.ant-tabs-tab-active {
background-color: @item-active-bg;
}
}
</style>

216
templates/abp-vnext-pro-nuget-all/vben28/src/views/admin/users/AbpUser.ts

@ -1,5 +1,5 @@
import { FormSchema } from "/@/components/Table";
import { BasicColumn } from "/@/components/Table";
import { FormSchema } from '/@/components/Table';
import { BasicColumn } from '/@/components/Table';
import { dateUtil } from '/@/utils/dateUtil';
import {
PagingUserListInput,
@ -8,198 +8,198 @@ import {
IdentityRoleDtoListResultDto,
RolesServiceProxy,
LockUserInput,
IdInput
} from "/@/services/ServiceProxies";
import { message } from "ant-design-vue";
import { useLoading } from "/@/components/Loading";
IdInput,
} from '/@/services/ServiceProxies';
import { message } from 'ant-design-vue';
import { useLoading } from '/@/components/Loading';
import { useI18n } from "/@/hooks/web/useI18n";
import { useI18n } from '/@/hooks/web/useI18n';
const { t } = useI18n();
const [openFullLoading, closeFullLoading] = useLoading({
tip: "Loading..."
tip: 'Loading...',
});
export const tableColumns: BasicColumn[] = [
{
title: t("routes.admin.userManagement_userName"),
dataIndex: "userName"
title: t('routes.admin.userManagement_userName'),
dataIndex: 'userName',
},
{
title: t("routes.admin.userManagement_name"),
dataIndex: "name"
title: t('routes.admin.userManagement_name'),
dataIndex: 'name',
},
{
title: t("routes.admin.userManagement_email"),
dataIndex: "email"
title: t('routes.admin.userManagement_email'),
dataIndex: 'email',
},
{
title: t("routes.admin.userManagement_phone"),
dataIndex: "phoneNumber"
title: t('routes.admin.userManagement_phone'),
dataIndex: 'phoneNumber',
},
{
title: t("common.status"),
dataIndex: "isActive"
title: t('common.status'),
dataIndex: 'isActive',
},
{
title: t("routes.admin.userManagement_createTime"),
dataIndex: "creationTime",
title: t('routes.admin.userManagement_createTime'),
dataIndex: 'creationTime',
customRender: ({ text }) => {
return dateUtil(text).format("YYYY-MM-DD HH:mm:ss");
}
}
return dateUtil(text).format('YYYY-MM-DD HH:mm:ss');
},
},
];
export const searchFormSchema: FormSchema[] = [
{
field: "filter",
label: t("routes.admin.userManagement_userName"),
component: "Input",
colProps: { span: 8 }
}
field: 'filter',
label: t('routes.admin.userManagement_userName'),
component: 'Input',
colProps: { span: 8 },
},
];
export const createFormSchema: FormSchema[] = [
{
field: "userName",
component: "Input",
label: t("routes.admin.userManagement_userName"),
field: 'userName',
component: 'Input',
label: t('routes.admin.userManagement_userName'),
labelWidth: 85,
required: true,
colProps: {
span: 12
span: 12,
},
componentProps: {
autocomplete: "off"
}
autocomplete: 'off',
},
},
{
field: "name",
component: "Input",
label: t("routes.admin.roleManagement_name"),
field: 'name',
component: 'Input',
label: t('routes.admin.roleManagement_name'),
labelWidth: 130,
required: true,
colProps: {
span: 12
span: 12,
},
componentProps: {
autocomplete: "off"
}
autocomplete: 'off',
},
},
{
field: "email",
component: "Input",
label: t("routes.admin.userManagement_email"),
field: 'email',
component: 'Input',
label: t('routes.admin.userManagement_email'),
required: true,
labelWidth: 85,
colProps: {
span: 12
}
span: 12,
},
},
{
field: "phoneNumber",
component: "Input",
label: t("routes.admin.userManagement_phone"),
field: 'phoneNumber',
component: 'Input',
label: t('routes.admin.userManagement_phone'),
required: false,
labelWidth: 130,
colProps: {
span: 12
}
span: 12,
},
},
{
field: "password",
component: "InputPassword",
label: t("routes.admin.userManagement_password"),
field: 'password',
component: 'InputPassword',
label: t('routes.admin.userManagement_password'),
required: true,
labelWidth: 85,
colProps: {
span: 12
span: 12,
},
componentProps: {
autocomplete: "off"
}
autocomplete: 'off',
},
},
{
field: "confirmPassword",
component: "InputPassword",
field: 'confirmPassword',
component: 'InputPassword',
componentProps: {
autocomplete: "off"
autocomplete: 'off',
},
label: t("routes.admin.userManagement_confirm_password"),
label: t('routes.admin.userManagement_confirm_password'),
required: true,
labelWidth: 130,
colProps: {
span: 12
}
}
span: 12,
},
},
];
export const editFormSchema: FormSchema[] = [
{
field: "userName",
component: "Input",
label: t("routes.admin.userManagement_userName"),
field: 'userName',
component: 'Input',
label: t('routes.admin.userManagement_userName'),
labelWidth: 85,
required: true,
colProps: {
span: 12
span: 12,
},
componentProps: {
autocomplete: "off",
disabled: true
}
autocomplete: 'off',
disabled: true,
},
},
{
field: "name",
component: "Input",
label: t("routes.admin.userManagement_name"),
field: 'name',
component: 'Input',
label: t('routes.admin.userManagement_name'),
labelWidth: 130,
required: true,
colProps: {
span: 12
}
span: 12,
},
},
{
field: "email",
component: "Input",
label: t("routes.admin.userManagement_email"),
field: 'email',
component: 'Input',
label: t('routes.admin.userManagement_email'),
required: true,
labelWidth: 85,
colProps: {
span: 12
}
span: 12,
},
},
{
field: "phoneNumber",
component: "Input",
label: t("routes.admin.userManagement_phone"),
field: 'phoneNumber',
component: 'Input',
label: t('routes.admin.userManagement_phone'),
required: false,
labelWidth: 130,
colProps: {
span: 12
}
span: 12,
},
},
{
field: "password",
component: "InputPassword",
label: t("routes.admin.userManagement_password"),
field: 'password',
component: 'InputPassword',
label: t('routes.admin.userManagement_password'),
required: false,
labelWidth: 85,
colProps: {
span: 12
}
span: 12,
},
},
{
field: "confirmPassword",
component: "InputPassword",
label: t("routes.admin.userManagement_confirm_password"),
field: 'confirmPassword',
component: 'InputPassword',
label: t('routes.admin.userManagement_confirm_password'),
required: false,
labelWidth: 130,
colProps: {
span: 12
}
}
span: 12,
},
},
];
/**
@ -208,7 +208,7 @@ export const editFormSchema: FormSchema[] = [
* @returns
*/
export async function getTableListAsync(
params: PagingUserListInput
params: PagingUserListInput,
): Promise<IdentityUserDtoPagedResultDto> {
const _userServiceProxy = new UsersServiceProxy();
return _userServiceProxy.page(params);
@ -222,10 +222,10 @@ export async function getTableListAsync(
export function exportAsync({ request }) {
openFullLoading();
const _userServiceProxy = new UsersServiceProxy();
_userServiceProxy.export(request).then(res => {
const a = document.createElement("a");
_userServiceProxy.export(request).then((res) => {
const a = document.createElement('a');
a.href = URL.createObjectURL(res.data);
a.download = "用户列表导出.xlsx";
a.download = '用户列表导出.xlsx';
a.click();
closeFullLoading();
});
@ -261,18 +261,18 @@ export async function createUserAsync({
changeOkLoading,
validate,
closeModal,
resetFields
resetFields,
}) {
changeOkLoading(true);
await validate();
if (request.password != request.confirmPassword) {
message.error("两次密码输入不一致");
throw new Error("两次密码输入不一致");
message.error('两次密码输入不一致');
throw new Error('两次密码输入不一致');
}
const _userServiceProxy = new UsersServiceProxy();
await _userServiceProxy.create(request);
changeOkLoading(false);
message.success(t("common.operationSuccess"));
message.success(t('common.operationSuccess'));
resetFields();
closeModal();
}
@ -289,7 +289,7 @@ export async function deleteUserAsync({ userId, reload }) {
request.id = userId;
await _userServiceProxy.delete(request);
closeFullLoading();
message.success(t("common.operationSuccess"));
message.success(t('common.operationSuccess'));
reload();
} catch (error) {
closeFullLoading();
@ -305,7 +305,7 @@ export async function updateUserAsync({
changeOkLoading,
validate,
closeModal,
resetFields
resetFields,
}) {
changeOkLoading(true);
await validate();
@ -314,7 +314,7 @@ export async function updateUserAsync({
await _userServiceProxy.update(request);
changeOkLoading(false);
resetFields();
message.success(t("common.operationSuccess"));
message.success(t('common.operationSuccess'));
closeModal();
}
@ -327,5 +327,3 @@ export async function lockUserAsync(request: LockUserInput): Promise<void> {
const _userServiceProxy = new UsersServiceProxy();
return _userServiceProxy.lock(request);
}

224
templates/abp-vnext-pro-nuget-all/vben28/src/views/admin/users/AbpUser.vue

@ -8,7 +8,7 @@
@click="openCreateAbpUserModal"
v-auth="'AbpIdentity.Users.Create'"
>
{{ t("common.createText") }}
{{ t('common.createText') }}
</a-button>
<a-button
preIcon="ant-design:cloud-download-outlined"
@ -16,16 +16,16 @@
@click="handleExport"
v-auth="'AbpIdentity.Users.Export'"
>
{{ t("common.export") }}
{{ t('common.export') }}
</a-button>
</template>
<template #bodyCell="{ column, record }">
<template v-if="column.key === 'isActive'">
<Tag :color="record.isActive ? 'green' : 'red'">
{{ record.isActive ? t("common.enabled") : t("common.disEnabled") }}
</Tag>
<template #bodyCell="{ column, record }">
<template v-if="column.key === 'isActive'">
<Tag :color="record.isActive ? 'green' : 'red'">
{{ record.isActive ? t('common.enabled') : t('common.disEnabled') }}
</Tag>
</template>
</template>
</template>
<template #action="{ record }">
<TableAction
@ -66,116 +66,116 @@
</template>
<script lang="ts">
import { defineComponent } from "vue";
import { useMessage } from "/@/hooks/web/useMessage";
import { BasicTable, useTable, TableAction } from "/@/components/Table";
import {
tableColumns,
searchFormSchema,
getTableListAsync,
deleteUserAsync,
lockUserAsync,
exportAsync
} from "/@/views/admin/users/AbpUser";
import { useModal } from "/@/components/Modal";
import CreateAbpUser from "./CreateAbpUser.vue";
import EditAbpUser from "./EditAbpUser.vue";
import { message } from "ant-design-vue";
import { useI18n } from "/@/hooks/web/useI18n";
import { LockUserInput } from "/@/services/ServiceProxies";
import { Tag } from "ant-design-vue";
import { defineComponent } from 'vue';
import { useMessage } from '/@/hooks/web/useMessage';
import { BasicTable, useTable, TableAction } from '/@/components/Table';
import {
tableColumns,
searchFormSchema,
getTableListAsync,
deleteUserAsync,
lockUserAsync,
exportAsync,
} from '/@/views/admin/users/AbpUser';
import { useModal } from '/@/components/Modal';
import CreateAbpUser from './CreateAbpUser.vue';
import EditAbpUser from './EditAbpUser.vue';
import { message } from 'ant-design-vue';
import { useI18n } from '/@/hooks/web/useI18n';
import { LockUserInput } from '/@/services/ServiceProxies';
import { Tag } from 'ant-design-vue';
export default defineComponent({
name: "AbpUser",
components: {
BasicTable,
TableAction,
CreateAbpUser,
EditAbpUser,
Tag
},
setup() {
const { createConfirm } = useMessage();
const { t } = useI18n();
const [registerCreateAbpUserModal, { openModal: openCreateAbpUserModal }] = useModal();
export default defineComponent({
name: 'AbpUser',
components: {
BasicTable,
TableAction,
CreateAbpUser,
EditAbpUser,
Tag,
},
setup() {
const { createConfirm } = useMessage();
const { t } = useI18n();
const [registerCreateAbpUserModal, { openModal: openCreateAbpUserModal }] = useModal();
const [registerEditAbpUserModal, { openModal: openEditAbpUserModal }] = useModal();
const [registerEditAbpUserModal, { openModal: openEditAbpUserModal }] = useModal();
// table配置
const [registerTable, { reload, getForm }] = useTable({
columns: tableColumns,
formConfig: {
labelWidth: 70,
schemas: searchFormSchema
},
api: getTableListAsync,
showTableSetting: true,
useSearchForm: true,
bordered: true,
canResize: true,
showIndexColumn: true,
actionColumn: {
width: 120,
title: t("common.action"),
dataIndex: "action",
slots: {
customRender: "action"
// table配置
const [registerTable, { reload, getForm }] = useTable({
columns: tableColumns,
formConfig: {
labelWidth: 70,
schemas: searchFormSchema,
},
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',
},
fixed: "right"
}
});
// 编辑用户
const handleEdit = (record: Recordable) => {
openEditAbpUserModal(true, {
record: record
});
};
// 删除用户
const handleDelete = async (record: Recordable) => {
if (record.name == "admin") {
message.error("admin not delete");
return;
} else {
let msg = t("common.askDelete");
createConfirm({
iconType: "warning",
title: t("common.tip"),
content: msg,
onOk: async () => {
await deleteUserAsync({ userId: record.id, reload });
}
// 编辑用户
const handleEdit = (record: Recordable) => {
openEditAbpUserModal(true, {
record: record,
});
}
};
};
// 删除用户
const handleDelete = async (record: Recordable) => {
if (record.name == 'admin') {
message.error('admin not delete');
return;
} else {
let msg = t('common.askDelete');
createConfirm({
iconType: 'warning',
title: t('common.tip'),
content: msg,
onOk: async () => {
await deleteUserAsync({ userId: record.id, reload });
},
});
}
};
const handleLock = async (record: Recordable) => {
let request = new LockUserInput();
request.userId = record.id;
request.locked = !record.isActive;
await lockUserAsync(request);
message.success(t("common.operationSuccess"));
await reload();
};
const handleExport = () => {
const { getFieldsValue } = getForm();
let request = getFieldsValue();
exportAsync({ request });
};
return {
registerTable,
handleEdit,
handleDelete,
getTableListAsync,
registerCreateAbpUserModal,
openCreateAbpUserModal,
registerEditAbpUserModal,
t,
reload,
handleLock,
handleExport
};
}
});
const handleLock = async (record: Recordable) => {
let request = new LockUserInput();
request.userId = record.id;
request.locked = !record.isActive;
await lockUserAsync(request);
message.success(t('common.operationSuccess'));
await reload();
};
const handleExport = () => {
const { getFieldsValue } = getForm();
let request = getFieldsValue();
exportAsync({ request });
};
return {
registerTable,
handleEdit,
handleDelete,
getTableListAsync,
registerCreateAbpUserModal,
openCreateAbpUserModal,
registerEditAbpUserModal,
t,
reload,
handleLock,
handleExport,
};
},
});
</script>

162
templates/abp-vnext-pro-nuget-all/vben28/src/views/admin/users/CreateAbpUser.vue

@ -25,7 +25,7 @@
v-for="(item, index) in itemRolesRef"
:key="index"
:value="item.name"
>{{ item.name }}
>{{ item.name }}
</a-checkbox>
</a-col>
</a-row>
@ -37,88 +37,88 @@
</template>
<script lang="ts">
import { defineComponent, ref } from "vue";
import { BasicModal, useModalInner } from "/@/components/Modal";
import { Tabs } from "ant-design-vue";
import { BasicForm, useForm } from "/@/components/Form/index";
import { createFormSchema, getAllRoleAsync, createUserAsync } from "/@/views/admin/users/AbpUser";
import { IdentityRoleDto, IdentityUserCreateDto } from "/@/services/ServiceProxies";
import { useI18n } from "/@/hooks/web/useI18n";
import { defineComponent, ref } from 'vue';
import { BasicModal, useModalInner } from '/@/components/Modal';
import { Tabs } from 'ant-design-vue';
import { BasicForm, useForm } from '/@/components/Form/index';
import { createFormSchema, getAllRoleAsync, createUserAsync } from '/@/views/admin/users/AbpUser';
import { IdentityRoleDto, IdentityUserCreateDto } from '/@/services/ServiceProxies';
import { useI18n } from '/@/hooks/web/useI18n';
export default defineComponent({
name: "CreateAbpUser",
components: {
BasicModal,
Tabs,
TabPane: Tabs.TabPane,
BasicForm
},
emits: ["reload", "register"],
setup(_, { emit }) {
const { t } = useI18n();
const [registerModal, { changeOkLoading, closeModal }] = useModalInner();
const [registerUserForm, { getFieldsValue, validate, resetFields }] = useForm({
labelWidth: 120,
schemas: createFormSchema,
showActionButtonGroup: false
});
export default defineComponent({
name: 'CreateAbpUser',
components: {
BasicModal,
Tabs,
TabPane: Tabs.TabPane,
BasicForm,
},
emits: ['reload', 'register'],
setup(_, { emit }) {
const { t } = useI18n();
const [registerModal, { changeOkLoading, closeModal }] = useModalInner();
const [registerUserForm, { getFieldsValue, validate, resetFields }] = useForm({
labelWidth: 120,
schemas: createFormSchema,
showActionButtonGroup: false,
});
let itemRoles: IdentityRoleDto[] = [];
let defaultRoles: string[] = [];
//选中数组
let defaultRolesRef = ref(defaultRoles);
let itemRolesRef = ref(itemRoles);
const visibleChange = async (visible: boolean) => {
if (visible) {
itemRolesRef.value.length = 0;
defaultRolesRef.value.splice(0, defaultRolesRef.value.length);
let roles = await getAllRoleAsync();
roles.items?.forEach((e) => {
itemRolesRef.value.push(e);
});
} else {
await resetFields();
itemRolesRef.value.length = 0;
defaultRolesRef.value.length = 0;
}
};
// 保存用户
const submit = async () => {
try {
let request = getFieldsValue() as IdentityUserCreateDto;
request.roleNames = defaultRolesRef.value;
await createUserAsync({
request,
changeOkLoading,
validate,
closeModal,
resetFields
});
defaultRolesRef.value.length = 0;
emit("reload");
} catch (error) {
changeOkLoading(false);
}
};
const cancel = () => {
resetFields();
closeModal();
};
return {
t,
cancel,
registerModal,
registerUserForm,
submit,
visibleChange,
defaultRolesRef,
itemRolesRef
};
}
});
let itemRoles: IdentityRoleDto[] = [];
let defaultRoles: string[] = [];
//选中数组
let defaultRolesRef = ref(defaultRoles);
let itemRolesRef = ref(itemRoles);
const visibleChange = async (visible: boolean) => {
if (visible) {
itemRolesRef.value.length = 0;
defaultRolesRef.value.splice(0, defaultRolesRef.value.length);
let roles = await getAllRoleAsync();
roles.items?.forEach((e) => {
itemRolesRef.value.push(e);
});
} else {
await resetFields();
itemRolesRef.value.length = 0;
defaultRolesRef.value.length = 0;
}
};
// 保存用户
const submit = async () => {
try {
let request = getFieldsValue() as IdentityUserCreateDto;
request.roleNames = defaultRolesRef.value;
await createUserAsync({
request,
changeOkLoading,
validate,
closeModal,
resetFields,
});
defaultRolesRef.value.length = 0;
emit('reload');
} catch (error) {
changeOkLoading(false);
}
};
const cancel = () => {
resetFields();
closeModal();
};
return {
t,
cancel,
registerModal,
registerUserForm,
submit,
visibleChange,
defaultRolesRef,
itemRolesRef,
};
},
});
</script>
<style lang="less" scoped>
.ant-checkbox-wrapper + .ant-checkbox-wrapper {
margin-left: 0;
}
.ant-checkbox-wrapper + .ant-checkbox-wrapper {
margin-left: 0;
}
</style>

70
templates/abp-vnext-pro-nuget-all/vben28/src/views/tenants/CreateConnectionString.vue

@ -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>

176
templates/abp-vnext-pro-nuget-all/vben28/src/views/tenants/EditConnectionString.vue

@ -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>

137
templates/abp-vnext-pro-nuget-all/vben28/src/views/tenants/ManageFeatrue.vue

@ -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>

96
templates/abp-vnext-pro-nuget-all/vben28/src/views/tenants/Tenant.ts

@ -2,7 +2,7 @@ import { FormSchema } from '/@/components/Table';
import { BasicColumn } from '/@/components/Table';
import { useI18n } from '/@/hooks/web/useI18n';
const { t } = useI18n();
import { TenantsServiceProxy, PagingTenantInput, IdInput } from '/@/services/ServiceProxies';
import { TenantsServiceProxy, PagingTenantInput, IdInput, PageTenantConnectionStringInput, FeaturesServiceProxy, GetFeatureListResultInput,UpdateFeatureInput,UpdateFeaturesDto, DeleteConnectionStringInput} from '/@/services/ServiceProxies';
export const searchFormSchema: FormSchema[] = [
{
field: 'filter',
@ -21,6 +21,8 @@ export const tableColumns: BasicColumn[] = [
},
];
export const createFormSchema: FormSchema[] = [
{
field: 'name',
@ -66,7 +68,8 @@ export const editFormSchema: FormSchema[] = [
colProps: { span: 20 },
},
];
export const updateConnectionStringFormSchema: FormSchema[] = [
export const createConnectionStringFormSchema: FormSchema[] = [
{
field: 'id',
label: 'Id',
@ -77,13 +80,62 @@ export const updateConnectionStringFormSchema: FormSchema[] = [
colProps: { span: 20 },
},
{
field: 'connectionString',
field: 'name',
label: t('routes.tenant.name'),
helpMessage: ['请谨慎修改', '请谨慎修改', '请谨慎修改'],
component: 'Input',
labelWidth: 150,
colProps: { span: 20 },
},
{
field: 'value',
label: t('routes.tenant.connectionString'),
helpMessage: ['请检查连接字符串正确性', '请检查连接字符串正确性', '请检查连接字符串正确性'],
component: 'Input',
labelWidth: 150,
colProps: { span: 20 },
},
];
export const updateConnectionStringFormSchema: FormSchema[] = [
{
field: 'id',
label: 'Id',
component: 'Input',
required: true,
labelWidth: 150,
show: false,
colProps: { span: 20 },
},
{
field: 'name',
label: t('routes.tenant.name'),
component: 'Input',
labelWidth: 150,
colProps: { span: 6 },
},
{
field: 'value',
label: t('routes.tenant.connectionString'),
component: 'Input',
labelWidth: 150,
colProps: { span: 12 },
},
];
export const editConnectionStringtableColumns: BasicColumn[] = [
{
title: t('routes.tenant.name'),
dataIndex: 'name',
width: 240,
},
{
title: t('routes.tenant.connectionString'),
dataIndex: 'value',
},
];
export async function getTenantListAsync(request: PagingTenantInput) {
const _tenantsServiceProxy = new TenantsServiceProxy();
return await _tenantsServiceProxy.page(request);
@ -112,13 +164,39 @@ export async function deleteTenantAsync({ id }) {
request.id = id;
await _tenantsServiceProxy.delete(request);
}
export async function getConnectionStringAsync({ id }) {
export async function pageConnectionStringAsync( request :PageTenantConnectionStringInput) {
const _tenantsServiceProxy = new TenantsServiceProxy();
let request = new IdInput();
request.id = id;
return await _tenantsServiceProxy.getConnectionString(request);
return await _tenantsServiceProxy.pageConnectionString(request);
}
export async function updateConnectionStringAsync({ request }) {
export async function addOrUpdateConnectionString({ request }) {
const _tenantsServiceProxy = new TenantsServiceProxy();
return await _tenantsServiceProxy.updateConnectionString(request);
return await _tenantsServiceProxy.addOrUpdateConnectionString(request);
}
export async function getTenantFeatureListAsync(tenantId) {
const _featuresServiceProxy = new FeaturesServiceProxy();
const request = new GetFeatureListResultInput();
request.providerKey = tenantId;
request.providerName = 'T';
return await _featuresServiceProxy.list(request);
}
export async function updateTenantFeatureListAsync(tenantId, params) {
const _featuresServiceProxy = new FeaturesServiceProxy();
const request = new UpdateFeatureInput();
request.providerKey = tenantId;
request.providerName = 'T';
request.updateFeaturesDto= new UpdateFeaturesDto();
request.updateFeaturesDto.features=params;
return await _featuresServiceProxy.update(request);
}
export async function deleteConnectionString(id, name) {
const _tenantsServiceProxy = new TenantsServiceProxy();
const request = new DeleteConnectionStringInput();
request.name=name;
request.tenantId=id;
return await _tenantsServiceProxy.deleteConnectionString(request);
}

38
templates/abp-vnext-pro-nuget-all/vben28/src/views/tenants/Tenant.vue

@ -21,14 +21,20 @@
label: t('common.editText'),
onClick: handleEdit.bind(null, record),
},
]"
:dropDownActions="[
// {
// auth: 'AbpTenantManagement.Tenants.ManageConnectionStrings',
// label: t('routes.tenant.connectionString'),
// onClick: handleConnectionString.bind(null, record),
// },
{
icon: 'ant-design:edit-outlined',
auth: 'AbpTenantManagement.Tenants.ManageConnectionStrings',
label: t('routes.tenant.connectionString'),
onClick: handleConnectionString.bind(null, record),
},
{
icon: 'ant-design:edit-outlined',
auth: 'AbpTenantManagement.Tenants.ManageFeatures',
label: t('routes.tenant.manageFeatures'),
onClick: handleManageFeatures.bind(null, record),
},
{
icon: 'ant-design:minus-outlined',
auth: 'AbpTenantManagement.Tenants.Delete',
label: t('common.delText'),
onClick: handleDelete.bind(null, record),
@ -52,6 +58,11 @@
@reload="reload"
:bodyStyle="{ 'padding-top': '0' }"
/>
<ManageFeatrue
@register="registerTenantFeatureModal"
@reload="reload"
:bodyStyle="{ 'padding-top': '0' }"
/>
</div>
</template>
@ -68,7 +79,7 @@
deleteTenantAsync,
} from '/@/views/tenants/Tenant';
import CreateTenant from './CreateTenant.vue';
import ManageFeatrue from './ManageFeatrue.vue';
import EditConnectionString from './EditConnectionString.vue';
import EditTenant from './EditTenant.vue';
import { useMessage } from '/@/hooks/web/useMessage';
@ -80,11 +91,13 @@
CreateTenant,
EditTenant,
EditConnectionString,
ManageFeatrue
},
setup() {
const { t } = useI18n();
const [registerCreateTenantModal, { openModal: openCreateTenantModal }] = useModal();
const [registerTenantFeatureModal, { openModal: openFeatureTenantModal }] = useModal();
const [registerEditTenantModal, { openModal: openEditTenantModal }] = useModal();
const [registerEditConnectionStringModal, { openModal: openEditConnectionStringModal }] =
useModal();
@ -106,7 +119,7 @@
slots: {
customRender: 'action',
},
width: 120,
width: 350,
fixed: 'right',
},
});
@ -115,7 +128,7 @@
const handleEdit = (record: Recordable) => {
openEditTenantModal(true, { record: record });
};
// 删除
const handleDelete = async (record: Recordable) => {
let msg = t('common.askDelete');
@ -133,6 +146,9 @@
const handleConnectionString = async (record: Recordable) => {
openEditConnectionStringModal(true, { record: record });
};
const handleManageFeatures = async (record: Recordable) => {
openFeatureTenantModal(true, { id: record.id });
};
return {
t,
registerTable,
@ -145,6 +161,8 @@
handleEdit,
registerEditTenantModal,
registerEditConnectionStringModal,
handleManageFeatures,
registerTenantFeatureModal
};
},
});

8
templates/abp-vnext-pro-nuget-all/vben28/tsconfig.json

@ -40,5 +40,11 @@
"mock/**/*.ts",
"vite.config.ts"
],
"exclude": ["node_modules", "tests/server/**/*.ts", "dist", "**/*.js"]
"exclude": [
"node_modules",
"tests/server/**/*.ts",
"dist",
"**/*.js",
"src/services/ServiceProxies.ts"
]
}

5
templates/abp-vnext-pro-nuget-all/vben28/vite.config.ts

@ -109,6 +109,11 @@ export default ({ command, mode }: ConfigEnv): UserConfig => {
'@iconify/iconify',
'ant-design-vue/es/locale/zh_CN',
'ant-design-vue/es/locale/en_US',
'ant-design-vue/es/style',
'echarts/core',
'echarts/charts',
'echarts/components',
'echarts/renderers',
],
},
};

11739
templates/abp-vnext-pro-nuget-all/vben28/yarn.lock

File diff suppressed because it is too large
Loading…
Cancel
Save