2024-11-03 11:21:47 +08:00
|
|
|
|
using System.Linq.Dynamic.Core;
|
|
|
|
|
using IronPython.Hosting;
|
|
|
|
|
using Microsoft.EntityFrameworkCore;
|
|
|
|
|
using Microsoft.IdentityModel.Tokens;
|
|
|
|
|
using Microsoft.Scripting.Hosting;
|
|
|
|
|
using SiteManagementSystem_SoftwareEngineering_.Entity;
|
|
|
|
|
using SiteManagementSystem_SoftwareEngineering_.Interface;
|
|
|
|
|
|
|
|
|
|
namespace SiteManagementSystem_SoftwareEngineering_.Service
|
|
|
|
|
{
|
|
|
|
|
public enum FieldType
|
|
|
|
|
{
|
|
|
|
|
Unspecified,
|
|
|
|
|
Tennis,
|
|
|
|
|
Basketball,
|
|
|
|
|
Badminton
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public class FieldService : IFieldService
|
|
|
|
|
{
|
|
|
|
|
private readonly EntityFrameworkPythonCompatibilityAndInterpretationLayer _layer;
|
|
|
|
|
private readonly ScriptEngine _engine = Python.CreateEngine();
|
|
|
|
|
private readonly dynamic _service;
|
|
|
|
|
|
2024-11-03 21:58:05 +08:00
|
|
|
|
public FieldService(SQLService storageService,ICacheService<FieldService>cacheService)
|
2024-11-03 11:21:47 +08:00
|
|
|
|
{
|
2024-11-03 21:58:05 +08:00
|
|
|
|
_layer = new EntityFrameworkPythonCompatibilityAndInterpretationLayer(storageService,cacheService);
|
2024-11-03 11:21:47 +08:00
|
|
|
|
var _engine = Python.CreateEngine();
|
|
|
|
|
var searchPaths = _engine.GetSearchPaths();
|
|
|
|
|
searchPaths.Add(@"./Service/PythonServiceFile/");
|
|
|
|
|
_engine.SetSearchPaths(searchPaths);
|
|
|
|
|
var source = _engine.CreateScriptSourceFromFile(@"./Service/PythonServiceFile/demo.py");
|
|
|
|
|
var scope = _engine.CreateScope();
|
|
|
|
|
scope.SetVariable("LAYER", _layer);
|
|
|
|
|
source.Execute(scope);
|
|
|
|
|
_service = scope.GetVariable("Service")();
|
|
|
|
|
}
|
|
|
|
|
|
2024-11-03 21:58:05 +08:00
|
|
|
|
public void RedisKeyExpired(string key)
|
|
|
|
|
{
|
|
|
|
|
var keys = key.Split('$', 2);
|
|
|
|
|
_service.RedisKeyExpired(keys[0], keys[1]);
|
|
|
|
|
}
|
2024-11-03 11:21:47 +08:00
|
|
|
|
public void AddField(string name, string value)
|
|
|
|
|
{
|
2024-11-05 23:06:55 +08:00
|
|
|
|
try
|
|
|
|
|
{
|
|
|
|
|
var t = (bool)
|
|
|
|
|
_service.AddAppointment(
|
|
|
|
|
new FieldRecord
|
2024-11-03 11:21:47 +08:00
|
|
|
|
{
|
2024-11-05 23:06:55 +08:00
|
|
|
|
Fid = Guid.NewGuid(),
|
|
|
|
|
Uid = Guid.NewGuid(),
|
|
|
|
|
StartTime = DateTime.Now,
|
|
|
|
|
EndTime = DateTime.Now + TimeSpan.FromMinutes(30)
|
2024-11-03 11:21:47 +08:00
|
|
|
|
}
|
|
|
|
|
);
|
2024-11-05 23:06:55 +08:00
|
|
|
|
}
|
|
|
|
|
catch (Exception)
|
|
|
|
|
{ }
|
|
|
|
|
Console.WriteLine(_layer.RecordDb.FindAll("Uid",Guid.Parse("bd422092-7f2b-4f53-ad08-47a75aa089ea")).First().StartTime);
|
|
|
|
|
Console.WriteLine(DateTime.Now);
|
2024-11-03 11:21:47 +08:00
|
|
|
|
//Console.WriteLine(_service.AddField());
|
|
|
|
|
throw new NotImplementedException();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public void RentField()
|
|
|
|
|
{
|
|
|
|
|
throw new NotImplementedException();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public class EntityFrameworkPythonCompatibilityAndInterpretationLayer
|
|
|
|
|
{
|
|
|
|
|
public readonly SQLHelperService<Field> FieldDb;
|
2024-11-04 22:26:45 +08:00
|
|
|
|
public readonly SQLHelperService<FieldRecord> RecordDb;
|
2024-11-05 21:04:21 +08:00
|
|
|
|
public readonly SQLHelperService<FieldRecord> FinishedFieldRecordDb;
|
2024-11-03 21:58:05 +08:00
|
|
|
|
private readonly ICacheService<FieldService> _cacheService;
|
2024-11-03 11:21:47 +08:00
|
|
|
|
|
2024-11-03 21:58:05 +08:00
|
|
|
|
public EntityFrameworkPythonCompatibilityAndInterpretationLayer(SQLService storageService, ICacheService<FieldService> cacheService)
|
2024-11-03 11:21:47 +08:00
|
|
|
|
{
|
2024-11-03 21:58:05 +08:00
|
|
|
|
_cacheService = cacheService;
|
2024-11-03 11:21:47 +08:00
|
|
|
|
FieldDb = new SQLHelperService<Field>(storageService, nameof(storageService.Fields));
|
2024-11-04 22:26:45 +08:00
|
|
|
|
RecordDb = new SQLHelperService<FieldRecord>(
|
2024-11-03 11:21:47 +08:00
|
|
|
|
storageService,
|
|
|
|
|
nameof(storageService.UserFieldRecords)
|
|
|
|
|
);
|
2024-11-05 21:04:21 +08:00
|
|
|
|
FinishedFieldRecordDb = new SQLHelperService<FieldRecord>(storageService,nameof(storageService.FinishedFieldRecords));
|
2024-11-03 21:58:05 +08:00
|
|
|
|
}
|
|
|
|
|
public void SetTimeOut(DateTime endTime,string info)
|
|
|
|
|
{
|
|
|
|
|
var now = DateTime.Now;
|
|
|
|
|
if (endTime <= now)
|
|
|
|
|
throw new InvalidOperationException("The end must be later than now.");
|
|
|
|
|
var span = endTime - now;
|
|
|
|
|
_cacheService.SetAsync(endTime.ToString() + "$" + info, "", span);
|
2024-11-03 11:21:47 +08:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public class SQLHelperService<TEntity>
|
|
|
|
|
where TEntity : class, new()
|
|
|
|
|
{
|
|
|
|
|
private readonly SQLService _sqlService;
|
|
|
|
|
private readonly DbSet<TEntity> _dbSet;
|
|
|
|
|
|
|
|
|
|
public SQLHelperService(SQLService sqlService, string dbName)
|
|
|
|
|
{
|
|
|
|
|
_sqlService = sqlService;
|
|
|
|
|
if (dbName.IsNullOrEmpty())
|
|
|
|
|
dbName = typeof(TEntity).Name;
|
|
|
|
|
_dbSet =
|
|
|
|
|
_sqlService.GetType().GetProperty(dbName)?.GetValue(_sqlService) as DbSet<TEntity>
|
|
|
|
|
?? throw new InvalidOperationException(
|
|
|
|
|
$"SQLHelper don't have DbSet which named {dbName}."
|
|
|
|
|
);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public SQLHelperService<TEntity> Add(TEntity entity) =>
|
|
|
|
|
Process((dbSet) => dbSet.Add(entity));
|
|
|
|
|
|
|
|
|
|
private SQLHelperService<TEntity> Update(TEntity oldEntity, TEntity newEntity) =>
|
|
|
|
|
Process(
|
|
|
|
|
(dbSet) =>
|
|
|
|
|
{
|
|
|
|
|
dbSet.Remove(oldEntity);
|
|
|
|
|
dbSet.Add(newEntity);
|
|
|
|
|
}
|
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
public SQLHelperService<TEntity> Update<TValue>(TEntity entity, string key, TValue value)
|
|
|
|
|
{
|
|
|
|
|
var t = FindAll(key, value);
|
|
|
|
|
switch (t.Count())
|
|
|
|
|
{
|
|
|
|
|
case 0:
|
|
|
|
|
throw new InvalidOperationException("No values match the criteria!");
|
|
|
|
|
case 1:
|
|
|
|
|
Update(t.First(), entity);
|
|
|
|
|
break;
|
|
|
|
|
default:
|
|
|
|
|
throw new InvalidOperationException("Multiple values match the criteria!");
|
|
|
|
|
}
|
|
|
|
|
return this;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public SQLHelperService<TEntity> AddOrUpdate<TValue>(
|
|
|
|
|
TEntity entity,
|
|
|
|
|
string key,
|
|
|
|
|
TValue value
|
|
|
|
|
)
|
|
|
|
|
{
|
|
|
|
|
var t = FindAll(key, value);
|
|
|
|
|
switch (t.Count())
|
|
|
|
|
{
|
|
|
|
|
case 0:
|
|
|
|
|
Add(entity);
|
|
|
|
|
break;
|
|
|
|
|
case 1:
|
|
|
|
|
Update(t.First(), entity);
|
|
|
|
|
break;
|
|
|
|
|
default:
|
|
|
|
|
throw new InvalidOperationException("Multiple values match the criteria!");
|
|
|
|
|
}
|
|
|
|
|
return this;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public TEntity? FindFirst<TValue>(string key, TValue value)
|
|
|
|
|
{
|
|
|
|
|
TEntity? ans = null;
|
|
|
|
|
if (value is null)
|
|
|
|
|
Process(key, (dbSet) => ans = dbSet.Where($"{key} == null").FirstOrDefault());
|
|
|
|
|
else
|
|
|
|
|
Process(key, (dbSet) => ans = dbSet.Where($"{key} == @0", value).FirstOrDefault());
|
|
|
|
|
return ans;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public IEnumerable<TEntity> FindAll<TValue>(string key, TValue value)
|
|
|
|
|
{
|
|
|
|
|
IEnumerable<TEntity> ans = null!;
|
|
|
|
|
var y = typeof(TEntity).GetType().GetProperty(key);
|
|
|
|
|
if (value is null)
|
|
|
|
|
Process(key, (dbSet) => ans = dbSet.Where($"{key} == null").ToList());
|
|
|
|
|
else
|
|
|
|
|
Process(key, (dbSet) => ans = dbSet.Where($"{key} == @0", value).ToList());
|
|
|
|
|
return ans;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public IEnumerable<TEntity> GetFirstNElements(int n)
|
|
|
|
|
{
|
|
|
|
|
List<TEntity> ans = null!;
|
|
|
|
|
Process((dbSet) => ans = dbSet.Take(n).ToList());
|
|
|
|
|
return ans;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public SQLHelperService<TEntity> Delete(TEntity entity) =>
|
|
|
|
|
Process((dbSet) => dbSet.Remove(entity));
|
|
|
|
|
|
|
|
|
|
public SQLHelperService<TEntity> TryDelete<TValue>(string key, TValue value)
|
|
|
|
|
{
|
|
|
|
|
var t = FindFirst(key, value);
|
|
|
|
|
if (t is null)
|
|
|
|
|
return this;
|
|
|
|
|
return Process((dbSet) => dbSet.Remove(t));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public SQLHelperService<TEntity> Save()
|
|
|
|
|
{
|
|
|
|
|
_sqlService.SaveChanges();
|
|
|
|
|
return this;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public SQLHelperService<TEntity> DeleteAll<TValue>(string key, TValue value) =>
|
|
|
|
|
Process((dbSet) => dbSet.RemoveRange(FindAll(key, value)));
|
|
|
|
|
|
|
|
|
|
public SQLHelperService<TEntity> Process(Action<DbSet<TEntity>> action)
|
|
|
|
|
{
|
|
|
|
|
action(_dbSet);
|
|
|
|
|
_sqlService.SaveChanges();
|
|
|
|
|
return this;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public TEntity GetDefaultEntity() => new();
|
|
|
|
|
|
|
|
|
|
public SQLHelperService<TEntity> Process(string key, Action<DbSet<TEntity>> action)
|
|
|
|
|
{
|
|
|
|
|
if (typeof(TEntity).GetProperty(key) is null)
|
|
|
|
|
throw new InvalidOperationException(
|
|
|
|
|
$"{typeof(TEntity).Name} does not have the property key: {key}"
|
|
|
|
|
);
|
|
|
|
|
action(_dbSet);
|
|
|
|
|
_sqlService.SaveChanges();
|
|
|
|
|
return this;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|