Compare commits
10 Commits
564429be01
...
ba3bffd9eb
Author | SHA1 | Date | |
---|---|---|---|
![]() |
ba3bffd9eb | ||
![]() |
4e31d34164 | ||
![]() |
8b4e21f29a | ||
![]() |
4748413951 | ||
![]() |
1ca1b4f1eb | ||
![]() |
2f66807bc1 | ||
![]() |
869d1f2ef1 | ||
![]() |
c889ce9e03 | ||
![]() |
6a2de3d7c2 | ||
![]() |
49304f93a2 |
30
.dockerignore
Normal file
30
.dockerignore
Normal file
@@ -0,0 +1,30 @@
|
||||
**/.classpath
|
||||
**/.dockerignore
|
||||
**/.env
|
||||
**/.git
|
||||
**/.gitignore
|
||||
**/.project
|
||||
**/.settings
|
||||
**/.toolstarget
|
||||
**/.vs
|
||||
**/.vscode
|
||||
**/*.*proj.user
|
||||
**/*.dbmdl
|
||||
**/*.jfm
|
||||
**/azds.yaml
|
||||
**/bin
|
||||
**/charts
|
||||
**/docker-compose*
|
||||
**/Dockerfile*
|
||||
**/node_modules
|
||||
**/npm-debug.log
|
||||
**/obj
|
||||
**/secrets.dev.yaml
|
||||
**/values.dev.yaml
|
||||
LICENSE
|
||||
README.md
|
||||
!**/.gitignore
|
||||
!.git/HEAD
|
||||
!.git/config
|
||||
!.git/packed-refs
|
||||
!.git/refs/heads/**
|
@@ -7,14 +7,13 @@ package aia;
|
||||
|
||||
service aiAssistance {
|
||||
rpc SendQuestion (aiaRequest) returns (aiaReply);
|
||||
rpc imageAnalize (aiaRequest) returns (aiaReply);
|
||||
}
|
||||
|
||||
message aiaRequest {
|
||||
string question = 1;
|
||||
string prompts = 2;
|
||||
string model = 3;
|
||||
string apitoken = 4;
|
||||
string url = 5;
|
||||
}
|
||||
|
||||
message aiaReply {
|
||||
|
@@ -23,6 +23,11 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "HushianWebApp", "Presentati
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "AIAss", "Presentation\AIAss\AIAss.csproj", "{AF6AE286-63CF-4A8A-A0B4-DBDA047FC9AE}"
|
||||
EndProject
|
||||
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{8EC462FD-D22E-90A8-E5CE-7E832BA40C5D}"
|
||||
ProjectSection(SolutionItems) = preProject
|
||||
command.txt = command.txt
|
||||
EndProjectSection
|
||||
EndProject
|
||||
Global
|
||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||
Debug|Any CPU = Debug|Any CPU
|
||||
|
@@ -39,7 +39,7 @@ namespace Hushian.Infrastructure.Ai_Ass
|
||||
(new aiaRequest()
|
||||
{ Prompts = Request.ToString(),
|
||||
Question = Request.question,
|
||||
Model=model,Apitoken=_aiSettings.apitoken,Url=_aiSettings.url });
|
||||
Model=model});
|
||||
|
||||
if (response!=null)
|
||||
{
|
||||
|
@@ -24,16 +24,16 @@ namespace AIAss.Protos {
|
||||
static AiaReflection() {
|
||||
byte[] descriptorData = global::System.Convert.FromBase64String(
|
||||
string.Concat(
|
||||
"CglhaWEucHJvdG8SA2FpYSJdCgphaWFSZXF1ZXN0EhAKCHF1ZXN0aW9uGAEg",
|
||||
"ASgJEg8KB3Byb21wdHMYAiABKAkSDQoFbW9kZWwYAyABKAkSEAoIYXBpdG9r",
|
||||
"ZW4YBCABKAkSCwoDdXJsGAUgASgJIhsKCGFpYVJlcGx5Eg8KB21lc3NhZ2UY",
|
||||
"ASABKAkyPgoMYWlBc3Npc3RhbmNlEi4KDFNlbmRRdWVzdGlvbhIPLmFpYS5h",
|
||||
"aWFSZXF1ZXN0Gg0uYWlhLmFpYVJlcGx5Qg+qAgxBSUFzcy5Qcm90b3NiBnBy",
|
||||
"b3RvMw=="));
|
||||
"CglhaWEucHJvdG8SA2FpYSI+CgphaWFSZXF1ZXN0EhAKCHF1ZXN0aW9uGAEg",
|
||||
"ASgJEg8KB3Byb21wdHMYAiABKAkSDQoFbW9kZWwYAyABKAkiGwoIYWlhUmVw",
|
||||
"bHkSDwoHbWVzc2FnZRgBIAEoCTJuCgxhaUFzc2lzdGFuY2USLgoMU2VuZFF1",
|
||||
"ZXN0aW9uEg8uYWlhLmFpYVJlcXVlc3QaDS5haWEuYWlhUmVwbHkSLgoMaW1h",
|
||||
"Z2VBbmFsaXplEg8uYWlhLmFpYVJlcXVlc3QaDS5haWEuYWlhUmVwbHlCD6oC",
|
||||
"DEFJQXNzLlByb3Rvc2IGcHJvdG8z"));
|
||||
descriptor = pbr::FileDescriptor.FromGeneratedCode(descriptorData,
|
||||
new pbr::FileDescriptor[] { },
|
||||
new pbr::GeneratedClrTypeInfo(null, null, new pbr::GeneratedClrTypeInfo[] {
|
||||
new pbr::GeneratedClrTypeInfo(typeof(global::AIAss.Protos.aiaRequest), global::AIAss.Protos.aiaRequest.Parser, new[]{ "Question", "Prompts", "Model", "Apitoken", "Url" }, null, null, null, null),
|
||||
new pbr::GeneratedClrTypeInfo(typeof(global::AIAss.Protos.aiaRequest), global::AIAss.Protos.aiaRequest.Parser, new[]{ "Question", "Prompts", "Model" }, null, null, null, null),
|
||||
new pbr::GeneratedClrTypeInfo(typeof(global::AIAss.Protos.aiaReply), global::AIAss.Protos.aiaReply.Parser, new[]{ "Message" }, null, null, null, null)
|
||||
}));
|
||||
}
|
||||
@@ -79,8 +79,6 @@ namespace AIAss.Protos {
|
||||
question_ = other.question_;
|
||||
prompts_ = other.prompts_;
|
||||
model_ = other.model_;
|
||||
apitoken_ = other.apitoken_;
|
||||
url_ = other.url_;
|
||||
_unknownFields = pb::UnknownFieldSet.Clone(other._unknownFields);
|
||||
}
|
||||
|
||||
@@ -126,30 +124,6 @@ namespace AIAss.Protos {
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>Field number for the "apitoken" field.</summary>
|
||||
public const int ApitokenFieldNumber = 4;
|
||||
private string apitoken_ = "";
|
||||
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
|
||||
[global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
|
||||
public string Apitoken {
|
||||
get { return apitoken_; }
|
||||
set {
|
||||
apitoken_ = pb::ProtoPreconditions.CheckNotNull(value, "value");
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>Field number for the "url" field.</summary>
|
||||
public const int UrlFieldNumber = 5;
|
||||
private string url_ = "";
|
||||
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
|
||||
[global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
|
||||
public string Url {
|
||||
get { return url_; }
|
||||
set {
|
||||
url_ = pb::ProtoPreconditions.CheckNotNull(value, "value");
|
||||
}
|
||||
}
|
||||
|
||||
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
|
||||
[global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
|
||||
public override bool Equals(object other) {
|
||||
@@ -168,8 +142,6 @@ namespace AIAss.Protos {
|
||||
if (Question != other.Question) return false;
|
||||
if (Prompts != other.Prompts) return false;
|
||||
if (Model != other.Model) return false;
|
||||
if (Apitoken != other.Apitoken) return false;
|
||||
if (Url != other.Url) return false;
|
||||
return Equals(_unknownFields, other._unknownFields);
|
||||
}
|
||||
|
||||
@@ -180,8 +152,6 @@ namespace AIAss.Protos {
|
||||
if (Question.Length != 0) hash ^= Question.GetHashCode();
|
||||
if (Prompts.Length != 0) hash ^= Prompts.GetHashCode();
|
||||
if (Model.Length != 0) hash ^= Model.GetHashCode();
|
||||
if (Apitoken.Length != 0) hash ^= Apitoken.GetHashCode();
|
||||
if (Url.Length != 0) hash ^= Url.GetHashCode();
|
||||
if (_unknownFields != null) {
|
||||
hash ^= _unknownFields.GetHashCode();
|
||||
}
|
||||
@@ -212,14 +182,6 @@ namespace AIAss.Protos {
|
||||
output.WriteRawTag(26);
|
||||
output.WriteString(Model);
|
||||
}
|
||||
if (Apitoken.Length != 0) {
|
||||
output.WriteRawTag(34);
|
||||
output.WriteString(Apitoken);
|
||||
}
|
||||
if (Url.Length != 0) {
|
||||
output.WriteRawTag(42);
|
||||
output.WriteString(Url);
|
||||
}
|
||||
if (_unknownFields != null) {
|
||||
_unknownFields.WriteTo(output);
|
||||
}
|
||||
@@ -242,14 +204,6 @@ namespace AIAss.Protos {
|
||||
output.WriteRawTag(26);
|
||||
output.WriteString(Model);
|
||||
}
|
||||
if (Apitoken.Length != 0) {
|
||||
output.WriteRawTag(34);
|
||||
output.WriteString(Apitoken);
|
||||
}
|
||||
if (Url.Length != 0) {
|
||||
output.WriteRawTag(42);
|
||||
output.WriteString(Url);
|
||||
}
|
||||
if (_unknownFields != null) {
|
||||
_unknownFields.WriteTo(ref output);
|
||||
}
|
||||
@@ -269,12 +223,6 @@ namespace AIAss.Protos {
|
||||
if (Model.Length != 0) {
|
||||
size += 1 + pb::CodedOutputStream.ComputeStringSize(Model);
|
||||
}
|
||||
if (Apitoken.Length != 0) {
|
||||
size += 1 + pb::CodedOutputStream.ComputeStringSize(Apitoken);
|
||||
}
|
||||
if (Url.Length != 0) {
|
||||
size += 1 + pb::CodedOutputStream.ComputeStringSize(Url);
|
||||
}
|
||||
if (_unknownFields != null) {
|
||||
size += _unknownFields.CalculateSize();
|
||||
}
|
||||
@@ -296,12 +244,6 @@ namespace AIAss.Protos {
|
||||
if (other.Model.Length != 0) {
|
||||
Model = other.Model;
|
||||
}
|
||||
if (other.Apitoken.Length != 0) {
|
||||
Apitoken = other.Apitoken;
|
||||
}
|
||||
if (other.Url.Length != 0) {
|
||||
Url = other.Url;
|
||||
}
|
||||
_unknownFields = pb::UnknownFieldSet.MergeFrom(_unknownFields, other._unknownFields);
|
||||
}
|
||||
|
||||
@@ -329,14 +271,6 @@ namespace AIAss.Protos {
|
||||
Model = input.ReadString();
|
||||
break;
|
||||
}
|
||||
case 34: {
|
||||
Apitoken = input.ReadString();
|
||||
break;
|
||||
}
|
||||
case 42: {
|
||||
Url = input.ReadString();
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
@@ -364,14 +298,6 @@ namespace AIAss.Protos {
|
||||
Model = input.ReadString();
|
||||
break;
|
||||
}
|
||||
case 34: {
|
||||
Apitoken = input.ReadString();
|
||||
break;
|
||||
}
|
||||
case 42: {
|
||||
Url = input.ReadString();
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -58,6 +58,14 @@ namespace AIAss.Protos {
|
||||
__Marshaller_aia_aiaRequest,
|
||||
__Marshaller_aia_aiaReply);
|
||||
|
||||
[global::System.CodeDom.Compiler.GeneratedCode("grpc_csharp_plugin", null)]
|
||||
static readonly grpc::Method<global::AIAss.Protos.aiaRequest, global::AIAss.Protos.aiaReply> __Method_imageAnalize = new grpc::Method<global::AIAss.Protos.aiaRequest, global::AIAss.Protos.aiaReply>(
|
||||
grpc::MethodType.Unary,
|
||||
__ServiceName,
|
||||
"imageAnalize",
|
||||
__Marshaller_aia_aiaRequest,
|
||||
__Marshaller_aia_aiaReply);
|
||||
|
||||
/// <summary>Service descriptor</summary>
|
||||
public static global::Google.Protobuf.Reflection.ServiceDescriptor Descriptor
|
||||
{
|
||||
@@ -74,6 +82,12 @@ namespace AIAss.Protos {
|
||||
throw new grpc::RpcException(new grpc::Status(grpc::StatusCode.Unimplemented, ""));
|
||||
}
|
||||
|
||||
[global::System.CodeDom.Compiler.GeneratedCode("grpc_csharp_plugin", null)]
|
||||
public virtual global::System.Threading.Tasks.Task<global::AIAss.Protos.aiaReply> imageAnalize(global::AIAss.Protos.aiaRequest request, grpc::ServerCallContext context)
|
||||
{
|
||||
throw new grpc::RpcException(new grpc::Status(grpc::StatusCode.Unimplemented, ""));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/// <summary>Client for aiAssistance</summary>
|
||||
@@ -123,6 +137,26 @@ namespace AIAss.Protos {
|
||||
{
|
||||
return CallInvoker.AsyncUnaryCall(__Method_SendQuestion, null, options, request);
|
||||
}
|
||||
[global::System.CodeDom.Compiler.GeneratedCode("grpc_csharp_plugin", null)]
|
||||
public virtual global::AIAss.Protos.aiaReply imageAnalize(global::AIAss.Protos.aiaRequest request, grpc::Metadata headers = null, global::System.DateTime? deadline = null, global::System.Threading.CancellationToken cancellationToken = default(global::System.Threading.CancellationToken))
|
||||
{
|
||||
return imageAnalize(request, new grpc::CallOptions(headers, deadline, cancellationToken));
|
||||
}
|
||||
[global::System.CodeDom.Compiler.GeneratedCode("grpc_csharp_plugin", null)]
|
||||
public virtual global::AIAss.Protos.aiaReply imageAnalize(global::AIAss.Protos.aiaRequest request, grpc::CallOptions options)
|
||||
{
|
||||
return CallInvoker.BlockingUnaryCall(__Method_imageAnalize, null, options, request);
|
||||
}
|
||||
[global::System.CodeDom.Compiler.GeneratedCode("grpc_csharp_plugin", null)]
|
||||
public virtual grpc::AsyncUnaryCall<global::AIAss.Protos.aiaReply> imageAnalizeAsync(global::AIAss.Protos.aiaRequest request, grpc::Metadata headers = null, global::System.DateTime? deadline = null, global::System.Threading.CancellationToken cancellationToken = default(global::System.Threading.CancellationToken))
|
||||
{
|
||||
return imageAnalizeAsync(request, new grpc::CallOptions(headers, deadline, cancellationToken));
|
||||
}
|
||||
[global::System.CodeDom.Compiler.GeneratedCode("grpc_csharp_plugin", null)]
|
||||
public virtual grpc::AsyncUnaryCall<global::AIAss.Protos.aiaReply> imageAnalizeAsync(global::AIAss.Protos.aiaRequest request, grpc::CallOptions options)
|
||||
{
|
||||
return CallInvoker.AsyncUnaryCall(__Method_imageAnalize, null, options, request);
|
||||
}
|
||||
/// <summary>Creates a new instance of client from given <c>ClientBaseConfiguration</c>.</summary>
|
||||
[global::System.CodeDom.Compiler.GeneratedCode("grpc_csharp_plugin", null)]
|
||||
protected override aiAssistanceClient NewInstance(ClientBaseConfiguration configuration)
|
||||
@@ -137,7 +171,8 @@ namespace AIAss.Protos {
|
||||
public static grpc::ServerServiceDefinition BindService(aiAssistanceBase serviceImpl)
|
||||
{
|
||||
return grpc::ServerServiceDefinition.CreateBuilder()
|
||||
.AddMethod(__Method_SendQuestion, serviceImpl.SendQuestion).Build();
|
||||
.AddMethod(__Method_SendQuestion, serviceImpl.SendQuestion)
|
||||
.AddMethod(__Method_imageAnalize, serviceImpl.imageAnalize).Build();
|
||||
}
|
||||
|
||||
/// <summary>Register service method with a service binder with or without implementation. Useful when customizing the service binding logic.
|
||||
@@ -148,6 +183,7 @@ namespace AIAss.Protos {
|
||||
public static void BindService(grpc::ServiceBinderBase serviceBinder, aiAssistanceBase serviceImpl)
|
||||
{
|
||||
serviceBinder.AddMethod(__Method_SendQuestion, serviceImpl == null ? null : new grpc::UnaryServerMethod<global::AIAss.Protos.aiaRequest, global::AIAss.Protos.aiaReply>(serviceImpl.SendQuestion));
|
||||
serviceBinder.AddMethod(__Method_imageAnalize, serviceImpl == null ? null : new grpc::UnaryServerMethod<global::AIAss.Protos.aiaRequest, global::AIAss.Protos.aiaReply>(serviceImpl.imageAnalize));
|
||||
}
|
||||
|
||||
}
|
||||
|
374
Presentation/AIAss/.dockerignore
Normal file
374
Presentation/AIAss/.dockerignore
Normal file
@@ -0,0 +1,374 @@
|
||||
# Build results
|
||||
[Dd]ebug/
|
||||
[Dd]ebugPublic/
|
||||
[Rr]elease/
|
||||
[Rr]eleases/
|
||||
x64/
|
||||
x86/
|
||||
[Ww][Ii][Nn]32/
|
||||
[Aa][Rr][Mm]/
|
||||
[Aa][Rr][Mm]64/
|
||||
bld/
|
||||
[Bb]in/
|
||||
[Oo]bj/
|
||||
[Ll]og/
|
||||
[Ll]ogs/
|
||||
|
||||
# Visual Studio 2015/2017 cache/options directory
|
||||
.vs/
|
||||
# Uncomment if you have tasks that create the project's static files in wwwroot
|
||||
#wwwroot/
|
||||
|
||||
# Visual Studio 2017 auto generated files
|
||||
Generated\ Files/
|
||||
|
||||
# MSTest test Results
|
||||
[Tt]est[Rr]esult*/
|
||||
[Bb]uild[Ll]og.*
|
||||
|
||||
# NUnit
|
||||
*.VisualState.xml
|
||||
TestResult.xml
|
||||
nunit-*.xml
|
||||
|
||||
# Build Results of an ATL Project
|
||||
[Dd]ebugPS/
|
||||
[Rr]eleasePS/
|
||||
dlldata.c
|
||||
|
||||
# Benchmark Results
|
||||
BenchmarkDotNet.Artifacts/
|
||||
|
||||
# .NET Core
|
||||
project.lock.json
|
||||
project.fragment.lock.json
|
||||
artifacts/
|
||||
|
||||
# StyleCop
|
||||
StyleCopReport.xml
|
||||
|
||||
# Files built by Visual Studio
|
||||
*_i.c
|
||||
*_p.c
|
||||
*_h.h
|
||||
*.ilk
|
||||
*.meta
|
||||
*.obj
|
||||
*.iobj
|
||||
*.pch
|
||||
*.pdb
|
||||
*.ipdb
|
||||
*.pgc
|
||||
*.pgd
|
||||
*.rsp
|
||||
*.sbr
|
||||
*.tlb
|
||||
*.tli
|
||||
*.tlh
|
||||
*.tmp
|
||||
*.tmp_proj
|
||||
*_wpftmp.csproj
|
||||
*.log
|
||||
*.tlog
|
||||
*.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
|
||||
|
||||
# Visual Studio Trace Files
|
||||
*.e2e
|
||||
|
||||
# TFS 2012 Local Workspace
|
||||
$tf/
|
||||
|
||||
# Guidance Automation Toolkit
|
||||
*.gpState
|
||||
|
||||
# ReSharper is a .NET coding add-in
|
||||
_ReSharper*/
|
||||
*.[Rr]e[Ss]harper
|
||||
*.DotSettings.user
|
||||
|
||||
# TeamCity is a build add-in
|
||||
_TeamCity*
|
||||
|
||||
# DotCover is a Code Coverage Tool
|
||||
*.dotCover
|
||||
|
||||
# AxoCover is a Code Coverage Tool
|
||||
.axoCover/*
|
||||
!.axoCover/settings.json
|
||||
|
||||
# Coverlet is a free, cross platform Code Coverage Tool
|
||||
coverage*.json
|
||||
coverage*.xml
|
||||
coverage*.info
|
||||
|
||||
# Visual Studio code coverage results
|
||||
*.coverage
|
||||
*.coveragexml
|
||||
|
||||
# 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
|
||||
|
||||
# Click-Once directory
|
||||
publish/
|
||||
|
||||
# Publish Web Output
|
||||
*.[Pp]ublish.xml
|
||||
*.azurePubxml
|
||||
# Note: 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 files will be unencrypted
|
||||
PublishScripts/
|
||||
|
||||
# NuGet Packages
|
||||
*.nupkg
|
||||
# NuGet Symbol Packages
|
||||
*.snupkg
|
||||
# The packages folder can be ignored because of Package Restore
|
||||
**/[Pp]ackages/*
|
||||
# except build/, which is used as an MSBuild target.
|
||||
!**/[Pp]ackages/build/
|
||||
# Uncomment if necessary however generally it will be regenerated when needed
|
||||
#!**/[Pp]ackages/repositories.config
|
||||
# NuGet v3's project.json files produces more ignorable 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
|
||||
*.appx
|
||||
*.appxbundle
|
||||
*.appxupload
|
||||
|
||||
# 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
|
||||
*.jfm
|
||||
*.pfx
|
||||
*.publishsettings
|
||||
orleans.codegen.cs
|
||||
|
||||
# Including strong name files can present a security risk
|
||||
# (https://github.com/github/gitignore/pull/2483#issue-259490424)
|
||||
#*.snk
|
||||
|
||||
# Since there are multiple workflows, uncomment the 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
|
||||
CConversionReport*.XML
|
||||
|
||||
# SQL Server files
|
||||
*.mdf
|
||||
*.ldf
|
||||
*.ndf
|
||||
|
||||
# Business Intelligence projects
|
||||
*.rdl.data
|
||||
*.bim.layout
|
||||
*.bim_*.settings
|
||||
*.rptproj.rsuser
|
||||
*- [Bb]ackup.rdl
|
||||
*- [Bb]ackup ([0-9]).rdl
|
||||
*- [Bb]ackup ([0-9][0-9]).rdl
|
||||
|
||||
# Microsoft Fakes
|
||||
FakesAssemblies/
|
||||
|
||||
# GhostDoc plugin setting file
|
||||
*.GhostDoc.xml
|
||||
|
||||
# Node.js Tools for Visual Studio
|
||||
.ntvs_analysis.dat
|
||||
node_modules/
|
||||
|
||||
# Visual Studio 6 build log
|
||||
*.plg
|
||||
|
||||
# Visual Studio 6 workspace options file
|
||||
*.opt
|
||||
|
||||
# Visual Studio 6 auto-generated workspace file (contains which files were open etc.)
|
||||
*.vbw
|
||||
|
||||
# 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/
|
||||
|
||||
# CodeRush personal settings
|
||||
.cr/personal
|
||||
|
||||
# Python Tools for Visual Studio (PTVS)
|
||||
__pycache__/
|
||||
*.pyc
|
||||
|
||||
# Cake - Uncomment if you are using it
|
||||
# tools/**
|
||||
# !tools/packages.config
|
||||
|
||||
# Tabs Studio
|
||||
*.tss
|
||||
|
||||
# Telerik's JustMock configuration file
|
||||
*.jmconfig
|
||||
|
||||
# BizTalk build output
|
||||
*.btp.cs
|
||||
*.btm.cs
|
||||
*.odx.cs
|
||||
*.xsd.cs
|
||||
|
||||
# OpenCover UI analysis results
|
||||
OpenCover/
|
||||
|
||||
# Azure Stream Analytics local run output
|
||||
ASALocalRun/
|
||||
|
||||
# MSBuild Binary and Structured Log
|
||||
*.binlog
|
||||
|
||||
# NVidia Nsight GPU debugger configuration file
|
||||
*.nvuser
|
||||
|
||||
# MFractors (Xamarin productivity tool) working folder
|
||||
.mfractor/
|
||||
|
||||
# Local History for Visual Studio
|
||||
.localhistory/
|
||||
|
||||
# BeatPulse healthcheck temp database
|
||||
healthchecksdb
|
||||
|
||||
# Backup folder for Package Reference Convert tool in Visual Studio 2017
|
||||
MigrationBackup/
|
||||
|
||||
# Ionide (cross platform F# VS Code tools) working folder
|
||||
.ionide/
|
||||
|
||||
# Fody - auto-generated XML schema
|
||||
FodyWeavers.xsd
|
||||
|
||||
# VS Code files for those working on multiple tools
|
||||
.vscode/*
|
||||
!.vscode/settings.json
|
||||
!.vscode/tasks.json
|
||||
!.vscode/launch.json
|
||||
!.vscode/extensions.json
|
||||
*.code-workspace
|
||||
|
||||
# Local History for Visual Studio Code
|
||||
.history/
|
||||
|
||||
# Windows Installer files from build outputs
|
||||
*.cab
|
||||
*.msi
|
||||
*.msix
|
||||
*.msm
|
||||
*.msp
|
||||
|
||||
# JetBrains Rider
|
||||
*.sln.iml
|
||||
|
||||
# Docker
|
||||
Dockerfile
|
||||
.dockerignore
|
||||
|
||||
# Git
|
||||
.git
|
||||
.gitignore
|
||||
|
||||
# IDE
|
||||
.vscode/
|
||||
.idea/
|
||||
*.user
|
||||
*.suo
|
||||
*.userosscache
|
||||
*.sln.docstates
|
||||
|
10
Presentation/AIAss/Docker Command.txt
Normal file
10
Presentation/AIAss/Docker Command.txt
Normal file
@@ -0,0 +1,10 @@
|
||||
docker build -t ai_assistance .
|
||||
|
||||
docker run --name openai_assistance -d -p 5042:5010 ai_assistance
|
||||
|
||||
|
||||
--------------------------------------------------------------------------------------------
|
||||
in local => docker build -t mmrbnjd/ai_assistance:latest .
|
||||
in local => docker push mmrbnjd/ai_assistance:latest
|
||||
in server => docker pull mmrbnjd/ai_assistance:latest
|
||||
in server => docker run -d -p 5042:5010 --restart always mmrbnjd/ai_assistance:latest
|
40
Presentation/AIAss/Dockerfile
Normal file
40
Presentation/AIAss/Dockerfile
Normal file
@@ -0,0 +1,40 @@
|
||||
# Use the official .NET 9.0 runtime image as the base image
|
||||
FROM mcr.microsoft.com/dotnet/aspnet:9.0 AS base
|
||||
WORKDIR /app
|
||||
EXPOSE 5010
|
||||
|
||||
# Use the official .NET 9.0 SDK image for building
|
||||
FROM mcr.microsoft.com/dotnet/sdk:9.0 AS build
|
||||
WORKDIR /src
|
||||
|
||||
# Copy the project file and restore dependencies
|
||||
COPY ["AIAss.csproj", "./"]
|
||||
RUN dotnet restore "AIAss.csproj"
|
||||
|
||||
# Copy the rest of the source code
|
||||
COPY . .
|
||||
WORKDIR "/src/."
|
||||
|
||||
# Build the application
|
||||
RUN dotnet build "AIAss.csproj" -c Release -o /app/build
|
||||
|
||||
# Publish the application
|
||||
FROM build AS publish
|
||||
RUN dotnet publish "AIAss.csproj" -c Release -o /app/publish /p:UseAppHost=false
|
||||
|
||||
# Final stage/image
|
||||
FROM base AS final
|
||||
WORKDIR /app
|
||||
COPY --from=publish /app/publish .
|
||||
|
||||
# Set environment variables
|
||||
ENV ASPNETCORE_URLS=http://+:5010;
|
||||
ENV ASPNETCORE_ENVIRONMENT=Production
|
||||
|
||||
# Create a non-root user for security
|
||||
RUN adduser --disabled-password --gecos "" appuser && chown -R appuser /app
|
||||
USER appuser
|
||||
|
||||
# Set the entry point
|
||||
ENTRYPOINT ["dotnet", "AIAss.dll"]
|
||||
|
110
Presentation/AIAss/README-Docker.md
Normal file
110
Presentation/AIAss/README-Docker.md
Normal file
@@ -0,0 +1,110 @@
|
||||
# AIAss Docker Setup
|
||||
|
||||
This document explains how to run the AIAss gRPC service using Docker.
|
||||
|
||||
## Prerequisites
|
||||
|
||||
- Docker Desktop installed and running
|
||||
- Docker Compose (usually comes with Docker Desktop)
|
||||
|
||||
## Quick Start
|
||||
|
||||
### Using Docker Compose (Recommended)
|
||||
|
||||
1. Navigate to the AIAss project directory:
|
||||
```bash
|
||||
cd Presentation/AIAss
|
||||
```
|
||||
|
||||
2. Build and run the service:
|
||||
```bash
|
||||
docker-compose up --build
|
||||
```
|
||||
|
||||
3. The service will be available at:
|
||||
- HTTP: http://localhost:5000
|
||||
- HTTPS: https://localhost:5001
|
||||
|
||||
### Using Docker directly
|
||||
|
||||
1. Build the Docker image:
|
||||
```bash
|
||||
docker build -t aiass .
|
||||
```
|
||||
|
||||
2. Run the container:
|
||||
```bash
|
||||
docker run -p 5000:80 -p 5001:443 aiass
|
||||
```
|
||||
|
||||
## Configuration
|
||||
|
||||
### Environment Variables
|
||||
|
||||
- `ASPNETCORE_ENVIRONMENT`: Set to `Development` or `Production`
|
||||
- `ASPNETCORE_URLS`: Configure the URLs the service listens on
|
||||
|
||||
### Ports
|
||||
|
||||
- Port 80: HTTP endpoint
|
||||
- Port 443: HTTPS endpoint
|
||||
|
||||
## Development
|
||||
|
||||
### Hot Reload
|
||||
|
||||
For development with hot reload, you can mount the source code:
|
||||
|
||||
```yaml
|
||||
volumes:
|
||||
- .:/src
|
||||
- /src/bin
|
||||
- /src/obj
|
||||
```
|
||||
|
||||
### Debugging
|
||||
|
||||
To debug the containerized application, you can:
|
||||
|
||||
1. Attach a debugger to the running container
|
||||
2. Use remote debugging tools
|
||||
3. Check logs: `docker-compose logs aiass`
|
||||
|
||||
## Production
|
||||
|
||||
For production deployment:
|
||||
|
||||
1. Set `ASPNETCORE_ENVIRONMENT=Production`
|
||||
2. Use proper SSL certificates
|
||||
3. Configure health checks
|
||||
4. Set up monitoring and logging
|
||||
|
||||
## Troubleshooting
|
||||
|
||||
### Common Issues
|
||||
|
||||
1. **Port already in use**: Change the port mappings in docker-compose.yml
|
||||
2. **Build failures**: Ensure all dependencies are properly restored
|
||||
3. **Permission issues**: Check file ownership and Docker user settings
|
||||
|
||||
### Logs
|
||||
|
||||
View container logs:
|
||||
```bash
|
||||
docker-compose logs -f aiass
|
||||
```
|
||||
|
||||
### Cleanup
|
||||
|
||||
Remove containers and images:
|
||||
```bash
|
||||
docker-compose down
|
||||
docker system prune -a
|
||||
```
|
||||
|
||||
## Security Notes
|
||||
|
||||
- The container runs as a non-root user (`appuser`)
|
||||
- Only necessary ports are exposed
|
||||
- Environment variables can be overridden for different deployment scenarios
|
||||
|
@@ -4,19 +4,29 @@ using AIAss.Protos;
|
||||
using System.Net.Http.Headers;
|
||||
using System.Text.Json;
|
||||
using System.Text;
|
||||
using Microsoft.Extensions.Configuration;
|
||||
|
||||
namespace AIAss.Services;
|
||||
|
||||
public class aiAssistanceService: aiAssistance.aiAssistanceBase
|
||||
public class aiAssistanceService : aiAssistance.aiAssistanceBase
|
||||
{
|
||||
private readonly string Apitoken;
|
||||
private readonly string url;
|
||||
public aiAssistanceService(IConfiguration configuration)
|
||||
{
|
||||
url = configuration["aiSettings:url"];
|
||||
Apitoken = configuration["aiSettings:apitoken"];
|
||||
|
||||
}
|
||||
|
||||
public async override Task<aiaReply> SendQuestion(aiaRequest request, ServerCallContext context)
|
||||
{
|
||||
using var client = new HttpClient();
|
||||
client.DefaultRequestHeaders.Authorization =
|
||||
new AuthenticationHeaderValue("Bearer", request.Apitoken);
|
||||
new AuthenticationHeaderValue("Bearer", Apitoken);
|
||||
var content = new
|
||||
{
|
||||
model= request.Model,
|
||||
model = request.Model,
|
||||
messages = new[]
|
||||
{
|
||||
new { role = "system", content = "شما یک دستیار پاسخگو به سوالات هستید." },
|
||||
@@ -24,7 +34,7 @@ namespace AIAss.Services;
|
||||
new { role = "system", content = "به سوالات غیره متن بالا پاسخ نده و بگو در این زمینه اطلاعی ندارم" }
|
||||
}
|
||||
};
|
||||
var response = await client.PostAsync(request.Url,
|
||||
var response = await client.PostAsync(url,
|
||||
new StringContent(JsonSerializer.Serialize(content), Encoding.UTF8, "application/json"));
|
||||
string reponse = "";
|
||||
if (response.IsSuccessStatusCode)
|
||||
@@ -35,7 +45,66 @@ namespace AIAss.Services;
|
||||
}
|
||||
else
|
||||
{
|
||||
reponse="خطا در ارتباط سرور ai";
|
||||
reponse = "خطا در ارتباط سرور ai";
|
||||
}
|
||||
|
||||
return new aiaReply
|
||||
{
|
||||
Message = $" {reponse}"
|
||||
};
|
||||
}
|
||||
public async override Task<aiaReply> imageAnalize(aiaRequest request, ServerCallContext context)
|
||||
{
|
||||
|
||||
|
||||
using var client = new HttpClient();
|
||||
client.DefaultRequestHeaders.Authorization =
|
||||
new AuthenticationHeaderValue("Bearer", Apitoken);
|
||||
var content = new
|
||||
{
|
||||
model = request.Model,
|
||||
messages = new object[]
|
||||
{
|
||||
new {
|
||||
role = "system",
|
||||
content = "شما دستیار برای توصیف آزمایشات هستید."
|
||||
},
|
||||
new {
|
||||
role = "user",
|
||||
content = new object[]
|
||||
{
|
||||
new { type = "text", text = "این تصویر اگر آزمایش انسان است توصیف کن در غیر اینصورت پاسخ نده" },
|
||||
new {
|
||||
type = "image_url",
|
||||
image_url = new {
|
||||
url = $"data:image/jpeg;base64,{request.Question}"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
var response = await client.PostAsync(url,
|
||||
new StringContent(JsonSerializer.Serialize(content), Encoding.UTF8, "application/json"));
|
||||
string reponse = "";
|
||||
if (response.IsSuccessStatusCode)
|
||||
{
|
||||
var json = await response.Content.ReadAsStringAsync();
|
||||
using var doc = JsonDocument.Parse(json);
|
||||
reponse = doc.RootElement.GetProperty("choices")[0].GetProperty("message").GetProperty("content").GetString();
|
||||
context.Status = new Status(StatusCode.OK,"is Success");
|
||||
}
|
||||
else
|
||||
{
|
||||
reponse = "خطا در ارتباط سرور ai";
|
||||
if (response.StatusCode==System.Net.HttpStatusCode.TooManyRequests)
|
||||
{
|
||||
throw new RpcException(new Status(StatusCode.Cancelled, "ترافیک بالای شبکه در زمان دیگری تلاش کنید"));
|
||||
|
||||
}
|
||||
else
|
||||
throw new RpcException(new Status(StatusCode.Cancelled, "خطا در ارتباط سرور"));
|
||||
}
|
||||
|
||||
return new aiaReply
|
||||
|
@@ -10,5 +10,11 @@
|
||||
"EndpointDefaults": {
|
||||
"Protocols": "Http2"
|
||||
}
|
||||
},
|
||||
"aiSettings": {
|
||||
"url": "https://api.openai.com/v1/chat/completions",
|
||||
"apitokenold": "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",
|
||||
"apitoken": "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"
|
||||
|
||||
}
|
||||
}
|
||||
|
@@ -24,16 +24,16 @@ namespace AIAss.Protos {
|
||||
static AiaReflection() {
|
||||
byte[] descriptorData = global::System.Convert.FromBase64String(
|
||||
string.Concat(
|
||||
"CglhaWEucHJvdG8SA2FpYSJdCgphaWFSZXF1ZXN0EhAKCHF1ZXN0aW9uGAEg",
|
||||
"ASgJEg8KB3Byb21wdHMYAiABKAkSDQoFbW9kZWwYAyABKAkSEAoIYXBpdG9r",
|
||||
"ZW4YBCABKAkSCwoDdXJsGAUgASgJIhsKCGFpYVJlcGx5Eg8KB21lc3NhZ2UY",
|
||||
"ASABKAkyPgoMYWlBc3Npc3RhbmNlEi4KDFNlbmRRdWVzdGlvbhIPLmFpYS5h",
|
||||
"aWFSZXF1ZXN0Gg0uYWlhLmFpYVJlcGx5Qg+qAgxBSUFzcy5Qcm90b3NiBnBy",
|
||||
"b3RvMw=="));
|
||||
"CglhaWEucHJvdG8SA2FpYSI+CgphaWFSZXF1ZXN0EhAKCHF1ZXN0aW9uGAEg",
|
||||
"ASgJEg8KB3Byb21wdHMYAiABKAkSDQoFbW9kZWwYAyABKAkiGwoIYWlhUmVw",
|
||||
"bHkSDwoHbWVzc2FnZRgBIAEoCTJuCgxhaUFzc2lzdGFuY2USLgoMU2VuZFF1",
|
||||
"ZXN0aW9uEg8uYWlhLmFpYVJlcXVlc3QaDS5haWEuYWlhUmVwbHkSLgoMaW1h",
|
||||
"Z2VBbmFsaXplEg8uYWlhLmFpYVJlcXVlc3QaDS5haWEuYWlhUmVwbHlCD6oC",
|
||||
"DEFJQXNzLlByb3Rvc2IGcHJvdG8z"));
|
||||
descriptor = pbr::FileDescriptor.FromGeneratedCode(descriptorData,
|
||||
new pbr::FileDescriptor[] { },
|
||||
new pbr::GeneratedClrTypeInfo(null, null, new pbr::GeneratedClrTypeInfo[] {
|
||||
new pbr::GeneratedClrTypeInfo(typeof(global::AIAss.Protos.aiaRequest), global::AIAss.Protos.aiaRequest.Parser, new[]{ "Question", "Prompts", "Model", "Apitoken", "Url" }, null, null, null, null),
|
||||
new pbr::GeneratedClrTypeInfo(typeof(global::AIAss.Protos.aiaRequest), global::AIAss.Protos.aiaRequest.Parser, new[]{ "Question", "Prompts", "Model" }, null, null, null, null),
|
||||
new pbr::GeneratedClrTypeInfo(typeof(global::AIAss.Protos.aiaReply), global::AIAss.Protos.aiaReply.Parser, new[]{ "Message" }, null, null, null, null)
|
||||
}));
|
||||
}
|
||||
@@ -79,8 +79,6 @@ namespace AIAss.Protos {
|
||||
question_ = other.question_;
|
||||
prompts_ = other.prompts_;
|
||||
model_ = other.model_;
|
||||
apitoken_ = other.apitoken_;
|
||||
url_ = other.url_;
|
||||
_unknownFields = pb::UnknownFieldSet.Clone(other._unknownFields);
|
||||
}
|
||||
|
||||
@@ -126,30 +124,6 @@ namespace AIAss.Protos {
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>Field number for the "apitoken" field.</summary>
|
||||
public const int ApitokenFieldNumber = 4;
|
||||
private string apitoken_ = "";
|
||||
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
|
||||
[global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
|
||||
public string Apitoken {
|
||||
get { return apitoken_; }
|
||||
set {
|
||||
apitoken_ = pb::ProtoPreconditions.CheckNotNull(value, "value");
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>Field number for the "url" field.</summary>
|
||||
public const int UrlFieldNumber = 5;
|
||||
private string url_ = "";
|
||||
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
|
||||
[global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
|
||||
public string Url {
|
||||
get { return url_; }
|
||||
set {
|
||||
url_ = pb::ProtoPreconditions.CheckNotNull(value, "value");
|
||||
}
|
||||
}
|
||||
|
||||
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
|
||||
[global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
|
||||
public override bool Equals(object other) {
|
||||
@@ -168,8 +142,6 @@ namespace AIAss.Protos {
|
||||
if (Question != other.Question) return false;
|
||||
if (Prompts != other.Prompts) return false;
|
||||
if (Model != other.Model) return false;
|
||||
if (Apitoken != other.Apitoken) return false;
|
||||
if (Url != other.Url) return false;
|
||||
return Equals(_unknownFields, other._unknownFields);
|
||||
}
|
||||
|
||||
@@ -180,8 +152,6 @@ namespace AIAss.Protos {
|
||||
if (Question.Length != 0) hash ^= Question.GetHashCode();
|
||||
if (Prompts.Length != 0) hash ^= Prompts.GetHashCode();
|
||||
if (Model.Length != 0) hash ^= Model.GetHashCode();
|
||||
if (Apitoken.Length != 0) hash ^= Apitoken.GetHashCode();
|
||||
if (Url.Length != 0) hash ^= Url.GetHashCode();
|
||||
if (_unknownFields != null) {
|
||||
hash ^= _unknownFields.GetHashCode();
|
||||
}
|
||||
@@ -212,14 +182,6 @@ namespace AIAss.Protos {
|
||||
output.WriteRawTag(26);
|
||||
output.WriteString(Model);
|
||||
}
|
||||
if (Apitoken.Length != 0) {
|
||||
output.WriteRawTag(34);
|
||||
output.WriteString(Apitoken);
|
||||
}
|
||||
if (Url.Length != 0) {
|
||||
output.WriteRawTag(42);
|
||||
output.WriteString(Url);
|
||||
}
|
||||
if (_unknownFields != null) {
|
||||
_unknownFields.WriteTo(output);
|
||||
}
|
||||
@@ -242,14 +204,6 @@ namespace AIAss.Protos {
|
||||
output.WriteRawTag(26);
|
||||
output.WriteString(Model);
|
||||
}
|
||||
if (Apitoken.Length != 0) {
|
||||
output.WriteRawTag(34);
|
||||
output.WriteString(Apitoken);
|
||||
}
|
||||
if (Url.Length != 0) {
|
||||
output.WriteRawTag(42);
|
||||
output.WriteString(Url);
|
||||
}
|
||||
if (_unknownFields != null) {
|
||||
_unknownFields.WriteTo(ref output);
|
||||
}
|
||||
@@ -269,12 +223,6 @@ namespace AIAss.Protos {
|
||||
if (Model.Length != 0) {
|
||||
size += 1 + pb::CodedOutputStream.ComputeStringSize(Model);
|
||||
}
|
||||
if (Apitoken.Length != 0) {
|
||||
size += 1 + pb::CodedOutputStream.ComputeStringSize(Apitoken);
|
||||
}
|
||||
if (Url.Length != 0) {
|
||||
size += 1 + pb::CodedOutputStream.ComputeStringSize(Url);
|
||||
}
|
||||
if (_unknownFields != null) {
|
||||
size += _unknownFields.CalculateSize();
|
||||
}
|
||||
@@ -296,12 +244,6 @@ namespace AIAss.Protos {
|
||||
if (other.Model.Length != 0) {
|
||||
Model = other.Model;
|
||||
}
|
||||
if (other.Apitoken.Length != 0) {
|
||||
Apitoken = other.Apitoken;
|
||||
}
|
||||
if (other.Url.Length != 0) {
|
||||
Url = other.Url;
|
||||
}
|
||||
_unknownFields = pb::UnknownFieldSet.MergeFrom(_unknownFields, other._unknownFields);
|
||||
}
|
||||
|
||||
@@ -329,14 +271,6 @@ namespace AIAss.Protos {
|
||||
Model = input.ReadString();
|
||||
break;
|
||||
}
|
||||
case 34: {
|
||||
Apitoken = input.ReadString();
|
||||
break;
|
||||
}
|
||||
case 42: {
|
||||
Url = input.ReadString();
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
@@ -364,14 +298,6 @@ namespace AIAss.Protos {
|
||||
Model = input.ReadString();
|
||||
break;
|
||||
}
|
||||
case 34: {
|
||||
Apitoken = input.ReadString();
|
||||
break;
|
||||
}
|
||||
case 42: {
|
||||
Url = input.ReadString();
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -58,6 +58,14 @@ namespace AIAss.Protos {
|
||||
__Marshaller_aia_aiaRequest,
|
||||
__Marshaller_aia_aiaReply);
|
||||
|
||||
[global::System.CodeDom.Compiler.GeneratedCode("grpc_csharp_plugin", null)]
|
||||
static readonly grpc::Method<global::AIAss.Protos.aiaRequest, global::AIAss.Protos.aiaReply> __Method_imageAnalize = new grpc::Method<global::AIAss.Protos.aiaRequest, global::AIAss.Protos.aiaReply>(
|
||||
grpc::MethodType.Unary,
|
||||
__ServiceName,
|
||||
"imageAnalize",
|
||||
__Marshaller_aia_aiaRequest,
|
||||
__Marshaller_aia_aiaReply);
|
||||
|
||||
/// <summary>Service descriptor</summary>
|
||||
public static global::Google.Protobuf.Reflection.ServiceDescriptor Descriptor
|
||||
{
|
||||
@@ -74,6 +82,12 @@ namespace AIAss.Protos {
|
||||
throw new grpc::RpcException(new grpc::Status(grpc::StatusCode.Unimplemented, ""));
|
||||
}
|
||||
|
||||
[global::System.CodeDom.Compiler.GeneratedCode("grpc_csharp_plugin", null)]
|
||||
public virtual global::System.Threading.Tasks.Task<global::AIAss.Protos.aiaReply> imageAnalize(global::AIAss.Protos.aiaRequest request, grpc::ServerCallContext context)
|
||||
{
|
||||
throw new grpc::RpcException(new grpc::Status(grpc::StatusCode.Unimplemented, ""));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/// <summary>Client for aiAssistance</summary>
|
||||
@@ -123,6 +137,26 @@ namespace AIAss.Protos {
|
||||
{
|
||||
return CallInvoker.AsyncUnaryCall(__Method_SendQuestion, null, options, request);
|
||||
}
|
||||
[global::System.CodeDom.Compiler.GeneratedCode("grpc_csharp_plugin", null)]
|
||||
public virtual global::AIAss.Protos.aiaReply imageAnalize(global::AIAss.Protos.aiaRequest request, grpc::Metadata headers = null, global::System.DateTime? deadline = null, global::System.Threading.CancellationToken cancellationToken = default(global::System.Threading.CancellationToken))
|
||||
{
|
||||
return imageAnalize(request, new grpc::CallOptions(headers, deadline, cancellationToken));
|
||||
}
|
||||
[global::System.CodeDom.Compiler.GeneratedCode("grpc_csharp_plugin", null)]
|
||||
public virtual global::AIAss.Protos.aiaReply imageAnalize(global::AIAss.Protos.aiaRequest request, grpc::CallOptions options)
|
||||
{
|
||||
return CallInvoker.BlockingUnaryCall(__Method_imageAnalize, null, options, request);
|
||||
}
|
||||
[global::System.CodeDom.Compiler.GeneratedCode("grpc_csharp_plugin", null)]
|
||||
public virtual grpc::AsyncUnaryCall<global::AIAss.Protos.aiaReply> imageAnalizeAsync(global::AIAss.Protos.aiaRequest request, grpc::Metadata headers = null, global::System.DateTime? deadline = null, global::System.Threading.CancellationToken cancellationToken = default(global::System.Threading.CancellationToken))
|
||||
{
|
||||
return imageAnalizeAsync(request, new grpc::CallOptions(headers, deadline, cancellationToken));
|
||||
}
|
||||
[global::System.CodeDom.Compiler.GeneratedCode("grpc_csharp_plugin", null)]
|
||||
public virtual grpc::AsyncUnaryCall<global::AIAss.Protos.aiaReply> imageAnalizeAsync(global::AIAss.Protos.aiaRequest request, grpc::CallOptions options)
|
||||
{
|
||||
return CallInvoker.AsyncUnaryCall(__Method_imageAnalize, null, options, request);
|
||||
}
|
||||
/// <summary>Creates a new instance of client from given <c>ClientBaseConfiguration</c>.</summary>
|
||||
[global::System.CodeDom.Compiler.GeneratedCode("grpc_csharp_plugin", null)]
|
||||
protected override aiAssistanceClient NewInstance(ClientBaseConfiguration configuration)
|
||||
@@ -137,7 +171,8 @@ namespace AIAss.Protos {
|
||||
public static grpc::ServerServiceDefinition BindService(aiAssistanceBase serviceImpl)
|
||||
{
|
||||
return grpc::ServerServiceDefinition.CreateBuilder()
|
||||
.AddMethod(__Method_SendQuestion, serviceImpl.SendQuestion).Build();
|
||||
.AddMethod(__Method_SendQuestion, serviceImpl.SendQuestion)
|
||||
.AddMethod(__Method_imageAnalize, serviceImpl.imageAnalize).Build();
|
||||
}
|
||||
|
||||
/// <summary>Register service method with a service binder with or without implementation. Useful when customizing the service binding logic.
|
||||
@@ -148,6 +183,7 @@ namespace AIAss.Protos {
|
||||
public static void BindService(grpc::ServiceBinderBase serviceBinder, aiAssistanceBase serviceImpl)
|
||||
{
|
||||
serviceBinder.AddMethod(__Method_SendQuestion, serviceImpl == null ? null : new grpc::UnaryServerMethod<global::AIAss.Protos.aiaRequest, global::AIAss.Protos.aiaReply>(serviceImpl.SendQuestion));
|
||||
serviceBinder.AddMethod(__Method_imageAnalize, serviceImpl == null ? null : new grpc::UnaryServerMethod<global::AIAss.Protos.aiaRequest, global::AIAss.Protos.aiaReply>(serviceImpl.imageAnalize));
|
||||
}
|
||||
|
||||
}
|
||||
|
10
Presentation/Hushian.WebApi/DockerCommand.txt
Normal file
10
Presentation/Hushian.WebApi/DockerCommand.txt
Normal file
@@ -0,0 +1,10 @@
|
||||
E:\_hushian> docker build -f Presentation\Hushian.WebApi\Dockerfile -t hushianapi .
|
||||
|
||||
docker run --name hushian_api -d -p 2201:8080 hushianapi
|
||||
|
||||
|
||||
--------------------------------------------------------------------------------------------
|
||||
in local => docker build -f Presentation\Hushian.WebApi\Dockerfile -t mmrbnjd/hushianapi:latest .
|
||||
in local => docker push mmrbnjd/hushianapi:latest
|
||||
in server => docker pull mmrbnjd/hushianapi:latest
|
||||
in server => docker run -d -p 2201:8080 --restart always mmrbnjd/hushianapi:latest
|
35
Presentation/Hushian.WebApi/Dockerfile
Normal file
35
Presentation/Hushian.WebApi/Dockerfile
Normal file
@@ -0,0 +1,35 @@
|
||||
# See https://aka.ms/customizecontainer to learn how to customize your debug container and how Visual Studio uses this Dockerfile to build your images for faster debugging.
|
||||
|
||||
# This stage is used when running from VS in fast mode (Default for Debug configuration)
|
||||
FROM mcr.microsoft.com/dotnet/aspnet:9.0 AS base
|
||||
USER $APP_UID
|
||||
WORKDIR /app
|
||||
EXPOSE 8080
|
||||
EXPOSE 8081
|
||||
|
||||
|
||||
# This stage is used to build the service project
|
||||
FROM mcr.microsoft.com/dotnet/sdk:9.0 AS build
|
||||
ARG BUILD_CONFIGURATION=Release
|
||||
WORKDIR /src
|
||||
COPY ["Presentation/Hushian.WebApi/Hushian.WebApi.csproj", "Presentation/Hushian.WebApi/"]
|
||||
COPY ["Common/Common.csproj", "Common/"]
|
||||
COPY ["Hushian.Application/Hushian.Application.csproj", "Hushian.Application/"]
|
||||
COPY ["Hushian.Domain/Hushian.Domain.csproj", "Hushian.Domain/"]
|
||||
COPY ["Infrastructure/Infrastructure/Hushian.Infrastructure.csproj", "Infrastructure/Infrastructure/"]
|
||||
COPY ["Infrastructure/Persistence/Hushian.Persistence.csproj", "Infrastructure/Persistence/"]
|
||||
RUN dotnet restore "./Presentation/Hushian.WebApi/Hushian.WebApi.csproj"
|
||||
COPY . .
|
||||
WORKDIR "/src/Presentation/Hushian.WebApi"
|
||||
RUN dotnet build "./Hushian.WebApi.csproj" -c $BUILD_CONFIGURATION -o /app/build
|
||||
|
||||
# This stage is used to publish the service project to be copied to the final stage
|
||||
FROM build AS publish
|
||||
ARG BUILD_CONFIGURATION=Release
|
||||
RUN dotnet publish "./Hushian.WebApi.csproj" -c $BUILD_CONFIGURATION -o /app/publish /p:UseAppHost=false
|
||||
|
||||
# This stage is used in production or when running from VS in regular mode (Default when not using the Debug configuration)
|
||||
FROM base AS final
|
||||
WORKDIR /app
|
||||
COPY --from=publish /app/publish .
|
||||
ENTRYPOINT ["dotnet", "Hushian.WebApi.dll"]
|
@@ -4,6 +4,9 @@
|
||||
<TargetFramework>net9.0</TargetFramework>
|
||||
<Nullable>enable</Nullable>
|
||||
<ImplicitUsings>enable</ImplicitUsings>
|
||||
<UserSecretsId>a648da2d-f055-444d-91e3-3d53de7d1f5a</UserSecretsId>
|
||||
<DockerDefaultTargetOS>Linux</DockerDefaultTargetOS>
|
||||
<DockerfileContext>..\..</DockerfileContext>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
@@ -16,6 +19,7 @@
|
||||
<PrivateAssets>all</PrivateAssets>
|
||||
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
|
||||
</PackageReference>
|
||||
<PackageReference Include="Microsoft.VisualStudio.Azure.Containers.Tools.Targets" Version="1.21.0" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
|
@@ -1,23 +1,31 @@
|
||||
{
|
||||
"$schema": "https://json.schemastore.org/launchsettings.json",
|
||||
{
|
||||
"profiles": {
|
||||
"http": {
|
||||
"commandName": "Project",
|
||||
"dotnetRunMessages": true,
|
||||
"launchBrowser": false,
|
||||
"applicationUrl": "http://localhost:5089",
|
||||
"environmentVariables": {
|
||||
"ASPNETCORE_ENVIRONMENT": "Development"
|
||||
}
|
||||
},
|
||||
"dotnetRunMessages": true,
|
||||
"applicationUrl": "http://localhost:5089"
|
||||
},
|
||||
"https": {
|
||||
"commandName": "Project",
|
||||
"dotnetRunMessages": true,
|
||||
"launchBrowser": false,
|
||||
"applicationUrl": "https://localhost:7046;http://localhost:5089",
|
||||
"environmentVariables": {
|
||||
"ASPNETCORE_ENVIRONMENT": "Development"
|
||||
}
|
||||
},
|
||||
"dotnetRunMessages": true,
|
||||
"applicationUrl": "https://localhost:7046;http://localhost:5089"
|
||||
},
|
||||
"Container (Dockerfile)": {
|
||||
"commandName": "Docker",
|
||||
"launchUrl": "{Scheme}://{ServiceHost}:{ServicePort}",
|
||||
"environmentVariables": {
|
||||
"ASPNETCORE_HTTPS_PORTS": "8081",
|
||||
"ASPNETCORE_HTTP_PORTS": "8080"
|
||||
},
|
||||
"publishAllPorts": true,
|
||||
"useSSL": true
|
||||
}
|
||||
}
|
||||
},
|
||||
"$schema": "https://json.schemastore.org/launchsettings.json"
|
||||
}
|
@@ -18,7 +18,7 @@
|
||||
|
||||
},
|
||||
"aigrpcserver": {
|
||||
"target": "localhost:5010"
|
||||
"target": "192.168.1.14:5042"
|
||||
|
||||
|
||||
},
|
||||
|
@@ -1,5 +1,4 @@
|
||||
|
||||
@using Common.Dtos.Verification
|
||||
@using Common.Dtos.Verification
|
||||
@using Common.Enums
|
||||
@using HushianWebApp.Service
|
||||
@inject VerificationService verificationService;
|
||||
@@ -10,27 +9,9 @@
|
||||
</div>
|
||||
@if (type == VerificationCodeType.ForgetPassword)
|
||||
{
|
||||
<div style="justify-content: space-between;margin-top:5px;;margin-bottom:15px">
|
||||
<input maxlength="1" type="text" inputmode="numeric" pattern="[0-9]*"
|
||||
@bind="code1" @oninput="MoveNext"
|
||||
style="width: 40px; height: 40px; text-align: center; border: 2px solid #ccc; border-radius: 5px; font-size: 20px;"
|
||||
@ref="input1" />
|
||||
|
||||
<input maxlength="1" type="text" inputmode="numeric" pattern="[0-9]*"
|
||||
@bind="code2" @oninput="MoveNext"
|
||||
style="width: 40px; height: 40px; text-align: center; border: 2px solid #ccc; border-radius: 5px; font-size: 20px;"
|
||||
@ref="input2" />
|
||||
|
||||
<input maxlength="1" type="text" inputmode="numeric" pattern="[0-9]*"
|
||||
@bind="code3" @oninput="MoveNext"
|
||||
style="width: 40px; height: 40px; text-align: center; border: 2px solid #ccc; border-radius: 5px; font-size: 20px;"
|
||||
@ref="input3" />
|
||||
|
||||
<input maxlength="1" type="text" inputmode="numeric" pattern="[0-9]*"
|
||||
@bind="code4" @oninput="OnLastInput"
|
||||
style="width: 40px; height: 40px; text-align: center; border: 2px solid #ccc; border-radius: 5px; font-size: 20px;"
|
||||
@ref="input4" />
|
||||
</div>
|
||||
<div style="justify-content: space-between;margin-top:5px;margin-bottom:15px">
|
||||
<input class="cus-input" maxlength='4' @bind-value="code" @bind-value:event="oninput" />
|
||||
</div>
|
||||
|
||||
<div style="justify-content: space-between">
|
||||
<TextInput @bind-value=Value type="password" name="Value" style="text-align:center;margin-top: 10px;;margin-left: 10px" placeholder="کلمه عبور جدید" required="required" />
|
||||
@@ -43,27 +24,7 @@
|
||||
else
|
||||
{
|
||||
<div style="justify-content: space-between;margin-top:5px">
|
||||
|
||||
<input maxlength="1" type="text" inputmode="numeric" pattern="[0-9]*"
|
||||
@bind="code1" @oninput="MoveNext"
|
||||
style="width: 40px; height: 40px; text-align: center; border: 2px solid #ccc; border-radius: 5px; font-size: 20px;"
|
||||
@ref="input1" />
|
||||
|
||||
<input maxlength="1" type="text" inputmode="numeric" pattern="[0-9]*"
|
||||
@bind="code2" @oninput="MoveNext"
|
||||
style="width: 40px; height: 40px; text-align: center; border: 2px solid #ccc; border-radius: 5px; font-size: 20px;"
|
||||
@ref="input2" />
|
||||
|
||||
<input maxlength="1" type="text" inputmode="numeric" pattern="[0-9]*"
|
||||
@bind="code3" @oninput="MoveNext"
|
||||
style="width: 40px; height: 40px; text-align: center; border: 2px solid #ccc; border-radius: 5px; font-size: 20px;"
|
||||
@ref="input3" />
|
||||
|
||||
<input maxlength="1" type="text" inputmode="numeric" pattern="[0-9]*"
|
||||
@bind="code4" @oninput="OnLastInput"
|
||||
style="width: 40px; height: 40px; text-align: center; border: 2px solid #ccc; border-radius: 5px; font-size: 20px;"
|
||||
@ref="input4" />
|
||||
|
||||
<input class="cus-input" maxlength='4' @bind-value="code" @bind-value:event="oninput" />
|
||||
|
||||
</div>
|
||||
}
|
||||
@@ -82,7 +43,18 @@ else
|
||||
public string sendValue { get; set; }
|
||||
[Parameter]
|
||||
public int? ID { get; set; }
|
||||
public string? code { get; set; }
|
||||
private string? _code = string.Empty;
|
||||
public string? code
|
||||
{
|
||||
get { return _code; }
|
||||
set
|
||||
{
|
||||
_code = value;
|
||||
if (value.Length == 4)
|
||||
onClick().ConfigureAwait(true);
|
||||
|
||||
}
|
||||
}
|
||||
[Parameter] public string? Title { get; set; }
|
||||
[Inject] protected ToastService ToastService { get; set; } = default!;
|
||||
[Parameter] public EventCallback<VerificationCodeType> OnMultipleOfThree { get; set; }
|
||||
@@ -92,7 +64,7 @@ else
|
||||
string resendmsg = "ارسال مجدد";
|
||||
bool Disabledresendmsg = false;
|
||||
//-----------------
|
||||
private string code1, code2, code3, code4;
|
||||
//private string code1, code2, code3, code4;
|
||||
|
||||
private ElementReference input1, input2, input3, input4;
|
||||
}
|
||||
@@ -144,8 +116,10 @@ else
|
||||
else
|
||||
{
|
||||
if (Value != ReValue)
|
||||
{ ToastService.Notify(new(ToastType.Warning, $"کلمه عبور جدید و تکرار متفاوت هستند"));
|
||||
return;}
|
||||
{
|
||||
ToastService.Notify(new(ToastType.Warning, $"کلمه عبور جدید و تکرار متفاوت هستند"));
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -161,35 +135,54 @@ else
|
||||
}
|
||||
loading = false;
|
||||
}
|
||||
private async Task MoveNext(ChangeEventArgs e)
|
||||
{
|
||||
if (e.Value?.ToString()?.Length == 1)
|
||||
{
|
||||
if (input1.Context == null) return;
|
||||
// private async Task MoveNext(ChangeEventArgs e)
|
||||
// {
|
||||
// if (e.Value?.ToString()?.Length == 1)
|
||||
// {
|
||||
// if (input1.Context == null) return;
|
||||
|
||||
if (string.IsNullOrEmpty(code1))
|
||||
await input2.FocusAsync();
|
||||
else if (string.IsNullOrEmpty(code2))
|
||||
await input3.FocusAsync();
|
||||
else if (string.IsNullOrEmpty(code3))
|
||||
await input4.FocusAsync();
|
||||
else if (string.IsNullOrEmpty(code4))
|
||||
{
|
||||
code = $"{code1}{code2}{code3}{code4}";
|
||||
}
|
||||
}
|
||||
}
|
||||
private async Task OnLastInput(ChangeEventArgs e)
|
||||
{
|
||||
code4 = e.Value?.ToString();
|
||||
// if (string.IsNullOrEmpty(code1))
|
||||
// await input2.FocusAsync();
|
||||
// else if (string.IsNullOrEmpty(code2))
|
||||
// await input3.FocusAsync();
|
||||
// else if (string.IsNullOrEmpty(code3))
|
||||
// await input4.FocusAsync();
|
||||
// else if (string.IsNullOrEmpty(code4))
|
||||
// {
|
||||
// code = $"{code1}{code2}{code3}{code4}";
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// private async Task OnLastInput(ChangeEventArgs e)
|
||||
// {
|
||||
// ///code4 = e.Value?.ToString();
|
||||
|
||||
if (!string.IsNullOrEmpty(code4) && code4.Length == 1)
|
||||
{
|
||||
code = $"{code1}{code2}{code3}{code4}";
|
||||
if(type==VerificationCodeType.PhoneNumberConfirmed)
|
||||
await onClick();
|
||||
}
|
||||
}
|
||||
// if (!string.IsNullOrEmpty(code) && code.Length == 4)
|
||||
// {
|
||||
// // code = $"{code1}{code2}{code3}{code4}";
|
||||
// if (type == VerificationCodeType.PhoneNumberConfirmed)
|
||||
// await onClick();
|
||||
// }
|
||||
// }
|
||||
|
||||
}
|
||||
|
||||
<style>
|
||||
.cus-input {
|
||||
direction: ltr;
|
||||
display: block;
|
||||
margin: 2em auto;
|
||||
border: none;
|
||||
padding: 0;
|
||||
width: 6ch;
|
||||
background: repeating-linear-gradient(90deg, dimgrey 0, dimgrey 1ch, transparent 0, transparent 1.5ch) 0 100%/ 5.5ch 2px no-repeat;
|
||||
font: 5ch droid sans mono, consolas, monospace;
|
||||
letter-spacing: 0.5ch;
|
||||
}
|
||||
|
||||
input:focus {
|
||||
outline: none;
|
||||
color: dodgerblue;
|
||||
}
|
||||
|
||||
</style>
|
12
Presentation/HushianWebApp/DockerCommand.txt
Normal file
12
Presentation/HushianWebApp/DockerCommand.txt
Normal file
@@ -0,0 +1,12 @@
|
||||
E:\_hushian> docker build -f Presentation\HushianWebApp\Dockerfile -t hushianapp .
|
||||
|
||||
|
||||
docker run --name hushian_app -d -p 5165:5165 sha256:cd08e4a869cb44e17fafdcf551e7eaa3f26c0c3d1420df78f695359bde08f0fb
|
||||
|
||||
|
||||
|
||||
--------------------------------------------------------------------------------------------
|
||||
in local => docker build -f Presentation\HushianWebApp\Dockerfile -t mmrbnjd/hushianapp:latest .
|
||||
in local => docker push mmrbnjd/hushianapp:latest
|
||||
in server => docker pull mmrbnjd/hushianapp:latest
|
||||
in server => docker run -d -p 2101:5165 --restart always mmrbnjd/hushianapp:latest
|
74
Presentation/HushianWebApp/Dockerfile
Normal file
74
Presentation/HushianWebApp/Dockerfile
Normal file
@@ -0,0 +1,74 @@
|
||||
# مرحله ۱: Build پروژه Blazor WASM با .NET 9
|
||||
FROM mcr.microsoft.com/dotnet/sdk:9.0 AS build
|
||||
WORKDIR /src
|
||||
|
||||
# نصب وابستگیها برای emscripten (python3 + سایر ابزارها)
|
||||
RUN apt-get update && apt-get install -y python3 make cmake clang zlib1g-dev \
|
||||
&& rm -rf /var/lib/apt/lists/*
|
||||
|
||||
# کپی کردن فایلهای پروژه
|
||||
COPY ["Presentation/HushianWebApp/HushianWebApp.csproj", "Presentation/HushianWebApp/"]
|
||||
COPY ["Common/Common.csproj", "Common/"]
|
||||
COPY . .
|
||||
RUN dotnet workload clean
|
||||
|
||||
# نصب wasm-tools برای Blazor
|
||||
RUN dotnet workload install wasm-tools
|
||||
|
||||
# انتشار (Publish) خروجی در حالت Release
|
||||
RUN dotnet publish "Presentation/HushianWebApp/HushianWebApp.csproj" -c Release -o /app \
|
||||
-p:TreatWarningsAsErrors=false \
|
||||
-p:RunAOTCompilation=false \
|
||||
-p:PublishTrimmed=false
|
||||
|
||||
# مرحله ۲: سرو کردن با Nginx
|
||||
FROM nginx:alpine AS final
|
||||
WORKDIR /usr/share/nginx/html
|
||||
|
||||
# حذف محتوای پیشفرض nginx
|
||||
RUN rm -rf ./*
|
||||
|
||||
# کپی خروجی Blazor WASM
|
||||
COPY --from=build /app/wwwroot ./
|
||||
|
||||
# فقط بلوک server داخل default.conf
|
||||
RUN printf 'server {\n\
|
||||
listen 5165;\n\
|
||||
server_name localhost;\n\
|
||||
\n\
|
||||
root /usr/share/nginx/html;\n\
|
||||
index index.html;\n\
|
||||
\n\
|
||||
location / {\n\
|
||||
try_files $uri $uri/ /index.html;\n\
|
||||
}\n\
|
||||
\n\
|
||||
location /_framework/ {\n\
|
||||
expires 1y;\n\
|
||||
add_header Cache-Control "public, immutable";\n\
|
||||
}\n\
|
||||
\n\
|
||||
location /_content/ {\n\
|
||||
expires 1y;\n\
|
||||
add_header Cache-Control "public, immutable";\n\
|
||||
}\n\
|
||||
\n\
|
||||
location /Before/ {\n\
|
||||
expires 7d;\n\
|
||||
add_header Cache-Control "public";\n\
|
||||
}\n\
|
||||
\n\
|
||||
location ~ \\.dll$ { add_header Content-Type application/octet-stream; }\n\
|
||||
location ~ \\.wasm$ { add_header Content-Type application/wasm; }\n\
|
||||
location ~ \\.pdb$ { add_header Content-Type application/octet-stream; }\n\
|
||||
location ~ \\.dat$ { add_header Content-Type application/octet-stream; }\n\
|
||||
\n\
|
||||
gzip on;\n\
|
||||
gzip_types text/plain application/xml text/css application/javascript application/json application/wasm;\n\
|
||||
gzip_min_length 256;\n\
|
||||
\n\
|
||||
error_page 404 /index.html;\n\
|
||||
}' > /etc/nginx/conf.d/default.conf
|
||||
|
||||
EXPOSE 5165
|
||||
CMD ["nginx", "-g", "daemon off;"]
|
@@ -45,38 +45,17 @@
|
||||
|
||||
<div class="d-flex justify-content-center">
|
||||
|
||||
<div class="verification-inputs" style="display: flex; gap: 8px; direction: ltr;">
|
||||
<input maxlength="1" type="text" inputmode="numeric" pattern="[0-9]*"
|
||||
@bind="code1" @oninput="MoveNext"
|
||||
style="width: 45px; height: 45px; text-align: center; border: 2px solid #ccc; border-radius: 8px; font-size: 18px; font-weight: bold;"
|
||||
@ref="input1" autoFocus />
|
||||
|
||||
<input maxlength="1" type="text" inputmode="numeric" pattern="[0-9]*"
|
||||
@bind="code2" @oninput="MoveNext"
|
||||
style="width: 45px; height: 45px; text-align: center; border: 2px solid #ccc; border-radius: 8px; font-size: 18px; font-weight: bold;"
|
||||
@ref="input2" />
|
||||
|
||||
<input maxlength="1" type="text" inputmode="numeric" pattern="[0-9]*"
|
||||
@bind="code3" @oninput="MoveNext"
|
||||
style="width: 45px; height: 45px; text-align: center; border: 2px solid #ccc; border-radius: 8px; font-size: 18px; font-weight: bold;"
|
||||
@ref="input3" />
|
||||
|
||||
<input maxlength="1" type="text" inputmode="numeric" pattern="[0-9]*"
|
||||
@bind="code4" @oninput="OnLastInput"
|
||||
style="width: 45px; height: 45px; text-align: center; border: 2px solid #ccc; border-radius: 8px; font-size: 18px; font-weight: bold;"
|
||||
@ref="input4" />
|
||||
|
||||
</div>
|
||||
<input class="cus-input" maxlength='4' @bind-value="Code" @bind-value:event="oninput"/>
|
||||
|
||||
</div>
|
||||
<Button Color="ButtonColor.Link"
|
||||
Disabled="@isButtonDisabled"
|
||||
@onclick="async () =>
|
||||
Disabled="@isButtonDisabled"
|
||||
@onclick="async () =>
|
||||
{
|
||||
await verificationService.ReSendCode(ID);
|
||||
await verifiTimer();
|
||||
}"
|
||||
Style="padding: 6px 16px; font-size: 14px; background-color: #f8f9fa; transition: all 0.3s ease; display: inline-flex; align-items: center; gap: 8px; margin-top: 10px;margin-bottom: -10px;">
|
||||
Style="padding: 6px 16px; font-size: 14px; background-color: #f8f9fa; transition: all 0.3s ease; display: inline-flex; align-items: center; gap: 8px; margin-top: 10px;margin-bottom: -10px;">
|
||||
|
||||
<span>ارسال مجدد</span>
|
||||
|
||||
@@ -98,9 +77,16 @@
|
||||
[Parameter] public EventCallback OnMultipleOfThree { get; set; }
|
||||
public string Username { get; set; }
|
||||
public int ID { get; set; } = 0;
|
||||
public string Code { get; set; } = string.Empty;
|
||||
private string _code = string.Empty;
|
||||
public string Code { get { return _code; } set
|
||||
{
|
||||
_code=value;
|
||||
if (value.Length == 4)
|
||||
ver().ConfigureAwait(true);
|
||||
|
||||
} }
|
||||
//-----------------
|
||||
private string code1, code2, code3, code4;
|
||||
// private string code1, code2, code3, code4;
|
||||
private ElementReference input1, input2, input3, input4;
|
||||
string validateStyleUser = "";
|
||||
private bool isButtonDisabled = true;
|
||||
@@ -161,35 +147,35 @@
|
||||
await OnMultipleOfThree.InvokeAsync();
|
||||
visible = false;
|
||||
}
|
||||
private async Task MoveNext(ChangeEventArgs e)
|
||||
{
|
||||
if (e.Value?.ToString()?.Length == 1)
|
||||
{
|
||||
if (input1.Context == null) return;
|
||||
// private async Task MoveNext(ChangeEventArgs e)
|
||||
// {
|
||||
// if (e.Value?.ToString()?.Length == 1)
|
||||
// {
|
||||
// if (input1.Context == null) return;
|
||||
|
||||
if (string.IsNullOrEmpty(code1))
|
||||
await input2.FocusAsync();
|
||||
else if (string.IsNullOrEmpty(code2))
|
||||
await input3.FocusAsync();
|
||||
else if (string.IsNullOrEmpty(code3))
|
||||
await input4.FocusAsync();
|
||||
else if (string.IsNullOrEmpty(code4))
|
||||
{
|
||||
Code = $"{code1}{code2}{code3}{code4}";
|
||||
}
|
||||
}
|
||||
}
|
||||
private async Task OnLastInput(ChangeEventArgs e)
|
||||
{
|
||||
code4 = e.Value?.ToString();
|
||||
// if (string.IsNullOrEmpty(code1))
|
||||
// await input2.FocusAsync();
|
||||
// else if (string.IsNullOrEmpty(code2))
|
||||
// await input3.FocusAsync();
|
||||
// else if (string.IsNullOrEmpty(code3))
|
||||
// await input4.FocusAsync();
|
||||
// else if (string.IsNullOrEmpty(code4))
|
||||
// {
|
||||
// Code = $"{code1}{code2}{code3}{code4}";
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// private async Task OnLastInput(ChangeEventArgs e)
|
||||
// {
|
||||
// code4 = e.Value?.ToString();
|
||||
|
||||
if (!string.IsNullOrEmpty(code4) && code4.Length == 1)
|
||||
{
|
||||
Code = $"{code1}{code2}{code3}{code4}";
|
||||
// if (!string.IsNullOrEmpty(code4) && code4.Length == 1)
|
||||
// {
|
||||
// Code = $"{code1}{code2}{code3}{code4}";
|
||||
|
||||
await ver();
|
||||
}
|
||||
}
|
||||
// await ver();
|
||||
// }
|
||||
// }
|
||||
}
|
||||
<script>
|
||||
function formatPhoneNumber(input) {
|
||||
@@ -281,4 +267,22 @@
|
||||
box-shadow: 0 0 0 0.2rem rgba(13, 110, 253, 0.25);
|
||||
transform: scale(1.05);
|
||||
}
|
||||
|
||||
.cus-input {
|
||||
direction:ltr;
|
||||
display: block;
|
||||
margin: 2em auto;
|
||||
border: none;
|
||||
padding: 0;
|
||||
width: 6ch;
|
||||
background: repeating-linear-gradient(90deg, dimgrey 0, dimgrey 1ch, transparent 0, transparent 1.5ch) 0 100%/ 5.5ch 2px no-repeat;
|
||||
font: 5ch droid sans mono, consolas, monospace;
|
||||
letter-spacing: 0.5ch;
|
||||
}
|
||||
|
||||
input:focus {
|
||||
outline: none;
|
||||
color: dodgerblue;
|
||||
}
|
||||
|
||||
</style>
|
@@ -7,8 +7,8 @@ using HushianWebApp.Service;
|
||||
var builder = WebAssemblyHostBuilder.CreateDefault(args);
|
||||
builder.RootComponents.Add<App>("#app");
|
||||
builder.RootComponents.Add<HeadOutlet>("head::after");
|
||||
|
||||
builder.Services.AddScoped(sp => new HttpClient { BaseAddress = new Uri("http://localhost:5089/api/") });
|
||||
string BaseAddress = builder.Configuration.GetSection("BaseAddress").Value;
|
||||
builder.Services.AddScoped(sp => new HttpClient { BaseAddress = new Uri(BaseAddress) });
|
||||
builder.Services.AddScoped<ILocalStorageService, LocalStorageService>();
|
||||
builder.Services.AddScoped<BaseController>();
|
||||
builder.Services.AddScoped<AuthService>();
|
||||
|
21
Presentation/HushianWebApp/default.conf
Normal file
21
Presentation/HushianWebApp/default.conf
Normal file
@@ -0,0 +1,21 @@
|
||||
server {
|
||||
listen 5089;
|
||||
server_name localhost;
|
||||
|
||||
root /usr/share/nginx/html;
|
||||
index index.html;
|
||||
|
||||
location / {
|
||||
try_files $uri $uri/ /index.html;
|
||||
}
|
||||
|
||||
location ~* \.(?:ico|css|js|gif|jpe?g|png|woff2?|eot|ttf|svg)$ {
|
||||
expires 6M;
|
||||
access_log off;
|
||||
add_header Cache-Control "public";
|
||||
}
|
||||
|
||||
location = /index.html {
|
||||
add_header Cache-Control "no-store, no-cache, must-revalidate, proxy-revalidate, max-age=0";
|
||||
}
|
||||
}
|
12
Presentation/HushianWebApp/nginx.conf
Normal file
12
Presentation/HushianWebApp/nginx.conf
Normal file
@@ -0,0 +1,12 @@
|
||||
worker_processes 1;
|
||||
|
||||
events { worker_connections 1024; }
|
||||
|
||||
http {
|
||||
include mime.types;
|
||||
default_type application/octet-stream;
|
||||
sendfile on;
|
||||
keepalive_timeout 65;
|
||||
|
||||
|
||||
}
|
10
Presentation/HushianWebApp/wwwroot/appsettings.json
Normal file
10
Presentation/HushianWebApp/wwwroot/appsettings.json
Normal file
@@ -0,0 +1,10 @@
|
||||
{
|
||||
"BaseAddress": "http://192.168.1.14:2201/api/",
|
||||
"Logging": {
|
||||
"LogLevel": {
|
||||
"Default": "Information",
|
||||
"Microsoft.AspNetCore": "Warning"
|
||||
}
|
||||
},
|
||||
"AllowedHosts": "*"
|
||||
}
|
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "HushianWebApp",
|
||||
"short_name": "HushianWebApp",
|
||||
"name": "هوشیان",
|
||||
"short_name": "هوشیان",
|
||||
"id": "./",
|
||||
"start_url": "./",
|
||||
"display": "standalone",
|
||||
|
1
command.txt
Normal file
1
command.txt
Normal file
@@ -0,0 +1 @@
|
||||
docker compose up -d --build
|
53
docker-compose.yml
Normal file
53
docker-compose.yml
Normal file
@@ -0,0 +1,53 @@
|
||||
version: '3.9'
|
||||
|
||||
services:
|
||||
aiass:
|
||||
build:
|
||||
context: ./Presentation/AIAss
|
||||
dockerfile: Dockerfile
|
||||
image: aiass:latest
|
||||
container_name: aiass
|
||||
environment:
|
||||
- ASPNETCORE_ENVIRONMENT=Production
|
||||
- ASPNETCORE_URLS=http://+:5010
|
||||
ports:
|
||||
- "5011:5010"
|
||||
networks:
|
||||
- hushainnet
|
||||
- aiassnet
|
||||
|
||||
webapi:
|
||||
build:
|
||||
context: .
|
||||
dockerfile: Presentation/Hushian.WebApi/Dockerfile
|
||||
image: hushian.webapi:latest
|
||||
container_name: hushian-webapi
|
||||
environment:
|
||||
- ASPNETCORE_ENVIRONMENT=Production
|
||||
ports:
|
||||
- "1011:8080"
|
||||
- "1012:8081"
|
||||
networks:
|
||||
- hushainnet
|
||||
|
||||
webapp:
|
||||
build:
|
||||
context: .
|
||||
dockerfile: Presentation/HushianWebApp/Dockerfile
|
||||
image: hushian.webapp:latest
|
||||
container_name: hushian-webapp
|
||||
ports:
|
||||
- "80:5165"
|
||||
depends_on:
|
||||
- webapi
|
||||
networks:
|
||||
- hushainnet
|
||||
|
||||
networks:
|
||||
hushainnet:
|
||||
name: hushainnet
|
||||
aiassnet:
|
||||
name: aiassnet
|
||||
|
||||
|
||||
|
Reference in New Issue
Block a user