Compare commits
41 Commits
dev-freesq
...
master
Author | SHA1 | Date |
---|---|---|
p53209761 | 351a86ba4b | |
p53209761 | 81b7a18773 | |
Argo-Lenovo | 760c83457a | |
Argo-Lenovo | c4eeda3ae8 | |
Argo-Lenovo | 544441a5fc | |
Argo-Lenovo | 4686a75744 | |
Argo-Lenovo | 9be53cf009 | |
Argo-Lenovo | 312f771313 | |
Argo-Lenovo | 234063b3bd | |
Argo-Lenovo | 43cb329757 | |
Argo-Lenovo | c0d21fcbb6 | |
Argo-Lenovo | 994f439d40 | |
Argo-Lenovo | 8bf3f20fa5 | |
Argo-Lenovo | c8329d5b84 | |
Argo-Lenovo | ea461e433e | |
Argo-Lenovo | 213e9155a5 | |
Argo-Lenovo | e3b67c9427 | |
Argo-Lenovo | 35cc0f5174 | |
OneNewPerson | 9343a9522e | |
Argo-Lenovo | 026b1bb990 | |
Argo-Lenovo | f030cb4be9 | |
zhangpeihang | 3f6834de5f | |
Argo-Lenovo | 08df8d8da0 | |
zhangpeihang | e9c5bd2c08 | |
Argo-Lenovo | 2ef69da9e1 | |
Argo-Lenovo | ed5790ff72 | |
Argo-Lenovo | 5d4de2c766 | |
zhangpeihang | 9a02d45e27 | |
zhangpeihang | ab6e260b6b | |
Argo-Lenovo | 0e58b81d19 | |
Argo-Lenovo | 34e376d712 | |
Argo-Lenovo | b96aab631f | |
Argo-Lenovo | 09bf567698 | |
Argo-Lenovo | 2481a4a577 | |
Argo-Lenovo | f7b2c059ef | |
Argo-Lenovo | 7a95ddc039 | |
Argo-Lenovo | 9dfd95ce41 | |
Argo-Lenovo | 371d188d76 | |
Argo-Lenovo | 134d0ee8a8 | |
Argo-Lenovo | 4995899c4c | |
Argo-Lenovo | 6ccbadd1ea |
|
@ -11,10 +11,7 @@
|
|||
"src\\blazor\\client\\BootstrapClient.Shared\\BootstrapClient.Web.Shared.csproj",
|
||||
"src\\blazor\\client\\BootstrapClient.Web.Core\\BootstrapClient.Web.Core.csproj",
|
||||
"src\\blazor\\client\\BootstrapClient.Web.Models\\BootstrapClient.DataAccess.Models.csproj",
|
||||
"src\\blazor\\client\\BootstrapClient.Web\\BootstrapClient.Web.csproj",
|
||||
"src\\mvc\\admin\\Bootstrap.Admin\\Bootstrap.Admin.csproj",
|
||||
"src\\mvc\\admin\\Bootstrap.DataAccess\\Bootstrap.DataAccess.csproj",
|
||||
"test\\UnitTest\\UnitTest.csproj"
|
||||
"src\\blazor\\client\\BootstrapClient.Web\\BootstrapClient.Web.csproj"
|
||||
]
|
||||
}
|
||||
}
|
|
@ -157,7 +157,7 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "BootstrapClient.Web", "src\
|
|||
EndProject
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "BootStarpAdmin.DataAccess.FreeSql", "src\blazor\admin\BootStarpAdmin.DataAccess.FreeSql\BootStarpAdmin.DataAccess.FreeSql.csproj", "{11122D97-B349-4A3E-B7DD-73B8B363C47C}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "BootStarpAdmin.DataAccess.SqlSugar", "src\blazor\admin\BootStarpAdmin.DataAccess.SqlSugar\BootStarpAdmin.DataAccess.SqlSugar.csproj", "{1D20E6CF-9825-4CDE-B732-AE586BD1AABA}"
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "BootStarpAdmin.DataAccess.SqlSugar", "src\blazor\admin\BootStarpAdmin.DataAccess.SqlSugar\BootStarpAdmin.DataAccess.SqlSugar.csproj", "{1D20E6CF-9825-4CDE-B732-AE586BD1AABA}"
|
||||
EndProject
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "BootstrapClient.Web.Core", "src\blazor\client\BootstrapClient.Web.Core\BootstrapClient.Web.Core.csproj", "{FFDF9FF9-0B29-47D3-AD42-53A476B570EC}"
|
||||
EndProject
|
||||
|
|
184
README.md
184
README.md
|
@ -1,178 +1,8 @@
|
|||
# BootstrapAdmin
|
||||
# 第一点
|
||||
## 部署手册
|
||||
|
||||
<span>English</span> | <a href="README.zh-CN.md">中文</a>
|
||||
|
||||
---
|
||||
|
||||
##### Version & Coverage
|
||||
[![Release](https://img.shields.io/endpoint.svg?logo=Groupon&logoColor=red&color=green&label=release&url=https://admin.blazor.zone/api/Gitee/Releases?userName=LongbowEnterprise)](https://gitee.com/LongbowEnterprise/BootstrapAdmin/releases)
|
||||
[![Coveralls](https://img.shields.io/coveralls/github/ArgoZhang/BootstrapAdmin/master.svg?logo=ReverbNation&logoColor=green&label=coveralls)](https://coveralls.io/github/ArgoZhang/BootstrapAdmin)
|
||||
[![Codecov](https://img.shields.io/codecov/c/gh/argozhang/bootstrapadmin/master.svg?logo=codecov&label=codecov)](https://codecov.io/gh/argozhang/bootstrapadmin/branch/master)
|
||||
|
||||
##### Gitee
|
||||
[![Appveyor build](https://img.shields.io/endpoint.svg?logo=appveyor&label=build&color=blueviolet&url=https://admin.blazor.zone/api/Gitee/Builds?projName=bootstrapadmin-9m1jm)](https://ci.appveyor.com/project/ArgoZhang/bootstrapadmin-9m1jm)
|
||||
[![Build Status](https://img.shields.io/appveyor/ci/ArgoZhang/bootstrapadmin-9m1jm/master.svg?logo=appveyor&label=master)](https://ci.appveyor.com/project/ArgoZhang/bootstrapadmin-9m1jm/branch/master)
|
||||
[![Test](https://img.shields.io/appveyor/tests/ArgoZhang/bootstrapadmin-9m1jm/master.svg?logo=appveyor&)](https://ci.appveyor.com/project/ArgoZhang/bootstrapadmin-9m1jm/branch/master/tests)
|
||||
[![Issue Status](https://img.shields.io/endpoint.svg?logo=Groupon&logoColor=critical&label=issues&url=https://admin.blazor.zone/api/Gitee/Issues?userName=LongbowEnterprise)](https://gitee.com/LongbowEnterprise/BootstrapAdmin/issues)
|
||||
[![Pull Status](https://img.shields.io/endpoint.svg?logo=Groupon&logoColor=green&color=success&label=pulls&url=https://admin.blazor.zone/api/Gitee/Pulls?userName=LongbowEnterprise)](https://gitee.com/LongbowEnterprise/BootstrapAdmin/pulls)
|
||||
|
||||
##### GitHub
|
||||
[![Appveyor build](https://img.shields.io/endpoint.svg?logo=appveyor&label=build&color=blueviolet&url=https://admin.blazor.zone/api/Gitee/Builds?projName=bootstrapadmin)](https://ci.appveyor.com/project/ArgoZhang/bootstrapadmin)
|
||||
[![master status](https://img.shields.io/appveyor/ci/ArgoZhang/bootstrapadmin/master.svg?logo=appveyor&label=master)](https://ci.appveyor.com/project/ArgoZhang/bootstrapadmin/branch/master)
|
||||
[![Test](https://img.shields.io/appveyor/tests/argozhang/bootstrapadmin/master.svg?logo=appveyor&)](https://ci.appveyor.com/project/ArgoZhang/bootstrapadmin/branch/master/tests)
|
||||
[![Github build](https://img.shields.io/github/workflow/status/ArgoZhang/BootstrapAdmin/Auto%20Build%20CI/master?label=master&logoColor=green&logo=github)](https://github.com/ArgoZhang/BootstrapAdmin/actions?query=workflow%3A%22Auto+Build+CI%22+branch%3Amaster)
|
||||
[![Repo Size](https://img.shields.io/github/repo-size/ArgoZhang/BootstrapAdmin.svg?logo=github&logoColor=green&label=repo)](https://github.com/ArgoZhang/BootstrapAdmin)
|
||||
[![Commit Date](https://img.shields.io/github/last-commit/ArgoZhang/BootstrapAdmin/master.svg?logo=github&logoColor=green&label=commit)](https://github.com/ArgoZhang/BootstrapAdmin)
|
||||
|
||||
## Introduce
|
||||
Because the dependent on Bootstrap v4, so it is called **Bootstrap Admin**. This system can be integrated with asp.net and asp.net core applications. The database supports multiple databases at the same time. The detailed list is shown in the following **database** detailed list. Switching the data source only needs to change the configuration file without restarting the application. The configuration is simple and flexible. The UI front-end uses the popular Bootstrap framework layout, which is very compatible with mobile devices and adapts to almost all terminal devices in the current market. The system also has the feature of single background supporting multi-front desk, and provides the ability of **single sign-on (SSO)**.
|
||||
|
||||
### Notes
|
||||
Bootstrap Admin does not require secondary development, but only integration with the front-end system. The front-end system model project is **Bootstrap. Client**
|
||||
The original starting point of the project is to separate the privilege system from the business system. The project development focuses on functions. For detailed configuration instructions, please click on [View Documents](https://gitee.com/LongbowEnterprise/BootstrapAdmin/wikis/%E7%B3%BB%E7%BB%9F%E9%89B%86%E6%88%90).
|
||||
|
||||
### Features
|
||||
1. Integration with Front-end Website through Configuration
|
||||
2. Constructing Hierarchical Menu of Front-end System
|
||||
3. Provide a single background to support multiple front-end application configurations
|
||||
4. Provide single sign-on(SSO)
|
||||
5. Integrated System Authentication and Authorization Module
|
||||
6. Provide role, department, user, menu, foreground application authorization
|
||||
Role Authorization to Users
|
||||
Role-to-Menu Authorization
|
||||
Role Authorization to Departments
|
||||
Role-to-application authorization (multiple front-end applications share a back-end privilege management system)
|
||||
Departments Authorize Users
|
||||
7. Provide dictionary tables for personalized configuration of front-end websites
|
||||
8. Fully responsive layout (supporting all mainstream devices such as computers, tablets, mobile phones, etc.)
|
||||
9. Built-in multi-data source support, simple configuration and immediate effect without restart
|
||||
10. Built-in data memory caching mechanism, page fast response
|
||||
11. Built-in Data **Operation Log** and User **Log on**
|
||||
|
||||
[Update log](https://gitee.com/LongbowEnterprise/BootstrapAdmin/wikis/更新日志)
|
||||
|
||||
### Advantage
|
||||
1. The front-end system does not need to write login, authorization and authentication modules; it is only responsible for writing business modules.
|
||||
2. Background system can be used directly without any secondary development.
|
||||
3. Front-end and back-end systems are separated, which are different systems (domain name can be independent)
|
||||
4. Extensible to multi-tenant applications
|
||||
|
||||
For more information, please click [wiki](https://gitee.com/LongbowEnterprise/BootstrapAdmin/wikis/%E9%A1%B9%E7%9B%AE%E4%BB%8B%E7%BB%8D)
|
||||
|
||||
### Database
|
||||
**MSSQL/Oracle/SQLite/MySql/MariaDB/Firebird/MongoDB**
|
||||
|
||||
For more information, please click [wiki](https://gitee.com/LongbowEnterprise/BootstrapAdmin/wikis/数据库连接配置?sort_id=1333482)
|
||||
|
||||
### Browser
|
||||
![chrome](https://img.shields.io/badge/chrome->%3D4.5-success.svg?logo=google%20chrome&logoColor=red)
|
||||
![firefox](https://img.shields.io/badge/firefox->38-success.svg?logo=mozilla%20firefox&logoColor=red)
|
||||
![edge](https://img.shields.io/badge/edge->%3D12-success.svg?logo=microsoft%20edge&logoColor=blue)
|
||||
![ie](https://img.shields.io/badge/ie->%3D11-success.svg?logo=internet%20explorer&logoColor=blue)
|
||||
![Safari](https://img.shields.io/badge/safari->%3D9-success.svg?logo=safari&logoColor=blue)
|
||||
![Andriod](https://img.shields.io/badge/andriod->%3D4.4-success.svg?logo=android)
|
||||
![oper](https://img.shields.io/badge/opera->%3D3.0-success.svg?logo=opera&logoColor=red)
|
||||
|
||||
```json
|
||||
"browserslist": [
|
||||
"Chrome >= 45",
|
||||
"Firefox >= 38",
|
||||
"Edge >= 12",
|
||||
"Explorer >= 11",
|
||||
"iOS >= 9",
|
||||
"Safari >= 9",
|
||||
"Android >= 4.4",
|
||||
"Opera >= 30"
|
||||
]
|
||||
```
|
||||
|
||||
### Mobile
|
||||
![ios](https://img.shields.io/badge/ios-supported-success.svg?logo=apple&logoColor=white)
|
||||
![Andriod](https://img.shields.io/badge/andriod-suported-success.svg?logo=android)
|
||||
![windows](https://img.shields.io/badge/windows-suported-success.svg?logo=windows&logoColor=blue)
|
||||
|
||||
| | **Chrome** | **Firefox** | **Safari** | **Android Browser & WebView** | **Microsoft Edge** |
|
||||
| ------- | --------- | --------- | ------ | ------------------------- | -------------- |
|
||||
| **iOS** | Supported | Supported | Supported | N/A | Supported |
|
||||
| **Android** | Supported | Supported | N/A | Android v5.0+ supported | Supported |
|
||||
| **Windows 10 Mobile** | N/A | N/A | N/A | N/A | Supported |
|
||||
|
||||
### Desktop
|
||||
![macOS](https://img.shields.io/badge/macOS-supported-success.svg?logo=apple&logoColor=white)
|
||||
![linux](https://img.shields.io/badge/linux-suported-success.svg?logo=linux&logoColor=white)
|
||||
![windows](https://img.shields.io/badge/windows-suported-success.svg?logo=windows)
|
||||
|
||||
| | Chrome | Firefox | Internet Explorer | Microsoft Edge | Opera | Safari |
|
||||
| ------- | --------- | --------- | ----------------- | -------------- | --------- | ------------- |
|
||||
| Mac | Supported | Supported | N/A | N/A | Supported | Supported |
|
||||
| Linux | Supported | Supported | N/A | N/A | N/A | N/A |
|
||||
| Windows | Supported | Supported | Supported, IE10+ | Supported | Supported | Not supported |
|
||||
|
||||
## QQ Group
|
||||
[![QQ](https://img.shields.io/badge/QQ-795206915-green.svg?logo=tencent%20qq&logoColor=red)](https://shang.qq.com/wpa/qunwpa?idkey=d381355e50ff91db410c3da3eadb081ba859f64c2877e86343f4709b171f28b8)
|
||||
|
||||
## Installation
|
||||
1. Install .net core sdk [Offical website](http://www.microsoft.com/net/download)
|
||||
2. Install Visual Studio 2019 lastest [Offical website](https://visualstudio.microsoft.com/vs/getting-started/)
|
||||
3. Git clone `git clone https://gitee.com/LongbowEnterprise/BootstrapAdmin.git`
|
||||
4. Login as Admin/123789
|
||||
|
||||
## Branchs
|
||||
[Details](https://gitee.com/LongbowEnterprise/BootstrapAdmin/wikis/分支说明)
|
||||
|
||||
## Online Demonstration
|
||||
[![website1](https://img.shields.io/badge/linux-http://ba.zylweb.cn-success.svg?logo=buzzfeed&logoColor=green)](http://ba.zylweb.cn)
|
||||
[![website2](https://img.shields.io/badge/linux-http://admin.blazor.zone-success.svg?logo=buzzfeed&logoColor=green)](http://admin.blazor.zone)
|
||||
|
||||
### Login
|
||||
Administrator: Admin/123789
|
||||
User: User/123789
|
||||
|
||||
## Docker Images
|
||||
[![Docker](https://img.shields.io/docker/cloud/automated/argozhang/ba.svg?logo=docker&logoColor=success)](https://hub.docker.com/r/argozhang/ba)
|
||||
[![Docker](https://img.shields.io/docker/cloud/build/argozhang/ba.svg?logo=docker&logoColor=success)](https://hub.docker.com/r/argozhang/ba/builds)
|
||||
[![Docker](https://img.shields.io/github/workflow/status/ArgoZhang/BootstrapAdmin/Docker%20Image%20CI/master?label=Docker%20Image%20CI&logo=github&logoColor=green)](https://github.com/ArgoZhang/BootstrapAdmin/actions?query=workflow%3A%22Docker+Image+CI%22%3Amaster)
|
||||
|
||||
### Docker Hub
|
||||
Mirror [Portal](https://hub.docker.com/r/argozhang/ba)
|
||||
```bash
|
||||
docker pull argozhang/ba
|
||||
```
|
||||
### Qiniu Cloud:
|
||||
Mirror [Portal](https://hub.qiniu.com/store/argozhang/ba)
|
||||
```bash
|
||||
docker pull reg.qiniu.com/argozhang/ba
|
||||
```
|
||||
|
||||
## Configurations
|
||||
Detailed configuration instructions please click [wikis](https://gitee.com/LongbowEnterprise/BootstrapAdmin/wikis)
|
||||
|
||||
## Q&A
|
||||
Please click [wikis](https://gitee.com/LongbowEnterprise/BootstrapAdmin/wikis/%E5%B8%B8%E8%A7%81%E9%97%AE%E9%A2%98Q&A)
|
||||
|
||||
## License
|
||||
[![Gitee license](https://img.shields.io/github/license/argozhang/bootstrapadmin.svg?logo=git&logoColor=red)](https://gitee.com/LongbowEnterprise/BootstrapAdmin/blob/master/LICENSE)
|
||||
|
||||
## GVP award
|
||||
[View](https://images.gitee.com/uploads/images/2021/0112/112021_9d570be1_554725.png "GiteeGVP.png")
|
||||
|
||||
## Screenshots
|
||||
|
||||
Home
|
||||
|
||||
![Home](https://gitee.com/LongbowEnterprise/Pictures/raw/master/BootstrapAdmin/BA02-01.png "BAHome-01.png")
|
||||
|
||||
For more screenshots, Click [wiki](https://gitee.com/LongbowEnterprise/BootstrapAdmin/wikis)
|
||||
|
||||
## Contribution
|
||||
|
||||
1. Fork
|
||||
2. Create Feat_xxx branch
|
||||
3. Commit
|
||||
4. Create Pull Request
|
||||
|
||||
## Donate
|
||||
|
||||
If this project is helpful to you, please scan the QR code below for a cup of coffee.
|
||||
|
||||
![WeChat](https://gitee.com/LongbowEnterprise/Pictures/raw/master/WeChat/WeChat.png "WeChat")
|
||||
# 第二点
|
||||
## 环境要求
|
||||
|
||||
# 第三点
|
||||
## 软件要求
|
|
@ -143,16 +143,6 @@ CREATE TABLE Tasks(
|
|||
AssignTime DATE NOT NULL
|
||||
);
|
||||
|
||||
CREATE TABLE RejectUsers(
|
||||
ID SERIAL PRIMARY KEY,
|
||||
UserName VARCHAR (50) NOT NULL,
|
||||
DisplayName VARCHAR (50) NOT NULL,
|
||||
RegisterTime DATE NOT NULL,
|
||||
RejectedBy VARCHAR (50) NOT NULL,
|
||||
RejectedTime DATE NOT NULL,
|
||||
RejectedReason VARCHAR (50) NULL
|
||||
);
|
||||
|
||||
CREATE TABLE RejectUsers(
|
||||
ID SERIAL PRIMARY KEY,
|
||||
UserName VARCHAR (50) NOT NULL,
|
||||
|
|
|
@ -6,8 +6,8 @@
|
|||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="BootstrapBlazor" Version="6.*" />
|
||||
<PackageReference Include="FreeSql.Provider.Sqlite" Version="3.0.100" />
|
||||
<PackageReference Include="BootstrapBlazor" Version="6.8.13" />
|
||||
<PackageReference Include="FreeSql.Provider.Sqlite" Version="3.2.665" />
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
||||
|
|
|
@ -24,6 +24,10 @@ static class FreeSqlExtensions
|
|||
i.Property(n => n.Period).IsIgnore(true);
|
||||
i.Property(n => n.IsReset).IsIgnore(true);
|
||||
});
|
||||
freeSql.CodeFirst.ConfigEntity<Trace>(i =>
|
||||
{
|
||||
i.Name("Traces");
|
||||
});
|
||||
freeSql.CodeFirst.ConfigEntity<Group>(i =>
|
||||
{
|
||||
i.Name("Groups");
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="BootstrapBlazor" Version="6.*" />
|
||||
<PackageReference Include="SqlSugarCore" Version="5.0.5.2" />
|
||||
<PackageReference Include="BootstrapBlazor" Version="6.8.13" />
|
||||
<PackageReference Include="SqlSugarCore" Version="5.0.9.7" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
|
|
|
@ -8,7 +8,7 @@
|
|||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Microsoft.Extensions.Caching.Abstractions" Version="6.0.0" />
|
||||
<PackageReference Include="Microsoft.Extensions.Caching.Memory" Version="6.0.0" />
|
||||
<PackageReference Include="Microsoft.Extensions.Caching.Memory" Version="6.0.1" />
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
||||
|
|
|
@ -1,9 +1,9 @@
|
|||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="BootstrapBlazor" Version="6.*" />
|
||||
<PackageReference Include="Microsoft.EntityFrameworkCore" Version="6.0.1" />
|
||||
<PackageReference Include="Microsoft.EntityFrameworkCore.Sqlite" Version="6.0.1" />
|
||||
<PackageReference Include="BootstrapBlazor" Version="6.8.13" />
|
||||
<PackageReference Include="Microsoft.EntityFrameworkCore" Version="6.0.7" />
|
||||
<PackageReference Include="Microsoft.EntityFrameworkCore.Sqlite" Version="6.0.7" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
|
|
|
@ -1,9 +1,9 @@
|
|||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="BootstrapBlazor" Version="6.*" />
|
||||
<PackageReference Include="Longbow.Security.Cryptography" Version="5.2.0" />
|
||||
<PackageReference Include="Microsoft.Data.Sqlite" Version="6.0.1" />
|
||||
<PackageReference Include="BootstrapBlazor" Version="6.8.13" />
|
||||
<PackageReference Include="Longbow.Security.Cryptography" Version="6.0.0" />
|
||||
<PackageReference Include="Microsoft.Data.Sqlite" Version="6.0.7" />
|
||||
<PackageReference Include="PetaPoco.Extensions" Version="6.0.0" />
|
||||
</ItemGroup>
|
||||
|
||||
|
|
|
@ -6,7 +6,6 @@ using BootstrapAdmin.DataAccess.PetaPoco;
|
|||
using BootstrapAdmin.DataAccess.PetaPoco.Services;
|
||||
using BootstrapAdmin.Web.Core;
|
||||
using BootstrapBlazor.Components;
|
||||
using BootstrapBlazor.DataAcces.PetaPoco.Services;
|
||||
using Microsoft.AspNetCore.Hosting;
|
||||
using Microsoft.Extensions.DependencyInjection.Extensions;
|
||||
using Microsoft.Extensions.Hosting;
|
||||
|
@ -27,43 +26,10 @@ public static class ServiceCollectionExtensions
|
|||
///
|
||||
/// </summary>
|
||||
/// <param name="services"></param>
|
||||
/// <param name="builder"></param>
|
||||
/// <returns></returns>
|
||||
public static IServiceCollection AddPetaPocoDataAccessServices(this IServiceCollection services, Action<IServiceProvider, IDatabaseBuildConfiguration> builder)
|
||||
public static IServiceCollection AddPetaPocoDataAccessServices(this IServiceCollection services)
|
||||
{
|
||||
services.TryAddSingleton<IDatabase>(provider =>
|
||||
{
|
||||
var option = DatabaseConfiguration.Build();
|
||||
builder(provider, option);
|
||||
option.UsingDefaultMapper<BootstrapAdminConventionMapper>();
|
||||
var db = new Database(option);
|
||||
|
||||
var logger = provider.GetRequiredService<ILogger<Database>>();
|
||||
db.ExceptionThrown += (sender, e) =>
|
||||
{
|
||||
var message = e.Exception.Format(new NameValueCollection()
|
||||
{
|
||||
[nameof(db.LastCommand)] = db.LastCommand,
|
||||
[nameof(db.LastArgs)] = string.Join(",", db.LastArgs)
|
||||
});
|
||||
logger.LogError(new EventId(1001, "GlobalException"), e.Exception, message);
|
||||
};
|
||||
var env = provider.GetRequiredService<IWebHostEnvironment>();
|
||||
if (env.IsDevelopment())
|
||||
{
|
||||
db.CommandExecuted += (sender, args) =>
|
||||
{
|
||||
var parameters = new StringBuilder();
|
||||
foreach (DbParameter p in args.Command.Parameters)
|
||||
{
|
||||
parameters.AppendFormat("{0}: {1} ", p.ParameterName, p.Value);
|
||||
}
|
||||
logger.LogInformation(args.Command.CommandText);
|
||||
logger.LogInformation(parameters.ToString());
|
||||
};
|
||||
};
|
||||
return db;
|
||||
});
|
||||
services.TryAddSingleton<IDBManager, DBManagerService>();
|
||||
|
||||
// 增加数据服务
|
||||
services.AddSingleton(typeof(IDataService<>), typeof(DefaultDataService<>));
|
||||
|
|
|
@ -12,29 +12,34 @@ class AppService : IApp
|
|||
{
|
||||
private const string AppServiceGetAppsByRoleIdCacheKey = "AppService-GetAppsByRoleId";
|
||||
|
||||
private IDatabase Database { get; }
|
||||
private IDBManager DBManager { get; }
|
||||
|
||||
public AppService(IDatabase db)
|
||||
public AppService(IDBManager db)
|
||||
{
|
||||
Database = db;
|
||||
DBManager = db;
|
||||
}
|
||||
|
||||
public List<string> GetAppsByRoleId(string? roleId) => CacheManager.GetOrAdd($"{AppServiceGetAppsByRoleIdCacheKey}-{roleId}", entry => Database.Fetch<string>("select AppID from RoleApp where RoleID = @0", roleId));
|
||||
public List<string> GetAppsByRoleId(string? roleId) => CacheManager.GetOrAdd($"{AppServiceGetAppsByRoleIdCacheKey}-{roleId}", entry =>
|
||||
{
|
||||
using var db = DBManager.Create();
|
||||
return db.Fetch<string>("select AppID from RoleApp where RoleID = @0", roleId);
|
||||
});
|
||||
|
||||
public bool SaveAppsByRoleId(string? roleId, IEnumerable<string> appIds)
|
||||
{
|
||||
var ret = false;
|
||||
using var db = DBManager.Create();
|
||||
try
|
||||
{
|
||||
Database.BeginTransaction();
|
||||
Database.Execute("delete from RoleApp where RoleID = @0", roleId);
|
||||
Database.InsertBatch("RoleApp", appIds.Select(g => new { AppID = g, RoleID = roleId }));
|
||||
Database.CompleteTransaction();
|
||||
db.BeginTransaction();
|
||||
db.Execute("delete from RoleApp where RoleID = @0", roleId);
|
||||
db.InsertBatch("RoleApp", appIds.Select(g => new { AppID = g, RoleID = roleId }));
|
||||
db.CompleteTransaction();
|
||||
ret = true;
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
Database.AbortTransaction();
|
||||
db.AbortTransaction();
|
||||
throw;
|
||||
}
|
||||
if (ret)
|
||||
|
|
|
@ -0,0 +1,78 @@
|
|||
// Copyright (c) Argo Zhang (argo@163.com). All rights reserved.
|
||||
// Licensed under the LGPL License, Version 3.0. See License.txt in the project root for license information.
|
||||
// Website: https://admin.blazor.zone
|
||||
|
||||
using BootstrapBlazor.Components;
|
||||
using Microsoft.AspNetCore.Hosting;
|
||||
using Microsoft.Extensions.Configuration;
|
||||
using Microsoft.Extensions.Hosting;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using PetaPoco;
|
||||
using PetaPoco.Providers;
|
||||
using System.Collections.Specialized;
|
||||
using System.Data.Common;
|
||||
using System.Text;
|
||||
|
||||
namespace BootstrapAdmin.DataAccess.PetaPoco.Services;
|
||||
|
||||
internal class DBManagerService : IDBManager
|
||||
{
|
||||
private IConfiguration Configuration { get; set; }
|
||||
|
||||
private ILogger<DBManagerService> Logger { get; set; }
|
||||
|
||||
private IWebHostEnvironment WebHost { get; set; }
|
||||
|
||||
public DBManagerService(IConfiguration configuration, ILogger<DBManagerService> logger, IWebHostEnvironment host)
|
||||
{
|
||||
Configuration = configuration;
|
||||
Logger = logger;
|
||||
WebHost = host;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 创建 IDatabase 实例方法
|
||||
/// </summary>
|
||||
/// <param name="connectionName">连接字符串键值</param>
|
||||
/// <param name="keepAlive"></param>
|
||||
/// <returns></returns>
|
||||
public IDatabase Create(string? connectionName = "ba", bool keepAlive = false)
|
||||
{
|
||||
var conn = Configuration.GetConnectionString(connectionName) ?? throw new ArgumentNullException(nameof(connectionName));
|
||||
|
||||
var option = DatabaseConfiguration.Build();
|
||||
option.UsingDefaultMapper<BootstrapAdminConventionMapper>();
|
||||
|
||||
// connectionstring
|
||||
option.UsingConnectionString(conn);
|
||||
|
||||
// provider
|
||||
option.UsingProvider<SQLiteDatabaseProvider>();
|
||||
|
||||
var db = new Database(option) { KeepConnectionAlive = keepAlive };
|
||||
|
||||
db.ExceptionThrown += (sender, e) =>
|
||||
{
|
||||
var message = e.Exception.Format(new NameValueCollection()
|
||||
{
|
||||
[nameof(db.LastCommand)] = db.LastCommand,
|
||||
[nameof(db.LastArgs)] = string.Join(",", db.LastArgs)
|
||||
});
|
||||
Logger.LogError(new EventId(1001, "GlobalException"), e.Exception, message);
|
||||
};
|
||||
if (WebHost.IsDevelopment())
|
||||
{
|
||||
db.CommandExecuted += (sender, args) =>
|
||||
{
|
||||
var parameters = new StringBuilder();
|
||||
foreach (DbParameter p in args.Command.Parameters)
|
||||
{
|
||||
parameters.AppendFormat("{0}: {1} ", p.ParameterName, p.Value);
|
||||
}
|
||||
Logger.LogInformation(args.Command.CommandText);
|
||||
Logger.LogInformation(parameters.ToString());
|
||||
};
|
||||
};
|
||||
return db;
|
||||
}
|
||||
}
|
|
@ -9,21 +9,21 @@ using BootstrapBlazor.Components;
|
|||
using PetaPoco;
|
||||
using PetaPoco.Extensions;
|
||||
|
||||
namespace BootstrapBlazor.DataAcces.PetaPoco.Services;
|
||||
namespace BootstrapAdmin.DataAccess.PetaPoco.Services;
|
||||
|
||||
/// <summary>
|
||||
/// PetaPoco ORM 的 IDataService 接口实现
|
||||
/// </summary>
|
||||
class DefaultDataService<TModel> : DataServiceBase<TModel> where TModel : class, new()
|
||||
{
|
||||
private IDatabase Database { get; }
|
||||
private IDBManager DBManager { get; }
|
||||
|
||||
private IUser UserService { get; }
|
||||
|
||||
/// <summary>
|
||||
/// 构造函数
|
||||
/// </summary>
|
||||
public DefaultDataService(IDatabase db, IUser userService) => (Database, UserService) = (db, userService);
|
||||
public DefaultDataService(IDBManager db, IUser userService) => (DBManager, UserService) = (db, userService);
|
||||
|
||||
/// <summary>
|
||||
/// 删除方法
|
||||
|
@ -34,7 +34,8 @@ class DefaultDataService<TModel> : DataServiceBase<TModel> where TModel : class,
|
|||
{
|
||||
// 通过模型获取主键列数据
|
||||
// 支持批量删除
|
||||
Database.DeleteBatch(models);
|
||||
using var db = DBManager.Create();
|
||||
db.DeleteBatch(models);
|
||||
return Task.FromResult(true);
|
||||
}
|
||||
|
||||
|
@ -52,13 +53,14 @@ class DefaultDataService<TModel> : DataServiceBase<TModel> where TModel : class,
|
|||
}
|
||||
else
|
||||
{
|
||||
using var db = DBManager.Create();
|
||||
if (changedType == ItemChangedType.Add)
|
||||
{
|
||||
await Database.InsertAsync(model);
|
||||
await db.InsertAsync(model);
|
||||
}
|
||||
else
|
||||
{
|
||||
await Database.UpdateAsync(model);
|
||||
await db.UpdateAsync(model);
|
||||
}
|
||||
}
|
||||
return true;
|
||||
|
@ -79,16 +81,17 @@ class DefaultDataService<TModel> : DataServiceBase<TModel> where TModel : class,
|
|||
IsAdvanceSearch = option.AdvanceSearchs.Any() || option.CustomerSearchs.Any()
|
||||
};
|
||||
|
||||
using var db = DBManager.Create();
|
||||
if (option.IsPage)
|
||||
{
|
||||
var items = await Database.PageAsync<TModel>(option);
|
||||
var items = await db.PageAsync<TModel>(option);
|
||||
|
||||
ret.TotalCount = Convert.ToInt32(items.TotalItems);
|
||||
ret.Items = items.Items;
|
||||
}
|
||||
else
|
||||
{
|
||||
var items = await Database.FetchAsync<TModel>(option);
|
||||
var items = await db.FetchAsync<TModel>(option);
|
||||
ret.TotalCount = items.Count;
|
||||
ret.Items = items;
|
||||
}
|
||||
|
|
|
@ -17,7 +17,7 @@ class DictService : IDict
|
|||
{
|
||||
private const string DictServiceCacheKey = "DictService-GetAll";
|
||||
|
||||
private IDatabase Database { get; }
|
||||
private IDBManager DBManager { get; }
|
||||
|
||||
private string AppId { get; set; }
|
||||
|
||||
|
@ -26,13 +26,17 @@ class DictService : IDict
|
|||
/// </summary>
|
||||
/// <param name="db"></param>
|
||||
/// <param name="configuration"></param>
|
||||
public DictService(IDatabase db, IConfiguration configuration)
|
||||
public DictService(IDBManager db, IConfiguration configuration)
|
||||
{
|
||||
Database = db;
|
||||
DBManager = db;
|
||||
AppId = configuration.GetValue("AppId", "BA");
|
||||
}
|
||||
|
||||
public List<Dict> GetAll() => CacheManager.GetOrAdd(DictServiceCacheKey, entry => Database.Fetch<Dict>());
|
||||
public List<Dict> GetAll() => CacheManager.GetOrAdd(DictServiceCacheKey, entry =>
|
||||
{
|
||||
using var db = DBManager.Create();
|
||||
return db.Fetch<Dict>();
|
||||
});
|
||||
|
||||
public Dictionary<string, string> GetApps()
|
||||
{
|
||||
|
@ -178,7 +182,8 @@ class DictService : IDict
|
|||
|
||||
private bool SaveDict(Dict dict)
|
||||
{
|
||||
var ret = Database.Update<Dict>("set Code = @Code where Category = @Category and Name = @Name", dict) == 1;
|
||||
using var db = DBManager.Create();
|
||||
var ret = db.Update<Dict>("set Code = @Code where Category = @Category and Name = @Name", dict) == 1;
|
||||
if (ret)
|
||||
{
|
||||
// 更新缓存
|
||||
|
@ -417,9 +422,10 @@ class DictService : IDict
|
|||
if (!string.IsNullOrEmpty(client.AppId))
|
||||
{
|
||||
DeleteClient(client.AppId);
|
||||
using var db = DBManager.Create();
|
||||
try
|
||||
{
|
||||
Database.BeginTransaction();
|
||||
db.BeginTransaction();
|
||||
var items = new List<Dict>()
|
||||
{
|
||||
new Dict { Category = "应用程序", Name = client.AppName, Code = client.AppId, Define = EnumDictDefine.System },
|
||||
|
@ -432,13 +438,13 @@ class DictService : IDict
|
|||
new Dict { Category = client.AppId, Name = "系统设置地址", Code = client.SettingsUrl, Define = EnumDictDefine.Customer },
|
||||
new Dict { Category = client.AppId, Name = "系统通知地址", Code = client.NotificationUrl, Define = EnumDictDefine.Customer }
|
||||
};
|
||||
Database.InsertBatch(items);
|
||||
Database.CompleteTransaction();
|
||||
db.InsertBatch(items);
|
||||
db.CompleteTransaction();
|
||||
ret = true;
|
||||
}
|
||||
catch (DbException)
|
||||
{
|
||||
Database.AbortTransaction();
|
||||
db.AbortTransaction();
|
||||
throw;
|
||||
}
|
||||
}
|
||||
|
@ -466,12 +472,13 @@ class DictService : IDict
|
|||
public bool DeleteClient(string appId)
|
||||
{
|
||||
bool ret;
|
||||
using var db = DBManager.Create();
|
||||
try
|
||||
{
|
||||
Database.BeginTransaction();
|
||||
Database.Execute("delete Dicts where Category=@0 and Name=@1 and Define=@2", "应用首页", appId, EnumDictDefine.System);
|
||||
Database.Execute("delete Dicts where Category=@0 and Code=@1 and Define=@2", "应用程序", appId, EnumDictDefine.System);
|
||||
Database.Execute("delete Dicts where Category=@Category and Name in (@Names)", new
|
||||
db.BeginTransaction();
|
||||
db.Execute("delete Dicts where Category=@0 and Name=@1 and Define=@2", "应用首页", appId, EnumDictDefine.System);
|
||||
db.Execute("delete Dicts where Category=@0 and Code=@1 and Define=@2", "应用程序", appId, EnumDictDefine.System);
|
||||
db.Execute("delete Dicts where Category=@Category and Name in (@Names)", new
|
||||
{
|
||||
Category = appId,
|
||||
Names = new List<string>
|
||||
|
@ -485,12 +492,12 @@ class DictService : IDict
|
|||
"系统通知地址"
|
||||
}
|
||||
});
|
||||
Database.CompleteTransaction();
|
||||
db.CompleteTransaction();
|
||||
ret = true;
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
Database.AbortTransaction();
|
||||
db.AbortTransaction();
|
||||
throw;
|
||||
}
|
||||
return ret;
|
||||
|
|
|
@ -10,15 +10,16 @@ namespace BootstrapAdmin.DataAccess.PetaPoco.Services;
|
|||
|
||||
class ExceptionService : IException
|
||||
{
|
||||
private IDatabase Database { get; }
|
||||
private IDBManager DBManager { get; }
|
||||
|
||||
public ExceptionService(IDatabase db) => Database = db;
|
||||
public ExceptionService(IDBManager db) => DBManager = db;
|
||||
|
||||
public bool Log(Error exception)
|
||||
{
|
||||
try
|
||||
{
|
||||
Database.Insert(exception);
|
||||
using var db = DBManager.Create();
|
||||
db.Insert(exception);
|
||||
}
|
||||
catch { }
|
||||
return true;
|
||||
|
@ -59,7 +60,8 @@ class ExceptionService : IException
|
|||
sql.OrderBy("Logtime desc", "ErrorPage", "UserId");
|
||||
}
|
||||
|
||||
var data = Database.Page<Error>(pageIndex, pageItems, sql);
|
||||
using var db = DBManager.Create();
|
||||
var data = db.Page<Error>(pageIndex, pageItems, sql);
|
||||
return (data.Items, Convert.ToInt32(data.TotalItems));
|
||||
}
|
||||
}
|
||||
|
|
|
@ -17,26 +17,34 @@ class GroupService : IGroup
|
|||
|
||||
private const string GroupServiceGetGroupsByRoleIdCacheKey = "GroupService-GetGroupsByRoleId";
|
||||
|
||||
private IDatabase Database { get; }
|
||||
private IDBManager DBManager { get; }
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
/// <param name="db"></param>
|
||||
public GroupService(IDatabase db) => Database = db;
|
||||
public GroupService(IDBManager db) => DBManager = db;
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public List<Group> GetAll() => CacheManager.GetOrAdd(GroupServiceGetAllCacheKey, entry => Database.Fetch<Group>());
|
||||
public List<Group> GetAll() => CacheManager.GetOrAdd(GroupServiceGetAllCacheKey, entry =>
|
||||
{
|
||||
using var db = DBManager.Create();
|
||||
return db.Fetch<Group>();
|
||||
});
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
/// <param name="userId"></param>
|
||||
/// <returns></returns>
|
||||
public List<string> GetGroupsByUserId(string? userId) => CacheManager.GetOrAdd($"{GroupServiceGetGroupsByUserIdCacheKey}-{userId}", entry => Database.Fetch<string>("select GroupID from UserGroup where UserID = @0", userId));
|
||||
public List<string> GetGroupsByUserId(string? userId) => CacheManager.GetOrAdd($"{GroupServiceGetGroupsByUserIdCacheKey}-{userId}", entry =>
|
||||
{
|
||||
using var db = DBManager.Create();
|
||||
return db.Fetch<string>("select GroupID from UserGroup where UserID = @0", userId);
|
||||
});
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
|
@ -47,17 +55,18 @@ class GroupService : IGroup
|
|||
public bool SaveGroupsByUserId(string? userId, IEnumerable<string> groupIds)
|
||||
{
|
||||
var ret = false;
|
||||
using var db = DBManager.Create();
|
||||
try
|
||||
{
|
||||
Database.BeginTransaction();
|
||||
Database.Execute("delete from UserGroup where UserID = @0", userId);
|
||||
Database.InsertBatch("UserGroup", groupIds.Select(g => new { GroupID = g, UserID = userId }));
|
||||
Database.CompleteTransaction();
|
||||
db.BeginTransaction();
|
||||
db.Execute("delete from UserGroup where UserID = @0", userId);
|
||||
db.InsertBatch("UserGroup", groupIds.Select(g => new { GroupID = g, UserID = userId }));
|
||||
db.CompleteTransaction();
|
||||
ret = true;
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
Database.AbortTransaction();
|
||||
db.AbortTransaction();
|
||||
throw;
|
||||
}
|
||||
if (ret)
|
||||
|
@ -72,7 +81,11 @@ class GroupService : IGroup
|
|||
/// </summary>
|
||||
/// <param name="roleId"></param>
|
||||
/// <returns></returns>
|
||||
public List<string> GetGroupsByRoleId(string? roleId) => CacheManager.GetOrAdd($"{GroupServiceGetGroupsByRoleIdCacheKey}-{roleId}", entry => Database.Fetch<string>("select GroupID from RoleGroup where RoleID = @0", roleId));
|
||||
public List<string> GetGroupsByRoleId(string? roleId) => CacheManager.GetOrAdd($"{GroupServiceGetGroupsByRoleIdCacheKey}-{roleId}", entry =>
|
||||
{
|
||||
using var db = DBManager.Create();
|
||||
return db.Fetch<string>("select GroupID from RoleGroup where RoleID = @0", roleId);
|
||||
});
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
|
@ -83,17 +96,18 @@ class GroupService : IGroup
|
|||
public bool SaveGroupsByRoleId(string? roleId, IEnumerable<string> groupIds)
|
||||
{
|
||||
var ret = false;
|
||||
using var db = DBManager.Create();
|
||||
try
|
||||
{
|
||||
Database.BeginTransaction();
|
||||
Database.Execute("delete from RoleGroup where RoleID = @0", roleId);
|
||||
Database.InsertBatch("RoleGroup", groupIds.Select(g => new { GroupID = g, RoleID = roleId }));
|
||||
Database.CompleteTransaction();
|
||||
db.BeginTransaction();
|
||||
db.Execute("delete from RoleGroup where RoleID = @0", roleId);
|
||||
db.InsertBatch("RoleGroup", groupIds.Select(g => new { GroupID = g, RoleID = roleId }));
|
||||
db.CompleteTransaction();
|
||||
ret = true;
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
Database.AbortTransaction();
|
||||
db.AbortTransaction();
|
||||
throw;
|
||||
}
|
||||
|
||||
|
|
|
@ -0,0 +1,19 @@
|
|||
// Copyright (c) Argo Zhang (argo@163.com). All rights reserved.
|
||||
// Licensed under the LGPL License, Version 3.0. See License.txt in the project root for license information.
|
||||
// Website: https://admin.blazor.zone
|
||||
|
||||
using PetaPoco;
|
||||
|
||||
namespace BootstrapAdmin.DataAccess.PetaPoco.Services;
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public interface IDBManager
|
||||
{
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
IDatabase Create(string? connectionName = "ba", bool keepAlive = false);
|
||||
}
|
|
@ -4,15 +4,14 @@
|
|||
|
||||
using BootstrapAdmin.DataAccess.Models;
|
||||
using BootstrapAdmin.Web.Core;
|
||||
using PetaPoco;
|
||||
|
||||
namespace BootstrapAdmin.DataAccess.PetaPoco.Services;
|
||||
|
||||
class LoginService : ILogin
|
||||
{
|
||||
private IDatabase Database { get; }
|
||||
private IDBManager DBManager { get; }
|
||||
|
||||
public LoginService(IDatabase database) => Database = database;
|
||||
public LoginService(IDBManager database) => DBManager = database;
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
|
@ -38,7 +37,8 @@ class LoginService : ILogin
|
|||
UserAgent = userAgent,
|
||||
Result = result ? "登录成功" : "登录失败"
|
||||
};
|
||||
Database.Insert(loginUser);
|
||||
using var db = DBManager.Create();
|
||||
db.Insert(loginUser);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -18,13 +18,16 @@ class NavigationService : INavigation
|
|||
|
||||
private const string NavigationServiceGetMenusByRoleIdCacheKey = "NavigationService-GetMenusByRoleId";
|
||||
|
||||
private IDatabase Database { get; }
|
||||
private IDBManager DBManager { get; }
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
/// <param name="db"></param>
|
||||
public NavigationService(IDatabase db) => Database = db;
|
||||
public NavigationService(IDBManager db)
|
||||
{
|
||||
DBManager = db;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获得指定用户名可访问的所有菜单集合
|
||||
|
@ -33,9 +36,10 @@ class NavigationService : INavigation
|
|||
/// <returns>未层次化的菜单集合</returns>
|
||||
public List<Navigation> GetAllMenus(string userName) => CacheManager.GetOrAdd($"{NavigationServiceGetAllCacheKey}-{userName}", entry =>
|
||||
{
|
||||
using var db = DBManager.Create();
|
||||
// 缓存所有菜单数据移除 SQL 语句降低复杂度
|
||||
var order = Database.Provider.EscapeSqlIdentifier("Order");
|
||||
return Database.Fetch<Models.Navigation>($"select n.ID, n.ParentId, n.Name, n.{order}, n.Icon, n.Url, n.Category, n.Target, n.IsResource, n.Application from Navigations n inner join (select nr.NavigationID from Users u inner join UserRole ur on ur.UserID = u.ID inner join NavigationRole nr on nr.RoleID = ur.RoleID where u.UserName = @UserName union select nr.NavigationID from Users u inner join UserGroup ug on u.ID = ug.UserID inner join RoleGroup rg on rg.GroupID = ug.GroupID inner join NavigationRole nr on nr.RoleID = rg.RoleID where u.UserName = @UserName union select n.ID from Navigations n where EXISTS (select UserName from Users u inner join UserRole ur on u.ID = ur.UserID inner join Roles r on ur.RoleID = r.ID where u.UserName = @UserName and r.RoleName = @RoleName)) nav on n.ID = nav.NavigationID ORDER BY n.Application, n.{order}", new { UserName = userName, RoleName = "Administrators" });
|
||||
var order = db.Provider.EscapeSqlIdentifier("Order");
|
||||
return db.Fetch<Models.Navigation>($"select n.ID, n.ParentId, n.Name, n.{order}, n.Icon, n.Url, n.Category, n.Target, n.IsResource, n.Application from Navigations n inner join (select nr.NavigationID from Users u inner join UserRole ur on ur.UserID = u.ID inner join NavigationRole nr on nr.RoleID = ur.RoleID where u.UserName = @UserName union select nr.NavigationID from Users u inner join UserGroup ug on u.ID = ug.UserID inner join RoleGroup rg on rg.GroupID = ug.GroupID inner join NavigationRole nr on nr.RoleID = rg.RoleID where u.UserName = @UserName union select n.ID from Navigations n where EXISTS (select UserName from Users u inner join UserRole ur on u.ID = ur.UserID inner join Roles r on ur.RoleID = r.ID where u.UserName = @UserName and r.RoleName = @RoleName)) nav on n.ID = nav.NavigationID ORDER BY n.Application, n.{order}", new { UserName = userName, RoleName = "Administrators" });
|
||||
});
|
||||
|
||||
/// <summary>
|
||||
|
@ -43,7 +47,11 @@ class NavigationService : INavigation
|
|||
/// </summary>
|
||||
/// <param name="roleId"></param>
|
||||
/// <returns></returns>
|
||||
public List<string> GetMenusByRoleId(string? roleId) => CacheManager.GetOrAdd($"{NavigationServiceGetMenusByRoleIdCacheKey}-{roleId}", entry => Database.Fetch<string>("select NavigationID from NavigationRole where RoleID = @0", roleId));
|
||||
public List<string> GetMenusByRoleId(string? roleId) => CacheManager.GetOrAdd($"{NavigationServiceGetMenusByRoleIdCacheKey}-{roleId}", entry =>
|
||||
{
|
||||
using var db = DBManager.Create();
|
||||
return db.Fetch<string>("select NavigationID from NavigationRole where RoleID = @0", roleId);
|
||||
});
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
|
@ -54,17 +62,18 @@ class NavigationService : INavigation
|
|||
public bool SaveMenusByRoleId(string? roleId, List<string> menuIds)
|
||||
{
|
||||
var ret = false;
|
||||
using var db = DBManager.Create();
|
||||
try
|
||||
{
|
||||
Database.BeginTransaction();
|
||||
Database.Execute("delete from NavigationRole where RoleID = @0", roleId);
|
||||
Database.InsertBatch("NavigationRole", menuIds.Select(g => new { NavigationID = g, RoleID = roleId }));
|
||||
Database.CompleteTransaction();
|
||||
db.BeginTransaction();
|
||||
db.Execute("delete from NavigationRole where RoleID = @0", roleId);
|
||||
db.InsertBatch("NavigationRole", menuIds.Select(g => new { NavigationID = g, RoleID = roleId }));
|
||||
db.CompleteTransaction();
|
||||
ret = true;
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
Database.AbortTransaction();
|
||||
db.AbortTransaction();
|
||||
throw;
|
||||
}
|
||||
if (ret)
|
||||
|
|
|
@ -19,25 +19,44 @@ class RoleService : IRole
|
|||
|
||||
private const string RoleServiceGetRolesByMenuIdCacheKey = "RoleService-GetRolesByMenusId";
|
||||
|
||||
private IDatabase Database { get; }
|
||||
private IDBManager DBManager { get; }
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
/// <param name="db"></param>
|
||||
public RoleService(IDatabase db) => Database = db;
|
||||
public RoleService(IDBManager db)
|
||||
{
|
||||
DBManager = db;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public List<Role> GetAll() => CacheManager.GetOrAdd(RoleServiceGetAllCacheKey, entry => CacheManager.GetOrAdd(RoleServiceGetAllCacheKey, entry => Database.Fetch<Role>()));
|
||||
public List<Role> GetAll() => CacheManager.GetOrAdd(RoleServiceGetAllCacheKey, entry => CacheManager.GetOrAdd(RoleServiceGetAllCacheKey, entry =>
|
||||
{
|
||||
using var db = DBManager.Create();
|
||||
return db.Fetch<Role>();
|
||||
}));
|
||||
|
||||
public List<string> GetRolesByGroupId(string? groupId) => CacheManager.GetOrAdd($"{RoleServiceGetRolesByGroupIdCacheKey}-{groupId}", entry => Database.Fetch<string>("select RoleID from RoleGroup where GroupID = @0", groupId));
|
||||
public List<string> GetRolesByGroupId(string? groupId) => CacheManager.GetOrAdd($"{RoleServiceGetRolesByGroupIdCacheKey}-{groupId}", entry =>
|
||||
{
|
||||
using var db = DBManager.Create();
|
||||
return db.Fetch<string>("select RoleID from RoleGroup where GroupID = @0", groupId);
|
||||
});
|
||||
|
||||
public List<string> GetRolesByUserId(string? userId) => CacheManager.GetOrAdd($"{RoleServiceGetRolesByUserIdCacheKey}-{userId}", entry => Database.Fetch<string>("select RoleID from UserRole where UserID = @0", userId));
|
||||
public List<string> GetRolesByUserId(string? userId) => CacheManager.GetOrAdd($"{RoleServiceGetRolesByUserIdCacheKey}-{userId}", entry =>
|
||||
{
|
||||
using var db = DBManager.Create();
|
||||
return db.Fetch<string>("select RoleID from UserRole where UserID = @0", userId);
|
||||
});
|
||||
|
||||
public List<string> GetRolesByMenuId(string? menuId) => CacheManager.GetOrAdd($"{RoleServiceGetRolesByMenuIdCacheKey}-{menuId}", entry => Database.Fetch<string>("select RoleID from NavigationRole where NavigationID = @0", menuId));
|
||||
public List<string> GetRolesByMenuId(string? menuId) => CacheManager.GetOrAdd($"{RoleServiceGetRolesByMenuIdCacheKey}-{menuId}", entry =>
|
||||
{
|
||||
using var db = DBManager.Create();
|
||||
return db.Fetch<string>("select RoleID from NavigationRole where NavigationID = @0", menuId);
|
||||
});
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
|
@ -48,17 +67,18 @@ class RoleService : IRole
|
|||
public bool SaveRolesByGroupId(string? groupId, IEnumerable<string> roleIds)
|
||||
{
|
||||
var ret = false;
|
||||
using var db = DBManager.Create();
|
||||
try
|
||||
{
|
||||
Database.BeginTransaction();
|
||||
Database.Execute("delete from RoleGroup where GroupID = @0", groupId);
|
||||
Database.InsertBatch("RoleGroup", roleIds.Select(g => new { RoleID = g, GroupID = groupId }));
|
||||
Database.CompleteTransaction();
|
||||
db.BeginTransaction();
|
||||
db.Execute("delete from RoleGroup where GroupID = @0", groupId);
|
||||
db.InsertBatch("RoleGroup", roleIds.Select(g => new { RoleID = g, GroupID = groupId }));
|
||||
db.CompleteTransaction();
|
||||
ret = true;
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
Database.AbortTransaction();
|
||||
db.AbortTransaction();
|
||||
throw;
|
||||
}
|
||||
if (ret)
|
||||
|
@ -77,17 +97,18 @@ class RoleService : IRole
|
|||
public bool SaveRolesByUserId(string? userId, IEnumerable<string> roleIds)
|
||||
{
|
||||
var ret = false;
|
||||
using var db = DBManager.Create();
|
||||
try
|
||||
{
|
||||
Database.BeginTransaction();
|
||||
Database.Execute("delete from UserRole where UserID = @0", userId);
|
||||
Database.InsertBatch("UserRole", roleIds.Select(g => new { RoleID = g, UserID = userId }));
|
||||
Database.CompleteTransaction();
|
||||
db.BeginTransaction();
|
||||
db.Execute("delete from UserRole where UserID = @0", userId);
|
||||
db.InsertBatch("UserRole", roleIds.Select(g => new { RoleID = g, UserID = userId }));
|
||||
db.CompleteTransaction();
|
||||
ret = true;
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
Database.AbortTransaction();
|
||||
db.AbortTransaction();
|
||||
throw;
|
||||
}
|
||||
if (ret)
|
||||
|
@ -100,17 +121,18 @@ class RoleService : IRole
|
|||
public bool SaveRolesByMenuId(string? menuId, IEnumerable<string> roleIds)
|
||||
{
|
||||
var ret = false;
|
||||
using var db = DBManager.Create();
|
||||
try
|
||||
{
|
||||
Database.BeginTransaction();
|
||||
Database.Execute("delete from NavigationRole where NavigationID = @0", menuId);
|
||||
Database.InsertBatch("NavigationRole", roleIds.Select(g => new { RoleID = g, NavigationID = menuId }));
|
||||
Database.CompleteTransaction();
|
||||
db.BeginTransaction();
|
||||
db.Execute("delete from NavigationRole where NavigationID = @0", menuId);
|
||||
db.InsertBatch("NavigationRole", roleIds.Select(g => new { RoleID = g, NavigationID = menuId }));
|
||||
db.CompleteTransaction();
|
||||
ret = true;
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
Database.AbortTransaction();
|
||||
db.AbortTransaction();
|
||||
throw;
|
||||
}
|
||||
if (ret)
|
||||
|
|
|
@ -10,13 +10,12 @@ namespace BootstrapAdmin.DataAccess.PetaPoco.Services;
|
|||
|
||||
class TraceService : ITrace
|
||||
{
|
||||
private IDatabase Database { get; }
|
||||
private IDBManager DBManager { get; }
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
/// <param name="db"></param>
|
||||
public TraceService(IDatabase db) => Database = db;
|
||||
public TraceService(IDBManager db)
|
||||
{
|
||||
DBManager = db;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
|
@ -24,7 +23,8 @@ class TraceService : ITrace
|
|||
/// <param name="trace"></param>
|
||||
public void Log(Trace trace)
|
||||
{
|
||||
Database.Insert(trace);
|
||||
using var db = DBManager.Create();
|
||||
db.Insert(trace);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
@ -39,7 +39,6 @@ class TraceService : ITrace
|
|||
public (IEnumerable<Trace> Items, int ItemsCount) GetAll(string? searchText, TraceFilter filter, int pageIndex, int pageItems, List<string> sortList)
|
||||
{
|
||||
var sql = new Sql();
|
||||
|
||||
if (!string.IsNullOrEmpty(searchText))
|
||||
{
|
||||
sql.Where("UserName Like @0 or Ip Like @0 or RequestUrl Like @0", $"%{searchText}%");
|
||||
|
@ -71,7 +70,8 @@ class TraceService : ITrace
|
|||
sql.OrderBy("Logtime desc");
|
||||
}
|
||||
|
||||
var data = Database.Page<Trace>(pageIndex, pageItems, sql);
|
||||
using var db = DBManager.Create();
|
||||
var data = db.Page<Trace>(pageIndex, pageItems, sql);
|
||||
return (data.Items, Convert.ToInt32(data.TotalItems));
|
||||
}
|
||||
}
|
||||
|
|
|
@ -12,19 +12,22 @@ namespace BootstrapAdmin.DataAccess.PetaPoco.Services;
|
|||
|
||||
class UserService : IUser
|
||||
{
|
||||
private IDatabase Database { get; }
|
||||
private IDBManager DBManager { get; }
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
/// <param name="db"></param>
|
||||
public UserService(IDatabase db) => Database = db;
|
||||
public UserService(IDBManager db)
|
||||
{
|
||||
DBManager = db;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public List<User> GetAll() => Database.Fetch<User>();
|
||||
public List<User> GetAll()
|
||||
{
|
||||
using var db = DBManager.Create();
|
||||
return db.Fetch<User>();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
|
@ -35,7 +38,8 @@ class UserService : IUser
|
|||
/// <exception cref="NotImplementedException"></exception>
|
||||
public bool Authenticate(string userName, string password)
|
||||
{
|
||||
var user = Database.SingleOrDefault<User>("select DisplayName, Password, PassSalt from Users where ApprovedTime is not null and UserName = @0", userName);
|
||||
using var db = DBManager.Create();
|
||||
var user = db.SingleOrDefault<User>("select DisplayName, Password, PassSalt from Users where ApprovedTime is not null and UserName = @0", userName);
|
||||
|
||||
var isAuth = false;
|
||||
if (user != null && !string.IsNullOrEmpty(user.PassSalt))
|
||||
|
@ -47,11 +51,19 @@ class UserService : IUser
|
|||
|
||||
private const string UserServiceGetUserByUserNameCacheKey = "UserService-GetUserByUserName";
|
||||
|
||||
public User? GetUserByUserName(string? userName) => CacheManager.GetOrAdd($"{UserServiceGetUserByUserNameCacheKey}-{userName}", entry => string.IsNullOrEmpty(userName) ? null : Database.FirstOrDefault<User>("Where UserName = @0", userName));
|
||||
public User? GetUserByUserName(string? userName) => CacheManager.GetOrAdd($"{UserServiceGetUserByUserNameCacheKey}-{userName}", entry =>
|
||||
{
|
||||
using var db = DBManager.Create();
|
||||
return string.IsNullOrEmpty(userName) ? null : db.FirstOrDefault<User>("Where UserName = @0", userName);
|
||||
});
|
||||
|
||||
private const string UserServiceGetAppsByUserNameCacheKey = "UserService-GetAppsByUserName";
|
||||
|
||||
public List<string> GetApps(string userName) => CacheManager.GetOrAdd($"{UserServiceGetAppsByUserNameCacheKey}-{userName}", entry => Database.Fetch<string>($"select d.Code from Dicts d inner join RoleApp ra on d.Code = ra.AppId inner join (select r.Id from Roles r inner join UserRole ur on r.ID = ur.RoleID inner join Users u on ur.UserID = u.ID where u.UserName = @0 union select r.Id from Roles r inner join RoleGroup rg on r.ID = rg.RoleID inner join {Database.Provider.EscapeSqlIdentifier("Groups")} g on rg.GroupID = g.ID inner join UserGroup ug on ug.GroupID = g.ID inner join Users u on ug.UserID = u.ID where u.UserName = @0) r on ra.RoleId = r.ID union select Code from Dicts where Category = @1 and exists(select r.ID from Roles r inner join UserRole ur on r.ID = ur.RoleID inner join Users u on ur.UserID = u.ID where u.UserName = @0 and r.RoleName = @2 union select r.ID from Roles r inner join RoleGroup rg on r.ID = rg.RoleID inner join {Database.Provider.EscapeSqlIdentifier("Groups")} g on rg.GroupID = g.ID inner join UserGroup ug on ug.GroupID = g.ID inner join Users u on ug.UserID = u.ID where u.UserName = @0 and r.RoleName = @2)", userName, "应用程序", "Administrators"));
|
||||
public List<string> GetApps(string userName) => CacheManager.GetOrAdd($"{UserServiceGetAppsByUserNameCacheKey}-{userName}", entry =>
|
||||
{
|
||||
using var db = DBManager.Create();
|
||||
return db.Fetch<string>($"select d.Code from Dicts d inner join RoleApp ra on d.Code = ra.AppId inner join (select r.Id from Roles r inner join UserRole ur on r.ID = ur.RoleID inner join Users u on ur.UserID = u.ID where u.UserName = @0 union select r.Id from Roles r inner join RoleGroup rg on r.ID = rg.RoleID inner join {db.Provider.EscapeSqlIdentifier("Groups")} g on rg.GroupID = g.ID inner join UserGroup ug on ug.GroupID = g.ID inner join Users u on ug.UserID = u.ID where u.UserName = @0) r on ra.RoleId = r.ID union select Code from Dicts where Category = @1 and exists(select r.ID from Roles r inner join UserRole ur on r.ID = ur.RoleID inner join Users u on ur.UserID = u.ID where u.UserName = @0 and r.RoleName = @2 union select r.ID from Roles r inner join RoleGroup rg on r.ID = rg.RoleID inner join {db.Provider.EscapeSqlIdentifier("Groups")} g on rg.GroupID = g.ID inner join UserGroup ug on ug.GroupID = g.ID inner join Users u on ug.UserID = u.ID where u.UserName = @0 and r.RoleName = @2)", userName, "应用程序", "Administrators");
|
||||
});
|
||||
|
||||
private const string UserServiceGetAppIdByUserNameCacheKey = "UserService-GetAppIdByUserName";
|
||||
|
||||
|
@ -60,7 +72,11 @@ class UserService : IUser
|
|||
/// </summary>
|
||||
/// <param name="userName"></param>
|
||||
/// <returns></returns>
|
||||
public string? GetAppIdByUserName(string userName) => CacheManager.GetOrAdd($"{UserServiceGetAppIdByUserNameCacheKey}-{userName}", entry => Database.FirstOrDefault<User>("Where UserName = @0", userName)?.App);
|
||||
public string? GetAppIdByUserName(string userName) => CacheManager.GetOrAdd($"{UserServiceGetAppIdByUserNameCacheKey}-{userName}", entry =>
|
||||
{
|
||||
using var db = DBManager.Create();
|
||||
return db.FirstOrDefault<User>("Where UserName = @0", userName)?.App;
|
||||
});
|
||||
|
||||
private const string UserServiceGetRolesByUserNameCacheKey = "UserService-GetRolesByUserName";
|
||||
|
||||
|
@ -70,7 +86,11 @@ class UserService : IUser
|
|||
/// <param name="userName"></param>
|
||||
/// <returns></returns>
|
||||
/// <exception cref="NotImplementedException"></exception>
|
||||
public List<string> GetRoles(string userName) => CacheManager.GetOrAdd($"{UserServiceGetRolesByUserNameCacheKey}-{userName}", entry => Database.Fetch<string>($"select r.RoleName from Roles r inner join UserRole ur on r.ID=ur.RoleID inner join Users u on ur.UserID = u.ID and u.UserName = @0 union select r.RoleName from Roles r inner join RoleGroup rg on r.ID = rg.RoleID inner join {Database.Provider.EscapeSqlIdentifier("Groups")} g on rg.GroupID = g.ID inner join UserGroup ug on ug.GroupID = g.ID inner join Users u on ug.UserID = u.ID and u.UserName = @0", userName));
|
||||
public List<string> GetRoles(string userName) => CacheManager.GetOrAdd($"{UserServiceGetRolesByUserNameCacheKey}-{userName}", entry =>
|
||||
{
|
||||
using var db = DBManager.Create();
|
||||
return db.Fetch<string>($"select r.RoleName from Roles r inner join UserRole ur on r.ID=ur.RoleID inner join Users u on ur.UserID = u.ID and u.UserName = @0 union select r.RoleName from Roles r inner join RoleGroup rg on r.ID = rg.RoleID inner join {db.Provider.EscapeSqlIdentifier("Groups")} g on rg.GroupID = g.ID inner join UserGroup ug on ug.GroupID = g.ID inner join Users u on ug.UserID = u.ID and u.UserName = @0", userName);
|
||||
});
|
||||
|
||||
private const string UserServiceGetUsersByGroupIdCacheKey = "UserService-GetUsersByGroupId";
|
||||
|
||||
|
@ -78,7 +98,11 @@ class UserService : IUser
|
|||
///
|
||||
/// </summary>
|
||||
/// <param name="groupId"></param>
|
||||
public List<string> GetUsersByGroupId(string? groupId) => CacheManager.GetOrAdd($"{UserServiceGetUsersByGroupIdCacheKey}-{groupId}", entry => Database.Fetch<string>("select UserID from UserGroup where GroupID = @0", groupId));
|
||||
public List<string> GetUsersByGroupId(string? groupId) => CacheManager.GetOrAdd($"{UserServiceGetUsersByGroupIdCacheKey}-{groupId}", entry =>
|
||||
{
|
||||
using var db = DBManager.Create();
|
||||
return db.Fetch<string>("select UserID from UserGroup where GroupID = @0", groupId);
|
||||
});
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
|
@ -90,17 +114,18 @@ class UserService : IUser
|
|||
public bool SaveUsersByGroupId(string? id, IEnumerable<string> userIds)
|
||||
{
|
||||
var ret = false;
|
||||
using var db = DBManager.Create();
|
||||
try
|
||||
{
|
||||
Database.BeginTransaction();
|
||||
Database.Execute("delete from UserGroup where GroupId = @0", id);
|
||||
Database.InsertBatch("UserGroup", userIds.Select(g => new { UserID = g, GroupID = id }));
|
||||
Database.CompleteTransaction();
|
||||
db.BeginTransaction();
|
||||
db.Execute("delete from UserGroup where GroupId = @0", id);
|
||||
db.InsertBatch("UserGroup", userIds.Select(g => new { UserID = g, GroupID = id }));
|
||||
db.CompleteTransaction();
|
||||
ret = true;
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
Database.AbortTransaction();
|
||||
db.AbortTransaction();
|
||||
throw;
|
||||
}
|
||||
if (ret)
|
||||
|
@ -117,7 +142,11 @@ class UserService : IUser
|
|||
/// </summary>
|
||||
/// <param name="roleId"></param>
|
||||
/// <returns></returns>
|
||||
public List<string> GetUsersByRoleId(string? roleId) => CacheManager.GetOrAdd($"{UserServiceGetUsersByRoleIdCacheKey}-{roleId}", entry => Database.Fetch<string>("select UserID from UserRole where RoleID = @0", roleId));
|
||||
public List<string> GetUsersByRoleId(string? roleId) => CacheManager.GetOrAdd($"{UserServiceGetUsersByRoleIdCacheKey}-{roleId}", entry =>
|
||||
{
|
||||
using var db = DBManager.Create();
|
||||
return db.Fetch<string>("select UserID from UserRole where RoleID = @0", roleId);
|
||||
});
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
|
@ -128,17 +157,18 @@ class UserService : IUser
|
|||
public bool SaveUsersByRoleId(string? roleId, IEnumerable<string> userIds)
|
||||
{
|
||||
var ret = false;
|
||||
using var db = DBManager.Create();
|
||||
try
|
||||
{
|
||||
Database.BeginTransaction();
|
||||
Database.Execute("delete from UserRole where RoleID = @0", roleId);
|
||||
Database.InsertBatch("UserRole", userIds.Select(g => new { UserID = g, RoleID = roleId }));
|
||||
Database.CompleteTransaction();
|
||||
db.BeginTransaction();
|
||||
db.Execute("delete from UserRole where RoleID = @0", roleId);
|
||||
db.InsertBatch("UserRole", userIds.Select(g => new { UserID = g, RoleID = roleId }));
|
||||
db.CompleteTransaction();
|
||||
ret = true;
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
Database.AbortTransaction();
|
||||
db.AbortTransaction();
|
||||
throw;
|
||||
}
|
||||
if (ret)
|
||||
|
@ -157,12 +187,13 @@ class UserService : IUser
|
|||
public bool ChangePassword(string userName, string password, string newPassword)
|
||||
{
|
||||
var ret = false;
|
||||
using var db = DBManager.Create();
|
||||
if (Authenticate(userName, password))
|
||||
{
|
||||
var passSalt = LgbCryptography.GenerateSalt();
|
||||
password = LgbCryptography.ComputeHash(newPassword, passSalt);
|
||||
string sql = "set Password = @0, PassSalt = @1 where UserName = @2";
|
||||
ret = Database.Update<User>(sql, password, passSalt, userName) == 1;
|
||||
ret = db.Update<User>(sql, password, passSalt, userName) == 1;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
@ -172,7 +203,8 @@ class UserService : IUser
|
|||
/// </summary>
|
||||
public bool SaveDisplayName(string userName, string displayName)
|
||||
{
|
||||
var ret = Database.Update<User>("set DisplayName = @1 where UserName = @0", userName, displayName) == 1;
|
||||
using var db = DBManager.Create();
|
||||
var ret = db.Update<User>("set DisplayName = @1 where UserName = @0", userName, displayName) == 1;
|
||||
if (ret)
|
||||
{
|
||||
CacheManager.Clear();
|
||||
|
@ -185,7 +217,8 @@ class UserService : IUser
|
|||
/// </summary>
|
||||
public bool SaveTheme(string userName, string theme)
|
||||
{
|
||||
var ret = Database.Update<User>("set Css = @1 where UserName = @0", userName, theme) == 1;
|
||||
using var db = DBManager.Create();
|
||||
var ret = db.Update<User>("set Css = @1 where UserName = @0", userName, theme) == 1;
|
||||
if (ret)
|
||||
{
|
||||
CacheManager.Clear();
|
||||
|
@ -198,7 +231,8 @@ class UserService : IUser
|
|||
/// </summary>
|
||||
public bool SaveLogo(string userName, string? logo)
|
||||
{
|
||||
var ret = Database.Update<User>("set Icon = @1 where UserName = @0", userName, logo) == 1;
|
||||
using var db = DBManager.Create();
|
||||
var ret = db.Update<User>("set Icon = @1 where UserName = @0", userName, logo) == 1;
|
||||
if (ret)
|
||||
{
|
||||
CacheManager.Clear();
|
||||
|
@ -217,14 +251,15 @@ class UserService : IUser
|
|||
public bool TryCreateUserByPhone(string phone, string code, string appId, ICollection<string> roles)
|
||||
{
|
||||
var ret = false;
|
||||
using var db = DBManager.Create();
|
||||
try
|
||||
{
|
||||
var salt = LgbCryptography.GenerateSalt();
|
||||
var pwd = LgbCryptography.ComputeHash(code, salt);
|
||||
var user = Database.FirstOrDefault<User>("Where UserName = @0", phone);
|
||||
var user = db.FirstOrDefault<User>("Where UserName = @0", phone);
|
||||
if (user == null)
|
||||
{
|
||||
Database.BeginTransaction();
|
||||
db.BeginTransaction();
|
||||
// 插入用户
|
||||
user = new User()
|
||||
{
|
||||
|
@ -238,23 +273,23 @@ class UserService : IUser
|
|||
Password = LgbCryptography.ComputeHash(code, salt),
|
||||
App = appId
|
||||
};
|
||||
Database.Save(user);
|
||||
db.Save(user);
|
||||
// Authorization
|
||||
var roleIds = Database.Fetch<string>("select ID from Roles where RoleName in (@roles)", new { roles });
|
||||
Database.InsertBatch("UserRole", roleIds.Select(g => new { RoleID = g, UserID = user.Id }));
|
||||
Database.CompleteTransaction();
|
||||
var roleIds = db.Fetch<string>("select ID from Roles where RoleName in (@roles)", new { roles });
|
||||
db.InsertBatch("UserRole", roleIds.Select(g => new { RoleID = g, UserID = user.Id }));
|
||||
db.CompleteTransaction();
|
||||
}
|
||||
else
|
||||
{
|
||||
user.PassSalt = salt;
|
||||
user.Password = pwd;
|
||||
Database.Update(user);
|
||||
db.Update(user);
|
||||
}
|
||||
ret = true;
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
Database.AbortTransaction();
|
||||
db.AbortTransaction();
|
||||
throw;
|
||||
}
|
||||
if (ret)
|
||||
|
@ -268,14 +303,15 @@ class UserService : IUser
|
|||
{
|
||||
var salt = LgbCryptography.GenerateSalt();
|
||||
var pwd = LgbCryptography.ComputeHash(password, salt);
|
||||
var user = Database.FirstOrDefault<User>("Where UserName = @0", userName);
|
||||
using var db = DBManager.Create();
|
||||
var user = db.FirstOrDefault<User>("Where UserName = @0", userName);
|
||||
bool ret;
|
||||
if (user == null)
|
||||
{
|
||||
try
|
||||
{
|
||||
// 开始事务
|
||||
Database.BeginTransaction();
|
||||
db.BeginTransaction();
|
||||
user = new User()
|
||||
{
|
||||
ApprovedBy = "System",
|
||||
|
@ -287,16 +323,16 @@ class UserService : IUser
|
|||
PassSalt = salt,
|
||||
Password = pwd
|
||||
};
|
||||
Database.Save(user);
|
||||
db.Save(user);
|
||||
// 授权 Default 角色
|
||||
Database.Execute("insert into UserRole (UserID, RoleID) select ID, (select ID from Roles where RoleName = 'Default') RoleId from Users where UserName = @0", userName);
|
||||
db.Execute("insert into UserRole (UserID, RoleID) select ID, (select ID from Roles where RoleName = 'Default') RoleId from Users where UserName = @0", userName);
|
||||
// 结束事务
|
||||
Database.CompleteTransaction();
|
||||
db.CompleteTransaction();
|
||||
ret = true;
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
Database.AbortTransaction();
|
||||
db.AbortTransaction();
|
||||
throw;
|
||||
}
|
||||
}
|
||||
|
@ -305,7 +341,7 @@ class UserService : IUser
|
|||
user.DisplayName = displayName;
|
||||
user.PassSalt = salt;
|
||||
user.Password = pwd;
|
||||
Database.Update(user);
|
||||
db.Update(user);
|
||||
ret = true;
|
||||
}
|
||||
if (ret)
|
||||
|
@ -317,7 +353,8 @@ class UserService : IUser
|
|||
|
||||
public bool SaveApp(string userName, string app)
|
||||
{
|
||||
var ret = Database.Update<User>("Set App = @1 Where UserName = @0", userName, app) == 1;
|
||||
using var db = DBManager.Create();
|
||||
var ret = db.Update<User>("Set App = @1 Where UserName = @0", userName, app) == 1;
|
||||
if (ret)
|
||||
{
|
||||
CacheManager.Clear();
|
||||
|
|
Binary file not shown.
|
@ -2,7 +2,7 @@
|
|||
|
||||
<Table TItem="TItem" IsBordered="true" IsStriped="true" IsMultipleSelect="IsMultipleSelect" @ref="Instance"
|
||||
IsPagination="IsPagination" PageItemsSource="PageItemsSource" IsFixedHeader="IsFixedHeader"
|
||||
IsTree="IsTree" OnTreeExpand="OnTreeExpand!" TreeIcon="fa-chevron-circle-right"
|
||||
IsTree="IsTree" OnTreeExpand="OnTreeExpand!" TreeNodeConverter="TreeNodeConverter!" TreeIcon="fa-chevron-circle-right"
|
||||
ShowDefaultButtons="ShowDefaultButtons" ShowAdvancedSearch="ShowAdvancedSearch"
|
||||
ShowEmpty="ShowEmpty" EmptyText="暂无数据" EmptyImage="images/empty.svg" SortString="@SortString"
|
||||
OnQueryAsync="OnQueryAsync!" OnDeleteAsync="OnDeleteAsync!" OnSaveAsync="OnSaveAsync!"
|
||||
|
@ -10,7 +10,7 @@
|
|||
ShowToolbar="ShowToolbar" ShowExtendButtons="ShowExtendButtons" ShowAddButton="@AuthorizeButton("add")"
|
||||
ShowDeleteButton="@AuthorizeButton("del")" ShowEditButton="@AuthorizeButton("edit")"
|
||||
ShowCardView="true" ShowColumnList="true" ExtendButtonColumnWidth="@ExtendButtonColumnWidth"
|
||||
CustomerSearchModel="CustomerSearchModel" SelectedRows="SelectedRows"
|
||||
CustomerSearchModel="CustomerSearchModel" SelectedRows="SelectedRows" ModelEqualityComparer="ModelEqualityComparer!"
|
||||
ShowEditButtonCallback="ShowEditButtonCallback!" ShowDeleteButtonCallback="ShowDeleteButtonCallback!"
|
||||
TableToolbarTemplate="TableToolbarTemplate" TableColumns="TableColumns" EditTemplate="EditTemplate!"
|
||||
CustomerSearchTemplate="CustomerSearchTemplate!" RowButtonTemplate="RowButtonTemplate!">
|
||||
|
|
|
@ -145,7 +145,13 @@ namespace BootstrapAdmin.Web.Components
|
|||
///
|
||||
/// </summary>
|
||||
[Parameter]
|
||||
public Func<TItem, Task<IEnumerable<TItem>>>? OnTreeExpand { get; set; }
|
||||
public Func<TItem, Task<IEnumerable<TableTreeNode<TItem>>>>? OnTreeExpand { get; set; }
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
[Parameter]
|
||||
public Func<IEnumerable<TItem>, Task<IEnumerable<TableTreeNode<TItem>>>>? TreeNodeConverter { get; set; }
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
|
@ -177,6 +183,12 @@ namespace BootstrapAdmin.Web.Components
|
|||
[Parameter]
|
||||
public Func<TItem, bool>? ShowDeleteButtonCallback { get; set; }
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
[Parameter]
|
||||
public Func<TItem, TItem, bool>? ModelEqualityComparer { get; set; }
|
||||
|
||||
[NotNull]
|
||||
private Table<TItem>? Instance { get; set; }
|
||||
|
||||
|
|
|
@ -30,11 +30,9 @@
|
|||
<div class="col-12 col-sm-12">
|
||||
<BootstrapInput @bind-Value="Value.Favicon" placeholder="不可为空,2000字以内"></BootstrapInput>
|
||||
</div>
|
||||
<div class="col-12 col-sm-12">
|
||||
<div class="table-modal-footer text-end">
|
||||
<Button ButtonType="ButtonType.Button" Text="关闭" Icon="fa fa-close" Color="Color.Secondary" OnClick="OnClickClose"></Button>
|
||||
<Button ButtonType="ButtonType.Submit" Text="保存" Icon="fa fa-save"></Button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-footer">
|
||||
<Button ButtonType="ButtonType.Button" Text="关闭" Icon="fa fa-close" Color="Color.Secondary" OnClick="OnClickClose"></Button>
|
||||
<Button ButtonType="ButtonType.Submit" Text="保存" Icon="fa fa-save"></Button>
|
||||
</div>
|
||||
</ValidateForm>
|
||||
|
|
|
@ -60,13 +60,12 @@ public partial class ClientDialog
|
|||
}
|
||||
}
|
||||
|
||||
private Task OnSaveCleint(EditContext context)
|
||||
private async Task OnSaveCleint(EditContext context)
|
||||
{
|
||||
if (OnSave != null)
|
||||
{
|
||||
OnSave(Value);
|
||||
await OnSave(Value);
|
||||
}
|
||||
return Task.CompletedTask;
|
||||
}
|
||||
|
||||
private async Task OnClickClose()
|
||||
|
|
|
@ -3,8 +3,8 @@
|
|||
{
|
||||
var value = DictService.GetClientUrl(item.Value);
|
||||
<div class="col-12 col-sm-12">
|
||||
<BootstrapInputGroup>
|
||||
<BootstrapInputGroupLabel Text="@item.Key"></BootstrapInputGroupLabel>
|
||||
<BootstrapInputGroup @key="item.Key">
|
||||
<BootstrapInputGroupLabel DisplayText="@item.Key"></BootstrapInputGroupLabel>
|
||||
<BootstrapInput Value="value" Readonly="true"></BootstrapInput>
|
||||
<PopConfirmButton Placement="Placement.Top" Color="Color.Danger" Icon="fa fa-trash-o" ConfirmIcon="fa fa-exclamation-circle text-danger" ConfirmButtonColor="Color.Danger" Text="删除" Content="确定删除当前应用吗?" OnConfirm="() => OnDeleteClient(item.Value)" />
|
||||
<Button Icon="fa fa-edit" Text="编辑" OnClickWithoutRender="() => OnEditClient(item.Value)" />
|
||||
|
|
|
@ -73,13 +73,7 @@ namespace Microsoft.Extensions.DependencyInjection
|
|||
// });
|
||||
|
||||
// 增加 PetaPoco 数据服务
|
||||
services.AddPetaPocoDataAccessServices((provider, builder) =>
|
||||
{
|
||||
var configuration = provider.GetRequiredService<IConfiguration>();
|
||||
var connString = configuration.GetConnectionString("bb");
|
||||
builder.UsingProvider<SQLiteDatabaseProvider>()
|
||||
.UsingConnectionString(connString);
|
||||
});
|
||||
services.AddPetaPocoDataAccessServices();
|
||||
|
||||
return services;
|
||||
}
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
@page "/Admin/Menus"
|
||||
|
||||
<AdminTable TItem="DataAccess.Models.Navigation"
|
||||
IsTree="true" OnTreeExpand="OnTreeExpand" ExtendButtonColumnWidth="200"
|
||||
CustomerSearchModel="SearchModel" OnQueryAsync="OnQueryAsync">
|
||||
IsTree="true" OnTreeExpand="OnTreeExpand" TreeNodeConverter="TreeNodeConverter" ModelEqualityComparer="ModelEqualityComparer"
|
||||
ExtendButtonColumnWidth="200" CustomerSearchModel="SearchModel" OnQueryAsync="OnQueryAsync">
|
||||
<TableToolbarTemplate>
|
||||
<TableToolbarButton TItem="DataAccess.Models.Navigation" Color="Color.Info" Icon="fa fa-sitemap" Text="分配角色"
|
||||
IsEnableWhenSelectedOneRow="true" IsShow="@AuthorizeButton("assignRole")"
|
||||
|
|
|
@ -123,9 +123,30 @@ public partial class Menus
|
|||
});
|
||||
}
|
||||
|
||||
private Task<IEnumerable<Navigation>> OnTreeExpand(Navigation menu)
|
||||
private Task<IEnumerable<TableTreeNode<Navigation>>> OnTreeExpand(Navigation menu)
|
||||
{
|
||||
var navs = NavigationService.GetAllMenus(AppContext.UserName);
|
||||
return Task.FromResult(navs.Where(m => m.ParentId == menu.Id).OrderBy(m => m.Order).AsEnumerable());
|
||||
return Task.FromResult(navs.Where(m => m.ParentId == menu.Id).OrderBy(m => m.Order).AsEnumerable().Select(i => new TableTreeNode<Navigation>(i)));
|
||||
}
|
||||
|
||||
private Task<IEnumerable<TableTreeNode<Navigation>>> TreeNodeConverter(IEnumerable<Navigation> items)
|
||||
{
|
||||
var ret = BuildTreeNodes(items, "0");
|
||||
return Task.FromResult(ret);
|
||||
|
||||
IEnumerable<TableTreeNode<Navigation>> BuildTreeNodes(IEnumerable<Navigation> items, string parentId)
|
||||
{
|
||||
var navs = NavigationService.GetAllMenus(AppContext.UserName);
|
||||
var ret = new List<TableTreeNode<Navigation>>();
|
||||
ret.AddRange(items.Where(i => i.ParentId == parentId).Select((nav, index) => new TableTreeNode<Navigation>(nav)
|
||||
{
|
||||
HasChildren = navs.Any(i => i.ParentId == nav.Id),
|
||||
IsExpand = navs.Any(i => i.ParentId == nav.Id),
|
||||
Items = BuildTreeNodes(navs.Where(i => i.ParentId == nav.Id), nav.Id)
|
||||
}));
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
|
||||
private bool ModelEqualityComparer(Navigation x, Navigation y) => x.Id == y.Id;
|
||||
}
|
||||
|
|
|
@ -8,7 +8,7 @@
|
|||
}
|
||||
},
|
||||
"profiles": {
|
||||
"BootstrapAdmin.Web": {
|
||||
"Console": {
|
||||
"commandName": "Project",
|
||||
"dotnetRunMessages": true,
|
||||
"launchBrowser": true,
|
||||
|
|
|
@ -16,59 +16,9 @@
|
|||
}
|
||||
},
|
||||
"SimulateUserName": "",
|
||||
"AutoGenerateDatabase": true,
|
||||
"BootstrapAdminAuthenticationOptions": {
|
||||
"KeyPath": "..\\..\\keys"
|
||||
},
|
||||
"DB": [
|
||||
{
|
||||
"Enabled": false,
|
||||
"ProviderName": "SqlServer",
|
||||
"SqlFolder": "..\\..\\..\\db\\SqlServer",
|
||||
"ConnectionStrings": {
|
||||
"ba": "Data Source=.;Initial Catalog=BootstrapAdmin;User ID=sa;Password=sa"
|
||||
}
|
||||
},
|
||||
{
|
||||
"Enabled": true,
|
||||
"ProviderName": "Sqlite",
|
||||
"SqlFolder": "..\\..\\..\\db\\SQLite",
|
||||
"ConnectionStrings": {
|
||||
"ba": "Data Source=BootstrapAdmin.db;"
|
||||
}
|
||||
},
|
||||
{
|
||||
"Enabled": false,
|
||||
"ProviderName": "MySql",
|
||||
"SqlFolder": "..\\..\\..\\db\\MySQL",
|
||||
"ConnectionStrings": {
|
||||
"ba": "Server=localhost;Database=BA;Uid=argozhang;Pwd=argo@163.com;SslMode=none;"
|
||||
}
|
||||
},
|
||||
{
|
||||
"Enabled": false,
|
||||
"ProviderName": "Oracle",
|
||||
"ConnectionStrings": {
|
||||
"ba": "Data Source=(DESCRIPTION=(ADDRESS=(PROTOCOL=tcp)(HOST=XXXXXX)(PORT=1521))(CONNECT_DATA=(SERVICE_NAME=ORCL)));User Id=XX;Password=XX"
|
||||
}
|
||||
},
|
||||
{
|
||||
"Enabled": false,
|
||||
"ProviderName": "Npgsql",
|
||||
"ConnectionStrings": {
|
||||
"ba": "Server=localhost;Database=BootstrapAdmin;User ID=argozhang;Password=argo@163.com;"
|
||||
}
|
||||
},
|
||||
{
|
||||
"Enabled": false,
|
||||
"Widget": "Bootstrap.DataAccess.MongoDB",
|
||||
"ProviderName": "MongoDB",
|
||||
"SqlFolder": "..\\..\\..\\db\\MongoDB",
|
||||
"ConnectionStrings": {
|
||||
"ba": "mongodb://localhost:27017/BootstrapAdmin"
|
||||
}
|
||||
}
|
||||
],
|
||||
"SwaggerPathBase": "",
|
||||
"GiteeHealthChecks": "true",
|
||||
"AllowOrigins": "http://localhost:49185",
|
||||
|
@ -157,194 +107,5 @@
|
|||
"第二层",
|
||||
"第三层",
|
||||
"第四层"
|
||||
],
|
||||
"LongbowCache": {
|
||||
"Enabled": true,
|
||||
"CorsItems": [
|
||||
{
|
||||
"Enabled": true,
|
||||
"Key": "ba",
|
||||
"Url": "CacheList.axd",
|
||||
"Desc": "后台管理数据缓存接口",
|
||||
"Self": true
|
||||
},
|
||||
{
|
||||
"Enabled": true,
|
||||
"Key": "App",
|
||||
"Url": "http://localhost:49185/CacheList.axd",
|
||||
"Desc": "测试系统",
|
||||
"Self": false
|
||||
}
|
||||
],
|
||||
"CacheItems": [
|
||||
{
|
||||
"Enabled": true,
|
||||
"Key": "RoleHelper-RetrieveRolesByUserName",
|
||||
"Interval": 600000,
|
||||
"SlidingExpiration": true,
|
||||
"Desc": "指定用户角色数据缓存"
|
||||
},
|
||||
{
|
||||
"Enabled": true,
|
||||
"Key": "RoleHelper-RetrieveRolesByUrl",
|
||||
"Interval": 600000,
|
||||
"SlidingExpiration": true,
|
||||
"Desc": "通过菜单获得角色数据"
|
||||
},
|
||||
{
|
||||
"Enabled": true,
|
||||
"Key": "AppHelper-RetrieveAppsByUserName",
|
||||
"Interval": 600000,
|
||||
"SlidingExpiration": true,
|
||||
"Desc": "指定用户授权应用数据缓存"
|
||||
},
|
||||
{
|
||||
"Enabled": true,
|
||||
"Key": "BootstrapUser-RetrieveUsersByName",
|
||||
"Interval": 600000,
|
||||
"SlidingExpiration": true,
|
||||
"Desc": "登录用户数据"
|
||||
},
|
||||
{
|
||||
"Enabled": true,
|
||||
"Key": "BootstrapDict-RetrieveDicts",
|
||||
"Interval": 600000,
|
||||
"SlidingExpiration": true,
|
||||
"Desc": "所有字典数据缓存"
|
||||
},
|
||||
{
|
||||
"Enabled": true,
|
||||
"Key": "BootstrapMenu-RetrieveMenus",
|
||||
"Interval": 600000,
|
||||
"SlidingExpiration": true,
|
||||
"Desc": "用户所有菜单数据缓存"
|
||||
},
|
||||
{
|
||||
"Enabled": true,
|
||||
"Key": "GroupHelper-RetrieveGroupsByUserName",
|
||||
"Interval": 600000,
|
||||
"SlidingExpiration": true,
|
||||
"Desc": "指定用户组数据缓存"
|
||||
},
|
||||
{
|
||||
"Enabled": true,
|
||||
"Key": "UserHelper-RetrieveUsers",
|
||||
"Interval": 600000,
|
||||
"SlidingExpiration": true,
|
||||
"Desc": "所有用户数据"
|
||||
},
|
||||
{
|
||||
"Enabled": true,
|
||||
"Key": "UserHelper-RetrieveUsersByRoleId",
|
||||
"Interval": 600000,
|
||||
"SlidingExpiration": true,
|
||||
"Desc": "通过角色ID获得所有用户数据"
|
||||
},
|
||||
{
|
||||
"Enabled": true,
|
||||
"Key": "UserHelper-RetrieveUsersByGroupId",
|
||||
"Interval": 600000,
|
||||
"SlidingExpiration": true,
|
||||
"Desc": "通过部门ID获得所有用户数据"
|
||||
},
|
||||
{
|
||||
"Enabled": true,
|
||||
"Key": "UserHelper-RetrieveNewUsers",
|
||||
"Interval": 600000,
|
||||
"SlidingExpiration": true,
|
||||
"Desc": "新用户数据"
|
||||
},
|
||||
{
|
||||
"Enabled": true,
|
||||
"Key": "MenuHelper-RetrieveMenusByRoleId",
|
||||
"Interval": 600000,
|
||||
"SlidingExpiration": true,
|
||||
"Desc": "通过角色ID获得所有菜单数据"
|
||||
},
|
||||
{
|
||||
"Enabled": true,
|
||||
"Key": "RoleHelper-RetrieveRoles",
|
||||
"Interval": 600000,
|
||||
"SlidingExpiration": true,
|
||||
"Desc": "所有角色数据"
|
||||
},
|
||||
{
|
||||
"Enabled": true,
|
||||
"Key": "RoleHelper-RetrieveRolesByUserId",
|
||||
"Interval": 600000,
|
||||
"SlidingExpiration": true,
|
||||
"Desc": "通过用户ID获得所有角色数据"
|
||||
},
|
||||
{
|
||||
"Enabled": true,
|
||||
"Key": "RoleHelper-RetrieveRolesByMenuId",
|
||||
"Interval": 600000,
|
||||
"SlidingExpiration": true,
|
||||
"Desc": "通过菜单ID获得所有角色数据"
|
||||
},
|
||||
{
|
||||
"Enabled": true,
|
||||
"Key": "RoleHelper-RetrieveRolesByGroupId",
|
||||
"Interval": 600000,
|
||||
"SlidingExpiration": true,
|
||||
"Desc": "通过部门ID获得所有角色数据"
|
||||
},
|
||||
{
|
||||
"Enabled": true,
|
||||
"Key": "GroupHelper-RetrieveGroups",
|
||||
"Interval": 600000,
|
||||
"SlidingExpiration": true,
|
||||
"Desc": "所有部门数据"
|
||||
},
|
||||
{
|
||||
"Enabled": true,
|
||||
"Key": "GroupHelper-RetrieveGroupsByUserId",
|
||||
"Interval": 600000,
|
||||
"SlidingExpiration": true,
|
||||
"Desc": "通过用户ID获得所有部门数据"
|
||||
},
|
||||
{
|
||||
"Enabled": true,
|
||||
"Key": "GroupHelper-RetrieveGroupsByRoleId",
|
||||
"Interval": 600000,
|
||||
"SlidingExpiration": true,
|
||||
"Desc": "通过角色ID获得所有部门数据"
|
||||
},
|
||||
{
|
||||
"Enabled": true,
|
||||
"Key": "AppHelper-RetrieveAppsByRoleId",
|
||||
"Interval": 600000,
|
||||
"SlidingExpiration": true,
|
||||
"Desc": "通过角色ID获得所有应用程序数据"
|
||||
},
|
||||
{
|
||||
"Enabled": true,
|
||||
"Key": "DictHelper-RetrieveDictsCategory",
|
||||
"Interval": 600000,
|
||||
"SlidingExpiration": true,
|
||||
"Desc": "字典分类数据"
|
||||
},
|
||||
{
|
||||
"Enabled": true,
|
||||
"Key": "ExceptionHelper-RetrieveExceptions",
|
||||
"Interval": 600000,
|
||||
"SlidingExpiration": true,
|
||||
"Desc": "程序异常数据"
|
||||
},
|
||||
{
|
||||
"Enabled": true,
|
||||
"Key": "MessageHelper-RetrieveMessages",
|
||||
"Interval": 600000,
|
||||
"SlidingExpiration": true,
|
||||
"Desc": "站内消息数据"
|
||||
},
|
||||
{
|
||||
"Enabled": true,
|
||||
"Key": "TaskHelper-RetrieveTasks",
|
||||
"Interval": 600000,
|
||||
"SlidingExpiration": true,
|
||||
"Desc": "所有任务数据"
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
|
@ -20,51 +20,9 @@
|
|||
}
|
||||
},
|
||||
"ConnectionStrings": {
|
||||
"ba": "Data Source=.;Initial Catalog=BootstrapAdmin;User ID=sa;Password=sa",
|
||||
"bb": "Data Source=BootstrapAdmin.db;"
|
||||
"ba": "Data Source=BootstrapAdmin.db;"
|
||||
},
|
||||
"AutoGenerateDatabase": false,
|
||||
"DB": [
|
||||
{
|
||||
"Enabled": false,
|
||||
"ProviderName": "SqlServer",
|
||||
"ConnectionStrings": {
|
||||
"ba": "Data Source=.;Initial Catalog=BootstrapAdmin;User ID=sa;Password=sa"
|
||||
}
|
||||
},
|
||||
{
|
||||
"Enabled": true,
|
||||
"ProviderName": "Sqlite",
|
||||
"ConnectionStrings": {
|
||||
"ba": "Data Source=BootstrapAdmin.db;"
|
||||
}
|
||||
},
|
||||
{
|
||||
"Enabled": false,
|
||||
"ProviderName": "MySql",
|
||||
"ConnectionStrings": {
|
||||
"ba": "Server=localhost;Database=BA;Uid=argozhang;Pwd=argo@163.com;SslMode=none;"
|
||||
}
|
||||
},
|
||||
{
|
||||
"Enabled": false,
|
||||
"ProviderName": "Npgsql",
|
||||
"ConnectionStrings": {
|
||||
"ba": "Server=localhost;Database=BootstrapAdmin;User ID=argozhang;Password=argo@163.com;"
|
||||
}
|
||||
},
|
||||
{
|
||||
"Enabled": false,
|
||||
"Widget": "Bootstrap.DataAccess.MongoDB",
|
||||
"ProviderName": "MongoDB",
|
||||
"ConnectionStrings": {
|
||||
"ba": "mongodb://localhost:27017/BootstrapAdmin"
|
||||
}
|
||||
}
|
||||
],
|
||||
"AppId": "BA",
|
||||
"UseHttps": true,
|
||||
"SwaggerPathBase": "",
|
||||
"AllowOrigins": "http://localhost,http://admin.blazor.zone",
|
||||
"HealthsCloudUrl": "https://client.blazor.zone/api/Interface/Healths",
|
||||
"GiteeHealthChecks": false,
|
||||
|
|
|
@ -1,9 +1,9 @@
|
|||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="BootstrapBlazor" Version="6.*" />
|
||||
<PackageReference Include="Longbow.Security.Cryptography" Version="5.2.0" />
|
||||
<PackageReference Include="Microsoft.Data.Sqlite" Version="6.0.1" />
|
||||
<PackageReference Include="BootstrapBlazor" Version="6.8.13" />
|
||||
<PackageReference Include="Longbow.Security.Cryptography" Version="6.0.0" />
|
||||
<PackageReference Include="Microsoft.Data.Sqlite" Version="6.0.7" />
|
||||
<PackageReference Include="PetaPoco.Extensions" Version="6.0.0" />
|
||||
</ItemGroup>
|
||||
|
||||
|
|
|
@ -26,56 +26,19 @@ public static class ServiceCollectionExtensions
|
|||
///
|
||||
/// </summary>
|
||||
/// <param name="services"></param>
|
||||
/// <param name="builder"></param>
|
||||
/// <returns></returns>
|
||||
public static IServiceCollection AddPetaPocoDataAccessServices(this IServiceCollection services, Action<IServiceProvider, IDatabaseBuildConfiguration> builder)
|
||||
public static IServiceCollection AddPetaPocoDataAccessServices(this IServiceCollection services)
|
||||
{
|
||||
services.TryAddSingleton<IDatabase>(provider =>
|
||||
{
|
||||
var option = DatabaseConfiguration.Build();
|
||||
builder(provider, option);
|
||||
option.UsingDefaultMapper<BootstrapAdminConventionMapper>();
|
||||
var db = new Database(option);
|
||||
// 增加多数据库支持服务
|
||||
services.TryAddSingleton<IDBManager, DBManagerService>();
|
||||
|
||||
var logger = provider.GetRequiredService<ILogger<Database>>();
|
||||
db.ExceptionThrown += (sender, e) =>
|
||||
{
|
||||
var message = e.Exception.Format(new NameValueCollection()
|
||||
{
|
||||
[nameof(db.LastCommand)] = db.LastCommand,
|
||||
[nameof(db.LastArgs)] = string.Join(",", db.LastArgs)
|
||||
});
|
||||
logger.LogError(new EventId(1001, "GlobalException"), e.Exception, message);
|
||||
};
|
||||
var env = provider.GetRequiredService<IWebHostEnvironment>();
|
||||
if (env.IsDevelopment())
|
||||
{
|
||||
db.CommandExecuted += (sender, args) =>
|
||||
{
|
||||
var parameters = new StringBuilder();
|
||||
foreach (DbParameter p in args.Command.Parameters)
|
||||
{
|
||||
parameters.AppendFormat("{0}: {1} ", p.ParameterName, p.Value);
|
||||
}
|
||||
logger.LogInformation(args.Command.CommandText);
|
||||
logger.LogInformation(parameters.ToString());
|
||||
};
|
||||
};
|
||||
return db;
|
||||
});
|
||||
|
||||
//// 增加数据服务
|
||||
//services.AddSingleton(typeof(IDataService<>), typeof(DefaultDataService<>));
|
||||
|
||||
//// 增加业务服务
|
||||
//services.AddSingleton<IApp, AppService>();
|
||||
// 增加业务服务
|
||||
services.AddSingleton<IDict, DictService>();
|
||||
//services.AddSingleton<IException, ExceptionService>();
|
||||
//services.AddSingleton<IGroup, GroupService>();
|
||||
//services.AddSingleton<ILogin, LoginService>();
|
||||
services.AddSingleton<INavigation, NavigationService>();
|
||||
//services.AddSingleton<IRole, RoleService>();
|
||||
services.AddSingleton<IUser, UserService>();
|
||||
|
||||
// 增加示例数据服务
|
||||
services.AddSingleton<IDummy, DummyService>();
|
||||
return services;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,78 @@
|
|||
// Copyright (c) Argo Zhang (argo@163.com). All rights reserved.
|
||||
// Licensed under the LGPL License, Version 3.0. See License.txt in the project root for license information.
|
||||
// Website: https://admin.blazor.zone
|
||||
|
||||
using BootstrapBlazor.Components;
|
||||
using Microsoft.AspNetCore.Hosting;
|
||||
using Microsoft.Extensions.Configuration;
|
||||
using Microsoft.Extensions.Hosting;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using PetaPoco;
|
||||
using PetaPoco.Providers;
|
||||
using System.Collections.Specialized;
|
||||
using System.Data.Common;
|
||||
using System.Text;
|
||||
|
||||
namespace BootstrapClient.DataAccess.PetaPoco.Services;
|
||||
|
||||
internal class DBManagerService : IDBManager
|
||||
{
|
||||
private IConfiguration Configuration { get; set; }
|
||||
|
||||
private ILogger<DBManagerService> Logger { get; set; }
|
||||
|
||||
private IWebHostEnvironment WebHost { get; set; }
|
||||
|
||||
public DBManagerService(IConfiguration configuration, ILogger<DBManagerService> logger, IWebHostEnvironment host)
|
||||
{
|
||||
Configuration = configuration;
|
||||
Logger = logger;
|
||||
WebHost = host;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 创建 IDatabase 实例方法
|
||||
/// </summary>
|
||||
/// <param name="connectionName">连接字符串键值</param>
|
||||
/// <param name="keepAlive"></param>
|
||||
/// <returns></returns>
|
||||
public IDatabase Create(string? connectionName = "ba", bool keepAlive = false)
|
||||
{
|
||||
var conn = Configuration.GetConnectionString(connectionName) ?? throw new ArgumentNullException(nameof(connectionName));
|
||||
|
||||
var option = DatabaseConfiguration.Build();
|
||||
option.UsingDefaultMapper<BootstrapAdminConventionMapper>();
|
||||
|
||||
// connectionstring
|
||||
option.UsingConnectionString(conn);
|
||||
|
||||
// provider
|
||||
option.UsingProvider<SQLiteDatabaseProvider>();
|
||||
|
||||
var db = new Database(option) { KeepConnectionAlive = keepAlive };
|
||||
|
||||
db.ExceptionThrown += (sender, e) =>
|
||||
{
|
||||
var message = e.Exception.Format(new NameValueCollection()
|
||||
{
|
||||
[nameof(db.LastCommand)] = db.LastCommand,
|
||||
[nameof(db.LastArgs)] = string.Join(",", db.LastArgs)
|
||||
});
|
||||
Logger.LogError(new EventId(1001, "GlobalException"), e.Exception, message);
|
||||
};
|
||||
if (WebHost.IsDevelopment())
|
||||
{
|
||||
db.CommandExecuted += (sender, args) =>
|
||||
{
|
||||
var parameters = new StringBuilder();
|
||||
foreach (DbParameter p in args.Command.Parameters)
|
||||
{
|
||||
parameters.AppendFormat("{0}: {1} ", p.ParameterName, p.Value);
|
||||
}
|
||||
Logger.LogInformation(args.Command.CommandText);
|
||||
Logger.LogInformation(parameters.ToString());
|
||||
};
|
||||
};
|
||||
return db;
|
||||
}
|
||||
}
|
|
@ -10,15 +10,19 @@ namespace BootstrapClient.DataAccess.PetaPoco.Services;
|
|||
|
||||
class DictService : IDict
|
||||
{
|
||||
private IDatabase Database { get; }
|
||||
private IDBManager DBManager { get; }
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
/// <param name="db"></param>
|
||||
public DictService(IDatabase db) => Database = db;
|
||||
public DictService(IDBManager db) => DBManager = db;
|
||||
|
||||
public List<Dict> GetAll() => Database.Fetch<Dict>();
|
||||
public List<Dict> GetAll()
|
||||
{
|
||||
using var db = DBManager.Create();
|
||||
return db.Fetch<Dict>();
|
||||
}
|
||||
|
||||
public bool IsDemo()
|
||||
{
|
||||
|
|
|
@ -0,0 +1,36 @@
|
|||
// Copyright (c) Argo Zhang (argo@163.com). All rights reserved.
|
||||
// Licensed under the LGPL License, Version 3.0. See License.txt in the project root for license information.
|
||||
// Website: https://admin.blazor.zone
|
||||
|
||||
using BootstrapClient.DataAccess.Models;
|
||||
using BootstrapClient.Web.Core;
|
||||
using PetaPoco;
|
||||
|
||||
namespace BootstrapClient.DataAccess.PetaPoco.Services;
|
||||
|
||||
internal class DummyService : IDummy
|
||||
{
|
||||
private IDBManager DBManager { get; }
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
/// <param name="db"></param>
|
||||
public DummyService(IDBManager db)
|
||||
{
|
||||
DBManager = db;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public List<DummyEntity> GetAll()
|
||||
{
|
||||
return new List<DummyEntity>()
|
||||
{
|
||||
new() { Id= "1", Name ="Dummy1" },
|
||||
new() { Id= "2", Name ="Dummy2" }
|
||||
};
|
||||
}
|
||||
}
|
|
@ -0,0 +1,19 @@
|
|||
// Copyright (c) Argo Zhang (argo@163.com). All rights reserved.
|
||||
// Licensed under the LGPL License, Version 3.0. See License.txt in the project root for license information.
|
||||
// Website: https://admin.blazor.zone
|
||||
|
||||
using PetaPoco;
|
||||
|
||||
namespace BootstrapClient.DataAccess.PetaPoco.Services;
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public interface IDBManager
|
||||
{
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
IDatabase Create(string? connectionName = "ba", bool keepAlive = false);
|
||||
}
|
|
@ -13,13 +13,13 @@ namespace BootstrapClient.DataAccess.PetaPoco.Services;
|
|||
/// </summary>
|
||||
class NavigationService : INavigation
|
||||
{
|
||||
private IDatabase Database { get; }
|
||||
private IDBManager DBManager { get; }
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
/// <param name="db"></param>
|
||||
public NavigationService(IDatabase db) => Database = db;
|
||||
public NavigationService(IDBManager db) => DBManager = db;
|
||||
|
||||
/// <summary>
|
||||
/// 获得指定用户名可访问的所有菜单集合
|
||||
|
@ -28,7 +28,8 @@ class NavigationService : INavigation
|
|||
/// <returns>未层次化的菜单集合</returns>
|
||||
public List<Navigation> GetMenus(string userName)
|
||||
{
|
||||
var order = Database.Provider.EscapeSqlIdentifier("Order");
|
||||
return Database.Fetch<Navigation>($"select n.ID, n.ParentId, n.Name, n.{order}, n.Icon, n.Url, n.Category, n.Target, n.IsResource, n.Application from Navigations n inner join (select nr.NavigationID from Users u inner join UserRole ur on ur.UserID = u.ID inner join NavigationRole nr on nr.RoleID = ur.RoleID where u.UserName = @UserName union select nr.NavigationID from Users u inner join UserGroup ug on u.ID = ug.UserID inner join RoleGroup rg on rg.GroupID = ug.GroupID inner join NavigationRole nr on nr.RoleID = rg.RoleID where u.UserName = @UserName union select n.ID from Navigations n where EXISTS (select UserName from Users u inner join UserRole ur on u.ID = ur.UserID inner join Roles r on ur.RoleID = r.ID where u.UserName = @UserName and r.RoleName = 'Administrators')) nav on n.ID = nav.NavigationID Where n.Category = '1' ORDER BY n.Application, n.{order}", new { UserName = userName });
|
||||
using var db = DBManager.Create ();
|
||||
var order = db.Provider.EscapeSqlIdentifier("Order");
|
||||
return db.Fetch<Navigation>($"select n.ID, n.ParentId, n.Name, n.{order}, n.Icon, n.Url, n.Category, n.Target, n.IsResource, n.Application from Navigations n inner join (select nr.NavigationID from Users u inner join UserRole ur on ur.UserID = u.ID inner join NavigationRole nr on nr.RoleID = ur.RoleID where u.UserName = @UserName union select nr.NavigationID from Users u inner join UserGroup ug on u.ID = ug.UserID inner join RoleGroup rg on rg.GroupID = ug.GroupID inner join NavigationRole nr on nr.RoleID = rg.RoleID where u.UserName = @UserName union select n.ID from Navigations n where EXISTS (select UserName from Users u inner join UserRole ur on u.ID = ur.UserID inner join Roles r on ur.RoleID = r.ID where u.UserName = @UserName and r.RoleName = 'Administrators')) nav on n.ID = nav.NavigationID Where n.Category = '1' ORDER BY n.Application, n.{order}", new { UserName = userName });
|
||||
}
|
||||
}
|
||||
|
|
|
@ -10,32 +10,49 @@ namespace BootstrapClient.DataAccess.PetaPoco.Services;
|
|||
|
||||
class UserService : IUser
|
||||
{
|
||||
private IDatabase Database { get; }
|
||||
private IDBManager DBManager { get; }
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
/// <param name="db"></param>
|
||||
public UserService(IDatabase db) => Database = db;
|
||||
public UserService(IDBManager db) => DBManager = db;
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
/// <param name="userName"></param>
|
||||
/// <returns></returns>
|
||||
public User? GetUserByUserName(string? userName) => string.IsNullOrEmpty(userName) ? null : Database.FirstOrDefault<User>("Where UserName = @0", userName);
|
||||
public User? GetUserByUserName(string? userName)
|
||||
{
|
||||
User? user = null;
|
||||
if (!string.IsNullOrEmpty(userName))
|
||||
{
|
||||
using var db = DBManager.Create();
|
||||
user = db.FirstOrDefault<User>("Where UserName = @0", userName);
|
||||
}
|
||||
return user;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
/// <param name="userName"></param>
|
||||
/// <returns></returns>
|
||||
public List<string> GetApps(string userName) => Database.Fetch<string>($"select d.Code from Dicts d inner join RoleApp ra on d.Code = ra.AppId inner join (select r.Id from Roles r inner join UserRole ur on r.ID = ur.RoleID inner join Users u on ur.UserID = u.ID where u.UserName = @0 union select r.Id from Roles r inner join RoleGroup rg on r.ID = rg.RoleID inner join {Database.Provider.EscapeSqlIdentifier("Groups")} g on rg.GroupID = g.ID inner join UserGroup ug on ug.GroupID = g.ID inner join Users u on ug.UserID = u.ID where u.UserName = @0) r on ra.RoleId = r.ID union select Code from Dicts where Category = @1 and exists(select r.ID from Roles r inner join UserRole ur on r.ID = ur.RoleID inner join Users u on ur.UserID = u.ID where u.UserName = @0 and r.RoleName = @2 union select r.ID from Roles r inner join RoleGroup rg on r.ID = rg.RoleID inner join {Database.Provider.EscapeSqlIdentifier("Groups")} g on rg.GroupID = g.ID inner join UserGroup ug on ug.GroupID = g.ID inner join Users u on ug.UserID = u.ID where u.UserName = @0 and r.RoleName = @2)", userName, "应用程序", "Administrators");
|
||||
public List<string> GetApps(string userName)
|
||||
{
|
||||
using var db = DBManager.Create();
|
||||
return db.Fetch<string>($"select d.Code from Dicts d inner join RoleApp ra on d.Code = ra.AppId inner join (select r.Id from Roles r inner join UserRole ur on r.ID = ur.RoleID inner join Users u on ur.UserID = u.ID where u.UserName = @0 union select r.Id from Roles r inner join RoleGroup rg on r.ID = rg.RoleID inner join {db.Provider.EscapeSqlIdentifier("Groups")} g on rg.GroupID = g.ID inner join UserGroup ug on ug.GroupID = g.ID inner join Users u on ug.UserID = u.ID where u.UserName = @0) r on ra.RoleId = r.ID union select Code from Dicts where Category = @1 and exists(select r.ID from Roles r inner join UserRole ur on r.ID = ur.RoleID inner join Users u on ur.UserID = u.ID where u.UserName = @0 and r.RoleName = @2 union select r.ID from Roles r inner join RoleGroup rg on r.ID = rg.RoleID inner join {db.Provider.EscapeSqlIdentifier("Groups")} g on rg.GroupID = g.ID inner join UserGroup ug on ug.GroupID = g.ID inner join Users u on ug.UserID = u.ID where u.UserName = @0 and r.RoleName = @2)", userName, "应用程序", "Administrators");
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
/// <param name="userName"></param>
|
||||
/// <returns></returns>
|
||||
public List<string> GetRoles(string userName) => Database.Fetch<string>($"select r.RoleName from Roles r inner join UserRole ur on r.ID=ur.RoleID inner join Users u on ur.UserID = u.ID and u.UserName = @0 union select r.RoleName from Roles r inner join RoleGroup rg on r.ID = rg.RoleID inner join {Database.Provider.EscapeSqlIdentifier("Groups")} g on rg.GroupID = g.ID inner join UserGroup ug on ug.GroupID = g.ID inner join Users u on ug.UserID = u.ID and u.UserName=@0", userName);
|
||||
public List<string> GetRoles(string userName)
|
||||
{
|
||||
using var db = DBManager.Create();
|
||||
return db.Fetch<string>($"select r.RoleName from Roles r inner join UserRole ur on r.ID=ur.RoleID inner join Users u on ur.UserID = u.ID and u.UserName = @0 union select r.RoleName from Roles r inner join RoleGroup rg on r.ID = rg.RoleID inner join {db.Provider.EscapeSqlIdentifier("Groups")} g on rg.GroupID = g.ID inner join UserGroup ug on ug.GroupID = g.ID inner join Users u on ug.UserID = u.ID and u.UserName=@0", userName);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -5,8 +5,8 @@
|
|||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Microsoft.AspNetCore.Components.Authorization" Version="6.0.1" />
|
||||
<PackageReference Include="Microsoft.AspNetCore.Components.Web" Version="6.0.1" />
|
||||
<PackageReference Include="Microsoft.AspNetCore.Components.Authorization" Version="6.0.7" />
|
||||
<PackageReference Include="Microsoft.AspNetCore.Components.Web" Version="6.0.7" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
|
|
|
@ -0,0 +1,17 @@
|
|||
@typeparam TItem
|
||||
|
||||
<Table TItem="TItem" IsBordered="true" IsStriped="true" IsMultipleSelect="IsMultipleSelect" @ref="Instance"
|
||||
IsPagination="IsPagination" PageItemsSource="PageItemsSource" IsFixedHeader="IsFixedHeader"
|
||||
IsTree="IsTree" OnTreeExpand="OnTreeExpand!" TreeNodeConverter="TreeNodeConverter!" TreeIcon="fa-chevron-circle-right"
|
||||
ShowDefaultButtons="ShowDefaultButtons" ShowAdvancedSearch="ShowAdvancedSearch"
|
||||
ShowEmpty="ShowEmpty" EmptyText="暂无数据" EmptyImage="images/empty.svg" SortString="@SortString"
|
||||
OnQueryAsync="OnQueryAsync!" OnDeleteAsync="OnDeleteAsync!" OnSaveAsync="OnSaveAsync!"
|
||||
ShowSkeleton="true" ShowLoading="ShowLoading" ShowSearch="ShowSearch"
|
||||
ShowToolbar="ShowToolbar" ShowExtendButtons="ShowExtendButtons" ShowAddButton="@AuthorizeButton("add")"
|
||||
ShowDeleteButton="@AuthorizeButton("del")" ShowEditButton="@AuthorizeButton("edit")"
|
||||
ShowCardView="true" ShowColumnList="true" ExtendButtonColumnWidth="@ExtendButtonColumnWidth"
|
||||
CustomerSearchModel="CustomerSearchModel" SelectedRows="SelectedRows"
|
||||
ShowEditButtonCallback="ShowEditButtonCallback!" ShowDeleteButtonCallback="ShowDeleteButtonCallback!"
|
||||
TableToolbarTemplate="TableToolbarTemplate" TableColumns="TableColumns" EditTemplate="EditTemplate!"
|
||||
CustomerSearchTemplate="CustomerSearchTemplate!" RowButtonTemplate="RowButtonTemplate!">
|
||||
</Table>
|
|
@ -0,0 +1,222 @@
|
|||
// Copyright (c) Argo Zhang (argo@163.com). All rights reserved.
|
||||
// Licensed under the LGPL License, Version 3.0. See License.txt in the project root for license information.
|
||||
// Website: https://admin.blazor.zone
|
||||
|
||||
using Bootstrap.Security.Blazor;
|
||||
using BootstrapClient.Web.Shared.Services;
|
||||
|
||||
namespace BootstrapClient.Web.Shared.Components
|
||||
{
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
[CascadingTypeParameter(nameof(TItem))]
|
||||
public partial class AdminTable<TItem> where TItem : class, new()
|
||||
{
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
[Parameter]
|
||||
public IEnumerable<int>? PageItemsSource { get; set; }
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
[Parameter]
|
||||
public int ExtendButtonColumnWidth { get; set; } = 130;
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
[Parameter]
|
||||
public string? SortString { get; set; }
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
[NotNull]
|
||||
[Parameter]
|
||||
public RenderFragment<TItem>? TableColumns { get; set; }
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
[Parameter]
|
||||
public RenderFragment<TItem>? RowButtonTemplate { get; set; }
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
[Parameter]
|
||||
public RenderFragment<ITableSearchModel>? CustomerSearchTemplate { get; set; }
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
[Parameter]
|
||||
public RenderFragment<TItem>? EditTemplate { get; set; }
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
[NotNull]
|
||||
[Parameter]
|
||||
public RenderFragment? TableToolbarTemplate { get; set; }
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
[Parameter]
|
||||
public bool IsPagination { get; set; }
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
[Parameter]
|
||||
public bool IsMultipleSelect { get; set; } = true;
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
[Parameter]
|
||||
public bool IsFixedHeader { get; set; } = true;
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
[Parameter]
|
||||
public bool IsTree { get; set; }
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
[Parameter]
|
||||
public bool ShowToolbar { get; set; } = true;
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
[Parameter]
|
||||
public bool ShowEmpty { get; set; } = true;
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
[Parameter]
|
||||
public bool ShowLoading { get; set; } = false;
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
[Parameter]
|
||||
public bool ShowSearch { get; set; } = true;
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
[Parameter]
|
||||
public bool ShowAdvancedSearch { get; set; } = true;
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
[Parameter]
|
||||
public bool ShowDefaultButtons { get; set; } = true;
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
[Parameter]
|
||||
public bool ShowExtendButtons { get; set; } = true;
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
[Parameter]
|
||||
public ITableSearchModel? CustomerSearchModel { get; set; }
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
[Parameter]
|
||||
public Func<QueryPageOptions, Task<QueryData<TItem>>>? OnQueryAsync { get; set; }
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
[Parameter]
|
||||
public Func<TItem, Task<IEnumerable<TableTreeNode<TItem>>>>? OnTreeExpand { get; set; }
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
[Parameter]
|
||||
public Func<IEnumerable<TItem>, Task<IEnumerable<TableTreeNode<TItem>>>>? TreeNodeConverter { get; set; }
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
[Parameter]
|
||||
public Func<TItem, ItemChangedType, Task<bool>>? OnSaveAsync { get; set; }
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
[Parameter]
|
||||
public Func<IEnumerable<TItem>, Task<bool>>? OnDeleteAsync { get; set; }
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
[Parameter]
|
||||
public List<TItem>? SelectedRows { get; set; } = new List<TItem>();
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
[Parameter]
|
||||
public Func<TItem, bool>? ShowEditButtonCallback { get; set; }
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
[Parameter]
|
||||
public Func<TItem, bool>? ShowDeleteButtonCallback { get; set; }
|
||||
|
||||
[NotNull]
|
||||
private Table<TItem>? Instance { get; set; }
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
/// <param name="v"></param>
|
||||
/// <returns></returns>
|
||||
/// <exception cref="NotImplementedException"></exception>
|
||||
public ValueTask ToggleLoading(bool v) => Instance.ToggleLoading(v);
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
/// <exception cref="NotImplementedException"></exception>
|
||||
public Task QueryAsync() => Instance.QueryAsync();
|
||||
|
||||
[Inject]
|
||||
[NotNull]
|
||||
private IBootstrapAdminService? AdminService { get; set; }
|
||||
|
||||
[Inject]
|
||||
[NotNull]
|
||||
private NavigationManager? NavigationManager { get; set; }
|
||||
|
||||
[Inject]
|
||||
[NotNull]
|
||||
private BootstrapAppContext? AppContext { get; set; }
|
||||
|
||||
private bool AuthorizeButton(string operate)
|
||||
{
|
||||
var url = NavigationManager.ToBaseRelativePath(NavigationManager.Uri);
|
||||
return AdminService.AuhorizingBlock(AppContext.UserName, url, operate);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,9 @@
|
|||
@using BootstrapClient.Web.Shared.Components
|
||||
@page "/dummy"
|
||||
|
||||
<AdminTable TItem="BootstrapClient.DataAccess.Models.DummyEntity" OnQueryAsync="OnQueryAsync">
|
||||
<TableColumns>
|
||||
<TableColumn @bind-Field="context.Id"></TableColumn>
|
||||
<TableColumn @bind-Field="context.Name"></TableColumn>
|
||||
</TableColumns>
|
||||
</AdminTable>
|
|
@ -0,0 +1,25 @@
|
|||
// Copyright (c) Argo Zhang (argo@163.com). All rights reserved.
|
||||
// Licensed under the LGPL License, Version 3.0. See License.txt in the project root for license information.
|
||||
// Website: https://admin.blazor.zone
|
||||
|
||||
using BootstrapClient.DataAccess.Models;
|
||||
using BootstrapClient.Web.Core;
|
||||
|
||||
namespace BootstrapClient.Web.Shared.Pages;
|
||||
|
||||
public partial class Dummy
|
||||
{
|
||||
[Inject]
|
||||
[NotNull]
|
||||
private IDummy? DummyService { get; set; }
|
||||
|
||||
private Task<QueryData<DummyEntity>> OnQueryAsync(QueryPageOptions options)
|
||||
{
|
||||
var items = DummyService.GetAll();
|
||||
var ret = new QueryData<DummyEntity>()
|
||||
{
|
||||
Items = items
|
||||
};
|
||||
return Task.FromResult(ret);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,19 @@
|
|||
// Copyright (c) Argo Zhang (argo@163.com). All rights reserved.
|
||||
// Licensed under the LGPL License, Version 3.0. See License.txt in the project root for license information.
|
||||
// Website: https://admin.blazor.zone
|
||||
|
||||
using BootstrapClient.DataAccess.Models;
|
||||
|
||||
namespace BootstrapClient.Web.Core;
|
||||
|
||||
/// <summary>
|
||||
/// 数据服务示例接口
|
||||
/// </summary>
|
||||
public interface IDummy
|
||||
{
|
||||
/// <summary>
|
||||
/// 获得 全部数据
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
List<DummyEntity> GetAll();
|
||||
}
|
|
@ -0,0 +1,21 @@
|
|||
// Copyright (c) Argo Zhang (argo@163.com). All rights reserved.
|
||||
// Licensed under the LGPL License, Version 3.0. See License.txt in the project root for license information.
|
||||
// Website: https://admin.blazor.zone
|
||||
|
||||
namespace BootstrapClient.DataAccess.Models;
|
||||
|
||||
/// <summary>
|
||||
/// 数据库实体类
|
||||
/// </summary>
|
||||
public class DummyEntity
|
||||
{
|
||||
/// <summary>
|
||||
/// 获得/设置 Id
|
||||
/// </summary>
|
||||
public string? Id { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 获得/设置 Name
|
||||
/// </summary>
|
||||
public string? Name { get; set; }
|
||||
}
|
|
@ -33,13 +33,7 @@ namespace Microsoft.Extensions.DependencyInjection
|
|||
services.AddScoped<BootstrapAppContext>();
|
||||
|
||||
// 增加 PetaPoco 数据服务
|
||||
services.AddPetaPocoDataAccessServices((provider, builder) =>
|
||||
{
|
||||
var configuration = provider.GetRequiredService<IConfiguration>();
|
||||
var connString = configuration.GetConnectionString("ba");
|
||||
builder.UsingProvider<SQLiteDatabaseProvider>()
|
||||
.UsingConnectionString(connString);
|
||||
});
|
||||
services.AddPetaPocoDataAccessServices();
|
||||
|
||||
return services;
|
||||
}
|
||||
|
|
|
@ -15,7 +15,7 @@
|
|||
"ASPNETCORE_ENVIRONMENT": "Development"
|
||||
}
|
||||
},
|
||||
"Bootstrap.Client.Blazor": {
|
||||
"Client": {
|
||||
"commandName": "Project",
|
||||
"dotnetRunMessages": "true",
|
||||
"launchBrowser": true,
|
||||
|
|
|
@ -12,34 +12,5 @@
|
|||
"BootstrapAdminAuthenticationOptions": {
|
||||
"AuthHost": "http://localhost:5210",
|
||||
"KeyPath": "..\\..\\keys"
|
||||
},
|
||||
"DB": [
|
||||
{
|
||||
"Enabled": false
|
||||
},
|
||||
{
|
||||
"Enabled": true,
|
||||
"ProviderName": "Sqlite",
|
||||
"ConnectionStrings": {
|
||||
"bb": "..\\..\\admin\\BootstrapAdmin.Web\\BootstrapAdmin.db;",
|
||||
"client": "Data Source=Client.db;"
|
||||
}
|
||||
},
|
||||
{
|
||||
"Enabled": false,
|
||||
"ProviderName": "MySql",
|
||||
"ConnectionStrings": {
|
||||
"ba": "Server=localhost;Database=BootstrapAdmin;Uid=root;Pwd=argo@163.com;SslMode=none;"
|
||||
}
|
||||
},
|
||||
{
|
||||
"Enabled": false,
|
||||
"Widget": "Bootstrap.Client.DataAccess.MongoDB",
|
||||
"ProviderName": "MongoDB",
|
||||
"ConnectionStrings": {
|
||||
"ba": "mongodb://localhost:27017/BootstrapAdmin",
|
||||
"client": "mongodb://localhost:27017/BootstrapClient"
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
|
|
|
@ -18,33 +18,5 @@
|
|||
},
|
||||
"BootstrapBlazorOptions": {
|
||||
"DefaultCultureInfo": "zh-CN"
|
||||
},
|
||||
"DB": [
|
||||
{
|
||||
"Enabled": false
|
||||
},
|
||||
{
|
||||
"Enabled": true,
|
||||
"ProviderName": "Sqlite",
|
||||
"ConnectionStrings": {
|
||||
"ba": "Data Source=..\\..\\admin\\BootstrapAdmin.Web\\BootstrapAdmin.db;",
|
||||
"client": "Data Source=Client.db;"
|
||||
}
|
||||
},
|
||||
{
|
||||
"Enabled": false,
|
||||
"ProviderName": "MySql",
|
||||
"ConnectionStrings": {
|
||||
"ba": "Server=localhost;Database=BootstrapAdmin;Uid=argozhang;Pwd=argo@163.com;SslMode=none;"
|
||||
}
|
||||
},
|
||||
{
|
||||
"Enabled": false,
|
||||
"Widget": "Bootstrap.Client.DataAccess.MongoDB",
|
||||
"ProviderName": "MongoDB",
|
||||
"ConnectionStrings": {
|
||||
"ba": "mongodb://localhost:27017/BootstrapAdmin"
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
|
|
|
@ -9,12 +9,12 @@
|
|||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="BootstrapBlazor" Version="6.2.9-beta07" />
|
||||
<PackageReference Include="Exceptionless.AspNetCore" Version="4.6.2" />
|
||||
<PackageReference Include="Longbow.Logging" Version="5.2.0" />
|
||||
<PackageReference Include="BootstrapBlazor" Version="6.8.13" />
|
||||
<PackageReference Include="Exceptionless.AspNetCore" Version="4.8.0" />
|
||||
<PackageReference Include="Longbow.Logging" Version="6.0.2" />
|
||||
<PackageReference Include="Microsoft.AspNetCore.Mvc.Versioning" Version="5.0.0" />
|
||||
<PackageReference Include="Sentry.AspNetCore" Version="3.10.0" />
|
||||
<PackageReference Include="Swashbuckle.AspNetCore" Version="6.2.3" />
|
||||
<PackageReference Include="Sentry.AspNetCore" Version="3.19.0" />
|
||||
<PackageReference Include="Swashbuckle.AspNetCore" Version="6.4.0" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
|
|
Binary file not shown.
|
@ -23,7 +23,8 @@ namespace Microsoft.Extensions.DependencyInjection
|
|||
/// <param name="services"></param>
|
||||
public static IServiceCollection AddBootstrapAdminBackgroundTask(this IServiceCollection services)
|
||||
{
|
||||
services.AddTaskServices(builder => builder.AddFileStorage());
|
||||
//services.AddTaskServices(builder => builder.AddFileStorage());
|
||||
services.AddTaskServices();
|
||||
services.AddHostedService<BootstrapAdminBackgroundServices>();
|
||||
return services;
|
||||
}
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Bootstrap.Security" Version="5.2.0" />
|
||||
<PackageReference Include="MongoDB.Driver" Version="2.13.2" />
|
||||
<PackageReference Include="MongoDB.Driver" Version="2.17.0" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
|
|
|
@ -2,23 +2,23 @@
|
|||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Bootstrap.Security.DataAccess" Version="5.2.0" />
|
||||
<PackageReference Include="Bootstrap.Security.Mvc" Version="5.2.0" />
|
||||
<PackageReference Include="Bootstrap.Security.Mvc" Version="6.0.0" />
|
||||
<PackageReference Include="Longbow" Version="5.2.0" />
|
||||
<PackageReference Include="Longbow.AlipayAuth" Version="5.2.0" />
|
||||
<PackageReference Include="Longbow.Cache" Version="5.2.0" />
|
||||
<PackageReference Include="Longbow.ComponentModel" Version="5.2.0" />
|
||||
<PackageReference Include="Longbow.ComponentModel" Version="6.0.0" />
|
||||
<PackageReference Include="Longbow.Data" Version="5.2.0" />
|
||||
<PackageReference Include="Longbow.GiteeAuth" Version="5.2.0" />
|
||||
<PackageReference Include="Longbow.GitHubAuth" Version="5.2.0" />
|
||||
<PackageReference Include="Longbow.OAuth" Version="5.2.0" />
|
||||
<PackageReference Include="Longbow.PetaPoco" Version="5.0.1" />
|
||||
<PackageReference Include="Longbow.Security.Cryptography" Version="5.2.0" />
|
||||
<PackageReference Include="Longbow.Tasks" Version="5.1.0" />
|
||||
<PackageReference Include="Longbow.Security.Cryptography" Version="6.0.0" />
|
||||
<PackageReference Include="Longbow.Tasks" Version="5.2.1" />
|
||||
<PackageReference Include="Longbow.TencentAuth" Version="5.2.0" />
|
||||
<PackageReference Include="Longbow.Web" Version="5.2.1" />
|
||||
<PackageReference Include="Longbow.WeChatAuth" Version="5.2.0" />
|
||||
<PackageReference Include="Microsoft.Data.Sqlite" Version="5.0.11" />
|
||||
<PackageReference Include="PetaPoco.Extensions" Version="5.2.0" />
|
||||
<PackageReference Include="Microsoft.Data.Sqlite" Version="6.0.7" />
|
||||
<PackageReference Include="PetaPoco.Extensions" Version="6.0.0" />
|
||||
<PackageReference Include="System.Data.SqlClient" Version="4.8.3" />
|
||||
</ItemGroup>
|
||||
|
||||
|
|
|
@ -4,6 +4,7 @@
|
|||
|
||||
using Longbow.Cache;
|
||||
using Longbow.Web.Mvc;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using PetaPoco;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
|
@ -25,13 +26,21 @@ namespace Bootstrap.DataAccess
|
|||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
/// <param name="provider"></param>
|
||||
/// <param name="eventId"></param>
|
||||
/// <param name="ex"></param>
|
||||
/// <param name="additionalInfo"></param>
|
||||
/// <returns></returns>
|
||||
public static void Log(Exception ex, NameValueCollection additionalInfo)
|
||||
public static void Log(IServiceProvider provider, EventId eventId, Exception? ex, NameValueCollection additionalInfo)
|
||||
{
|
||||
var ret = DbContextManager.Create<Exceptions>()?.Log(ex, additionalInfo) ?? false;
|
||||
if (ret) CacheManager.Clear(RetrieveExceptionsDataKey);
|
||||
if (ex != null)
|
||||
{
|
||||
var ret = DbContextManager.Create<Exceptions>()?.Log(ex, additionalInfo) ?? false;
|
||||
if (ret)
|
||||
{
|
||||
CacheManager.Clear(RetrieveExceptionsDataKey);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
|
|
@ -35,30 +35,40 @@ namespace Bootstrap.DataAccess
|
|||
/// <returns></returns>
|
||||
public static bool Save(BootstrapMenu p)
|
||||
{
|
||||
// 不允许保存系统菜单与前台演示系统的默认菜单
|
||||
var ret = false;
|
||||
|
||||
if (DictHelper.RetrieveSystemModel())
|
||||
{
|
||||
if (p.Category == "0") return true;
|
||||
|
||||
// 查找原有数据比对是否为系统菜单与演示菜单
|
||||
if (!string.IsNullOrEmpty(p.Id))
|
||||
// 不允许保存系统菜单与前台演示系统的默认菜单
|
||||
if (p.Category == "0")
|
||||
{
|
||||
|
||||
// 系统菜单
|
||||
ret = true;
|
||||
}
|
||||
else if (!string.IsNullOrEmpty(p.Id))
|
||||
{
|
||||
// 查找原有数据比对是否为系统菜单与演示菜单
|
||||
var menus = RetrieveAllMenus("Admin");
|
||||
#pragma warning disable CS8602 // 取消引用可能出现的空引用。
|
||||
var menu = menus.FirstOrDefault(m => m.Id.Equals(p.Id, System.StringComparison.OrdinalIgnoreCase));
|
||||
#pragma warning restore CS8602 // 取消引用可能出现的空引用。
|
||||
if (menu != null && menu.Category == "0") return true;
|
||||
|
||||
// 演示系统
|
||||
var appMenus = BootstrapAppContext.Configuration.GetSection("AppMenus").Get<ICollection<string>>();
|
||||
if (appMenus.Any(m => m.Equals(menu?.Name, StringComparison.OrdinalIgnoreCase))) return true;
|
||||
var menu = menus.FirstOrDefault(m => m.Id?.Equals(p.Id, System.StringComparison.OrdinalIgnoreCase) ?? false);
|
||||
if (menu != null && menu.Category == "0")
|
||||
{
|
||||
// 系统菜单
|
||||
ret = true;
|
||||
}
|
||||
else if (BootstrapAppContext.Configuration != null)
|
||||
{
|
||||
var appMenus = BootstrapAppContext.Configuration.GetSection("AppMenus").Get<ICollection<string>>();
|
||||
if (appMenus.Any(m => m.Equals(menu?.Name, StringComparison.OrdinalIgnoreCase)))
|
||||
{
|
||||
ret = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
var ret = DbContextManager.Create<Menu>()?.Save(p) ?? false;
|
||||
if (ret) CacheCleanUtility.ClearCache(menuIds: string.IsNullOrEmpty(p.Id) ? new List<string>() : new List<string>() { p.Id });
|
||||
else
|
||||
{
|
||||
ret = DbContextManager.Create<Menu>()?.Save(p) ?? false;
|
||||
if (ret) CacheCleanUtility.ClearCache(menuIds: string.IsNullOrEmpty(p.Id) ? new List<string>() : new List<string>() { p.Id });
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
@ -69,23 +79,38 @@ namespace Bootstrap.DataAccess
|
|||
/// <returns></returns>
|
||||
public static bool Delete(IEnumerable<string> value)
|
||||
{
|
||||
var ret = false;
|
||||
if (DictHelper.RetrieveSystemModel())
|
||||
{
|
||||
// 不允许删除系统菜单与前台演示系统的默认菜单
|
||||
var systemMenus = RetrieveAllMenus("Admin").Where(m => m.Category == "0");
|
||||
value = value.Where(v => !systemMenus.Any(m => m.Id == v));
|
||||
if (!value.Any()) return true;
|
||||
|
||||
// 演示系统
|
||||
var appMenus = BootstrapAppContext.Configuration.GetSection("AppMenus").Get<ICollection<string>>();
|
||||
var appIds = RetrieveAllMenus("Admin").Where(m => appMenus.Any(app => m.Name.Equals(app, System.StringComparison.OrdinalIgnoreCase))).Select(m => m.Id);
|
||||
#pragma warning disable CS8602 // 取消引用可能出现的空引用。
|
||||
value = value.Where(m => !appIds.Any(app => app.Equals(m, StringComparison.OrdinalIgnoreCase)));
|
||||
#pragma warning restore CS8602 // 取消引用可能出现的空引用。
|
||||
if (!value.Any()) return true;
|
||||
if (!value.Any())
|
||||
{
|
||||
ret = true;
|
||||
}
|
||||
else if (BootstrapAppContext.Configuration != null)
|
||||
{
|
||||
// 演示系统
|
||||
var appMenus = BootstrapAppContext.Configuration.GetSection("AppMenus").Get<ICollection<string>>();
|
||||
var appIds = RetrieveAllMenus("Admin")
|
||||
.Where(m => appMenus.Any(app => m.Name.Equals(app, System.StringComparison.OrdinalIgnoreCase)))
|
||||
.Select(m => m.Id);
|
||||
value = value.Where(m => !appIds.Any(app => app?.Equals(m, StringComparison.OrdinalIgnoreCase) ?? false));
|
||||
if (!value.Any())
|
||||
{
|
||||
ret = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
ret = DbContextManager.Create<Menu>()?.Delete(value) ?? false;
|
||||
if (ret)
|
||||
{
|
||||
CacheCleanUtility.ClearCache(menuIds: value);
|
||||
}
|
||||
}
|
||||
var ret = DbContextManager.Create<Menu>()?.Delete(value) ?? false;
|
||||
if (ret) CacheCleanUtility.ClearCache(menuIds: value);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
@ -101,7 +126,7 @@ namespace Bootstrap.DataAccess
|
|||
/// </summary>
|
||||
/// <param name="roleId"></param>
|
||||
/// <returns></returns>
|
||||
public static IEnumerable<string> RetrieveMenusByRoleId(string roleId) => CacheManager.GetOrAdd($"{RetrieveMenusByRoleIdDataKey}-{roleId}", k => DbContextManager.Create<Menu>()?.RetrieveMenusByRoleId(roleId), RetrieveMenusByRoleIdDataKey) ?? new string[0];
|
||||
public static IEnumerable<string> RetrieveMenusByRoleId(string roleId) => CacheManager.GetOrAdd($"{RetrieveMenusByRoleIdDataKey}-{roleId}", k => DbContextManager.Create<Menu>()?.RetrieveMenusByRoleId(roleId), RetrieveMenusByRoleIdDataKey) ?? Array.Empty<string>();
|
||||
|
||||
/// <summary>
|
||||
/// 保存指定角色的所有菜单
|
||||
|
@ -125,7 +150,7 @@ namespace Bootstrap.DataAccess
|
|||
/// <returns></returns>
|
||||
public static IEnumerable<BootstrapMenu> RetrieveAppMenus(string? appId, string? userName, string? activeUrl)
|
||||
{
|
||||
if (string.IsNullOrEmpty(appId) || string.IsNullOrEmpty(userName)) return new BootstrapMenu[0];
|
||||
if (string.IsNullOrEmpty(appId) || string.IsNullOrEmpty(userName)) return Array.Empty<BootstrapMenu>();
|
||||
|
||||
var menus = RetrieveAllMenus(userName).Where(m => m.Category == "1" && m.IsResource == 0);
|
||||
menus = menus.Where(m => m.Application.Equals(appId, StringComparison.OrdinalIgnoreCase));
|
||||
|
@ -162,7 +187,11 @@ namespace Bootstrap.DataAccess
|
|||
/// </summary>
|
||||
/// <param name="userName"></param>
|
||||
/// <returns></returns>
|
||||
public static IEnumerable<BootstrapMenu> RetrieveAllMenus(string? userName) => string.IsNullOrEmpty(userName) ? new BootstrapMenu[0] : CacheManager.GetOrAdd($"{RetrieveMenusAll}-{userName}", key => DbContextManager.Create<Menu>()?.RetrieveAllMenus(userName), RetrieveMenusAll) ?? Array.Empty<BootstrapMenu>();
|
||||
public static IEnumerable<BootstrapMenu> RetrieveAllMenus(string? userName) => string.IsNullOrEmpty(userName)
|
||||
? Array.Empty<BootstrapMenu>()
|
||||
: CacheManager.GetOrAdd($"{RetrieveMenusAll}-{userName}", key => DbContextManager.Create<Menu>()
|
||||
?.RetrieveAllMenus(userName), RetrieveMenusAll)
|
||||
?? Array.Empty<BootstrapMenu>();
|
||||
|
||||
/// <summary>
|
||||
/// 通过当前用户名与指定菜单路径获取此菜单下所有授权按钮集合 (userName, url, auths) => bool
|
||||
|
|
|
@ -1,3 +1,3 @@
|
|||
<lgb>
|
||||
<token>FP7PPYuq1IxBnd8cHAFQbr73FxUGxIUVotbCDEU49T5WJASIg3kEeZErdwxZVDjOHUOXIy7mQmfWKdKxLNSYRcsf2qlqNTkxzkjKnPMyPC6nU2pxPqjgaMj+9ktgnr34KUUbq4Of/XbSln+PY3BoHXP+FC8lJ39op/sJOi5LzqIA</token>
|
||||
<token>3/Ld1RBfVsDzesgUamNUo3gDGd1oiImeiCTEGpybeGKk+DIC+Q4ExWvxKjYfh31howpH7L5L41hVoybFT68unJXWG9uowxA2YhlE44ujnNS7sIBzMFT/SNzqzY5mga+ajvgna48mR3kVIa5dfUh+5TGc1W5QmfVsbcm/g40ApqAA</token>
|
||||
</lgb>
|
|
@ -1,7 +1,7 @@
|
|||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="MongoDB.Driver" Version="2.13.2" />
|
||||
<PackageReference Include="MongoDB.Driver" Version="2.17.0" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
|
|
|
@ -2,12 +2,12 @@
|
|||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Bootstrap.Security.DataAccess" Version="5.2.0" />
|
||||
<PackageReference Include="Bootstrap.Security.Mvc" Version="5.2.0" />
|
||||
<PackageReference Include="Bootstrap.Security.Mvc" Version="6.0.0" />
|
||||
<PackageReference Include="Longbow" Version="5.2.0" />
|
||||
<PackageReference Include="Longbow.Cache" Version="5.2.0" />
|
||||
<PackageReference Include="Longbow.ComponentModel" Version="5.2.0" />
|
||||
<PackageReference Include="Longbow.ComponentModel" Version="6.0.0" />
|
||||
<PackageReference Include="Longbow.Data" Version="5.2.0" />
|
||||
<PackageReference Include="Longbow.Security.Cryptography" Version="5.2.0" />
|
||||
<PackageReference Include="Longbow.Security.Cryptography" Version="6.0.0" />
|
||||
<PackageReference Include="Longbow.Web" Version="5.2.1" />
|
||||
<PackageReference Include="System.Data.SqlClient" Version="4.8.3" />
|
||||
</ItemGroup>
|
||||
|
|
|
@ -5,9 +5,9 @@
|
|||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="BootstrapBlazor" Version="6.2.7-beta02" />
|
||||
<PackageReference Include="Longbow.Logging" Version="5.2.0" />
|
||||
<PackageReference Include="Microsoft.Data.Sqlite" Version="5.0.11" />
|
||||
<PackageReference Include="BootstrapBlazor" Version="6.8.13" />
|
||||
<PackageReference Include="Longbow.Logging" Version="6.0.2" />
|
||||
<PackageReference Include="Microsoft.Data.Sqlite" Version="6.0.7" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
|
|
|
@ -8,8 +8,8 @@
|
|||
|
||||
<Target Name="PostBuildTest" AfterTargets="PostBuildEvent">
|
||||
<Message Text="Copy db file -> $(TargetDir)" Importance="high" />
|
||||
<Copy Condition="'$(OS)' == 'Windows_NT'" DestinationFolder="$(TargetDir)" SourceFiles="$(MSBuildThisFileDirectory)..\src\admin\Bootstrap.Admin\BootstrapAdmin.db" SkipUnchangedFiles="true" />
|
||||
<Copy Condition="'$(OS)' == 'UNIX'" DestinationFolder="$(TargetDir)" SourceFiles="$(MSBuildThisFileDirectory)../src/admin/Bootstrap.Admin/BootstrapAdmin.db" SkipUnchangedFiles="true" />
|
||||
<Copy Condition="'$(OS)' == 'Windows_NT'" DestinationFolder="$(TargetDir)" SourceFiles="$(MSBuildThisFileDirectory)..\src\mvc\admin\Bootstrap.Admin\BootstrapAdmin.db" SkipUnchangedFiles="true" />
|
||||
<Copy Condition="'$(OS)' == 'UNIX'" DestinationFolder="$(TargetDir)" SourceFiles="$(MSBuildThisFileDirectory)../src/mvc/admin/Bootstrap.Admin/BootstrapAdmin.db" SkipUnchangedFiles="true" />
|
||||
</Target>
|
||||
|
||||
</Project>
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFramework>net5.0</TargetFramework>
|
||||
<TargetFramework>net6.0</TargetFramework>
|
||||
<IsPackable>false</IsPackable>
|
||||
<DebugType>Full</DebugType>
|
||||
</PropertyGroup>
|
||||
|
@ -13,16 +13,16 @@
|
|||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="coverlet.msbuild" Version="2.7.0">
|
||||
<PackageReference Include="coverlet.msbuild" Version="3.1.2">
|
||||
<PrivateAssets>all</PrivateAssets>
|
||||
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
|
||||
</PackageReference>
|
||||
<PackageReference Include="Microsoft.AspNetCore.Mvc.Testing" Version="5.0.11" />
|
||||
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="16.11.0" />
|
||||
<PackageReference Include="MySql.Data" Version="8.0.27" />
|
||||
<PackageReference Include="System.Net.Http.Json" Version="5.0.0" />
|
||||
<PackageReference Include="Microsoft.AspNetCore.Mvc.Testing" Version="6.0.7" />
|
||||
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.2.0" />
|
||||
<PackageReference Include="MySql.Data" Version="8.0.29" />
|
||||
<PackageReference Include="System.Net.Http.Json" Version="6.0.0" />
|
||||
<PackageReference Include="xunit" Version="2.4.1" />
|
||||
<PackageReference Include="xunit.runner.visualstudio" Version="2.4.3">
|
||||
<PackageReference Include="xunit.runner.visualstudio" Version="2.4.5">
|
||||
<PrivateAssets>all</PrivateAssets>
|
||||
<IncludeAssets>runtime; build; native; contentfiles; analyzers</IncludeAssets>
|
||||
</PackageReference>
|
||||
|
|
Loading…
Reference in New Issue