init project
This commit is contained in:
commit
e1a9562b22
1346 changed files with 1138526 additions and 0 deletions
5
.gitignore
vendored
Normal file
5
.gitignore
vendored
Normal file
|
|
@ -0,0 +1,5 @@
|
|||
configs/**/data/**
|
||||
|
||||
**/node_modules
|
||||
**/.DS_Store
|
||||
files/
|
||||
700
My_workflow.json
Normal file
700
My_workflow.json
Normal file
File diff suppressed because one or more lines are too long
4
api/.dockerignore
Normal file
4
api/.dockerignore
Normal file
|
|
@ -0,0 +1,4 @@
|
|||
**/bin
|
||||
**/obj
|
||||
bin/
|
||||
obj/
|
||||
147
api/.editorconfig
Normal file
147
api/.editorconfig
Normal file
|
|
@ -0,0 +1,147 @@
|
|||
# To learn more about .editorconfig see https://aka.ms/editorconfigdocs
|
||||
###############################
|
||||
# Core EditorConfig Options #
|
||||
###############################
|
||||
root = true
|
||||
# All files
|
||||
[*]
|
||||
indent_style = space
|
||||
end_of_line = crlf
|
||||
|
||||
# XML project files
|
||||
[*.{csproj,vbproj,vcxproj,vcxproj.filters,proj,projitems,shproj}]
|
||||
indent_size = 2
|
||||
|
||||
# XML config files
|
||||
[*.{props,targets,ruleset,config,nuspec,resx,vsixmanifest,vsct}]
|
||||
indent_size = 2
|
||||
|
||||
# Code files
|
||||
[*.{cs,csx,vb,vbx}]
|
||||
indent_size = 4
|
||||
insert_final_newline = true
|
||||
charset = utf-8-bom
|
||||
###############################
|
||||
# .NET Coding Conventions #
|
||||
###############################
|
||||
[*.{cs,vb}]
|
||||
# Organize usings
|
||||
dotnet_sort_system_directives_first = true
|
||||
# this. preferences
|
||||
dotnet_style_qualification_for_field = false:silent
|
||||
dotnet_style_qualification_for_property = false:silent
|
||||
dotnet_style_qualification_for_method = false:silent
|
||||
dotnet_style_qualification_for_event = false:silent
|
||||
# Language keywords vs BCL types preferences
|
||||
dotnet_style_predefined_type_for_locals_parameters_members = true:silent
|
||||
dotnet_style_predefined_type_for_member_access = true:silent
|
||||
# Parentheses preferences
|
||||
dotnet_style_parentheses_in_arithmetic_binary_operators = always_for_clarity:silent
|
||||
dotnet_style_parentheses_in_relational_binary_operators = always_for_clarity:silent
|
||||
dotnet_style_parentheses_in_other_binary_operators = always_for_clarity:silent
|
||||
dotnet_style_parentheses_in_other_operators = never_if_unnecessary:silent
|
||||
# Modifier preferences
|
||||
dotnet_style_require_accessibility_modifiers = for_non_interface_members:silent
|
||||
dotnet_style_readonly_field = true:suggestion
|
||||
# Expression-level preferences
|
||||
dotnet_style_object_initializer = true:suggestion
|
||||
dotnet_style_collection_initializer = true:suggestion
|
||||
dotnet_style_explicit_tuple_names = true:suggestion
|
||||
dotnet_style_null_propagation = true:suggestion
|
||||
dotnet_style_coalesce_expression = true:suggestion
|
||||
dotnet_style_prefer_is_null_check_over_reference_equality_method = true:silent
|
||||
dotnet_style_prefer_inferred_tuple_names = true:suggestion
|
||||
dotnet_style_prefer_inferred_anonymous_type_member_names = true:suggestion
|
||||
dotnet_style_prefer_auto_properties = true:silent
|
||||
dotnet_style_prefer_conditional_expression_over_assignment = true:silent
|
||||
dotnet_style_prefer_conditional_expression_over_return = true:silent
|
||||
###############################
|
||||
# Naming Conventions #
|
||||
###############################
|
||||
# Style Definitions
|
||||
dotnet_naming_style.pascal_case_style.capitalization = pascal_case
|
||||
# Use PascalCase for constant fields
|
||||
dotnet_naming_rule.constant_fields_should_be_pascal_case.severity = suggestion
|
||||
dotnet_naming_rule.constant_fields_should_be_pascal_case.symbols = constant_fields
|
||||
dotnet_naming_rule.constant_fields_should_be_pascal_case.style = pascal_case_style
|
||||
dotnet_naming_symbols.constant_fields.applicable_kinds = field
|
||||
dotnet_naming_symbols.constant_fields.applicable_accessibilities = *
|
||||
dotnet_naming_symbols.constant_fields.required_modifiers = const
|
||||
dotnet_style_operator_placement_when_wrapping = beginning_of_line
|
||||
tab_width = 4
|
||||
end_of_line = crlf
|
||||
dotnet_style_prefer_simplified_boolean_expressions = true:suggestion
|
||||
dotnet_style_prefer_compound_assignment = true:suggestion
|
||||
dotnet_style_prefer_simplified_interpolation = true:suggestion
|
||||
dotnet_style_namespace_match_folder = true:suggestion
|
||||
###############################
|
||||
# C# Coding Conventions #
|
||||
###############################
|
||||
[*.cs]
|
||||
# var preferences
|
||||
csharp_style_var_for_built_in_types = true:silent
|
||||
csharp_style_var_when_type_is_apparent = true:silent
|
||||
csharp_style_var_elsewhere = true:silent
|
||||
# Expression-bodied members
|
||||
csharp_style_expression_bodied_methods = false:silent
|
||||
csharp_style_expression_bodied_constructors = false:silent
|
||||
csharp_style_expression_bodied_operators = false:silent
|
||||
csharp_style_expression_bodied_properties = true:silent
|
||||
csharp_style_expression_bodied_indexers = true:silent
|
||||
csharp_style_expression_bodied_accessors = true:silent
|
||||
# Pattern matching preferences
|
||||
csharp_style_pattern_matching_over_is_with_cast_check = true:suggestion
|
||||
csharp_style_pattern_matching_over_as_with_null_check = true:suggestion
|
||||
# Null-checking preferences
|
||||
csharp_style_throw_expression = true:suggestion
|
||||
csharp_style_conditional_delegate_call = true:suggestion
|
||||
# Modifier preferences
|
||||
csharp_preferred_modifier_order = public,private,protected,internal,static,extern,new,virtual,abstract,sealed,override,readonly,unsafe,volatile,async:suggestion
|
||||
# Expression-level preferences
|
||||
csharp_prefer_braces = true:silent
|
||||
csharp_style_deconstructed_variable_declaration = true:suggestion
|
||||
csharp_prefer_simple_default_expression = true:suggestion
|
||||
csharp_style_pattern_local_over_anonymous_function = true:suggestion
|
||||
csharp_style_inlined_variable_declaration = true:suggestion
|
||||
###############################
|
||||
# C# Formatting Rules #
|
||||
###############################
|
||||
# New line preferences
|
||||
csharp_new_line_before_open_brace = all
|
||||
csharp_new_line_before_else = true
|
||||
csharp_new_line_before_catch = true
|
||||
csharp_new_line_before_finally = true
|
||||
csharp_new_line_before_members_in_object_initializers = true
|
||||
csharp_new_line_before_members_in_anonymous_types = true
|
||||
csharp_new_line_between_query_expression_clauses = true
|
||||
# Indentation preferences
|
||||
csharp_indent_case_contents = true
|
||||
csharp_indent_switch_labels = true
|
||||
csharp_indent_labels = flush_left
|
||||
# Space preferences
|
||||
csharp_space_after_cast = false
|
||||
csharp_space_after_keywords_in_control_flow_statements = true
|
||||
csharp_space_between_method_call_parameter_list_parentheses = false
|
||||
csharp_space_between_method_declaration_parameter_list_parentheses = false
|
||||
csharp_space_between_parentheses = false
|
||||
csharp_space_before_colon_in_inheritance_clause = true
|
||||
csharp_space_after_colon_in_inheritance_clause = true
|
||||
csharp_space_around_binary_operators = before_and_after
|
||||
csharp_space_between_method_declaration_empty_parameter_list_parentheses = false
|
||||
csharp_space_between_method_call_name_and_opening_parenthesis = false
|
||||
csharp_space_between_method_call_empty_parameter_list_parentheses = false
|
||||
# Wrapping preferences
|
||||
csharp_preserve_single_line_statements = true
|
||||
csharp_preserve_single_line_blocks = true
|
||||
csharp_using_directive_placement = outside_namespace:silent
|
||||
csharp_prefer_simple_using_statement = true:suggestion
|
||||
csharp_style_namespace_declarations = block_scoped:silent
|
||||
csharp_style_prefer_method_group_conversion = true:silent
|
||||
csharp_style_expression_bodied_lambdas = true:silent
|
||||
csharp_style_expression_bodied_local_functions = false:silent
|
||||
###############################
|
||||
# VB Coding Conventions #
|
||||
###############################
|
||||
[*.vb]
|
||||
# Modifier preferences
|
||||
visual_basic_preferred_modifier_order = Partial,Default,Private,Protected,Public,Friend,NotOverridable,Overridable,MustOverride,Overloads,Overrides,MustInherit,NotInheritable,Static,Shared,Shadows,ReadOnly,WriteOnly,Dim,Const,WithEvents,Widening,Narrowing,Custom,Async:suggestion
|
||||
1
api/.gitattributes
vendored
Normal file
1
api/.gitattributes
vendored
Normal file
|
|
@ -0,0 +1 @@
|
|||
**/wwwroot/libs/** linguist-vendored
|
||||
266
api/.gitignore
vendored
Normal file
266
api/.gitignore
vendored
Normal file
|
|
@ -0,0 +1,266 @@
|
|||
## Ignore Visual Studio temporary files, build results, and
|
||||
## files generated by popular Visual Studio add-ons.
|
||||
|
||||
# User-specific files
|
||||
*.suo
|
||||
*.user
|
||||
*.userosscache
|
||||
*.sln.docstates
|
||||
|
||||
# User-specific files (MonoDevelop/Xamarin Studio)
|
||||
*.userprefs
|
||||
|
||||
# Build results
|
||||
[Dd]ebug/
|
||||
[Dd]ebugPublic/
|
||||
[Rr]elease/
|
||||
[Rr]eleases/
|
||||
x64/
|
||||
x86/
|
||||
bld/
|
||||
[Bb]in/
|
||||
[Oo]bj/
|
||||
[Ll]og/
|
||||
|
||||
# Visual Studio 2015 cache/options directory
|
||||
.vs/
|
||||
# Uncomment if you have tasks that create the project's static files in wwwroot
|
||||
#wwwroot/
|
||||
|
||||
# MSTest test Results
|
||||
[Tt]est[Rr]esult*/
|
||||
[Bb]uild[Ll]og.*
|
||||
|
||||
# NUNIT
|
||||
*.VisualState.xml
|
||||
TestResult.xml
|
||||
|
||||
# Build Results of an ATL Project
|
||||
[Dd]ebugPS/
|
||||
[Rr]eleasePS/
|
||||
dlldata.c
|
||||
|
||||
# DNX
|
||||
project.lock.json
|
||||
artifacts/
|
||||
|
||||
*_i.c
|
||||
*_p.c
|
||||
*_i.h
|
||||
*.ilk
|
||||
*.meta
|
||||
*.obj
|
||||
*.pch
|
||||
*.pdb
|
||||
*.pgc
|
||||
*.pgd
|
||||
*.rsp
|
||||
*.sbr
|
||||
*.tlb
|
||||
*.tli
|
||||
*.tlh
|
||||
*.tmp
|
||||
*.tmp_proj
|
||||
*.log
|
||||
*.vspscc
|
||||
*.vssscc
|
||||
.builds
|
||||
*.pidb
|
||||
*.svclog
|
||||
*.scc
|
||||
|
||||
# Chutzpah Test files
|
||||
_Chutzpah*
|
||||
|
||||
# Visual C++ cache files
|
||||
ipch/
|
||||
*.aps
|
||||
*.ncb
|
||||
*.opendb
|
||||
*.opensdf
|
||||
*.sdf
|
||||
*.cachefile
|
||||
*.VC.db
|
||||
*.VC.VC.opendb
|
||||
|
||||
# Visual Studio profiler
|
||||
*.psess
|
||||
*.vsp
|
||||
*.vspx
|
||||
*.sap
|
||||
|
||||
# TFS 2012 Local Workspace
|
||||
$tf/
|
||||
|
||||
# Guidance Automation Toolkit
|
||||
*.gpState
|
||||
|
||||
# ReSharper is a .NET coding add-in
|
||||
_ReSharper*/
|
||||
*.[Rr]e[Ss]harper
|
||||
*.DotSettings.user
|
||||
|
||||
# JustCode is a .NET coding add-in
|
||||
.JustCode
|
||||
|
||||
# TeamCity is a build add-in
|
||||
_TeamCity*
|
||||
|
||||
# DotCover is a Code Coverage Tool
|
||||
*.dotCover
|
||||
|
||||
# NCrunch
|
||||
_NCrunch_*
|
||||
.*crunch*.local.xml
|
||||
nCrunchTemp_*
|
||||
|
||||
# MightyMoose
|
||||
*.mm.*
|
||||
AutoTest.Net/
|
||||
|
||||
# Web workbench (sass)
|
||||
.sass-cache/
|
||||
|
||||
# Installshield output folder
|
||||
[Ee]xpress/
|
||||
|
||||
# DocProject is a documentation generator add-in
|
||||
DocProject/buildhelp/
|
||||
DocProject/Help/*.HxT
|
||||
DocProject/Help/*.HxC
|
||||
DocProject/Help/*.hhc
|
||||
DocProject/Help/*.hhk
|
||||
DocProject/Help/*.hhp
|
||||
DocProject/Help/Html2
|
||||
DocProject/Help/html
|
||||
|
||||
# Click-Once directory
|
||||
publish/
|
||||
|
||||
# Publish Web Output
|
||||
*.[Pp]ublish.xml
|
||||
*.azurePubxml
|
||||
# TODO: Comment the next line if you want to checkin your web deploy settings
|
||||
# but database connection strings (with potential passwords) will be unencrypted
|
||||
*.pubxml
|
||||
*.publishproj
|
||||
|
||||
# Microsoft Azure Web App publish settings. Comment the next line if you want to
|
||||
# checkin your Azure Web App publish settings, but sensitive information contained
|
||||
# in these scripts will be unencrypted
|
||||
PublishScripts/
|
||||
|
||||
# NuGet Packages
|
||||
*.nupkg
|
||||
# The packages folder can be ignored because of Package Restore
|
||||
**/packages/*
|
||||
# except build/, which is used as an MSBuild target.
|
||||
!**/packages/build/
|
||||
# Uncomment if necessary however generally it will be regenerated when needed
|
||||
#!**/packages/repositories.config
|
||||
# NuGet v3's project.json files produces more ignoreable files
|
||||
*.nuget.props
|
||||
*.nuget.targets
|
||||
|
||||
# Microsoft Azure Build Output
|
||||
csx/
|
||||
*.build.csdef
|
||||
|
||||
# Microsoft Azure Emulator
|
||||
ecf/
|
||||
rcf/
|
||||
|
||||
# Windows Store app package directories and files
|
||||
AppPackages/
|
||||
BundleArtifacts/
|
||||
Package.StoreAssociation.xml
|
||||
_pkginfo.txt
|
||||
|
||||
# Visual Studio cache files
|
||||
# files ending in .cache can be ignored
|
||||
*.[Cc]ache
|
||||
# but keep track of directories ending in .cache
|
||||
!*.[Cc]ache/
|
||||
|
||||
# Others
|
||||
ClientBin/
|
||||
~$*
|
||||
*~
|
||||
*.dbmdl
|
||||
*.dbproj.schemaview
|
||||
*.pfx
|
||||
*.publishsettings
|
||||
node_modules/
|
||||
orleans.codegen.cs
|
||||
|
||||
# Since there are multiple workflows, uncomment next line to ignore bower_components
|
||||
# (https://github.com/github/gitignore/pull/1529#issuecomment-104372622)
|
||||
#bower_components/
|
||||
|
||||
# RIA/Silverlight projects
|
||||
Generated_Code/
|
||||
|
||||
# Backup & report files from converting an old project file
|
||||
# to a newer Visual Studio version. Backup files are not needed,
|
||||
# because we have git ;-)
|
||||
_UpgradeReport_Files/
|
||||
Backup*/
|
||||
UpgradeLog*.XML
|
||||
UpgradeLog*.htm
|
||||
|
||||
# SQL Server files
|
||||
*.mdf
|
||||
*.ldf
|
||||
|
||||
# Business Intelligence projects
|
||||
*.rdl.data
|
||||
*.bim.layout
|
||||
*.bim_*.settings
|
||||
|
||||
# Microsoft Fakes
|
||||
FakesAssemblies/
|
||||
|
||||
# GhostDoc plugin setting file
|
||||
*.GhostDoc.xml
|
||||
|
||||
# Node.js Tools for Visual Studio
|
||||
.ntvs_analysis.dat
|
||||
|
||||
# Visual Studio 6 build log
|
||||
*.plg
|
||||
|
||||
# Visual Studio 6 workspace options file
|
||||
*.opt
|
||||
|
||||
# Visual Studio LightSwitch build output
|
||||
**/*.HTMLClient/GeneratedArtifacts
|
||||
**/*.DesktopClient/GeneratedArtifacts
|
||||
**/*.DesktopClient/ModelManifest.xml
|
||||
**/*.Server/GeneratedArtifacts
|
||||
**/*.Server/ModelManifest.xml
|
||||
_Pvt_Extensions
|
||||
|
||||
# Paket dependency manager
|
||||
.paket/paket.exe
|
||||
paket-files/
|
||||
|
||||
# FAKE - F# Make
|
||||
.fake/
|
||||
|
||||
# JetBrains Rider
|
||||
.idea/
|
||||
*.sln.iml
|
||||
|
||||
# Platform
|
||||
src/Kurs.Platform.Web/Logs/*
|
||||
src/Kurs.Platform.Web.Host/Logs/*
|
||||
src/Kurs.Platform.AuthServer/Logs/*
|
||||
src/Kurs.Platform.HttpApi.Host/Logs/*
|
||||
src/Kurs.Platform.HttpApi.Host/Logs/*
|
||||
src/Kurs.Platform.DbMigrator/Logs/*
|
||||
src/Kurs.Platform.Blazor.Server/Logs/*
|
||||
src/Kurs.Platform.Blazor.Server.Tiered/Logs/*
|
||||
|
||||
# Use abp install-libs to restore.
|
||||
**/wwwroot/libs/*
|
||||
*appsettings.development.json
|
||||
5
api/.prettierrc
Normal file
5
api/.prettierrc
Normal file
|
|
@ -0,0 +1,5 @@
|
|||
{
|
||||
"singleQuote": true,
|
||||
"useTabs": false,
|
||||
"tabWidth": 4
|
||||
}
|
||||
46
api/Kurs.Platform.DbMigrator.Dockerfile
Normal file
46
api/Kurs.Platform.DbMigrator.Dockerfile
Normal file
|
|
@ -0,0 +1,46 @@
|
|||
FROM mcr.microsoft.com/dotnet/sdk:9.0-alpine AS build
|
||||
ENV DOTNET_NUGET_SIGNATURE_VERIFICATION=false
|
||||
WORKDIR /app
|
||||
|
||||
COPY "modules/Kurs.Languages/Kurs.Languages.Application.Contracts/Kurs.Languages.Application.Contracts.csproj" "modules/Kurs.Languages/Kurs.Languages.Application.Contracts/"
|
||||
COPY "modules/Kurs.Languages/Kurs.Languages.Domain/Kurs.Languages.Domain.csproj" "modules/Kurs.Languages/Kurs.Languages.Domain/"
|
||||
COPY "modules/Kurs.Languages/Kurs.Languages.Domain.Shared/Kurs.Languages.Domain.Shared.csproj" "modules/Kurs.Languages/Kurs.Languages.Domain.Shared/"
|
||||
COPY "modules/Kurs.Languages/Kurs.Languages.EntityFrameworkCore/Kurs.Languages.EntityFrameworkCore.csproj" "modules/Kurs.Languages/Kurs.Languages.EntityFrameworkCore/"
|
||||
COPY "modules/Kurs.MailQueue/Kurs.MailQueue.csproj" "modules/Kurs.MailQueue/"
|
||||
COPY "modules/Kurs.Notifications/Kurs.Notifications.Application.Contracts/Kurs.Notifications.Application.Contracts.csproj" "modules/Kurs.Notifications/Kurs.Notifications.Application.Contracts/"
|
||||
COPY "modules/Kurs.Notifications/Kurs.Notifications.Domain/Kurs.Notifications.Domain.csproj" "modules/Kurs.Notifications/Kurs.Notifications.Domain/"
|
||||
COPY "modules/Kurs.Notifications/Kurs.Notifications.Domain.Shared/Kurs.Notifications.Domain.Shared.csproj" "modules/Kurs.Notifications/Kurs.Notifications.Domain.Shared/"
|
||||
COPY "modules/Kurs.Notifications/Kurs.Notifications.EntityFrameworkCore/Kurs.Notifications.EntityFrameworkCore.csproj" "modules/Kurs.Notifications/Kurs.Notifications.EntityFrameworkCore/"
|
||||
COPY "modules/Kurs.Sender/Kurs.Sender.csproj" "modules/Kurs.Sender/"
|
||||
COPY "modules/Kurs.Settings/Kurs.Settings.Application.Contracts/Kurs.Settings.Application.Contracts.csproj" "modules/Kurs.Settings/Kurs.Settings.Application.Contracts/"
|
||||
COPY "modules/Kurs.Settings/Kurs.Settings.Domain/Kurs.Settings.Domain.csproj" "modules/Kurs.Settings/Kurs.Settings.Domain/"
|
||||
COPY "modules/Kurs.Settings/Kurs.Settings.Domain.Shared/Kurs.Settings.Domain.Shared.csproj" "modules/Kurs.Settings/Kurs.Settings.Domain.Shared/"
|
||||
COPY "modules/Kurs.Settings/Kurs.Settings.EntityFrameworkCore/Kurs.Settings.EntityFrameworkCore.csproj" "modules/Kurs.Settings/Kurs.Settings.EntityFrameworkCore/"
|
||||
COPY "src/Kurs.Platform.Application.Contracts/Kurs.Platform.Application.Contracts.csproj" "src/Kurs.Platform.Application.Contracts/"
|
||||
COPY "src/Kurs.Platform.DbMigrator/Kurs.Platform.DbMigrator.csproj" "src/Kurs.Platform.DbMigrator/"
|
||||
COPY "src/Kurs.Platform.Domain/Kurs.Platform.Domain.csproj" "src/Kurs.Platform.Domain/"
|
||||
COPY "src/Kurs.Platform.Domain.Shared/Kurs.Platform.Domain.Shared.csproj" "src/Kurs.Platform.Domain.Shared/"
|
||||
COPY "src/Kurs.Platform.EntityFrameworkCore/Kurs.Platform.EntityFrameworkCore.csproj" "src/Kurs.Platform.EntityFrameworkCore/"
|
||||
RUN dotnet restore "src/Kurs.Platform.DbMigrator/Kurs.Platform.DbMigrator.csproj"
|
||||
|
||||
COPY . .
|
||||
RUN dotnet publish "src/Kurs.Platform.DbMigrator/Kurs.Platform.DbMigrator.csproj" -c Release -o /app/publish --no-restore
|
||||
|
||||
FROM mcr.microsoft.com/dotnet/aspnet:9.0-alpine AS final
|
||||
ENV DOTNET_SYSTEM_GLOBALIZATION_INVARIANT=false \
|
||||
LC_ALL=tr_TR.UTF-8 \
|
||||
LANG=tr_TR.UTF-8
|
||||
|
||||
# icu'lar dotnet culture icin gerekli
|
||||
# lib'ler wkhtmltopdf icin gerekli
|
||||
RUN apk update
|
||||
RUN apk add --no-cache \
|
||||
icu-data-full \
|
||||
icu-libs \
|
||||
libgdiplus \
|
||||
libc6-compat \
|
||||
libc-dev
|
||||
|
||||
WORKDIR /srv/app
|
||||
COPY --from=build /app/publish .
|
||||
ENTRYPOINT ["./Kurs.Platform.DbMigrator"]
|
||||
75
api/Kurs.Platform.HttpApi.Host.Dockerfile
Normal file
75
api/Kurs.Platform.HttpApi.Host.Dockerfile
Normal file
|
|
@ -0,0 +1,75 @@
|
|||
FROM mcr.microsoft.com/dotnet/sdk:9.0-alpine AS build
|
||||
ENV DOTNET_NUGET_SIGNATURE_VERIFICATION=false
|
||||
WORKDIR /app
|
||||
RUN apk update && apk upgrade
|
||||
RUN apk add nodejs~=22 npm~=10
|
||||
|
||||
RUN dotnet tool install -g Volo.Abp.Cli
|
||||
ENV PATH="/root/.dotnet/tools:${PATH}"
|
||||
COPY "src/Kurs.Platform.HttpApi.Host/Kurs.Platform.HttpApi.Host.csproj" "src/Kurs.Platform.HttpApi.Host/"
|
||||
COPY "src/Kurs.Platform.HttpApi.Host/package.json" "src/Kurs.Platform.HttpApi.Host/"
|
||||
COPY "src/Kurs.Platform.HttpApi.Host/package-lock.json" "src/Kurs.Platform.HttpApi.Host/"
|
||||
WORKDIR /app/src/Kurs.Platform.HttpApi.Host
|
||||
RUN abp install-libs
|
||||
WORKDIR /app
|
||||
|
||||
COPY "modules/Kurs.Languages/Kurs.Languages.Application/Kurs.Languages.Application.csproj" "modules/Kurs.Languages/Kurs.Languages.Application/"
|
||||
COPY "modules/Kurs.Languages/Kurs.Languages.Application.Contracts/Kurs.Languages.Application.Contracts.csproj" "modules/Kurs.Languages/Kurs.Languages.Application.Contracts/"
|
||||
COPY "modules/Kurs.Languages/Kurs.Languages.Domain/Kurs.Languages.Domain.csproj" "modules/Kurs.Languages/Kurs.Languages.Domain/"
|
||||
COPY "modules/Kurs.Languages/Kurs.Languages.Domain.Shared/Kurs.Languages.Domain.Shared.csproj" "modules/Kurs.Languages/Kurs.Languages.Domain.Shared/"
|
||||
COPY "modules/Kurs.Languages/Kurs.Languages.EntityFrameworkCore/Kurs.Languages.EntityFrameworkCore.csproj" "modules/Kurs.Languages/Kurs.Languages.EntityFrameworkCore/"
|
||||
COPY "modules/Kurs.MailQueue/Kurs.MailQueue.csproj" "modules/Kurs.MailQueue/"
|
||||
COPY "modules/Kurs.Notifications/Kurs.Notifications.Application/Kurs.Notifications.Application.csproj" "modules/Kurs.Notifications/Kurs.Notifications.Application/"
|
||||
COPY "modules/Kurs.Notifications/Kurs.Notifications.Application.Contracts/Kurs.Notifications.Application.Contracts.csproj" "modules/Kurs.Notifications/Kurs.Notifications.Application.Contracts/"
|
||||
COPY "modules/Kurs.Notifications/Kurs.Notifications.Domain/Kurs.Notifications.Domain.csproj" "modules/Kurs.Notifications/Kurs.Notifications.Domain/"
|
||||
COPY "modules/Kurs.Notifications/Kurs.Notifications.Domain.Shared/Kurs.Notifications.Domain.Shared.csproj" "modules/Kurs.Notifications/Kurs.Notifications.Domain.Shared/"
|
||||
COPY "modules/Kurs.Notifications/Kurs.Notifications.EntityFrameworkCore/Kurs.Notifications.EntityFrameworkCore.csproj" "modules/Kurs.Notifications/Kurs.Notifications.EntityFrameworkCore/"
|
||||
COPY "modules/Kurs.Sender/Kurs.Sender.csproj" "modules/Kurs.Sender/"
|
||||
COPY "modules/Kurs.Settings/Kurs.Settings.Application/Kurs.Settings.Application.csproj" "modules/Kurs.Settings/Kurs.Settings.Application/"
|
||||
COPY "modules/Kurs.Settings/Kurs.Settings.Application.Contracts/Kurs.Settings.Application.Contracts.csproj" "modules/Kurs.Settings/Kurs.Settings.Application.Contracts/"
|
||||
COPY "modules/Kurs.Settings/Kurs.Settings.Domain/Kurs.Settings.Domain.csproj" "modules/Kurs.Settings/Kurs.Settings.Domain/"
|
||||
COPY "modules/Kurs.Settings/Kurs.Settings.Domain.Shared/Kurs.Settings.Domain.Shared.csproj" "modules/Kurs.Settings/Kurs.Settings.Domain.Shared/"
|
||||
COPY "modules/Kurs.Settings/Kurs.Settings.EntityFrameworkCore/Kurs.Settings.EntityFrameworkCore.csproj" "modules/Kurs.Settings/Kurs.Settings.EntityFrameworkCore/"
|
||||
COPY "src/Kurs.Platform.Application/Kurs.Platform.Application.csproj" "src/Kurs.Platform.Application/"
|
||||
COPY "src/Kurs.Platform.Application.Contracts/Kurs.Platform.Application.Contracts.csproj" "src/Kurs.Platform.Application.Contracts/"
|
||||
COPY "src/Kurs.Platform.Domain/Kurs.Platform.Domain.csproj" "src/Kurs.Platform.Domain/"
|
||||
COPY "src/Kurs.Platform.Domain.Shared/Kurs.Platform.Domain.Shared.csproj" "src/Kurs.Platform.Domain.Shared/"
|
||||
COPY "src/Kurs.Platform.EntityFrameworkCore/Kurs.Platform.EntityFrameworkCore.csproj" "src/Kurs.Platform.EntityFrameworkCore/"
|
||||
COPY "src/Kurs.Platform.HttpApi/Kurs.Platform.HttpApi.csproj" "src/Kurs.Platform.HttpApi/"
|
||||
COPY "src/Kurs.Platform.HttpApi.Client/Kurs.Platform.HttpApi.Client.csproj" "src/Kurs.Platform.HttpApi.Client/"
|
||||
COPY "src/Kurs.Platform.HttpApi.Host/Kurs.Platform.HttpApi.Host.csproj" "src/Kurs.Platform.HttpApi.Host/"
|
||||
COPY "test/Kurs.Platform.EntityFrameworkCore.Tests/Kurs.Platform.EntityFrameworkCore.Tests.csproj" "test/Kurs.Platform.EntityFrameworkCore.Tests/"
|
||||
COPY "test/Kurs.Platform.TestBase/Kurs.Platform.TestBase.csproj" "test/Kurs.Platform.TestBase/"
|
||||
RUN dotnet restore "src/Kurs.Platform.HttpApi.Host/Kurs.Platform.HttpApi.Host.csproj"
|
||||
|
||||
COPY . .
|
||||
RUN mkdir -p publish
|
||||
RUN dotnet publish "src/Kurs.Platform.HttpApi.Host/Kurs.Platform.HttpApi.Host.csproj" -c Release -o /app/publish --no-restore
|
||||
|
||||
FROM mcr.microsoft.com/dotnet/aspnet:9.0-alpine AS final
|
||||
ENV DOTNET_SYSTEM_GLOBALIZATION_INVARIANT=false \
|
||||
LC_ALL=tr_TR.UTF-8 \
|
||||
LANG=tr_TR.UTF-8
|
||||
|
||||
# icu'lar dotnet culture icin gerekli
|
||||
# lib'ler wkhtmltopdf icin gerekli
|
||||
RUN apk update
|
||||
RUN apk add --no-cache \
|
||||
icu-data-full \
|
||||
icu-libs \
|
||||
libgdiplus \
|
||||
libc6-compat \
|
||||
libc-dev
|
||||
|
||||
# OpenSSL default TLSv3 desteklediği için MSSQL 2012'ye bağlanmıyor. Bunu çözmek için gerekli
|
||||
RUN sed -i 's/\[openssl_init\]/# [openssl_init]/' /etc/ssl/openssl.cnf
|
||||
RUN printf "\n\n[openssl_init]\nssl_conf = ssl_sect" >> /etc/ssl/openssl.cnf
|
||||
RUN printf "\n\n[ssl_sect]\nsystem_default = ssl_default_sect" >> /etc/ssl/openssl.cnf
|
||||
RUN printf "\n\n[ssl_default_sect]\nMinProtocol = TLSv1\nCipherString = DEFAULT@SECLEVEL=0\n" >> /etc/ssl/openssl.cnf
|
||||
|
||||
EXPOSE 80
|
||||
EXPOSE 443
|
||||
|
||||
WORKDIR /srv/app
|
||||
COPY --from=build /app/publish .
|
||||
ENTRYPOINT ["./Kurs.Platform.HttpApi.Host"]
|
||||
243
api/Kurs.Platform.sln
Normal file
243
api/Kurs.Platform.sln
Normal file
|
|
@ -0,0 +1,243 @@
|
|||
|
||||
Microsoft Visual Studio Solution File, Format Version 12.00
|
||||
# Visual Studio Version 17
|
||||
VisualStudioVersion = 17.4.33213.308
|
||||
MinimumVisualStudioVersion = 10.0.40219.1
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Kurs.Platform.Domain", "src\Kurs.Platform.Domain\Kurs.Platform.Domain.csproj", "{554AD327-6DBA-4F8F-96F8-81CE7A0C863F}"
|
||||
EndProject
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Kurs.Platform.Application", "src\Kurs.Platform.Application\Kurs.Platform.Application.csproj", "{1A94A50E-06DC-43C1-80B5-B662820EC3EB}"
|
||||
EndProject
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Kurs.Platform.EntityFrameworkCore", "src\Kurs.Platform.EntityFrameworkCore\Kurs.Platform.EntityFrameworkCore.csproj", "{C956DD76-69C8-4A9C-83EA-D17DF83340FD}"
|
||||
EndProject
|
||||
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "src", "src", "{CA9AC87F-097E-4F15-8393-4BC07735A5B0}"
|
||||
EndProject
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Kurs.Platform.Domain.Shared", "src\Kurs.Platform.Domain.Shared\Kurs.Platform.Domain.Shared.csproj", "{42F719ED-8413-4895-B5B4-5AB56079BC66}"
|
||||
EndProject
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Kurs.Platform.Application.Contracts", "src\Kurs.Platform.Application.Contracts\Kurs.Platform.Application.Contracts.csproj", "{520659C8-C734-4298-A3DA-B539DB9DFC0B}"
|
||||
EndProject
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Kurs.Platform.HttpApi", "src\Kurs.Platform.HttpApi\Kurs.Platform.HttpApi.csproj", "{4164BDF7-F527-4E85-9CE6-E3C2D7426A27}"
|
||||
EndProject
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Kurs.Platform.HttpApi.Client", "src\Kurs.Platform.HttpApi.Client\Kurs.Platform.HttpApi.Client.csproj", "{3B5A0094-670D-4BB1-BFDD-61B88A8773DC}"
|
||||
EndProject
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Kurs.Platform.DbMigrator", "src\Kurs.Platform.DbMigrator\Kurs.Platform.DbMigrator.csproj", "{AA94D832-1CCC-4715-95A9-A483F23A1A5D}"
|
||||
EndProject
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Kurs.Platform.HttpApi.Host", "src\Kurs.Platform.HttpApi.Host\Kurs.Platform.HttpApi.Host.csproj", "{748584B1-BA69-4F6A-81AA-F4BDE6BCE29D}"
|
||||
EndProject
|
||||
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "modules", "modules", "{03E1C8DA-035E-4882-AF81-F392139FCF38}"
|
||||
EndProject
|
||||
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Kurs.Sender", "Kurs.Sender", "{4D886EEF-D4CF-4879-A10D-249D762E4ED9}"
|
||||
EndProject
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Kurs.Sender", "modules\Kurs.Sender\Kurs.Sender.csproj", "{21B52B6A-FC09-4EDA-8A73-9516726BF50B}"
|
||||
EndProject
|
||||
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Kurs.Languages", "Kurs.Languages", "{3B18248C-EE9C-43ED-9025-D3A78986EA7D}"
|
||||
EndProject
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Kurs.Languages.Application", "modules\Kurs.Languages\Kurs.Languages.Application\Kurs.Languages.Application.csproj", "{E9D256F2-B12F-4A90-8CF6-B52724716A94}"
|
||||
EndProject
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Kurs.Languages.Application.Contracts", "modules\Kurs.Languages\Kurs.Languages.Application.Contracts\Kurs.Languages.Application.Contracts.csproj", "{F1EC497F-D361-4927-AFE6-156A0F7D8A1C}"
|
||||
EndProject
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Kurs.Languages.Domain", "modules\Kurs.Languages\Kurs.Languages.Domain\Kurs.Languages.Domain.csproj", "{9020ECD8-81D6-4604-A379-260796918C28}"
|
||||
EndProject
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Kurs.Languages.Domain.Shared", "modules\Kurs.Languages\Kurs.Languages.Domain.Shared\Kurs.Languages.Domain.Shared.csproj", "{A3933E06-9DFE-480D-85C4-66F28F076164}"
|
||||
EndProject
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Kurs.Languages.EntityFrameworkCore", "modules\Kurs.Languages\Kurs.Languages.EntityFrameworkCore\Kurs.Languages.EntityFrameworkCore.csproj", "{556AC2C2-9765-4B3D-8F38-9EAF3DA61AC5}"
|
||||
EndProject
|
||||
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Kurs.Settings", "Kurs.Settings", "{4D880243-0276-49A9-9FF2-FAD8BA727F74}"
|
||||
EndProject
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Kurs.Settings.Application", "modules\Kurs.Settings\Kurs.Settings.Application\Kurs.Settings.Application.csproj", "{5F288ACC-A9CF-470B-BB68-B1C8B102CDDD}"
|
||||
EndProject
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Kurs.Settings.Application.Contracts", "modules\Kurs.Settings\Kurs.Settings.Application.Contracts\Kurs.Settings.Application.Contracts.csproj", "{A926F04F-631B-4A05-853C-6C76555BF26A}"
|
||||
EndProject
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Kurs.Settings.Domain", "modules\Kurs.Settings\Kurs.Settings.Domain\Kurs.Settings.Domain.csproj", "{E14E0128-D4FF-462D-B684-7238EA876D69}"
|
||||
EndProject
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Kurs.Settings.Domain.Shared", "modules\Kurs.Settings\Kurs.Settings.Domain.Shared\Kurs.Settings.Domain.Shared.csproj", "{DBFD0F4B-5592-4E34-8624-04F7540E34B9}"
|
||||
EndProject
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Kurs.Settings.EntityFrameworkCore", "modules\Kurs.Settings\Kurs.Settings.EntityFrameworkCore\Kurs.Settings.EntityFrameworkCore.csproj", "{C2F5630E-A6E2-48D5-B182-5FE9278D3E37}"
|
||||
EndProject
|
||||
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "test", "test", "{62A235F3-B95E-4CB4-B59E-AAE30A0E6C5B}"
|
||||
EndProject
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Kurs.Platform.TestBase", "test\Kurs.Platform.TestBase\Kurs.Platform.TestBase.csproj", "{3E13749E-82D1-434B-B867-F7B094B66065}"
|
||||
EndProject
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Kurs.Platform.EntityFrameworkCore.Tests", "test\Kurs.Platform.EntityFrameworkCore.Tests\Kurs.Platform.EntityFrameworkCore.Tests.csproj", "{620D9F08-EB9F-469F-806A-64E915437154}"
|
||||
EndProject
|
||||
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Kurs.MailQueue", "Kurs.MailQueue", "{70BCE3C5-D122-4EF8-97EC-DB804AEE92D5}"
|
||||
EndProject
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Kurs.MailQueue", "modules\Kurs.MailQueue\Kurs.MailQueue.csproj", "{088B3139-68D3-4A5F-B159-0C8FE94CD969}"
|
||||
EndProject
|
||||
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Kurs.Notifications", "Kurs.Notifications", "{41A473FE-2537-4223-8CF3-A4A2A4A4F41E}"
|
||||
EndProject
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Kurs.Notifications.Application", "modules\Kurs.Notifications\Kurs.Notifications.Application\Kurs.Notifications.Application.csproj", "{A972109D-D974-4BB2-BA01-72BD845ACBBA}"
|
||||
EndProject
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Kurs.Notifications.Application.Contracts", "modules\Kurs.Notifications\Kurs.Notifications.Application.Contracts\Kurs.Notifications.Application.Contracts.csproj", "{297B7268-DEF3-4669-98DF-78FA08619EDF}"
|
||||
EndProject
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Kurs.Notifications.Domain", "modules\Kurs.Notifications\Kurs.Notifications.Domain\Kurs.Notifications.Domain.csproj", "{631092C7-B59D-4EA7-92D0-5E181AB4F9F6}"
|
||||
EndProject
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Kurs.Notifications.Domain.Shared", "modules\Kurs.Notifications\Kurs.Notifications.Domain.Shared\Kurs.Notifications.Domain.Shared.csproj", "{23659070-58F7-403B-8973-B2E20B5E9BE1}"
|
||||
EndProject
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Kurs.Notifications.EntityFrameworkCore", "modules\Kurs.Notifications\Kurs.Notifications.EntityFrameworkCore\Kurs.Notifications.EntityFrameworkCore.csproj", "{D9E0D333-60F3-493F-A5B2-5758ACA42A17}"
|
||||
EndProject
|
||||
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{722BAAEF-70B8-4381-A8AD-7F2C205D2D0A}"
|
||||
ProjectSection(SolutionItems) = preProject
|
||||
README.md = README.md
|
||||
EndProjectSection
|
||||
EndProject
|
||||
Global
|
||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||
Debug|Any CPU = Debug|Any CPU
|
||||
Release|Any CPU = Release|Any CPU
|
||||
EndGlobalSection
|
||||
GlobalSection(ProjectConfigurationPlatforms) = postSolution
|
||||
{554AD327-6DBA-4F8F-96F8-81CE7A0C863F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{554AD327-6DBA-4F8F-96F8-81CE7A0C863F}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{554AD327-6DBA-4F8F-96F8-81CE7A0C863F}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{554AD327-6DBA-4F8F-96F8-81CE7A0C863F}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{1A94A50E-06DC-43C1-80B5-B662820EC3EB}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{1A94A50E-06DC-43C1-80B5-B662820EC3EB}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{1A94A50E-06DC-43C1-80B5-B662820EC3EB}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{1A94A50E-06DC-43C1-80B5-B662820EC3EB}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{C956DD76-69C8-4A9C-83EA-D17DF83340FD}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{C956DD76-69C8-4A9C-83EA-D17DF83340FD}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{C956DD76-69C8-4A9C-83EA-D17DF83340FD}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{C956DD76-69C8-4A9C-83EA-D17DF83340FD}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{42F719ED-8413-4895-B5B4-5AB56079BC66}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{42F719ED-8413-4895-B5B4-5AB56079BC66}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{42F719ED-8413-4895-B5B4-5AB56079BC66}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{42F719ED-8413-4895-B5B4-5AB56079BC66}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{520659C8-C734-4298-A3DA-B539DB9DFC0B}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{520659C8-C734-4298-A3DA-B539DB9DFC0B}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{520659C8-C734-4298-A3DA-B539DB9DFC0B}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{520659C8-C734-4298-A3DA-B539DB9DFC0B}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{4164BDF7-F527-4E85-9CE6-E3C2D7426A27}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{4164BDF7-F527-4E85-9CE6-E3C2D7426A27}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{4164BDF7-F527-4E85-9CE6-E3C2D7426A27}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{4164BDF7-F527-4E85-9CE6-E3C2D7426A27}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{3B5A0094-670D-4BB1-BFDD-61B88A8773DC}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{3B5A0094-670D-4BB1-BFDD-61B88A8773DC}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{3B5A0094-670D-4BB1-BFDD-61B88A8773DC}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{3B5A0094-670D-4BB1-BFDD-61B88A8773DC}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{AA94D832-1CCC-4715-95A9-A483F23A1A5D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{AA94D832-1CCC-4715-95A9-A483F23A1A5D}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{AA94D832-1CCC-4715-95A9-A483F23A1A5D}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{AA94D832-1CCC-4715-95A9-A483F23A1A5D}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{748584B1-BA69-4F6A-81AA-F4BDE6BCE29D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{748584B1-BA69-4F6A-81AA-F4BDE6BCE29D}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{748584B1-BA69-4F6A-81AA-F4BDE6BCE29D}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{748584B1-BA69-4F6A-81AA-F4BDE6BCE29D}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{21B52B6A-FC09-4EDA-8A73-9516726BF50B}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{21B52B6A-FC09-4EDA-8A73-9516726BF50B}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{21B52B6A-FC09-4EDA-8A73-9516726BF50B}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{21B52B6A-FC09-4EDA-8A73-9516726BF50B}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{E9D256F2-B12F-4A90-8CF6-B52724716A94}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{E9D256F2-B12F-4A90-8CF6-B52724716A94}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{E9D256F2-B12F-4A90-8CF6-B52724716A94}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{E9D256F2-B12F-4A90-8CF6-B52724716A94}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{F1EC497F-D361-4927-AFE6-156A0F7D8A1C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{F1EC497F-D361-4927-AFE6-156A0F7D8A1C}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{F1EC497F-D361-4927-AFE6-156A0F7D8A1C}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{F1EC497F-D361-4927-AFE6-156A0F7D8A1C}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{9020ECD8-81D6-4604-A379-260796918C28}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{9020ECD8-81D6-4604-A379-260796918C28}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{9020ECD8-81D6-4604-A379-260796918C28}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{9020ECD8-81D6-4604-A379-260796918C28}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{A3933E06-9DFE-480D-85C4-66F28F076164}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{A3933E06-9DFE-480D-85C4-66F28F076164}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{A3933E06-9DFE-480D-85C4-66F28F076164}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{A3933E06-9DFE-480D-85C4-66F28F076164}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{556AC2C2-9765-4B3D-8F38-9EAF3DA61AC5}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{556AC2C2-9765-4B3D-8F38-9EAF3DA61AC5}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{556AC2C2-9765-4B3D-8F38-9EAF3DA61AC5}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{556AC2C2-9765-4B3D-8F38-9EAF3DA61AC5}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{5F288ACC-A9CF-470B-BB68-B1C8B102CDDD}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{5F288ACC-A9CF-470B-BB68-B1C8B102CDDD}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{5F288ACC-A9CF-470B-BB68-B1C8B102CDDD}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{5F288ACC-A9CF-470B-BB68-B1C8B102CDDD}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{A926F04F-631B-4A05-853C-6C76555BF26A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{A926F04F-631B-4A05-853C-6C76555BF26A}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{A926F04F-631B-4A05-853C-6C76555BF26A}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{A926F04F-631B-4A05-853C-6C76555BF26A}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{E14E0128-D4FF-462D-B684-7238EA876D69}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{E14E0128-D4FF-462D-B684-7238EA876D69}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{E14E0128-D4FF-462D-B684-7238EA876D69}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{E14E0128-D4FF-462D-B684-7238EA876D69}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{DBFD0F4B-5592-4E34-8624-04F7540E34B9}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{DBFD0F4B-5592-4E34-8624-04F7540E34B9}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{DBFD0F4B-5592-4E34-8624-04F7540E34B9}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{DBFD0F4B-5592-4E34-8624-04F7540E34B9}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{C2F5630E-A6E2-48D5-B182-5FE9278D3E37}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{C2F5630E-A6E2-48D5-B182-5FE9278D3E37}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{C2F5630E-A6E2-48D5-B182-5FE9278D3E37}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{C2F5630E-A6E2-48D5-B182-5FE9278D3E37}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{3E13749E-82D1-434B-B867-F7B094B66065}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{3E13749E-82D1-434B-B867-F7B094B66065}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{3E13749E-82D1-434B-B867-F7B094B66065}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{3E13749E-82D1-434B-B867-F7B094B66065}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{620D9F08-EB9F-469F-806A-64E915437154}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{620D9F08-EB9F-469F-806A-64E915437154}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{620D9F08-EB9F-469F-806A-64E915437154}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{620D9F08-EB9F-469F-806A-64E915437154}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{088B3139-68D3-4A5F-B159-0C8FE94CD969}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{088B3139-68D3-4A5F-B159-0C8FE94CD969}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{088B3139-68D3-4A5F-B159-0C8FE94CD969}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{088B3139-68D3-4A5F-B159-0C8FE94CD969}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{A972109D-D974-4BB2-BA01-72BD845ACBBA}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{A972109D-D974-4BB2-BA01-72BD845ACBBA}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{A972109D-D974-4BB2-BA01-72BD845ACBBA}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{A972109D-D974-4BB2-BA01-72BD845ACBBA}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{297B7268-DEF3-4669-98DF-78FA08619EDF}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{297B7268-DEF3-4669-98DF-78FA08619EDF}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{297B7268-DEF3-4669-98DF-78FA08619EDF}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{297B7268-DEF3-4669-98DF-78FA08619EDF}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{631092C7-B59D-4EA7-92D0-5E181AB4F9F6}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{631092C7-B59D-4EA7-92D0-5E181AB4F9F6}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{631092C7-B59D-4EA7-92D0-5E181AB4F9F6}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{631092C7-B59D-4EA7-92D0-5E181AB4F9F6}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{23659070-58F7-403B-8973-B2E20B5E9BE1}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{23659070-58F7-403B-8973-B2E20B5E9BE1}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{23659070-58F7-403B-8973-B2E20B5E9BE1}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{23659070-58F7-403B-8973-B2E20B5E9BE1}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{D9E0D333-60F3-493F-A5B2-5758ACA42A17}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{D9E0D333-60F3-493F-A5B2-5758ACA42A17}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{D9E0D333-60F3-493F-A5B2-5758ACA42A17}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{D9E0D333-60F3-493F-A5B2-5758ACA42A17}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
EndGlobalSection
|
||||
GlobalSection(SolutionProperties) = preSolution
|
||||
HideSolutionNode = FALSE
|
||||
EndGlobalSection
|
||||
GlobalSection(NestedProjects) = preSolution
|
||||
{554AD327-6DBA-4F8F-96F8-81CE7A0C863F} = {CA9AC87F-097E-4F15-8393-4BC07735A5B0}
|
||||
{1A94A50E-06DC-43C1-80B5-B662820EC3EB} = {CA9AC87F-097E-4F15-8393-4BC07735A5B0}
|
||||
{C956DD76-69C8-4A9C-83EA-D17DF83340FD} = {CA9AC87F-097E-4F15-8393-4BC07735A5B0}
|
||||
{42F719ED-8413-4895-B5B4-5AB56079BC66} = {CA9AC87F-097E-4F15-8393-4BC07735A5B0}
|
||||
{520659C8-C734-4298-A3DA-B539DB9DFC0B} = {CA9AC87F-097E-4F15-8393-4BC07735A5B0}
|
||||
{4164BDF7-F527-4E85-9CE6-E3C2D7426A27} = {CA9AC87F-097E-4F15-8393-4BC07735A5B0}
|
||||
{3B5A0094-670D-4BB1-BFDD-61B88A8773DC} = {CA9AC87F-097E-4F15-8393-4BC07735A5B0}
|
||||
{AA94D832-1CCC-4715-95A9-A483F23A1A5D} = {CA9AC87F-097E-4F15-8393-4BC07735A5B0}
|
||||
{748584B1-BA69-4F6A-81AA-F4BDE6BCE29D} = {CA9AC87F-097E-4F15-8393-4BC07735A5B0}
|
||||
{4D886EEF-D4CF-4879-A10D-249D762E4ED9} = {03E1C8DA-035E-4882-AF81-F392139FCF38}
|
||||
{21B52B6A-FC09-4EDA-8A73-9516726BF50B} = {4D886EEF-D4CF-4879-A10D-249D762E4ED9}
|
||||
{3B18248C-EE9C-43ED-9025-D3A78986EA7D} = {03E1C8DA-035E-4882-AF81-F392139FCF38}
|
||||
{E9D256F2-B12F-4A90-8CF6-B52724716A94} = {3B18248C-EE9C-43ED-9025-D3A78986EA7D}
|
||||
{F1EC497F-D361-4927-AFE6-156A0F7D8A1C} = {3B18248C-EE9C-43ED-9025-D3A78986EA7D}
|
||||
{9020ECD8-81D6-4604-A379-260796918C28} = {3B18248C-EE9C-43ED-9025-D3A78986EA7D}
|
||||
{A3933E06-9DFE-480D-85C4-66F28F076164} = {3B18248C-EE9C-43ED-9025-D3A78986EA7D}
|
||||
{556AC2C2-9765-4B3D-8F38-9EAF3DA61AC5} = {3B18248C-EE9C-43ED-9025-D3A78986EA7D}
|
||||
{4D880243-0276-49A9-9FF2-FAD8BA727F74} = {03E1C8DA-035E-4882-AF81-F392139FCF38}
|
||||
{5F288ACC-A9CF-470B-BB68-B1C8B102CDDD} = {4D880243-0276-49A9-9FF2-FAD8BA727F74}
|
||||
{A926F04F-631B-4A05-853C-6C76555BF26A} = {4D880243-0276-49A9-9FF2-FAD8BA727F74}
|
||||
{E14E0128-D4FF-462D-B684-7238EA876D69} = {4D880243-0276-49A9-9FF2-FAD8BA727F74}
|
||||
{DBFD0F4B-5592-4E34-8624-04F7540E34B9} = {4D880243-0276-49A9-9FF2-FAD8BA727F74}
|
||||
{C2F5630E-A6E2-48D5-B182-5FE9278D3E37} = {4D880243-0276-49A9-9FF2-FAD8BA727F74}
|
||||
{3E13749E-82D1-434B-B867-F7B094B66065} = {62A235F3-B95E-4CB4-B59E-AAE30A0E6C5B}
|
||||
{620D9F08-EB9F-469F-806A-64E915437154} = {62A235F3-B95E-4CB4-B59E-AAE30A0E6C5B}
|
||||
{70BCE3C5-D122-4EF8-97EC-DB804AEE92D5} = {03E1C8DA-035E-4882-AF81-F392139FCF38}
|
||||
{088B3139-68D3-4A5F-B159-0C8FE94CD969} = {70BCE3C5-D122-4EF8-97EC-DB804AEE92D5}
|
||||
{41A473FE-2537-4223-8CF3-A4A2A4A4F41E} = {03E1C8DA-035E-4882-AF81-F392139FCF38}
|
||||
{A972109D-D974-4BB2-BA01-72BD845ACBBA} = {41A473FE-2537-4223-8CF3-A4A2A4A4F41E}
|
||||
{297B7268-DEF3-4669-98DF-78FA08619EDF} = {41A473FE-2537-4223-8CF3-A4A2A4A4F41E}
|
||||
{631092C7-B59D-4EA7-92D0-5E181AB4F9F6} = {41A473FE-2537-4223-8CF3-A4A2A4A4F41E}
|
||||
{23659070-58F7-403B-8973-B2E20B5E9BE1} = {41A473FE-2537-4223-8CF3-A4A2A4A4F41E}
|
||||
{D9E0D333-60F3-493F-A5B2-5758ACA42A17} = {41A473FE-2537-4223-8CF3-A4A2A4A4F41E}
|
||||
EndGlobalSection
|
||||
GlobalSection(ExtensibilityGlobals) = postSolution
|
||||
SolutionGuid = {28315BFD-90E7-4E14-A2EA-F3D23AF4126F}
|
||||
EndGlobalSection
|
||||
EndGlobal
|
||||
23
api/Kurs.Platform.sln.DotSettings
Normal file
23
api/Kurs.Platform.sln.DotSettings
Normal file
|
|
@ -0,0 +1,23 @@
|
|||
<wpf:ResourceDictionary xml:space="preserve" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:s="clr-namespace:System;assembly=mscorlib" xmlns:ss="urn:shemas-jetbrains-com:settings-storage-xaml" xmlns:wpf="http://schemas.microsoft.com/winfx/2006/xaml/presentation">
|
||||
<s:Boolean x:Key="/Default/CodeEditing/Intellisense/CodeCompletion/IntelliSenseCompletingCharacters/CSharpCompletingCharacters/UpgradedFromVSSettings/@EntryValue">True</s:Boolean>
|
||||
<s:String x:Key="/Default/CodeInspection/Highlighting/InspectionSeverities/=EnforceDoWhileStatementBraces/@EntryIndexedValue">WARNING</s:String>
|
||||
<s:String x:Key="/Default/CodeInspection/Highlighting/InspectionSeverities/=EnforceFixedStatementBraces/@EntryIndexedValue">WARNING</s:String>
|
||||
<s:String x:Key="/Default/CodeInspection/Highlighting/InspectionSeverities/=EnforceForeachStatementBraces/@EntryIndexedValue">WARNING</s:String>
|
||||
<s:String x:Key="/Default/CodeInspection/Highlighting/InspectionSeverities/=EnforceForStatementBraces/@EntryIndexedValue">WARNING</s:String>
|
||||
<s:String x:Key="/Default/CodeInspection/Highlighting/InspectionSeverities/=EnforceIfStatementBraces/@EntryIndexedValue">WARNING</s:String>
|
||||
<s:String x:Key="/Default/CodeInspection/Highlighting/InspectionSeverities/=EnforceLockStatementBraces/@EntryIndexedValue">WARNING</s:String>
|
||||
<s:String x:Key="/Default/CodeInspection/Highlighting/InspectionSeverities/=EnforceUsingStatementBraces/@EntryIndexedValue">WARNING</s:String>
|
||||
<s:String x:Key="/Default/CodeInspection/Highlighting/InspectionSeverities/=EnforceWhileStatementBraces/@EntryIndexedValue">WARNING</s:String>
|
||||
<s:String x:Key="/Default/CodeStyle/CodeFormatting/CSharpCodeStyle/BRACES_FOR_FOR/@EntryValue">Required</s:String>
|
||||
<s:String x:Key="/Default/CodeStyle/CodeFormatting/CSharpCodeStyle/BRACES_FOR_FOREACH/@EntryValue">Required</s:String>
|
||||
<s:String x:Key="/Default/CodeStyle/CodeFormatting/CSharpCodeStyle/BRACES_FOR_IFELSE/@EntryValue">Required</s:String>
|
||||
<s:String x:Key="/Default/CodeStyle/CodeFormatting/CSharpCodeStyle/BRACES_FOR_WHILE/@EntryValue">Required</s:String>
|
||||
<s:Boolean x:Key="/Default/CodeStyle/CodeFormatting/CSharpCodeStyle/BRACES_REDUNDANT/@EntryValue">False</s:Boolean>
|
||||
<s:Boolean x:Key="/Default/CodeStyle/Generate/=Implementations/@KeyIndexDefined">True</s:Boolean>
|
||||
<s:String x:Key="/Default/CodeStyle/Generate/=Implementations/Options/=Async/@EntryIndexedValue">False</s:String>
|
||||
<s:String x:Key="/Default/CodeStyle/Generate/=Implementations/Options/=Mutable/@EntryIndexedValue">False</s:String>
|
||||
<s:Boolean x:Key="/Default/CodeStyle/Generate/=Overrides/@KeyIndexDefined">True</s:Boolean>
|
||||
<s:String x:Key="/Default/CodeStyle/Generate/=Overrides/Options/=Async/@EntryIndexedValue">False</s:String>
|
||||
<s:String x:Key="/Default/CodeStyle/Generate/=Overrides/Options/=Mutable/@EntryIndexedValue">False</s:String>
|
||||
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/Abbreviations/=SQL/@EntryIndexedValue">SQL</s:String>
|
||||
</wpf:ResourceDictionary>
|
||||
5
api/NuGet.Config
Normal file
5
api/NuGet.Config
Normal file
|
|
@ -0,0 +1,5 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<configuration>
|
||||
<packageSources>
|
||||
</packageSources>
|
||||
</configuration>
|
||||
110
api/README.md
Normal file
110
api/README.md
Normal file
|
|
@ -0,0 +1,110 @@
|
|||
# Yeni Modul Ekleme
|
||||
|
||||
`abp new Kurs.Notification -t module --no-ui -m none --database-provider ef --version 7.2.2 --old`
|
||||
|
||||
# Code Format
|
||||
|
||||
`dotnet format --include .\modules\Kurs.Notification\ --folder`
|
||||
|
||||
# Migrations
|
||||
|
||||
- Yeni migration ekleme
|
||||
`EntityFrameworkCore projesine gir`
|
||||
`dotnet ef migrations add ""`
|
||||
`dotnet ef database update`
|
||||
|
||||
- Son migrationi siler ve snapshot revert eder
|
||||
`dotnet ef migrations remove`
|
||||
`dotnet ef database update "20240822114716_ABP_822"`
|
||||
|
||||
# Public Api
|
||||
|
||||
```
|
||||
Token İsteği Örnek:
|
||||
POST /connect/token HTTP/1.1
|
||||
Host: localhost:44344
|
||||
Content-Type: application/x-www-form-urlencoded
|
||||
|
||||
username=sedat%40kadifeteks.com
|
||||
&password=...
|
||||
&grant_type=password
|
||||
&client_id=Platform_PublicApi
|
||||
&scope=offline_access%20Platform
|
||||
```
|
||||
|
||||
## Whatsapp Ayarları
|
||||
|
||||
- Normal facebook üyeliği yapılır.
|
||||
- https://developers.facebook.com/ sitesinden yeni developer üyeliği oluşturulur. Developer üyeliği seçilir.
|
||||
- CreateApp butonu ile yeni uygulama oluşturulur. Uygulama adı belirlenir. 'Sozsoft Messenger'
|
||||
- AppType olarak İşletme seçilir ve App oluşturulur.
|
||||
- Add Products kısmında WhatsApp seçilir ve Business Account oluşturulur.
|
||||
- 3 noktadan (menüden) WhatsApp Manager sayfasına gidilir. Manage Templates seçilir, istenirse yeni template oluşturulur. 'hello_world'
|
||||
- WhatsApp Manager üzerinde menüden Settings -> Users -> System Users eklenir. Kullanıcı adı 'admin' ve Role ise 'Admin' seçilir.
|
||||
- Eklenen 'admin' kullanıcısında 'Assign Assets' seçilir ve full yetki verilir.
|
||||
- admin kullanıcısı üzerinden 'Generate Token' seçilir ve aşağıdaki yetkiler verilir.
|
||||
|
||||
```
|
||||
- whatsapp_business_management'
|
||||
- 'whatsapp_business_messaging'
|
||||
```
|
||||
|
||||
- WhatsApp -> API Setup kısmından "From" kısmında yeni telefon numarası eklenir.
|
||||
- WhatsApp -> API Setup kısmından Generate Access Token oluşturulur.
|
||||
|
||||
- token: EAASM83pDJf0BO0ZCYBr3Fx4SES0ox8XiZCgP3FIteprYpwawZCkGYjpMlKk4OZCWgRNZC2Ttofgf8amMf929ZBuDcgYIOsXkPMGBNmVxm2czipzq63LmtbYfyCWsKVy0q1jtay0nRoeDuO2FKhqCfLLtNn9cSWjINVLcz26ptK8a2Oko83cZBzrNsp3cpIECnzqRfEjHdEz1U73y3ZB1MZBOhHilax7yZALf4ZA1Tmk
|
||||
- WhatsApp telefon numarasını Register etmek için aşağıdaki postman Curl gönderilir.
|
||||
|
||||
```
|
||||
curl --location 'https://graph.facebook.com/v21.0/521106361082067/register' \
|
||||
--header 'Content-Type: application/json' \
|
||||
--header 'Authorization: Bearer <access token>' \
|
||||
--data '{
|
||||
"messaging_product": "whatsapp",
|
||||
"pin": "238567"
|
||||
}'
|
||||
```
|
||||
|
||||
- Message göndermek için url : https://graph.facebook.com/v21.0/521106361082067/messages
|
||||
|
||||
```
|
||||
{
|
||||
"messaging_product": "whatsapp",
|
||||
"to": "{+gönderilecek gsm numarası}",
|
||||
"type": "template",
|
||||
"template": {
|
||||
"name": "{message_template_name}",
|
||||
"language": {
|
||||
"code": "en"
|
||||
},
|
||||
"components": [
|
||||
{
|
||||
"type": "body",
|
||||
"parameters": [
|
||||
{
|
||||
"type": "text",
|
||||
"text": "Test mesajı"
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
# ABP Update
|
||||
- https://abp.io/docs/latest/release-info/upgrading
|
||||
- https://abp.io/docs/9.0/release-info/migration-guides/abp-9-0
|
||||
- https://learn.microsoft.com/en-us/aspnet/core/migration/80-90?view=aspnetcore-9.0&tabs=visual-studio-code
|
||||
- Adımlar:
|
||||
- abp cli güncellenir dotnet tool update --global Volo.Abp.Cli
|
||||
- abp update ile sln içindeki referanslar update edilir
|
||||
- modules/ klasörü *.csproj içinde ara&düzenle ile update edilir (örn. 8.3.4 -> 9.0.2)
|
||||
- .net sürümü arttıysa Microsoft'un dotnet upgrade dokümanı takip edilir
|
||||
- Yeni dotnet sdk kurulumu yapılır (örn dotnet 9 sdk)
|
||||
- ef tools güncellenir (dotnet tool update --global dotnet-ef)
|
||||
- Dockerfile dosyalarındaki base imajlar yeni dotnet sürümüne güncellenir
|
||||
- Abp upgrade dokümanı takip edilir
|
||||
- Proje build olmuyorsa hatalar çözülür
|
||||
- Yeni migration eklenir (varsa). Migration boş çıkıyorsa kaldırılır. (Örn dotnet ef migrations add Abp902 ve dotnet ef migrations remove)
|
||||
- Migration boş değilse çalıştırılır (dotnet ef database update)
|
||||
19
api/common.props
Normal file
19
api/common.props
Normal file
|
|
@ -0,0 +1,19 @@
|
|||
<Project>
|
||||
<PropertyGroup>
|
||||
<LangVersion>latest</LangVersion>
|
||||
<Version>1.0.0</Version>
|
||||
<NoWarn>$(NoWarn);CS1591</NoWarn>
|
||||
<AbpProjectType>app</AbpProjectType>
|
||||
</PropertyGroup>
|
||||
|
||||
<Target Name="NoWarnOnRazorViewImportedTypeConflicts" BeforeTargets="RazorCoreCompile">
|
||||
<PropertyGroup>
|
||||
<NoWarn>$(NoWarn);0436</NoWarn>
|
||||
</PropertyGroup>
|
||||
</Target>
|
||||
|
||||
<ItemGroup>
|
||||
<Content Remove="$(UserProfile)\.nuget\packages\*\*\contentFiles\any\*\*.abppkg*.json" />
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
||||
6
api/global.json
Normal file
6
api/global.json
Normal file
|
|
@ -0,0 +1,6 @@
|
|||
{
|
||||
"sdk": {
|
||||
"version": "9.0.101",
|
||||
"rollForward": "latestMajor"
|
||||
}
|
||||
}
|
||||
1
api/migrate-database.ps1
Normal file
1
api/migrate-database.ps1
Normal file
|
|
@ -0,0 +1 @@
|
|||
dotnet run --project src/Kurs.Platform.DbMigrator
|
||||
|
|
@ -0,0 +1,24 @@
|
|||
using System;
|
||||
using System.ComponentModel.DataAnnotations;
|
||||
using Volo.Abp.Application.Dtos;
|
||||
|
||||
namespace Kurs.Languages;
|
||||
|
||||
public class LanguageDto : FullAuditedEntityDto<Guid>
|
||||
{
|
||||
[Required]
|
||||
public string CultureName { get; set; }
|
||||
|
||||
[Required]
|
||||
public string UiCultureName { get; set; }
|
||||
|
||||
[Required]
|
||||
public string DisplayName { get; set; }
|
||||
|
||||
[Required]
|
||||
public bool IsEnabled { get; set; }
|
||||
|
||||
/// <summary> multiple select icin test amacli olarak eklendi
|
||||
/// </summary>
|
||||
public string MultipleCultures { get; set; }
|
||||
}
|
||||
|
|
@ -0,0 +1,14 @@
|
|||
using System;
|
||||
using System.ComponentModel.DataAnnotations;
|
||||
using Volo.Abp.Application.Dtos;
|
||||
|
||||
namespace Kurs.Languages;
|
||||
|
||||
public class LanguageKeyDto : FullAuditedEntityDto<Guid>
|
||||
{
|
||||
[Required]
|
||||
public string Key { get; set; }
|
||||
|
||||
[Required]
|
||||
public string ResourceName { get; set; }
|
||||
}
|
||||
|
|
@ -0,0 +1,18 @@
|
|||
using System.ComponentModel.DataAnnotations;
|
||||
|
||||
namespace Kurs.Languages;
|
||||
|
||||
public class LanguageTextCreateUpdateDto
|
||||
{
|
||||
[Required]
|
||||
public string CultureName { get; set; }
|
||||
|
||||
[Required]
|
||||
public string Key { get; set; }
|
||||
|
||||
[Required]
|
||||
public string Value { get; set; }
|
||||
|
||||
[Required]
|
||||
public string ResourceName { get; set; }
|
||||
}
|
||||
|
|
@ -0,0 +1,12 @@
|
|||
using System;
|
||||
using Volo.Abp.Application.Dtos;
|
||||
|
||||
namespace Kurs.Languages;
|
||||
|
||||
public class LanguageTextDto : FullAuditedEntityDto<Guid>
|
||||
{
|
||||
public string CultureName { get; set; }
|
||||
public string ResourceName { get; set; }
|
||||
public string Key { get; set; }
|
||||
public string Value { get; set; }
|
||||
}
|
||||
|
|
@ -0,0 +1,15 @@
|
|||
using System.ComponentModel.DataAnnotations;
|
||||
|
||||
namespace Kurs.Languages;
|
||||
|
||||
public class LanguageTextFilteredDto
|
||||
{
|
||||
[Required]
|
||||
public string CultureName { get; set; }
|
||||
|
||||
[Required]
|
||||
public string ResourceName { get; set; }
|
||||
|
||||
[Required]
|
||||
public string Key { get; set; }
|
||||
}
|
||||
|
|
@ -0,0 +1,14 @@
|
|||
using System;
|
||||
using Volo.Abp.Application.Dtos;
|
||||
|
||||
namespace Kurs.Languages;
|
||||
|
||||
public class LanguageTextTranslatedDto : FullAuditedEntityDto<Guid>
|
||||
{
|
||||
public string BaseCultureName { get; set; }
|
||||
public string BaseValue { get; set; }
|
||||
public string TargetCultureName { get; set; }
|
||||
public string TargetValue { get; set; }
|
||||
public string ResourceName { get; set; }
|
||||
public string Key { get; set; }
|
||||
}
|
||||
|
|
@ -0,0 +1,17 @@
|
|||
using System.ComponentModel.DataAnnotations;
|
||||
using Volo.Abp.Application.Dtos;
|
||||
|
||||
namespace Kurs.Languages;
|
||||
|
||||
public class LanguageTextTranslatedRequestDto : PagedAndSortedResultRequestDto
|
||||
{
|
||||
[Required]
|
||||
public string BaseCultureName { get; set; }
|
||||
|
||||
[Required]
|
||||
public string TargetCultureName { get; set; }
|
||||
|
||||
public string ResourceName { get; set; }
|
||||
|
||||
public string Key { get; set; }
|
||||
}
|
||||
|
|
@ -0,0 +1,3 @@
|
|||
<Weavers xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="FodyWeavers.xsd">
|
||||
<ConfigureAwait ContinueOnCapturedContext="false" />
|
||||
</Weavers>
|
||||
|
|
@ -0,0 +1,30 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">
|
||||
<!-- This file was generated by Fody. Manual changes to this file will be lost when your project is rebuilt. -->
|
||||
<xs:element name="Weavers">
|
||||
<xs:complexType>
|
||||
<xs:all>
|
||||
<xs:element name="ConfigureAwait" minOccurs="0" maxOccurs="1">
|
||||
<xs:complexType>
|
||||
<xs:attribute name="ContinueOnCapturedContext" type="xs:boolean" />
|
||||
</xs:complexType>
|
||||
</xs:element>
|
||||
</xs:all>
|
||||
<xs:attribute name="VerifyAssembly" type="xs:boolean">
|
||||
<xs:annotation>
|
||||
<xs:documentation>'true' to run assembly verification (PEVerify) on the target assembly after all weavers have been executed.</xs:documentation>
|
||||
</xs:annotation>
|
||||
</xs:attribute>
|
||||
<xs:attribute name="VerifyIgnoreCodes" type="xs:string">
|
||||
<xs:annotation>
|
||||
<xs:documentation>A comma-separated list of error codes that can be safely ignored in assembly verification.</xs:documentation>
|
||||
</xs:annotation>
|
||||
</xs:attribute>
|
||||
<xs:attribute name="GenerateXsd" type="xs:boolean">
|
||||
<xs:annotation>
|
||||
<xs:documentation>'false' to turn off automatic generation of the XML Schema file.</xs:documentation>
|
||||
</xs:annotation>
|
||||
</xs:attribute>
|
||||
</xs:complexType>
|
||||
</xs:element>
|
||||
</xs:schema>
|
||||
|
|
@ -0,0 +1,14 @@
|
|||
using System;
|
||||
using System.Threading.Tasks;
|
||||
using Volo.Abp.Application.Dtos;
|
||||
using Volo.Abp.Application.Services;
|
||||
|
||||
namespace Kurs.Languages;
|
||||
|
||||
public interface ILanguageAppService : ICrudAppService<
|
||||
LanguageDto,
|
||||
Guid,
|
||||
PagedAndSortedResultRequestDto>
|
||||
{
|
||||
Task<LanguageDto> GetLanguageByCultureNameAsync(string CultureName);
|
||||
}
|
||||
|
|
@ -0,0 +1,13 @@
|
|||
using System;
|
||||
using Volo.Abp.Application.Dtos;
|
||||
using Volo.Abp.Application.Services;
|
||||
|
||||
namespace Kurs.Languages;
|
||||
|
||||
public interface ILanguageKeyAppService : ICrudAppService<
|
||||
LanguageKeyDto,
|
||||
Guid,
|
||||
PagedAndSortedResultRequestDto>
|
||||
{
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,21 @@
|
|||
using System.Threading.Tasks;
|
||||
using Volo.Abp;
|
||||
|
||||
namespace Kurs.Languages;
|
||||
|
||||
[IntegrationService]
|
||||
public interface ILanguageKeyIntegrationService
|
||||
{
|
||||
Task CreateKeysForSettingsAsync(
|
||||
string NameKey,
|
||||
string DescriptionKey,
|
||||
string MainGroupKey,
|
||||
string SubGroupKey
|
||||
);
|
||||
|
||||
Task DeleteKeysForSettingsAsync(
|
||||
string NameKey,
|
||||
string DescriptionKey,
|
||||
string MainGroupKey,
|
||||
string SubGroupKey);
|
||||
}
|
||||
|
|
@ -0,0 +1,17 @@
|
|||
using System;
|
||||
using System.Threading.Tasks;
|
||||
using Volo.Abp.Application.Dtos;
|
||||
using Volo.Abp.Application.Services;
|
||||
|
||||
namespace Kurs.Languages;
|
||||
|
||||
public interface ILanguageTextAppService : ICrudAppService<
|
||||
LanguageTextDto,
|
||||
Guid,
|
||||
PagedAndSortedResultRequestDto,
|
||||
LanguageTextCreateUpdateDto>
|
||||
{
|
||||
Task<PagedResultDto<LanguageTextTranslatedDto>> GetLanguageTextTranslatedAsync(LanguageTextTranslatedRequestDto input);
|
||||
Task<LanguageTextDto> GetLanguageTextAsync(LanguageTextFilteredDto input);
|
||||
Task UpdateLanguageTextAsync(LanguageTextCreateUpdateDto input);
|
||||
}
|
||||
|
|
@ -0,0 +1,3 @@
|
|||
{
|
||||
"role": "lib.application-contracts"
|
||||
}
|
||||
|
|
@ -0,0 +1,16 @@
|
|||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<Import Project="..\common.props" />
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFramework>net9.0</TargetFramework>
|
||||
<RootNamespace>Kurs.Languages</RootNamespace>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Volo.Abp.Ddd.Application.Contracts" Version="9.0.2" />
|
||||
<PackageReference Include="Volo.Abp.Authorization" Version="9.0.2" />
|
||||
<ProjectReference Include="..\Kurs.Languages.Domain.Shared\Kurs.Languages.Domain.Shared.csproj" />
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
||||
|
|
@ -0,0 +1,15 @@
|
|||
using Volo.Abp.Application;
|
||||
using Volo.Abp.Modularity;
|
||||
using Volo.Abp.Authorization;
|
||||
|
||||
namespace Kurs.Languages;
|
||||
|
||||
[DependsOn(
|
||||
typeof(LanguagesDomainSharedModule),
|
||||
typeof(AbpDddApplicationContractsModule),
|
||||
typeof(AbpAuthorizationModule)
|
||||
)]
|
||||
public class LanguagesApplicationContractsModule : AbpModule
|
||||
{
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,8 @@
|
|||
namespace Kurs.Languages;
|
||||
|
||||
public class LanguagesRemoteServiceConsts
|
||||
{
|
||||
public const string RemoteServiceName = "Languages";
|
||||
|
||||
public const string ModuleName = "languages";
|
||||
}
|
||||
|
|
@ -0,0 +1,18 @@
|
|||
using Kurs.Languages.Localization;
|
||||
using Volo.Abp.Authorization.Permissions;
|
||||
using Volo.Abp.Localization;
|
||||
|
||||
namespace Kurs.Languages.Permissions;
|
||||
|
||||
public class LanguagesPermissionDefinitionProvider : PermissionDefinitionProvider
|
||||
{
|
||||
public override void Define(IPermissionDefinitionContext context)
|
||||
{
|
||||
var myGroup = context.AddGroup(LanguagesPermissions.GroupName, L("Permission:Languages"));
|
||||
}
|
||||
|
||||
private static LocalizableString L(string name)
|
||||
{
|
||||
return LocalizableString.Create<LanguagesResource>(name);
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,13 @@
|
|||
using Volo.Abp.Reflection;
|
||||
|
||||
namespace Kurs.Languages.Permissions;
|
||||
|
||||
public class LanguagesPermissions
|
||||
{
|
||||
public const string GroupName = "Languages";
|
||||
|
||||
public static string[] GetAll()
|
||||
{
|
||||
return ReflectionHelper.GetPublicConstantsRecursively(typeof(LanguagesPermissions));
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,3 @@
|
|||
<Weavers xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="FodyWeavers.xsd">
|
||||
<ConfigureAwait ContinueOnCapturedContext="false" />
|
||||
</Weavers>
|
||||
|
|
@ -0,0 +1,30 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">
|
||||
<!-- This file was generated by Fody. Manual changes to this file will be lost when your project is rebuilt. -->
|
||||
<xs:element name="Weavers">
|
||||
<xs:complexType>
|
||||
<xs:all>
|
||||
<xs:element name="ConfigureAwait" minOccurs="0" maxOccurs="1">
|
||||
<xs:complexType>
|
||||
<xs:attribute name="ContinueOnCapturedContext" type="xs:boolean" />
|
||||
</xs:complexType>
|
||||
</xs:element>
|
||||
</xs:all>
|
||||
<xs:attribute name="VerifyAssembly" type="xs:boolean">
|
||||
<xs:annotation>
|
||||
<xs:documentation>'true' to run assembly verification (PEVerify) on the target assembly after all weavers have been executed.</xs:documentation>
|
||||
</xs:annotation>
|
||||
</xs:attribute>
|
||||
<xs:attribute name="VerifyIgnoreCodes" type="xs:string">
|
||||
<xs:annotation>
|
||||
<xs:documentation>A comma-separated list of error codes that can be safely ignored in assembly verification.</xs:documentation>
|
||||
</xs:annotation>
|
||||
</xs:attribute>
|
||||
<xs:attribute name="GenerateXsd" type="xs:boolean">
|
||||
<xs:annotation>
|
||||
<xs:documentation>'false' to turn off automatic generation of the XML Schema file.</xs:documentation>
|
||||
</xs:annotation>
|
||||
</xs:attribute>
|
||||
</xs:complexType>
|
||||
</xs:element>
|
||||
</xs:schema>
|
||||
|
|
@ -0,0 +1,3 @@
|
|||
{
|
||||
"role": "lib.application"
|
||||
}
|
||||
|
|
@ -0,0 +1,18 @@
|
|||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<Import Project="..\common.props" />
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFramework>net9.0</TargetFramework>
|
||||
<RootNamespace>Kurs.Languages</RootNamespace>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Volo.Abp.AutoMapper" Version="9.0.2" />
|
||||
<PackageReference Include="Volo.Abp.Ddd.Application" Version="9.0.2" />
|
||||
<PackageReference Include="Volo.Abp.EntityFrameworkCore" Version="9.0.2" />
|
||||
<ProjectReference Include="..\Kurs.Languages.Application.Contracts\Kurs.Languages.Application.Contracts.csproj" />
|
||||
<ProjectReference Include="..\Kurs.Languages.Domain\Kurs.Languages.Domain.csproj" />
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
||||
|
|
@ -0,0 +1,53 @@
|
|||
using Kurs.Languages.Entities;
|
||||
using Kurs.Languages.Localization;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.ComponentModel.DataAnnotations;
|
||||
using System.Threading.Tasks;
|
||||
using Volo.Abp.Application.Dtos;
|
||||
using Volo.Abp.Application.Services;
|
||||
using Volo.Abp.Domain.Entities;
|
||||
using Volo.Abp.Domain.Repositories;
|
||||
using Volo.Abp.Validation;
|
||||
|
||||
namespace Kurs.Languages;
|
||||
|
||||
public class LanguageAppService : CrudAppService<
|
||||
Language,
|
||||
LanguageDto,
|
||||
Guid,
|
||||
PagedAndSortedResultRequestDto>,
|
||||
ILanguageAppService
|
||||
{
|
||||
public LanguageAppService(IRepository<Language, Guid> repository) : base(repository)
|
||||
{
|
||||
LocalizationResource = typeof(LanguagesResource);
|
||||
ObjectMapperContext = typeof(LanguagesApplicationModule);
|
||||
}
|
||||
|
||||
public override async Task<LanguageDto> CreateAsync(LanguageDto input)
|
||||
{
|
||||
var recordExists = await Repository.AnyAsync(a => a.CultureName == input.CultureName);
|
||||
if (recordExists)
|
||||
{
|
||||
var validationErrors = new ValidationResult(
|
||||
L["Error:UniqueControl"],
|
||||
new string[] { "CultureName" }
|
||||
);
|
||||
throw new AbpValidationException(new List<ValidationResult> { validationErrors });
|
||||
}
|
||||
|
||||
return await base.CreateAsync(input);
|
||||
}
|
||||
|
||||
public async Task<LanguageDto> GetLanguageByCultureNameAsync(string CultureName)
|
||||
{
|
||||
var item = await Repository.FirstOrDefaultAsync(a => a.CultureName == CultureName);
|
||||
if (item is null)
|
||||
{
|
||||
throw new EntityNotFoundException(L["RecordNotFound"]);
|
||||
}
|
||||
|
||||
return ObjectMapper.Map<Language, LanguageDto>(item);
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,48 @@
|
|||
using Kurs.Languages.Entities;
|
||||
using Kurs.Languages.Localization;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.ComponentModel.DataAnnotations;
|
||||
using System.Threading.Tasks;
|
||||
using Volo.Abp.Application.Dtos;
|
||||
using Volo.Abp.Application.Services;
|
||||
using Volo.Abp.Domain.Repositories;
|
||||
using Volo.Abp.Validation;
|
||||
|
||||
namespace Kurs.Languages;
|
||||
|
||||
public class LanguageKeyAppService : CrudAppService<
|
||||
LanguageKey,
|
||||
LanguageKeyDto,
|
||||
Guid,
|
||||
PagedAndSortedResultRequestDto>,
|
||||
ILanguageKeyAppService
|
||||
{
|
||||
private readonly IRepository<LanguageKey, Guid> _repository;
|
||||
|
||||
public LanguageKeyAppService(
|
||||
IRepository<LanguageKey, Guid> repository
|
||||
) : base(repository)
|
||||
{
|
||||
LocalizationResource = typeof(LanguagesResource);
|
||||
ObjectMapperContext = typeof(LanguagesApplicationModule);
|
||||
_repository = repository;
|
||||
}
|
||||
|
||||
public override async Task<LanguageKeyDto> CreateAsync(LanguageKeyDto input)
|
||||
{
|
||||
var recordExists = await _repository.AnyAsync(
|
||||
a => a.ResourceName == input.ResourceName
|
||||
&& a.Key == input.Key);
|
||||
if (recordExists)
|
||||
{
|
||||
var validationErrors = new ValidationResult(
|
||||
L["Error:UniqueControl"],
|
||||
new string[] { "ResourceName", "Key" }
|
||||
);
|
||||
throw new AbpValidationException(new List<ValidationResult> { validationErrors });
|
||||
}
|
||||
|
||||
return await base.CreateAsync(input);
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,63 @@
|
|||
using System;
|
||||
using System.Threading.Tasks;
|
||||
using Kurs.Languages.Entities;
|
||||
using Volo.Abp;
|
||||
using Volo.Abp.DependencyInjection;
|
||||
using Volo.Abp.Domain.Repositories;
|
||||
|
||||
namespace Kurs.Languages;
|
||||
|
||||
[IntegrationService]
|
||||
public class LanguageKeyIntegrationService : ILanguageKeyIntegrationService, ITransientDependency
|
||||
{
|
||||
private readonly IRepository<LanguageKey, Guid> _repository;
|
||||
|
||||
public LanguageKeyIntegrationService(IRepository<LanguageKey, Guid> repository)
|
||||
{
|
||||
_repository = repository;
|
||||
}
|
||||
|
||||
public async Task CreateKeysForSettingsAsync(
|
||||
string NameKey,
|
||||
string DescriptionKey,
|
||||
string MainGroupKey,
|
||||
string SubGroupKey
|
||||
)
|
||||
{
|
||||
//NameKey
|
||||
if (!await _repository.AnyAsync(a => a.Key == NameKey && a.ResourceName == LanguagesConsts.AppName))
|
||||
{
|
||||
await _repository.InsertAsync(new LanguageKey { Key = NameKey, ResourceName = LanguagesConsts.AppName });
|
||||
}
|
||||
|
||||
//DescriptionKey
|
||||
if (!await _repository.AnyAsync(a => a.Key == DescriptionKey && a.ResourceName == LanguagesConsts.AppName))
|
||||
{
|
||||
await _repository.InsertAsync(new LanguageKey { Key = DescriptionKey, ResourceName = LanguagesConsts.AppName });
|
||||
}
|
||||
|
||||
//MainGroupKey
|
||||
if (!await _repository.AnyAsync(a => a.Key == MainGroupKey && a.ResourceName == LanguagesConsts.AppName))
|
||||
{
|
||||
await _repository.InsertAsync(new LanguageKey { Key = MainGroupKey, ResourceName = LanguagesConsts.AppName });
|
||||
}
|
||||
|
||||
//SubGroupKey
|
||||
if (!await _repository.AnyAsync(a => a.Key == SubGroupKey && a.ResourceName == LanguagesConsts.AppName))
|
||||
{
|
||||
await _repository.InsertAsync(new LanguageKey { Key = SubGroupKey, ResourceName = LanguagesConsts.AppName });
|
||||
}
|
||||
}
|
||||
|
||||
public async Task DeleteKeysForSettingsAsync(
|
||||
string NameKey,
|
||||
string DescriptionKey,
|
||||
string MainGroupKey,
|
||||
string SubGroupKey)
|
||||
{
|
||||
await _repository.DeleteAsync(a => a.Key == NameKey && a.ResourceName == LanguagesConsts.AppName);
|
||||
await _repository.DeleteAsync(a => a.Key == DescriptionKey && a.ResourceName == LanguagesConsts.AppName);
|
||||
await _repository.DeleteAsync(a => a.Key == MainGroupKey && a.ResourceName == LanguagesConsts.AppName);
|
||||
await _repository.DeleteAsync(a => a.Key == SubGroupKey && a.ResourceName == LanguagesConsts.AppName);
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,164 @@
|
|||
using Kurs.Languages.Entities;
|
||||
using Kurs.Languages.Localization;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.ComponentModel.DataAnnotations;
|
||||
using System.Linq;
|
||||
using System.Linq.Dynamic.Core;
|
||||
using System.Threading.Tasks;
|
||||
using Volo.Abp;
|
||||
using Volo.Abp.Application.Dtos;
|
||||
using Volo.Abp.Application.Services;
|
||||
using Volo.Abp.Auditing;
|
||||
using Volo.Abp.Domain.Repositories;
|
||||
using Volo.Abp.Validation;
|
||||
|
||||
namespace Kurs.Languages;
|
||||
|
||||
public class LanguageTextAppService : CrudAppService<
|
||||
LanguageText,
|
||||
LanguageTextDto,
|
||||
Guid,
|
||||
PagedAndSortedResultRequestDto,
|
||||
LanguageTextCreateUpdateDto>,
|
||||
ILanguageTextAppService
|
||||
{
|
||||
private readonly IRepository<LanguageText, Guid> _repositoryText;
|
||||
private readonly IRepository<LanguageKey, Guid> _repositoryKey;
|
||||
|
||||
public LanguageTextAppService(
|
||||
IRepository<LanguageText, Guid> repositoryText,
|
||||
IRepository<LanguageKey, Guid> repositoryKey
|
||||
)
|
||||
: base(repositoryText)
|
||||
{
|
||||
LocalizationResource = typeof(LanguagesResource);
|
||||
ObjectMapperContext = typeof(LanguagesApplicationModule);
|
||||
_repositoryText = repositoryText;
|
||||
_repositoryKey = repositoryKey;
|
||||
}
|
||||
|
||||
public override async Task<LanguageTextDto> CreateAsync(LanguageTextCreateUpdateDto input)
|
||||
{
|
||||
var recordExists = await _repositoryText.AnyAsync(
|
||||
a => a.CultureName == input.CultureName &&
|
||||
a.Key == input.Key &&
|
||||
a.ResourceName == input.ResourceName);
|
||||
if (recordExists)
|
||||
{
|
||||
var validationErrors = new ValidationResult(
|
||||
L["Error:UniqueControl"],
|
||||
new string[] { "CultureName", "Key", "ResourceName" }
|
||||
);
|
||||
throw new AbpValidationException(new List<ValidationResult> { validationErrors });
|
||||
}
|
||||
|
||||
return await base.CreateAsync(input);
|
||||
}
|
||||
|
||||
public async Task UpdateLanguageTextAsync(LanguageTextCreateUpdateDto input)
|
||||
{
|
||||
var entity = await _repositoryText.GetAsync(
|
||||
a => a.CultureName == input.CultureName &&
|
||||
a.ResourceName == input.ResourceName &&
|
||||
a.Key == input.Key);
|
||||
if (entity != null)
|
||||
{
|
||||
entity.Value = input.Value;
|
||||
|
||||
await _repositoryText.UpdateAsync(entity);
|
||||
}
|
||||
}
|
||||
|
||||
public async Task<PagedResultDto<LanguageTextTranslatedDto>> GetLanguageTextTranslatedAsync(LanguageTextTranslatedRequestDto input)
|
||||
{
|
||||
var query = await _repositoryKey.GetQueryableAsync();
|
||||
query = query
|
||||
.WhereIf(!input.ResourceName.IsNullOrEmpty(), a => a.ResourceName == input.ResourceName)
|
||||
.WhereIf(!input.Key.IsNullOrEmpty(), a => a.Key == input.Key);
|
||||
var totalCount = await query.CountAsync();
|
||||
query = ApplySorting(query, input);
|
||||
query = ApplyPaging(query, input);
|
||||
var keys = await query.ToListAsync();
|
||||
|
||||
var dtoLanguageTextTranslate = ObjectMapper.Map<List<LanguageKey>, List<LanguageTextTranslatedDto>>(keys);
|
||||
|
||||
var dtoBaseCulturesValue = await _repositoryText.GetListAsync(a => a.CultureName == input.BaseCultureName);
|
||||
var dtoTargetCulturesValue = await _repositoryText.GetListAsync(a => a.CultureName == input.TargetCultureName);
|
||||
|
||||
dtoLanguageTextTranslate.ForEach(dto =>
|
||||
{
|
||||
var baseEntity = dtoBaseCulturesValue.FirstOrDefault(a => a.Key == dto.Key && a.ResourceName == dto.ResourceName);
|
||||
|
||||
dto.BaseCultureName = input.BaseCultureName;
|
||||
dto.BaseValue = baseEntity?.Value;
|
||||
|
||||
var targetEntity = dtoTargetCulturesValue.FirstOrDefault(a => a.Key == dto.Key && a.ResourceName == dto.ResourceName);
|
||||
|
||||
dto.TargetCultureName = input.TargetCultureName;
|
||||
dto.TargetValue = targetEntity?.Value;
|
||||
});
|
||||
|
||||
return new PagedResultDto<LanguageTextTranslatedDto>(totalCount, dtoLanguageTextTranslate);
|
||||
}
|
||||
|
||||
public async Task<LanguageTextDto> GetLanguageTextAsync(LanguageTextFilteredDto input)
|
||||
{
|
||||
var entity = await _repositoryText.FirstOrDefaultAsync(a =>
|
||||
a.CultureName == input.CultureName &&
|
||||
a.ResourceName == input.ResourceName &&
|
||||
a.Key == input.Key);
|
||||
|
||||
return ObjectMapper.Map<LanguageText, LanguageTextDto>(entity);
|
||||
}
|
||||
|
||||
protected virtual IQueryable<LanguageKey> ApplySorting(IQueryable<LanguageKey> query, LanguageTextTranslatedRequestDto input)
|
||||
{
|
||||
//Try to sort query if available
|
||||
if (input is ISortedResultRequest sortInput)
|
||||
{
|
||||
if (!sortInput.Sorting.IsNullOrWhiteSpace())
|
||||
{
|
||||
return query.OrderBy(sortInput.Sorting);
|
||||
}
|
||||
}
|
||||
|
||||
//IQueryable.Task requires sorting, so we should sort if Take will be used.
|
||||
if (input is ILimitedResultRequest)
|
||||
{
|
||||
return ApplyDefaultSorting(query);
|
||||
}
|
||||
|
||||
//No sorting
|
||||
return query;
|
||||
}
|
||||
|
||||
protected virtual IQueryable<LanguageKey> ApplyDefaultSorting(IQueryable<LanguageKey> query)
|
||||
{
|
||||
if (typeof(LanguageKey).IsAssignableTo<IHasCreationTime>())
|
||||
{
|
||||
return query.OrderByDescending(e => ((IHasCreationTime)e).CreationTime);
|
||||
}
|
||||
|
||||
throw new AbpException("No sorting specified but this query requires sorting. Override the ApplyDefaultSorting method for your application service derived from AbstractKeyReadOnlyAppService!");
|
||||
}
|
||||
|
||||
protected virtual IQueryable<LanguageKey> ApplyPaging(IQueryable<LanguageKey> query, LanguageTextTranslatedRequestDto input)
|
||||
{
|
||||
//Try to use paging if available
|
||||
if (input is IPagedResultRequest pagedInput)
|
||||
{
|
||||
return query.PageBy(pagedInput);
|
||||
}
|
||||
|
||||
//Try to limit query result if available
|
||||
if (input is ILimitedResultRequest limitedInput)
|
||||
{
|
||||
return query.Take(limitedInput.MaxResultCount);
|
||||
}
|
||||
|
||||
//No paging
|
||||
return query;
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,13 @@
|
|||
using Kurs.Languages.Localization;
|
||||
using Volo.Abp.Application.Services;
|
||||
|
||||
namespace Kurs.Languages;
|
||||
|
||||
public abstract class LanguagesAppService : ApplicationService
|
||||
{
|
||||
protected LanguagesAppService()
|
||||
{
|
||||
LocalizationResource = typeof(LanguagesResource);
|
||||
ObjectMapperContext = typeof(LanguagesApplicationModule);
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,26 @@
|
|||
using AutoMapper;
|
||||
using Kurs.Languages.Entities;
|
||||
using Volo.Abp.AutoMapper;
|
||||
using Volo.Abp.Localization;
|
||||
|
||||
namespace Kurs.Languages;
|
||||
|
||||
public class LanguagesApplicationAutoMapperProfile : Profile
|
||||
{
|
||||
public LanguagesApplicationAutoMapperProfile()
|
||||
{
|
||||
CreateMap<Language, LanguageInfo>();
|
||||
CreateMap<Language, LanguageDto>();
|
||||
CreateMap<LanguageKey, LanguageKeyDto>();
|
||||
CreateMap<LanguageText, LanguageTextDto>();
|
||||
CreateMap<LanguageText, LanguageTextEto>();
|
||||
CreateMap<LanguageTextCreateUpdateDto, LanguageText>()
|
||||
.IgnoreAllPropertiesWithAnInaccessibleSetter()
|
||||
.IgnoreFullAuditedObjectProperties();
|
||||
CreateMap<LanguageKey, LanguageTextTranslatedDto>()
|
||||
.ForMember(d => d.Key, o => o.MapFrom(s => s.Key))
|
||||
.ForMember(d => d.ResourceName, o => o.MapFrom(s => s.ResourceName))
|
||||
.ForAllMembers(o => o.Ignore());
|
||||
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,25 @@
|
|||
using Microsoft.Extensions.DependencyInjection;
|
||||
using Volo.Abp.Application;
|
||||
using Volo.Abp.AutoMapper;
|
||||
using Volo.Abp.Modularity;
|
||||
|
||||
namespace Kurs.Languages;
|
||||
|
||||
[DependsOn(
|
||||
typeof(LanguagesDomainModule),
|
||||
typeof(LanguagesApplicationContractsModule),
|
||||
typeof(AbpDddApplicationModule),
|
||||
typeof(AbpAutoMapperModule)
|
||||
)]
|
||||
public class LanguagesApplicationModule : AbpModule
|
||||
{
|
||||
public override void ConfigureServices(ServiceConfigurationContext context)
|
||||
{
|
||||
context.Services.AddAutoMapperObjectMapper<LanguagesApplicationModule>();
|
||||
|
||||
Configure<AbpAutoMapperOptions>(options =>
|
||||
{
|
||||
options.AddMaps<LanguagesApplicationModule>(validate: true);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,3 @@
|
|||
<Weavers xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="FodyWeavers.xsd">
|
||||
<ConfigureAwait ContinueOnCapturedContext="false" />
|
||||
</Weavers>
|
||||
|
|
@ -0,0 +1,30 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">
|
||||
<!-- This file was generated by Fody. Manual changes to this file will be lost when your project is rebuilt. -->
|
||||
<xs:element name="Weavers">
|
||||
<xs:complexType>
|
||||
<xs:all>
|
||||
<xs:element name="ConfigureAwait" minOccurs="0" maxOccurs="1">
|
||||
<xs:complexType>
|
||||
<xs:attribute name="ContinueOnCapturedContext" type="xs:boolean" />
|
||||
</xs:complexType>
|
||||
</xs:element>
|
||||
</xs:all>
|
||||
<xs:attribute name="VerifyAssembly" type="xs:boolean">
|
||||
<xs:annotation>
|
||||
<xs:documentation>'true' to run assembly verification (PEVerify) on the target assembly after all weavers have been executed.</xs:documentation>
|
||||
</xs:annotation>
|
||||
</xs:attribute>
|
||||
<xs:attribute name="VerifyIgnoreCodes" type="xs:string">
|
||||
<xs:annotation>
|
||||
<xs:documentation>A comma-separated list of error codes that can be safely ignored in assembly verification.</xs:documentation>
|
||||
</xs:annotation>
|
||||
</xs:attribute>
|
||||
<xs:attribute name="GenerateXsd" type="xs:boolean">
|
||||
<xs:annotation>
|
||||
<xs:documentation>'false' to turn off automatic generation of the XML Schema file.</xs:documentation>
|
||||
</xs:annotation>
|
||||
</xs:attribute>
|
||||
</xs:complexType>
|
||||
</xs:element>
|
||||
</xs:schema>
|
||||
|
|
@ -0,0 +1,3 @@
|
|||
{
|
||||
"role": "lib.domain-shared"
|
||||
}
|
||||
|
|
@ -0,0 +1,19 @@
|
|||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<Import Project="..\common.props" />
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFramework>net9.0</TargetFramework>
|
||||
<GenerateEmbeddedFilesManifest>true</GenerateEmbeddedFilesManifest>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Volo.Abp.Ddd.Domain.Shared" Version="9.0.2" />
|
||||
<PackageReference Include="Volo.Abp.Validation" Version="9.0.2" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Microsoft.Extensions.FileProviders.Embedded" Version="9.0.0" />
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
||||
|
|
@ -0,0 +1,7 @@
|
|||
namespace Kurs.Languages;
|
||||
|
||||
public static class LanguagesConsts
|
||||
{
|
||||
public const string AppName = "Languages";
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,34 @@
|
|||
using Kurs.Languages.Localization;
|
||||
using Volo.Abp.Domain;
|
||||
using Volo.Abp.Localization;
|
||||
using Volo.Abp.Localization.ExceptionHandling;
|
||||
using Volo.Abp.Modularity;
|
||||
using Volo.Abp.Validation;
|
||||
using Volo.Abp.VirtualFileSystem;
|
||||
|
||||
namespace Kurs.Languages;
|
||||
|
||||
[DependsOn(
|
||||
typeof(AbpValidationModule),
|
||||
typeof(AbpDddDomainSharedModule)
|
||||
)]
|
||||
public class LanguagesDomainSharedModule : AbpModule
|
||||
{
|
||||
public override void ConfigureServices(ServiceConfigurationContext context)
|
||||
{
|
||||
Configure<AbpVirtualFileSystemOptions>(options =>
|
||||
{
|
||||
options.FileSets.AddEmbedded<LanguagesDomainSharedModule>();
|
||||
});
|
||||
|
||||
Configure<AbpLocalizationOptions>(options =>
|
||||
{
|
||||
options.Resources.Add<LanguagesResource>("en");
|
||||
});
|
||||
|
||||
Configure<AbpExceptionLocalizationOptions>(options =>
|
||||
{
|
||||
options.MapCodeNamespace("Languages", typeof(LanguagesResource));
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,6 @@
|
|||
namespace Kurs.Languages;
|
||||
|
||||
public static class LanguagesErrorCodes
|
||||
{
|
||||
//Add your business exception error codes here...
|
||||
}
|
||||
|
|
@ -0,0 +1,44 @@
|
|||
namespace Kurs.Languages.Languages
|
||||
{
|
||||
public static class LanguageCodes
|
||||
{
|
||||
public const string Ar = "ar";
|
||||
public const string Cs = "cs";
|
||||
public const string De = "de-DE";
|
||||
public const string En = "en";
|
||||
public const string Es = "es";
|
||||
public const string Fi = "fi";
|
||||
public const string Fr = "fr";
|
||||
public const string Hi = "hi";
|
||||
public const string Hr = "hr";
|
||||
public const string Hu = "hu";
|
||||
public const string It = "it";
|
||||
public const string Pt = "pt-BR";
|
||||
public const string Ru = "ru";
|
||||
public const string Sk = "sk";
|
||||
public const string Sl = "sl";
|
||||
public const string Tr = "tr";
|
||||
public const string Zh = "zh-Hans";
|
||||
}
|
||||
|
||||
public static class LanguageNames
|
||||
{
|
||||
public const string Ar = "العربية";
|
||||
public const string Cs = "Čeština";
|
||||
public const string De = "Deutsch";
|
||||
public const string En = "English";
|
||||
public const string Es = "Español";
|
||||
public const string Fi = "Finnish";
|
||||
public const string Fr = "Français";
|
||||
public const string Hi = "Hindi";
|
||||
public const string Hr = "Croatian";
|
||||
public const string Hu = "Magyar";
|
||||
public const string It = "Italiano";
|
||||
public const string Pt = "Português";
|
||||
public const string Ru = "Русский";
|
||||
public const string Sk = "Slovak";
|
||||
public const string Sl = "Slovenščina";
|
||||
public const string Tr = "Türkçe";
|
||||
public const string Zh = "繁體中文";
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,9 @@
|
|||
using Volo.Abp.Localization;
|
||||
|
||||
namespace Kurs.Languages.Localization;
|
||||
|
||||
[LocalizationResourceName(LanguagesConsts.AppName)]
|
||||
public class LanguagesResource
|
||||
{
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,17 @@
|
|||
using System;
|
||||
using Volo.Abp.Domain.Entities.Auditing;
|
||||
|
||||
namespace Kurs.Languages.Entities;
|
||||
|
||||
public class Language : FullAuditedEntity<Guid>
|
||||
{
|
||||
public string CultureName { get; set; }
|
||||
public string UiCultureName { get; set; }
|
||||
public string DisplayName { get; set; }
|
||||
public bool IsEnabled { get; set; }
|
||||
public string TwoLetterISOLanguageName { get; set; }
|
||||
/// <summary> multiple select icin test amacli olarak eklendi
|
||||
/// </summary>
|
||||
public string MultipleCultures { get; set; }
|
||||
}
|
||||
|
||||
|
|
@ -0,0 +1,14 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using Volo.Abp.Domain.Entities.Auditing;
|
||||
|
||||
namespace Kurs.Languages.Entities;
|
||||
|
||||
public class LanguageKey : FullAuditedEntity<Guid>
|
||||
{
|
||||
public string Key { get; set; }
|
||||
public string ResourceName { get; set; }
|
||||
|
||||
public ICollection<LanguageText> Texts { get; set; }
|
||||
}
|
||||
|
||||
|
|
@ -0,0 +1,13 @@
|
|||
using System;
|
||||
using Volo.Abp.Domain.Entities.Auditing;
|
||||
|
||||
namespace Kurs.Languages.Entities;
|
||||
|
||||
public class LanguageText : FullAuditedEntity<Guid>
|
||||
{
|
||||
public string CultureName { get; set; }
|
||||
public string? Key { get; set; }
|
||||
public string Value { get; set; }
|
||||
public string? ResourceName { get; set; }
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,3 @@
|
|||
<Weavers xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="FodyWeavers.xsd">
|
||||
<ConfigureAwait ContinueOnCapturedContext="false" />
|
||||
</Weavers>
|
||||
|
|
@ -0,0 +1,30 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">
|
||||
<!-- This file was generated by Fody. Manual changes to this file will be lost when your project is rebuilt. -->
|
||||
<xs:element name="Weavers">
|
||||
<xs:complexType>
|
||||
<xs:all>
|
||||
<xs:element name="ConfigureAwait" minOccurs="0" maxOccurs="1">
|
||||
<xs:complexType>
|
||||
<xs:attribute name="ContinueOnCapturedContext" type="xs:boolean" />
|
||||
</xs:complexType>
|
||||
</xs:element>
|
||||
</xs:all>
|
||||
<xs:attribute name="VerifyAssembly" type="xs:boolean">
|
||||
<xs:annotation>
|
||||
<xs:documentation>'true' to run assembly verification (PEVerify) on the target assembly after all weavers have been executed.</xs:documentation>
|
||||
</xs:annotation>
|
||||
</xs:attribute>
|
||||
<xs:attribute name="VerifyIgnoreCodes" type="xs:string">
|
||||
<xs:annotation>
|
||||
<xs:documentation>A comma-separated list of error codes that can be safely ignored in assembly verification.</xs:documentation>
|
||||
</xs:annotation>
|
||||
</xs:attribute>
|
||||
<xs:attribute name="GenerateXsd" type="xs:boolean">
|
||||
<xs:annotation>
|
||||
<xs:documentation>'false' to turn off automatic generation of the XML Schema file.</xs:documentation>
|
||||
</xs:annotation>
|
||||
</xs:attribute>
|
||||
</xs:complexType>
|
||||
</xs:element>
|
||||
</xs:schema>
|
||||
|
|
@ -0,0 +1,3 @@
|
|||
{
|
||||
"role": "lib.domain"
|
||||
}
|
||||
|
|
@ -0,0 +1,16 @@
|
|||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<Import Project="..\common.props" />
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFramework>net9.0</TargetFramework>
|
||||
<RootNamespace>Kurs.Languages</RootNamespace>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Volo.Abp.Caching.StackExchangeRedis" Version="9.0.2" />
|
||||
<PackageReference Include="Volo.Abp.Ddd.Domain" Version="9.0.2" />
|
||||
<ProjectReference Include="..\Kurs.Languages.Domain.Shared\Kurs.Languages.Domain.Shared.csproj" />
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
||||
|
|
@ -0,0 +1,9 @@
|
|||
using System.Collections.Generic;
|
||||
using Volo.Abp.Localization;
|
||||
|
||||
namespace Kurs.Languages;
|
||||
|
||||
public class LanguageListCacheItem
|
||||
{
|
||||
public IReadOnlyList<LanguageInfo> Languages { get; set; }
|
||||
}
|
||||
|
|
@ -0,0 +1,17 @@
|
|||
using System.Collections.Generic;
|
||||
|
||||
namespace Kurs.Languages;
|
||||
|
||||
public class LanguageTextCacheItem : object
|
||||
{
|
||||
public Dictionary<string, string> Dictionary { get; set; }
|
||||
|
||||
public LanguageTextCacheItem()
|
||||
{ }
|
||||
|
||||
public static string CalculateCacheKey(string resourceName, string cultureName)
|
||||
{
|
||||
// .en.Kurs.Dynamics
|
||||
return $".{cultureName}.{resourceName}";
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,28 @@
|
|||
using System.Threading.Tasks;
|
||||
using Kurs.Languages.Entities;
|
||||
using Volo.Abp.Caching;
|
||||
using Volo.Abp.DependencyInjection;
|
||||
using Volo.Abp.Domain.Entities.Events;
|
||||
using Volo.Abp.EventBus;
|
||||
|
||||
namespace Kurs.Languages;
|
||||
|
||||
public class LanguageTextCacheItemInvalidator :
|
||||
ILocalEventHandler<EntityChangedEventData<LanguageText>>,
|
||||
ITransientDependency
|
||||
{
|
||||
private readonly IDistributedCache<LanguageTextCacheItem> cache;
|
||||
|
||||
public LanguageTextCacheItemInvalidator(IDistributedCache<LanguageTextCacheItem> cache)
|
||||
{
|
||||
this.cache = cache;
|
||||
}
|
||||
|
||||
public async Task HandleEventAsync(EntityChangedEventData<LanguageText> eventData)
|
||||
{
|
||||
//distributedCacheOptions.Value.KeyPrefix
|
||||
var key = LanguageTextCacheItem.CalculateCacheKey(eventData.Entity.ResourceName, eventData.Entity.CultureName);
|
||||
await cache.RemoveAsync(key);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,77 @@
|
|||
using Kurs.Languages.Entities;
|
||||
using System;
|
||||
using System.Threading.Tasks;
|
||||
using Volo.Abp.Caching;
|
||||
using Volo.Abp.DependencyInjection;
|
||||
using Volo.Abp.Domain.Entities.Events.Distributed;
|
||||
using Volo.Abp.Domain.Repositories;
|
||||
using Volo.Abp.EventBus.Distributed;
|
||||
|
||||
namespace Kurs.Languages;
|
||||
|
||||
public class LanguageTextCacheItemInvalidatorDistributed :
|
||||
IDistributedEventHandler<EntityCreatedEto<LanguageTextEto>>,
|
||||
IDistributedEventHandler<EntityUpdatedEto<LanguageTextEto>>,
|
||||
IDistributedEventHandler<EntityDeletedEto<LanguageTextEto>>,
|
||||
ITransientDependency
|
||||
{
|
||||
private readonly IRepository<LanguageText, Guid> languageTextRepository;
|
||||
private readonly IDistributedCache<LanguageTextCacheItem> cache;
|
||||
|
||||
public LanguageTextCacheItemInvalidatorDistributed(
|
||||
IRepository<LanguageText, Guid> languageTextRepository,
|
||||
IDistributedCache<LanguageTextCacheItem> cache)
|
||||
{
|
||||
this.languageTextRepository = languageTextRepository;
|
||||
this.cache = cache;
|
||||
}
|
||||
|
||||
public async Task HandleEventAsync(EntityCreatedEto<LanguageTextEto> eventData)
|
||||
{
|
||||
await InvalidateCacheAsync(eventData.Entity);
|
||||
}
|
||||
|
||||
public async Task HandleEventAsync(EntityUpdatedEto<LanguageTextEto> eventData)
|
||||
{
|
||||
await InvalidateCacheAsync(eventData.Entity);
|
||||
}
|
||||
|
||||
public async Task HandleEventAsync(EntityDeletedEto<LanguageTextEto> eventData)
|
||||
{
|
||||
await InvalidateCacheAsync(eventData.Entity);
|
||||
}
|
||||
|
||||
private async Task InvalidateCacheAsync(LanguageTextEto eventData)
|
||||
{
|
||||
var key = LanguageTextCacheItem.CalculateCacheKey(eventData.ResourceName, eventData.CultureName);
|
||||
await cache.RemoveAsync(key);
|
||||
}
|
||||
}
|
||||
|
||||
public class LanguageTextEto
|
||||
{
|
||||
public string CultureName { get; set; }
|
||||
public string ResourceName { get; set; }
|
||||
}
|
||||
|
||||
|
||||
// For distributed event bus
|
||||
//private void ConfigureDistributedEventBus()
|
||||
//{
|
||||
// Configure<AbpDistributedEntityEventOptions>(options =>
|
||||
// {
|
||||
// //Enable for all entities
|
||||
// //options.AutoEventSelectors.AddAll();
|
||||
|
||||
// //Enable for a single entity
|
||||
// options.AutoEventSelectors.Add<LanguageText>();
|
||||
// options.EtoMappings.Add<LanguageText, LanguageTextEto>();
|
||||
|
||||
// //Enable for all entities in a namespace (and child namespaces)
|
||||
// //options.AutoEventSelectors.AddNamespace("MyProject.Products");
|
||||
|
||||
// //Custom predicate expression that should return true to select a type
|
||||
// //options.AutoEventSelectors.Add(type => type.Namespace.StartsWith("MyProject."));
|
||||
// });
|
||||
//}
|
||||
|
||||
|
|
@ -0,0 +1,10 @@
|
|||
namespace Kurs.Languages;
|
||||
|
||||
public static class LanguagesDbProperties
|
||||
{
|
||||
public static string DbTablePrefix { get; set; } = "P";
|
||||
|
||||
public static string? DbSchema { get; set; } = null;
|
||||
|
||||
public const string ConnectionStringName = "Languages";
|
||||
}
|
||||
|
|
@ -0,0 +1,24 @@
|
|||
using Kurs.Languages.Localization;
|
||||
using Volo.Abp.Caching.StackExchangeRedis;
|
||||
using Volo.Abp.Domain;
|
||||
using Volo.Abp.Localization;
|
||||
using Volo.Abp.Modularity;
|
||||
|
||||
namespace Kurs.Languages;
|
||||
|
||||
[DependsOn(
|
||||
typeof(AbpDddDomainModule),
|
||||
typeof(AbpLocalizationModule),
|
||||
typeof(AbpCachingStackExchangeRedisModule),
|
||||
typeof(LanguagesDomainSharedModule)
|
||||
)]
|
||||
public class LanguagesDomainModule : AbpModule
|
||||
{
|
||||
public override void ConfigureServices(ServiceConfigurationContext context)
|
||||
{
|
||||
Configure<AbpLocalizationOptions>(options =>
|
||||
{
|
||||
options.GlobalContributors.Add<DatabaseLocalizationResourceContributor>();
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,45 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
using Kurs.Languages.Entities;
|
||||
using Volo.Abp.Caching;
|
||||
using Volo.Abp.DependencyInjection;
|
||||
using Volo.Abp.Domain.Repositories;
|
||||
using Volo.Abp.Localization;
|
||||
|
||||
namespace Kurs.Languages.Localization;
|
||||
|
||||
[Dependency(ReplaceServices = true)]
|
||||
public class DatabaseLanguageProvider : ILanguageProvider, ITransientDependency
|
||||
{
|
||||
private readonly IReadOnlyBasicRepository<Language, Guid> languageRepository;
|
||||
private readonly IDistributedCache<LanguageListCacheItem> cache;
|
||||
|
||||
public const string CacheKey = "Languages";
|
||||
|
||||
public DatabaseLanguageProvider(
|
||||
IReadOnlyBasicRepository<Language, Guid> languageRepository,
|
||||
IDistributedCache<LanguageListCacheItem> cache)
|
||||
{
|
||||
this.languageRepository = languageRepository;
|
||||
this.cache = cache;
|
||||
}
|
||||
|
||||
public async Task<IReadOnlyList<LanguageInfo>> GetLanguagesAsync()
|
||||
{
|
||||
var langs = await cache.GetOrAddAsync(CacheKey, GetLanguagesFromDB);
|
||||
return langs.Languages;
|
||||
}
|
||||
|
||||
private async Task<LanguageListCacheItem> GetLanguagesFromDB()
|
||||
{
|
||||
var langs = await languageRepository.GetListAsync();
|
||||
return new LanguageListCacheItem
|
||||
{
|
||||
Languages = langs.OrderBy(o => o.DisplayName)
|
||||
.Select(a => new LanguageInfo(a.CultureName, a.UiCultureName, a.DisplayName))
|
||||
.ToList()
|
||||
};
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,45 @@
|
|||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using Microsoft.Extensions.Localization;
|
||||
using Volo.Abp.Localization;
|
||||
|
||||
namespace Kurs.Languages.Localization;
|
||||
|
||||
public class DatabaseLocalizationResourceContributor : ILocalizationResourceContributor
|
||||
{
|
||||
private LocalizationResourceBase _resource;
|
||||
private IDatabaseResourceLocalizer _databaseResourceLocalizer;
|
||||
private ILanguageProvider _languageProvider;
|
||||
|
||||
public bool IsDynamic => false;
|
||||
|
||||
public void Initialize(LocalizationResourceInitializationContext context)
|
||||
{
|
||||
_resource = context.Resource;
|
||||
_databaseResourceLocalizer = context.ServiceProvider.GetRequiredService<IDatabaseResourceLocalizer>();
|
||||
_languageProvider = context.ServiceProvider.GetRequiredService<ILanguageProvider>();
|
||||
}
|
||||
|
||||
public LocalizedString GetOrNull(string cultureName, string name)
|
||||
{
|
||||
return _databaseResourceLocalizer.GetOrNull(_resource, cultureName, name);
|
||||
}
|
||||
|
||||
public async Task FillAsync(string cultureName, Dictionary<string, LocalizedString> dictionary)
|
||||
{
|
||||
await _databaseResourceLocalizer.FillAsync(_resource, cultureName, dictionary);
|
||||
}
|
||||
|
||||
public void Fill(string cultureName, Dictionary<string, LocalizedString> dictionary)
|
||||
{
|
||||
_databaseResourceLocalizer.Fill(_resource, cultureName, dictionary);
|
||||
}
|
||||
|
||||
public async Task<IEnumerable<string>> GetSupportedCulturesAsync()
|
||||
{
|
||||
var langs = await _languageProvider.GetLanguagesAsync();
|
||||
return langs.Select(a => a.CultureName).ToList();
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,89 @@
|
|||
using Kurs.Languages.Entities;
|
||||
using Microsoft.Extensions.Localization;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
using Volo.Abp.Caching;
|
||||
using Volo.Abp.DependencyInjection;
|
||||
using Volo.Abp.Domain.Repositories;
|
||||
using Volo.Abp.Localization;
|
||||
using Volo.Abp.Threading;
|
||||
|
||||
namespace Kurs.Languages.Localization;
|
||||
|
||||
public class DatabaseResourceLocalizer : IDatabaseResourceLocalizer, ISingletonDependency
|
||||
{
|
||||
private readonly IRepository<LanguageText, Guid> languageTextRepository;
|
||||
private readonly IDistributedCache<LanguageTextCacheItem> cache;
|
||||
|
||||
public DatabaseResourceLocalizer(
|
||||
IRepository<LanguageText, Guid> languageTextRepository,
|
||||
IDistributedCache<LanguageTextCacheItem> cache)
|
||||
{
|
||||
this.languageTextRepository = languageTextRepository;
|
||||
this.cache = cache;
|
||||
}
|
||||
|
||||
public LocalizedString GetOrNull(LocalizationResourceBase resource, string cultureName, string name)
|
||||
{
|
||||
var item = GetCacheItem(resource, cultureName);
|
||||
var value = item.Dictionary?.GetOrDefault(name);
|
||||
if (item == null || value == null)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
return new LocalizedString(name, value);
|
||||
}
|
||||
|
||||
protected LanguageTextCacheItem GetCacheItem(LocalizationResourceBase resource, string cultureName)
|
||||
{
|
||||
// culture, resource, key
|
||||
var key = LanguageTextCacheItem.CalculateCacheKey(resource.ResourceName, cultureName);
|
||||
return cache.GetOrAdd(key, () => CreateCacheItem(resource, cultureName));
|
||||
}
|
||||
|
||||
public void Fill(LocalizationResourceBase resource, string cultureName, Dictionary<string, LocalizedString> dictionary)
|
||||
{
|
||||
var item = GetCacheItem(resource, cultureName);
|
||||
|
||||
foreach (var kvp in item.Dictionary)
|
||||
{
|
||||
dictionary[kvp.Key] = new LocalizedString(kvp.Key, kvp.Value);
|
||||
}
|
||||
}
|
||||
|
||||
protected virtual LanguageTextCacheItem CreateCacheItem(LocalizationResourceBase resource, string cultureName)
|
||||
{
|
||||
//TODO VT'den textleri alip cache'e dolduran kismi yazalim
|
||||
//TODO:SÖ
|
||||
var task = languageTextRepository.GetListAsync(a => a.ResourceName == resource.ResourceName && a.CultureName == cultureName);
|
||||
var texts = AsyncHelper.RunSync(() => task);
|
||||
|
||||
return new LanguageTextCacheItem
|
||||
{
|
||||
Dictionary = texts.ToDictionary(a => a.Key, a => a.Value)
|
||||
};
|
||||
}
|
||||
|
||||
public async Task FillAsync(LocalizationResourceBase resource, string cultureName, Dictionary<string, LocalizedString> dictionary)
|
||||
{
|
||||
var key = LanguageTextCacheItem.CalculateCacheKey(resource.ResourceName, cultureName);
|
||||
var item = await cache.GetOrAddAsync(key, () => CreateCacheItemAsync(resource, cultureName));
|
||||
|
||||
foreach (var kvp in item.Dictionary)
|
||||
{
|
||||
dictionary[kvp.Key] = new LocalizedString(kvp.Key, kvp.Value);
|
||||
}
|
||||
}
|
||||
|
||||
protected virtual async Task<LanguageTextCacheItem> CreateCacheItemAsync(LocalizationResourceBase resource, string cultureName)
|
||||
{
|
||||
var texts = await languageTextRepository.GetListAsync(a => a.ResourceName == resource.ResourceName && a.CultureName == cultureName);
|
||||
|
||||
return new LanguageTextCacheItem
|
||||
{
|
||||
Dictionary = texts.ToDictionary(a => a.Key, a => a.Value)
|
||||
};
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,13 @@
|
|||
using Microsoft.Extensions.Localization;
|
||||
using System.Collections.Generic;
|
||||
using System.Threading.Tasks;
|
||||
using Volo.Abp.Localization;
|
||||
|
||||
namespace Kurs.Languages.Localization;
|
||||
|
||||
public interface IDatabaseResourceLocalizer
|
||||
{
|
||||
void Fill(LocalizationResourceBase resource, string cultureName, Dictionary<string, LocalizedString> dictionary);
|
||||
Task FillAsync(LocalizationResourceBase resource, string cultureName, Dictionary<string, LocalizedString> dictionary);
|
||||
LocalizedString GetOrNull(LocalizationResourceBase resource, string cultureName, string name);
|
||||
}
|
||||
|
|
@ -0,0 +1,12 @@
|
|||
using Volo.Abp.Data;
|
||||
using Volo.Abp.EntityFrameworkCore;
|
||||
|
||||
namespace Kurs.Languages.EntityFrameworkCore;
|
||||
|
||||
[ConnectionStringName(LanguagesDbProperties.ConnectionStringName)]
|
||||
public interface ILanguagesDbContext : IEfCoreDbContext
|
||||
{
|
||||
/* Add DbSet for each Aggregate Root here. Example:
|
||||
* DbSet<Question> Questions { get; }
|
||||
*/
|
||||
}
|
||||
|
|
@ -0,0 +1,27 @@
|
|||
using Kurs.Languages.Entities;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using Volo.Abp.Data;
|
||||
using Volo.Abp.EntityFrameworkCore;
|
||||
|
||||
namespace Kurs.Languages.EntityFrameworkCore;
|
||||
|
||||
[ConnectionStringName(LanguagesDbProperties.ConnectionStringName)]
|
||||
public class LanguagesDbContext : AbpDbContext<LanguagesDbContext>, ILanguagesDbContext
|
||||
{
|
||||
public DbSet<Language> Languages { get; set; }
|
||||
public DbSet<LanguageKey> LanguageKeys { get; set; }
|
||||
public DbSet<LanguageText> LanguageTexts { get; set; }
|
||||
|
||||
public LanguagesDbContext(DbContextOptions<LanguagesDbContext> options)
|
||||
: base(options)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
protected override void OnModelCreating(ModelBuilder builder)
|
||||
{
|
||||
base.OnModelCreating(builder);
|
||||
|
||||
builder.ConfigureLanguages();
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,50 @@
|
|||
using Kurs.Languages.Entities;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using Volo.Abp;
|
||||
using Volo.Abp.EntityFrameworkCore.Modeling;
|
||||
|
||||
namespace Kurs.Languages.EntityFrameworkCore;
|
||||
|
||||
public static class LanguagesDbContextModelCreatingExtensions
|
||||
{
|
||||
public static void ConfigureLanguages(
|
||||
this ModelBuilder builder)
|
||||
{
|
||||
Check.NotNull(builder, nameof(builder));
|
||||
|
||||
builder.Entity<Language>(b =>
|
||||
{
|
||||
b.ToTable(LanguagesDbProperties.DbTablePrefix + nameof(Language), LanguagesDbProperties.DbSchema);
|
||||
b.ConfigureByConvention();
|
||||
|
||||
b.Property(a => a.CultureName).HasMaxLength(10).IsRequired();
|
||||
b.Property(a => a.UiCultureName).HasMaxLength(10).IsRequired();
|
||||
b.Property(a => a.DisplayName).HasMaxLength(50).IsRequired();
|
||||
});
|
||||
|
||||
builder.Entity<LanguageKey>(b =>
|
||||
{
|
||||
b.ToTable(LanguagesDbProperties.DbTablePrefix + nameof(LanguageKey), LanguagesDbProperties.DbSchema);
|
||||
b.ConfigureByConvention();
|
||||
|
||||
b.HasKey(a => new { a.ResourceName, a.Key });
|
||||
b.HasMany(a => a.Texts).WithOne()
|
||||
.HasForeignKey(a => new { a.ResourceName, a.Key })
|
||||
.OnDelete(DeleteBehavior.SetNull);
|
||||
|
||||
b.Property(a => a.Key).HasMaxLength(100).IsRequired();
|
||||
b.Property(a => a.ResourceName).HasMaxLength(50).IsRequired();
|
||||
});
|
||||
|
||||
builder.Entity<LanguageText>(b =>
|
||||
{
|
||||
b.ToTable(LanguagesDbProperties.DbTablePrefix + nameof(LanguageText), LanguagesDbProperties.DbSchema);
|
||||
b.ConfigureByConvention();
|
||||
|
||||
b.Property(a => a.CultureName).HasMaxLength(10).IsRequired();
|
||||
b.Property(a => a.ResourceName).HasMaxLength(50);
|
||||
b.Property(a => a.Key).HasMaxLength(100);
|
||||
b.Property(a => a.Value).HasMaxLength(250).IsRequired();
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,23 @@
|
|||
using Microsoft.Extensions.DependencyInjection;
|
||||
using Volo.Abp.EntityFrameworkCore;
|
||||
using Volo.Abp.Modularity;
|
||||
|
||||
namespace Kurs.Languages.EntityFrameworkCore;
|
||||
|
||||
[DependsOn(
|
||||
typeof(LanguagesDomainModule),
|
||||
typeof(AbpEntityFrameworkCoreModule)
|
||||
)]
|
||||
public class LanguagesEntityFrameworkCoreModule : AbpModule
|
||||
{
|
||||
public override void ConfigureServices(ServiceConfigurationContext context)
|
||||
{
|
||||
context.Services.AddAbpDbContext<LanguagesDbContext>(options =>
|
||||
{
|
||||
/* Add custom repositories here. Example:
|
||||
* options.AddRepository<Question, EfCoreQuestionRepository>();
|
||||
*/
|
||||
options.AddDefaultRepositories(includeAllEntities: true);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,3 @@
|
|||
<Weavers xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="FodyWeavers.xsd">
|
||||
<ConfigureAwait ContinueOnCapturedContext="false" />
|
||||
</Weavers>
|
||||
|
|
@ -0,0 +1,30 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">
|
||||
<!-- This file was generated by Fody. Manual changes to this file will be lost when your project is rebuilt. -->
|
||||
<xs:element name="Weavers">
|
||||
<xs:complexType>
|
||||
<xs:all>
|
||||
<xs:element name="ConfigureAwait" minOccurs="0" maxOccurs="1">
|
||||
<xs:complexType>
|
||||
<xs:attribute name="ContinueOnCapturedContext" type="xs:boolean" />
|
||||
</xs:complexType>
|
||||
</xs:element>
|
||||
</xs:all>
|
||||
<xs:attribute name="VerifyAssembly" type="xs:boolean">
|
||||
<xs:annotation>
|
||||
<xs:documentation>'true' to run assembly verification (PEVerify) on the target assembly after all weavers have been executed.</xs:documentation>
|
||||
</xs:annotation>
|
||||
</xs:attribute>
|
||||
<xs:attribute name="VerifyIgnoreCodes" type="xs:string">
|
||||
<xs:annotation>
|
||||
<xs:documentation>A comma-separated list of error codes that can be safely ignored in assembly verification.</xs:documentation>
|
||||
</xs:annotation>
|
||||
</xs:attribute>
|
||||
<xs:attribute name="GenerateXsd" type="xs:boolean">
|
||||
<xs:annotation>
|
||||
<xs:documentation>'false' to turn off automatic generation of the XML Schema file.</xs:documentation>
|
||||
</xs:annotation>
|
||||
</xs:attribute>
|
||||
</xs:complexType>
|
||||
</xs:element>
|
||||
</xs:schema>
|
||||
|
|
@ -0,0 +1,3 @@
|
|||
{
|
||||
"role": "lib.ef"
|
||||
}
|
||||
|
|
@ -0,0 +1,15 @@
|
|||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<Import Project="..\common.props" />
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFramework>net9.0</TargetFramework>
|
||||
<RootNamespace>Kurs.Languages</RootNamespace>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Volo.Abp.EntityFrameworkCore" Version="9.0.2" />
|
||||
<ProjectReference Include="..\Kurs.Languages.Domain\Kurs.Languages.Domain.csproj" />
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
||||
24
api/modules/Kurs.Languages/common.props
Normal file
24
api/modules/Kurs.Languages/common.props
Normal file
|
|
@ -0,0 +1,24 @@
|
|||
<Project>
|
||||
<PropertyGroup>
|
||||
<LangVersion>latest</LangVersion>
|
||||
<Version>0.1.0</Version>
|
||||
<NoWarn>$(NoWarn);CS1591</NoWarn>
|
||||
<AbpProjectType>module</AbpProjectType>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="ConfigureAwait.Fody" Version="3.3.1" PrivateAssets="All" />
|
||||
<PackageReference Include="Fody" Version="6.5.3">
|
||||
<PrivateAssets>All</PrivateAssets>
|
||||
<IncludeAssets>runtime; build; native; contentfiles; analyzers</IncludeAssets>
|
||||
</PackageReference>
|
||||
</ItemGroup>
|
||||
|
||||
|
||||
<Target Name="NoWarnOnRazorViewImportedTypeConflicts" BeforeTargets="RazorCoreCompile">
|
||||
<PropertyGroup>
|
||||
<NoWarn>$(NoWarn);0436</NoWarn>
|
||||
</PropertyGroup>
|
||||
</Target>
|
||||
|
||||
</Project>
|
||||
|
|
@ -0,0 +1,13 @@
|
|||
using Kurs.MailQueue.Domain.Shared;
|
||||
using Volo.Abp.Application.Services;
|
||||
|
||||
namespace Kurs.MailQueue.Application;
|
||||
|
||||
public abstract class MailQueueAppService : ApplicationService
|
||||
{
|
||||
protected MailQueueAppService()
|
||||
{
|
||||
LocalizationResource = typeof(KursMailQueueResource);
|
||||
ObjectMapperContext = typeof(KursMailQueueModule);
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,12 @@
|
|||
using AutoMapper;
|
||||
|
||||
namespace Kurs.MailQueue.Application;
|
||||
|
||||
public class MailQueueAutoMapperProfile : Profile
|
||||
{
|
||||
public MailQueueAutoMapperProfile()
|
||||
{
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,8 @@
|
|||
using Volo.Abp.Localization;
|
||||
|
||||
namespace Kurs.MailQueue.Domain.Shared;
|
||||
|
||||
[LocalizationResourceName(MailQueueConsts.AppName)]
|
||||
public class KursMailQueueResource
|
||||
{
|
||||
}
|
||||
|
|
@ -0,0 +1,7 @@
|
|||
namespace Kurs.MailQueue.Domain.Shared;
|
||||
|
||||
public static class MailQueueConsts
|
||||
{
|
||||
public const string AppName = "MailQueue";
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,9 @@
|
|||
namespace Kurs.MailQueue.Domain.Shared;
|
||||
|
||||
public class MailQueueWorkerOptions
|
||||
{
|
||||
public string MailType { get; set; } // Template Tipi
|
||||
public string MailSubject { get; set; } // Mail konusu
|
||||
public string MailTemplate { get; set; } // Render edilecek html template
|
||||
public string Tablo { get; set; } // Bu maildeki tablolar örn. {0:MT3_GECIKEN_SIPARIS:IN:Order Delay Notification:0:}
|
||||
}
|
||||
|
|
@ -0,0 +1,34 @@
|
|||
using System.ComponentModel.DataAnnotations;
|
||||
using System.ComponentModel.DataAnnotations.Schema;
|
||||
using Volo.Abp.Domain.Entities.Auditing;
|
||||
|
||||
namespace Kurs.MailQueue.Domain.Entities;
|
||||
|
||||
public class BackgroundWorker_MailQueue : FullAuditedEntity<Guid>
|
||||
{
|
||||
public Guid TemplateId { get; set; }
|
||||
[Required]
|
||||
[StringLength(100)]
|
||||
public string From { get; set; }
|
||||
[Required]
|
||||
[StringLength(100)]
|
||||
public string To { get; set; }
|
||||
[StringLength(8000)]
|
||||
public string MailParameter { get; set; } //{0:KURYE=FEDEX&ABWNO=777705877048}
|
||||
[StringLength(100)]
|
||||
public string Table { get; set; }
|
||||
[StringLength(500)]
|
||||
public string TableParameter { get; set; }
|
||||
[StringLength(100)]
|
||||
public string Attachment { get; set; }
|
||||
[StringLength(500)]
|
||||
public string AttachmentParameter { get; set; }
|
||||
public bool SendStatus { get; set; } // Mail gönderildi mi, vs
|
||||
// [Column(TypeName = "datetime")]
|
||||
public DateTime? SendTime { get; set; } // Gönderim zamanı
|
||||
[StringLength(100)]
|
||||
public string AwsMessageId { get; set; } // AWS'ten gelen response
|
||||
[StringLength(100)]
|
||||
public string RelatedRecordId { get; set; } // İlgili kaydın ID'si
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,19 @@
|
|||
using System.ComponentModel.DataAnnotations;
|
||||
using System.ComponentModel.DataAnnotations.Schema;
|
||||
using Volo.Abp.Domain.Entities.Auditing;
|
||||
|
||||
namespace Kurs.MailQueue.Domain.Entities;
|
||||
|
||||
public partial class BackgroundWorker_MailQueueEvents : FullAuditedEntity<Guid>
|
||||
{
|
||||
[Required]
|
||||
[StringLength(100)]
|
||||
public string AwsMessageId { get; set; }
|
||||
// [Column(TypeName = "datetime")]
|
||||
public DateTime? EventDate { get; set; }
|
||||
[StringLength(20)]
|
||||
public string Event { get; set; }
|
||||
[StringLength(100)]
|
||||
public string MailAddress { get; set; }
|
||||
public string ResponseDescription { get; set; }
|
||||
}
|
||||
|
|
@ -0,0 +1,33 @@
|
|||
using System.ComponentModel.DataAnnotations;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using Volo.Abp.Domain.Entities;
|
||||
|
||||
namespace Kurs.MailQueue.Domain.Entities;
|
||||
|
||||
[Index(nameof(TableName), nameof(Order), Name = "IX_MailQueueTableFormat", IsUnique = true)]
|
||||
public partial class BackgroundWorker_MailQueueTableFormat : Entity<int>
|
||||
{
|
||||
[Required]
|
||||
[StringLength(100)]
|
||||
public string TableName { get; set; }
|
||||
public short Order { get; set; }
|
||||
[StringLength(50)]
|
||||
public string ColumnName { get; set; }
|
||||
[StringLength(50)]
|
||||
public string Caption { get; set; }
|
||||
[StringLength(1000)]
|
||||
public string HeaderCss { get; set; }
|
||||
[StringLength(1000)]
|
||||
public string Css { get; set; }
|
||||
[StringLength(1000)]
|
||||
public string FooterCss { get; set; }
|
||||
[StringLength(50)]
|
||||
public string DataType { get; set; }
|
||||
[StringLength(50)]
|
||||
public string DataFormat { get; set; }
|
||||
public bool IsHidden { get; set; }
|
||||
public bool IsProtected { get; set; } // Excel'deki sutun korumali mi olacak?
|
||||
[StringLength(50)]
|
||||
public string SubTotal { get; set; }
|
||||
public int Width { get; set; }
|
||||
}
|
||||
42
api/modules/Kurs.MailQueue/Domain/LogManager.cs
Normal file
42
api/modules/Kurs.MailQueue/Domain/LogManager.cs
Normal file
|
|
@ -0,0 +1,42 @@
|
|||
using Microsoft.Extensions.Logging;
|
||||
using Volo.Abp.Domain.Services;
|
||||
|
||||
namespace Kurs.MailQueue.Domain;
|
||||
|
||||
public interface ILogManager : IDomainService
|
||||
{
|
||||
void Log(
|
||||
LogLevel logTipi,
|
||||
string logDetayi,
|
||||
string kategori = null,
|
||||
string kayitTipi = null,
|
||||
Guid? kayitId = null,
|
||||
string jobId = null);
|
||||
void LogInformation(string logDetayi, string kategori = null, string kayitTipi = null, Guid? kayitId = null, string jobId = null);
|
||||
void LogError(string logDetayi, string kategori = null, string kayitTipi = null, Guid? kayitId = null, string jobId = null);
|
||||
void LogWarning(string logDetayi, string kategori = null, string kayitTipi = null, Guid? kayitId = null, string jobId = null);
|
||||
}
|
||||
|
||||
public class NullLogManager : DomainService, ILogManager
|
||||
{
|
||||
public NullLogManager()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
public void Log(
|
||||
LogLevel logTipi,
|
||||
string logDetayi,
|
||||
string kategori = null,
|
||||
string kayitTipi = null,
|
||||
Guid? kayitId = null,
|
||||
string jobId = null)
|
||||
{
|
||||
Logger.Log(logTipi, logDetayi);
|
||||
}
|
||||
|
||||
public void LogInformation(string logDetayi, string kategori = null, string kayitTipi = null, Guid? kayitId = null, string jobId = null) => Log(LogLevel.Information, logDetayi, kategori, kayitTipi, kayitId, jobId);
|
||||
public void LogError(string logDetayi, string kategori = null, string kayitTipi = null, Guid? kayitId = null, string jobId = null) => Log(LogLevel.Error, logDetayi, kategori, kayitTipi, kayitId, jobId);
|
||||
public void LogWarning(string logDetayi, string kategori = null, string kayitTipi = null, Guid? kayitId = null, string jobId = null) => Log(LogLevel.Warning, logDetayi, kategori, kayitTipi, kayitId, jobId);
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,63 @@
|
|||
using Kurs.MailQueue.MailGeneration.Models;
|
||||
using Volo.Abp.DependencyInjection;
|
||||
|
||||
namespace Kurs.MailQueue.Domain.MailGeneration;
|
||||
|
||||
public interface IAttachmentExtractor
|
||||
{
|
||||
IList<AttachmentModel> Extract(string attachment, string attachmentParametre);
|
||||
}
|
||||
|
||||
public class AttachmentExtractor : IAttachmentExtractor, ITransientDependency
|
||||
{
|
||||
protected readonly IParameterExtractor ParameterExtractor;
|
||||
|
||||
public AttachmentExtractor(
|
||||
IParameterExtractor parameterExtractor)
|
||||
{
|
||||
ParameterExtractor = parameterExtractor;
|
||||
}
|
||||
|
||||
public IList<AttachmentModel> Extract(string attachment, string attachmentParametre)
|
||||
{
|
||||
var result = new List<AttachmentModel>();
|
||||
|
||||
if (attachment.IsNullOrWhiteSpace())
|
||||
return result;
|
||||
|
||||
var parameters = ParameterExtractor.Extract(attachmentParametre);
|
||||
/*
|
||||
Dict<
|
||||
0, Dict<
|
||||
Tarih, 1232
|
||||
No 4334
|
||||
>
|
||||
1, Dict<
|
||||
QUERY, ghghg
|
||||
QUERYSQL select ffddf
|
||||
*/
|
||||
//Attachment:
|
||||
//{0:MRP:rpt_DepoCikisCekiListesi:PDF:MailEkteGozukecekAd};{1:CRM:rpt_DepoCikisCekiListesiCarpet:XLS:MailEkteGozukecekAd}
|
||||
//AttachmentParametre:
|
||||
//Filtre değerleri olabilir {0:Tarih=1232&No=4334};{1:Tarih=213}
|
||||
//Veya query olabilir {0:QUERY=…&QUERYSQL=..};{1:QUERY=…&QUERYSQL=..}
|
||||
foreach (var item in attachment.Split("};{"))
|
||||
{
|
||||
var keyValue = item.Trim('{').Trim('}').Split(":");
|
||||
if (keyValue.Length == 5)
|
||||
{
|
||||
result.Add(new AttachmentModel
|
||||
{
|
||||
Index = keyValue[0],
|
||||
DbAdi = keyValue[1],
|
||||
RaporAdi = keyValue[2],
|
||||
ExportDosyaTipi = keyValue[3],
|
||||
Filtreler = parameters.GetOrDefault(keyValue[0]),
|
||||
MailEkAdi = keyValue[4]
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,43 @@
|
|||
using Volo.Abp.DependencyInjection;
|
||||
|
||||
namespace Kurs.MailQueue.Domain.MailGeneration;
|
||||
|
||||
public interface ICssExtractor
|
||||
{
|
||||
Dictionary<string, string> Extract(string text);
|
||||
}
|
||||
|
||||
public class CssExtractor : ICssExtractor, ITransientDependency
|
||||
{
|
||||
//color: #FFF;background-color:#000;
|
||||
// color=#FFF
|
||||
// background-color=#000
|
||||
public Dictionary<string, string> Extract(string text)
|
||||
{
|
||||
if (text.IsNullOrWhiteSpace())
|
||||
return null;
|
||||
var values = new Dictionary<string, string>();
|
||||
|
||||
try
|
||||
{
|
||||
foreach (var css in text.Split(";", StringSplitOptions.RemoveEmptyEntries))
|
||||
{
|
||||
var rule = css.Split(":", StringSplitOptions.RemoveEmptyEntries);
|
||||
if (rule.Length == 2)
|
||||
{
|
||||
var key = rule[0].Trim();
|
||||
var value = rule[1].Trim();
|
||||
if (values.ContainsKey(key))
|
||||
values.Add(key, value);
|
||||
else
|
||||
values[key] = value;
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
}
|
||||
|
||||
return values;
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,79 @@
|
|||
using Volo.Abp.DependencyInjection;
|
||||
|
||||
namespace Kurs.MailQueue.Domain.MailGeneration;
|
||||
|
||||
public interface IParameterExtractor
|
||||
{
|
||||
Dictionary<string, Dictionary<string, string>> Extract(string text);
|
||||
}
|
||||
|
||||
public class ParameterExtractor : IParameterExtractor, ITransientDependency
|
||||
{
|
||||
//{0:FISID=xyz&TARIH=12321};{1:FISID=abc&TARIH=32121}
|
||||
// [0]=> FISID=xyz,TARIH=12321
|
||||
// [1]=> FISID=abc,TARIH=32121
|
||||
public Dictionary<string, Dictionary<string, string>> Extract(string text)
|
||||
{
|
||||
return ExtractPart(text)
|
||||
.Select(a => ExtractParameters(a))
|
||||
.Where(a => a.HasValue)
|
||||
.Select(a => a.Value)
|
||||
.ToDictionary(x => x.Key, x => x.Value);
|
||||
}
|
||||
|
||||
/*
|
||||
0=>{FISID=xyz&TARIH=12321}
|
||||
0.0=>FISID=xyz
|
||||
0.1=>TARIH=12321
|
||||
1=>{FISID=xyz&TARIH=12321}
|
||||
1.0=>FISID=xyz
|
||||
1.1=>TARIH=12321
|
||||
*/
|
||||
|
||||
//{0:FISID=xyz&TARIH=12321};{1:FISID=xyz&TARIH=12321}
|
||||
// [0] => 0:FISID=xyz&TARIH=12321, [1] => 1:FISID=xyz&TARIH=12321
|
||||
//{x=1};{y=2};{z=3}
|
||||
// [0] => x=1, [1] => y=2, [2] => z=3
|
||||
private List<string> ExtractPart(string text)
|
||||
{
|
||||
return text?
|
||||
.Split("};{")
|
||||
.Select(a => a.Trim('{').Trim('}'))
|
||||
.ToList() ?? new List<string>();
|
||||
}
|
||||
|
||||
//2:FISID=xyz&TARIH=12321
|
||||
// 2 => List([0] => FISID=xyz, [1] => TARIH=12321)
|
||||
private KeyValuePair<string, Dictionary<string, string>>? ExtractParameters(string text)
|
||||
{
|
||||
if (text.IsNullOrWhiteSpace())
|
||||
return null;
|
||||
|
||||
var index = "0";
|
||||
if (text.Contains(":"))
|
||||
{
|
||||
index = text.Substring(0, text.IndexOf(':'));
|
||||
text = text.Substring(text.IndexOf(':') + 1);
|
||||
}
|
||||
|
||||
var values = text
|
||||
.Split("&")?
|
||||
.Select(a => ExtractKeyValue(a))
|
||||
.Where(a => a.HasValue)
|
||||
.Select(a => a.Value)
|
||||
.ToDictionary(x => x.Key, x => x.Value);
|
||||
|
||||
return new KeyValuePair<string, Dictionary<string, string>>(index, values);
|
||||
}
|
||||
|
||||
//x=1
|
||||
// [x] => 1
|
||||
private KeyValuePair<string, string>? ExtractKeyValue(string text)
|
||||
{
|
||||
var keyValue = text?.Split("=");
|
||||
if (keyValue != null && keyValue.Length == 2)
|
||||
return new KeyValuePair<string, string>(keyValue[0], keyValue[1]);
|
||||
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,48 @@
|
|||
using Kurs.MailQueue.MailGeneration.Models;
|
||||
using Volo.Abp.DependencyInjection;
|
||||
|
||||
namespace Kurs.MailQueue.Domain.MailGeneration;
|
||||
|
||||
public interface ITableExtractor
|
||||
{
|
||||
IList<MailTemplateTableModel> Extract(string text, string parameters);
|
||||
}
|
||||
|
||||
public class TableExtractor : ITableExtractor, ITransientDependency
|
||||
{
|
||||
public IParameterExtractor ParameterExtractor { get; }
|
||||
|
||||
public TableExtractor(IParameterExtractor parameterExtractor)
|
||||
{
|
||||
ParameterExtractor = parameterExtractor;
|
||||
}
|
||||
|
||||
public IList<MailTemplateTableModel> Extract(string text, string parameters)
|
||||
{
|
||||
var result = new List<MailTemplateTableModel>();
|
||||
|
||||
if (text.IsNullOrWhiteSpace())
|
||||
return result;
|
||||
|
||||
var parametreler = ParameterExtractor.Extract(parameters);
|
||||
|
||||
//{0:MT3_GECIKEN_SIPARIS:IN:DosyaAdi;0:};{1:MT7_SIPARIS_DURUM:PDF:DosyaAdi.pdf:0:BRU,3,1}
|
||||
foreach (var item in text.Split("};{"))
|
||||
{
|
||||
var keyValue = item.Trim('{').Trim('}').Split(":");
|
||||
if (keyValue.Length == 6)
|
||||
result.Add(new MailTemplateTableModel
|
||||
{
|
||||
Index = keyValue[0],
|
||||
TabloAdi = keyValue[1],
|
||||
DosyaTipi = keyValue[2],
|
||||
MailEkAdi = keyValue[3],
|
||||
Korumalimi = keyValue[4],
|
||||
DosyaAciklama = keyValue[5],
|
||||
Parametreler = parametreler.GetOrDefault(keyValue[0])
|
||||
});
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,226 @@
|
|||
using Kurs.MailQueue.FileGeneration;
|
||||
using Kurs.MailQueue.MailGeneration.Models;
|
||||
using Microsoft.Extensions.Configuration;
|
||||
using Volo.Abp.DependencyInjection;
|
||||
using Volo.Abp.Guids;
|
||||
using Volo.Abp.TextTemplating;
|
||||
|
||||
namespace Kurs.MailQueue.Domain.MailGeneration;
|
||||
|
||||
public interface IAttachmentGenerator
|
||||
{
|
||||
Task<Dictionary<string, string>> GenerateAsync(
|
||||
Guid kuyrukId,
|
||||
string attachment,
|
||||
string attachmentParametre,
|
||||
string jobId = null);
|
||||
|
||||
Task<Dictionary<string, string>> GenerateAsync(List<MailTemplateTableModel> tables, Guid? kuyrukId = null, string jobId = null);
|
||||
|
||||
}
|
||||
|
||||
public class AttachmentGenerator : IAttachmentGenerator, ITransientDependency
|
||||
{
|
||||
public IParameterExtractor ParameterExtractor { get; }
|
||||
public IAttachmentExtractor AttachmentExtractor { get; }
|
||||
public ITemplateRenderer TemplateRenderer { get; }
|
||||
public IGuidGenerator GuidGenerator { get; }
|
||||
public IServiceProvider ServiceProvider { get; }
|
||||
protected ILogManager LogManager { get; }
|
||||
private readonly IConfiguration Configuration;
|
||||
|
||||
public AttachmentGenerator(
|
||||
IAttachmentExtractor attachmentExtractor,
|
||||
ITemplateRenderer templateRenderer,
|
||||
IGuidGenerator guidGenerator,
|
||||
IServiceProvider serviceProvider,
|
||||
ILogManager logManager,
|
||||
IConfiguration configuration
|
||||
)
|
||||
{
|
||||
AttachmentExtractor = attachmentExtractor;
|
||||
TemplateRenderer = templateRenderer;
|
||||
GuidGenerator = guidGenerator;
|
||||
ServiceProvider = serviceProvider;
|
||||
LogManager = logManager;
|
||||
Configuration = configuration;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Verilen parametreler (attachment parametreleri) ile KIM raporlari ile istenilen formatta dosya uretir
|
||||
/// </summary>
|
||||
/// <param name="attachment">Export edilecek olan attachmentlar</param>
|
||||
/// <param name="attachmentParametre">Her attachment için parametreler</param>
|
||||
/// <returns>Uretilen ekleri Key: MailEkAdi, Value: Base64 encode edilmis dosya olan dictionary olarak döner</returns>
|
||||
public async Task<Dictionary<string, string>> GenerateAsync(
|
||||
Guid kuyrukId,
|
||||
string attachment,
|
||||
string attachmentParametre,
|
||||
string jobId)
|
||||
{
|
||||
var result = new Dictionary<string, string>();
|
||||
var models = AttachmentExtractor.Extract(attachment, attachmentParametre);
|
||||
var attachmentFolder = $"{kuyrukId}-{jobId}";
|
||||
foreach (var item in models)
|
||||
{
|
||||
var file = GenerateAttachment(item, attachmentFolder);
|
||||
if (file.IsNullOrEmpty())
|
||||
{
|
||||
LogManager.LogError($"Attachment oluşturulamadı. Index: {item.Index}", "ATTACHMENT", "KUYRUK", kuyrukId, jobId);
|
||||
continue;
|
||||
}
|
||||
|
||||
var base64 = await ConvertFileToBase64Async(file);
|
||||
var key = item.MailEkAdi;
|
||||
if (result.ContainsKey(key))
|
||||
{
|
||||
key = result.Count + "-" + item.MailEkAdi;
|
||||
}
|
||||
result.Add(key, base64);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Verilan tablo modeli ile istenilen dosya tipinde (PDF, XLS, TXT) ek üretir
|
||||
/// </summary>
|
||||
/// <param name="tables">Tablo modeli listesi</param>
|
||||
/// <returns>Uretilen ekleri Key: MailEkAdi, Value: Base64 encode edilmis dosya olan dictionary olarak döner</returns>
|
||||
public async Task<Dictionary<string, string>> GenerateAsync(List<MailTemplateTableModel> tables, Guid? kuyrukId = null, string jobId = null)
|
||||
{
|
||||
var attachments = new Dictionary<string, string>();
|
||||
foreach (var table in tables.Where(a => a.DosyaTipi != "IN"))
|
||||
{
|
||||
IFileGenerator fileGenerator = null;
|
||||
switch (table.DosyaTipi)
|
||||
{
|
||||
case "PDF":
|
||||
fileGenerator = (IFileGenerator)ServiceProvider.GetService(typeof(PDFFileGenerator));
|
||||
break;
|
||||
case "XLS":
|
||||
fileGenerator = (IFileGenerator)ServiceProvider.GetService(typeof(XLSFileGenerator));
|
||||
break;
|
||||
case "TXT":
|
||||
fileGenerator = (IFileGenerator)ServiceProvider.GetService(typeof(TXTFileGenerator));
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
if (fileGenerator == null)
|
||||
{
|
||||
LogManager.LogError($"File Generator oluşturulamadı. Index: {table.Index}, Dosya Tipi: {table.DosyaTipi}", "ATTACHMENT-TABLO", "KUYRUK", kuyrukId, jobId);
|
||||
continue;
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
var attachment = await fileGenerator.Generate(table);
|
||||
if (kuyrukId.HasValue)
|
||||
{
|
||||
LogToFile(kuyrukId.Value, attachment, table.MailEkAdi);
|
||||
}
|
||||
var base64 = Convert.ToBase64String(attachment);
|
||||
attachments.Add(table.MailEkAdi, base64);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
LogManager.LogError($"Dosya oluşturulamadı. Index: {table.Index}. {ex}", "ATTACHMENT-TABLO", "KUYRUK", kuyrukId, jobId);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
return attachments;
|
||||
}
|
||||
|
||||
private string GenerateAttachment(AttachmentModel model, string attachmentFolder)
|
||||
{
|
||||
if (model.Filtreler.IsNullOrEmpty() || model.RaporAdi.IsNullOrWhiteSpace())
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
return null;
|
||||
|
||||
// if (model.Filtreler.ContainsKey("QUERY") && model.Filtreler.ContainsKey("QUERYSQL"))
|
||||
// {
|
||||
// /*
|
||||
//Parametrelerden asagidaki sekilde gelen queryleri en alttaki formata donusturuyoruz
|
||||
//params
|
||||
//0 =>
|
||||
// QUERY -> qryDepo_Cikis_CekiListesi_Detayli
|
||||
// QUERYSQL -> Ksp_Depo_Cikis_CekiListesi_Detayli 252993
|
||||
// QUERY2 -> qryDepo_Cikis_CekiListesi_Sub
|
||||
// QUERY2SQL -> KSp_Depo_Cikis_CekiListesi_Sub 252993
|
||||
|
||||
//SQL olan keyvalue'lari cikar ve sadece querylerde foreach yap
|
||||
// QUERY -> qryDepo_Cikis_CekiListesi_Detayli
|
||||
// dict.add(item.Value, params[item.Key + "SQL"].Value)
|
||||
// QUERY2 -> qryDepo_Cikis_CekiListesi_Sub
|
||||
// dict.add(item.Value, params[item.Key + "SQL"].Value)
|
||||
|
||||
//Bunlari yeni dict'e ekle
|
||||
//dict
|
||||
//qryDepo_Cikis_CekiListesi_Detayli -> Ksp_Depo_Cikis_CekiListesi_Detayli 252993
|
||||
//qryDepo_Cikis_CekiListesi_Sub -> KSp_Depo_Cikis_CekiListesi_Sub 252993
|
||||
// */
|
||||
// //dict -> key (name), value (sql)
|
||||
// var queries = model.Filtreler
|
||||
// .Where(a => a.Key.StartsWith("QUERY"))
|
||||
// .Where(a => !a.Key.EndsWith("SQL"))
|
||||
// .Where(a => !a.Value.IsNullOrWhiteSpace())
|
||||
// .ToDictionary(x => x.Value, x => model.Filtreler.GetValueOrDefault(x.Key + "SQL"));
|
||||
|
||||
// return MsAccessReportManager.GenerateAccessReport(
|
||||
// model.DbAdi,
|
||||
// model.Index,
|
||||
// model.RaporAdi,
|
||||
// model.ExportDosyaTipi,
|
||||
// queries,
|
||||
// attachmentFolder);
|
||||
// }
|
||||
// else
|
||||
// {
|
||||
// return MsAccessReportManager.GenerateAccessReport(
|
||||
// model.DbAdi,
|
||||
// model.Index,
|
||||
// model.RaporAdi,
|
||||
// string.Join(" AND ", model.Filtreler.Select(a => $"{a.Key}={a.Value}")),
|
||||
// model.ExportDosyaTipi,
|
||||
// attachmentFolder);
|
||||
// }
|
||||
}
|
||||
|
||||
private async Task<string> ConvertFileToBase64Async(string filePath)
|
||||
{
|
||||
var bytes = await File.ReadAllBytesAsync(filePath);
|
||||
return Convert.ToBase64String(bytes);
|
||||
}
|
||||
|
||||
private void LogToFile(Guid id, byte[] content, string fileName)
|
||||
{
|
||||
if (!Configuration.GetValue<bool>("App:LogMailToFile"))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
var path = Configuration.GetValue<string>("App:AttachmentsPath");
|
||||
if (path.IsNullOrWhiteSpace())
|
||||
{
|
||||
return;
|
||||
}
|
||||
path = Path.Combine(path, id.ToString());
|
||||
|
||||
try
|
||||
{
|
||||
if (!Directory.Exists(path))
|
||||
{
|
||||
Directory.CreateDirectory(path);
|
||||
}
|
||||
File.WriteAllBytes(Path.Combine(path, fileName), content);
|
||||
}
|
||||
catch
|
||||
{
|
||||
LogManager.LogError($"Dosya diske kaydedilemedi. Yol:{path}, Dosya: {fileName}", "ATTACHMENT-TABLO", "KUYRUK", id);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,103 @@
|
|||
using Kurs.MailQueue.MailGeneration.Models;
|
||||
using Microsoft.Extensions.Configuration;
|
||||
using Volo.Abp.DependencyInjection;
|
||||
using Volo.Abp.TextTemplating;
|
||||
|
||||
namespace Kurs.MailQueue.Domain.MailGeneration;
|
||||
|
||||
public interface IMailBodyGenerator
|
||||
{
|
||||
Task<string> GenerateAsync(
|
||||
string templateName,
|
||||
string mailParametreleri,
|
||||
Guid kuyrukId,
|
||||
Dictionary<string, MailTemplateTableModel> tablolar,
|
||||
string jobId = null
|
||||
);
|
||||
}
|
||||
|
||||
public class MailBodyGenerator : IMailBodyGenerator, ITransientDependency
|
||||
{
|
||||
private readonly IConfiguration configuration;
|
||||
|
||||
public IParameterExtractor ParameterExtractor { get; }
|
||||
public ITemplateRenderer TemplateRenderer { get; }
|
||||
protected ILogManager LogManager { get; }
|
||||
|
||||
public MailBodyGenerator(
|
||||
IParameterExtractor parameterExtractor,
|
||||
ITemplateRenderer templateRenderer,
|
||||
IConfiguration configuration,
|
||||
ILogManager logManager)
|
||||
{
|
||||
ParameterExtractor = parameterExtractor;
|
||||
TemplateRenderer = templateRenderer;
|
||||
this.configuration = configuration;
|
||||
LogManager = logManager;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Verilen parametreler ile mail body render eder
|
||||
/// </summary>
|
||||
/// <param name="templateName">Render edilecek olan template adı</param>
|
||||
/// <param name="mailParametreleri">Dinamik parametreler</param>
|
||||
/// <returns></returns>
|
||||
public async Task<string> GenerateAsync(
|
||||
string templateName,
|
||||
string mailParametreleri,
|
||||
Guid kuyrukId,
|
||||
Dictionary<string, MailTemplateTableModel> tablolar,
|
||||
string jobId = null
|
||||
)
|
||||
{
|
||||
var parametreler = ParameterExtractor.Extract(mailParametreleri);
|
||||
//Mail icin 0: ile baslayan tek bir parametre grubu oldugu icin, onu aliyoruz
|
||||
var model = new MailTemplateModel
|
||||
{
|
||||
MailParametreleri = parametreler.GetOrDefault("0"),
|
||||
Tablolar = tablolar
|
||||
};
|
||||
|
||||
try
|
||||
{
|
||||
var result = await TemplateRenderer.RenderAsync(templateName, model);
|
||||
LogToFile(kuyrukId, result);
|
||||
return result;
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
LogManager.LogError($"Template Render Başarısız: {templateName}", "MAILBODY", "KUYRUK", kuyrukId, jobId);
|
||||
throw;
|
||||
}
|
||||
}
|
||||
|
||||
private void LogToFile(Guid id, string content)
|
||||
{
|
||||
if (!configuration.GetValue<bool>("App:LogMailToFile"))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
var path = configuration.GetValue<string>("App:AttachmentsPath");
|
||||
if (path.IsNullOrWhiteSpace())
|
||||
{
|
||||
return;
|
||||
}
|
||||
path = Path.Combine(path, id.ToString());
|
||||
var date = DateTime.Now.ToString("yyyy-MM-dd-HH-mm-ss");
|
||||
var dosyaAdi = $"mail-{id}-{date}.html ";
|
||||
try
|
||||
{
|
||||
if (!Directory.Exists(path))
|
||||
{
|
||||
Directory.CreateDirectory(path);
|
||||
}
|
||||
|
||||
File.AppendAllText(Path.Combine(path, dosyaAdi), content);
|
||||
}
|
||||
catch
|
||||
{
|
||||
LogManager.LogError($"Mail diske kaydedilemedi. Yol:{path}: Dosya {dosyaAdi}", "MAILBODY", "KUYRUK", id);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,104 @@
|
|||
using System.Data;
|
||||
using Kurs.MailQueue.Domain.Entities;
|
||||
using Kurs.MailQueue.EntityFrameworkCore;
|
||||
using Kurs.MailQueue.MailGeneration.Models;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using Volo.Abp.DependencyInjection;
|
||||
using Volo.Abp.Domain.Repositories;
|
||||
using Volo.Abp.TextTemplating;
|
||||
|
||||
namespace Kurs.MailQueue.Domain.MailGeneration;
|
||||
|
||||
public interface ITableGenerator
|
||||
{
|
||||
Task<Dictionary<string, MailTemplateTableModel>>
|
||||
GenerateAsync(
|
||||
string tabloTemplate,
|
||||
string tabloParametreleri,
|
||||
Guid kuyrukId);
|
||||
}
|
||||
|
||||
public class TableGenerator : ITableGenerator, ITransientDependency
|
||||
{
|
||||
public ITableExtractor TableExtractor { get; }
|
||||
public ITemplateRenderer TemplateRenderer { get; }
|
||||
public IRepository<BackgroundWorker_MailQueueTableFormat> RepositoryTablo { get; }
|
||||
public IQueryRepository QueryHelper { get; }
|
||||
public ICssExtractor CssExtractor { get; }
|
||||
|
||||
public TableGenerator(
|
||||
ITableExtractor tableExtractor,
|
||||
ITemplateRenderer templateRenderer,
|
||||
IRepository<BackgroundWorker_MailQueueTableFormat> repositoryTablo,
|
||||
IQueryRepository queryHelper,
|
||||
ICssExtractor cssExtractor
|
||||
)
|
||||
{
|
||||
TableExtractor = tableExtractor;
|
||||
TemplateRenderer = templateRenderer;
|
||||
RepositoryTablo = repositoryTablo;
|
||||
QueryHelper = queryHelper;
|
||||
CssExtractor = cssExtractor;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Verilen parametreler ile tablo render eder
|
||||
/// </summary>
|
||||
/// <param name="templateName">Render edilecek olan template adı</param>
|
||||
/// <param name="mailParametreleri">Dinamik parametreler</param>
|
||||
/// <returns></returns>
|
||||
public async Task<Dictionary<string, MailTemplateTableModel>> GenerateAsync(string tabloTemplate, string tabloParametreleri, Guid kuyrukId)
|
||||
{
|
||||
var tablolar = TableExtractor.Extract(tabloTemplate, tabloParametreleri);
|
||||
|
||||
int i = 0;
|
||||
foreach (var tablo in tablolar)
|
||||
{
|
||||
var query = await RepositoryTablo.GetQueryableAsync();
|
||||
var sutunlar = await query.Where(a => a.TableName == tablo.TabloAdi)
|
||||
.OrderBy(o => o.Order)
|
||||
.ToListAsync();
|
||||
|
||||
var table = await QueryHelper.QueryAsync(tablo.TabloAdi, tablo.Parametreler);
|
||||
|
||||
tablo.TabloSutunlari = sutunlar
|
||||
.Select(a => new MailTemplateTableColumnModel
|
||||
{
|
||||
SiraNo = a.Order,
|
||||
SutunAdi = a.ColumnName,
|
||||
SutunBaslik = a.Caption,
|
||||
BaslikCss = CssExtractor.Extract(a.HeaderCss),
|
||||
Css = CssExtractor.Extract(a.Css),
|
||||
AltBilgiCss = CssExtractor.Extract(a.FooterCss),
|
||||
VeriTipi = a.DataType,
|
||||
VeriFormati = a.DataFormat,
|
||||
Gizlimi = a.IsHidden,
|
||||
Korumalimi = a.IsProtected,
|
||||
AltToplam = a.SubTotal,
|
||||
Genislik = a.Width
|
||||
})
|
||||
.ToList();
|
||||
|
||||
var degerler = new List<Dictionary<string, object>>();
|
||||
foreach (var row in table.AsEnumerable())
|
||||
{
|
||||
var dict = new Dictionary<string, object>();
|
||||
for (int j = 0; j < table.Columns.Count; j++)
|
||||
{
|
||||
var column = table.Columns[j];
|
||||
dict.Add(
|
||||
column.ColumnName,
|
||||
row[column.ColumnName]);
|
||||
}
|
||||
degerler.Add(dict);
|
||||
}
|
||||
tablo.TabloDegerleri = degerler;
|
||||
|
||||
i++;
|
||||
}
|
||||
|
||||
return tablolar.ToDictionary(
|
||||
x => $"{x.DosyaTipi}{x.Index}",
|
||||
x => x);
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,11 @@
|
|||
namespace Kurs.MailQueue.MailGeneration.Models;
|
||||
|
||||
public class AttachmentModel
|
||||
{
|
||||
public string Index { get; set; }
|
||||
public string DbAdi { get; set; } //MRP.mdb, CRM.mdb
|
||||
public string RaporAdi { get; set; }
|
||||
public string ExportDosyaTipi { get; set; } //PDF, TXT, XLS, ..
|
||||
public Dictionary<string, string> Filtreler { get; set; }
|
||||
public string MailEkAdi { get; set; }
|
||||
}
|
||||
|
|
@ -0,0 +1,8 @@
|
|||
namespace Kurs.MailQueue.MailGeneration.Models;
|
||||
|
||||
public class MailTemplateModel
|
||||
{
|
||||
public Dictionary<string, string> MailParametreleri { get; set; }
|
||||
public Dictionary<string, MailTemplateTableModel> Tablolar { get; set; }
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,18 @@
|
|||
namespace Kurs.MailQueue.MailGeneration.Models;
|
||||
|
||||
public class MailTemplateTableColumnModel
|
||||
{
|
||||
public int SiraNo { get; set; }
|
||||
public string SutunAdi { get; set; }
|
||||
public string SutunBaslik { get; set; }
|
||||
public Dictionary<string, string> BaslikCss { get; set; }
|
||||
public Dictionary<string, string> Css { get; set; }
|
||||
public Dictionary<string, string> AltBilgiCss { get; set; }
|
||||
public string VeriTipi { get; set; }
|
||||
public string VeriFormati { get; set; }
|
||||
public bool Gizlimi { get; set; }
|
||||
public bool Korumalimi { get; set; }
|
||||
public string AltToplam { get; set; }
|
||||
public int Genislik { get; set; }
|
||||
|
||||
}
|
||||
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue