using Azure.Cosmos;
using Azure.Storage.Blobs.Models;
using Azure.Storage.Sas;
using HTEXLib.COMM.Helpers;
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Text;
using System.Text.Json;
using System.Threading.Tasks;
using TEAMModelOS.SDK.DI;
using TEAMModelOS.SDK.Extension;
using TEAMModelOS.SDK.Models;
using TEAMModelOS.Services;
using Activity = TEAMModelOS.SDK.Models.Activity;
namespace TEAMModelOS.SDK
{
public static class ActivityService
{
///
/// 删除活动关联的数据
///
///
///
///
public static async Task DeleteActivityRelated(AzureCosmosFactory _azureCosmos,Activity activity)
{
//删除模块,Contest, Training ,Research, ReviewRule规则(ReviewRule-disposable"; 存为活动)
await _azureCosmos.GetCosmosClient().GetContainer(Constant.TEAMModelOS, Constant.Common).DeleteItemStreamAsync(activity.id, new PartitionKey("Contest"));
await _azureCosmos.GetCosmosClient().GetContainer(Constant.TEAMModelOS, Constant.Common).DeleteItemStreamAsync(activity.id, new PartitionKey("Training"));
await _azureCosmos.GetCosmosClient().GetContainer(Constant.TEAMModelOS, Constant.Common).DeleteItemStreamAsync(activity.id, new PartitionKey("Research"));
await _azureCosmos.GetCosmosClient().GetContainer(Constant.TEAMModelOS, Constant.Normal).DeleteItemStreamAsync(activity.id, new PartitionKey("ReviewRule-disposable"));
//删除邀请教师 ActivityTeacher,
var resultTeacher = await _azureCosmos.GetCosmosClient().GetContainer(Constant.TEAMModelOS, Constant.Teacher)
.GetList("select c.id ,c.code from c where c.pk='ActivityEnroll' and c.", $"ActivityTeacher-{activity.id}");
if (resultTeacher.list.IsNotEmpty())
{
await _azureCosmos.GetCosmosClient().GetContainer(Constant.TEAMModelOS, Constant.Teacher).DeleteItemsStreamAsync(resultTeacher.list.Select(z => z.id).ToList(), $"ActivityTeacher-{activity.id}");
}
//删除报名数据 ActivityEnroll
var resultEnroll = await _azureCosmos.GetCosmosClient().GetContainer(Constant.TEAMModelOS, Constant.Teacher)
.GetList("select c.id ,c.code from c where c.pk='ActivityEnroll' and c.", $"ActivityEnroll-{activity.id}");
if (resultEnroll.list.IsNotEmpty())
{
await _azureCosmos.GetCosmosClient().GetContainer(Constant.TEAMModelOS, Constant.Teacher).DeleteItemsStreamAsync(resultEnroll.list.Select(z => z.id).ToList(), $"ActivityEnroll-{activity.id}");
}
//删除专家数据 ActivityExpert
await _azureCosmos.GetCosmosClient().GetContainer(Constant.TEAMModelOS, Constant.Teacher).DeleteItemStreamAsync(activity.id, new PartitionKey("ActivityExpert"));
}
///
/// 生成组队口令
///
///
///
///
///
///
///
public static async Task GenCipher(CosmosClient client, DingDing _dingDing, TEAMModelOS.Models.Option _option, string _activityId)
{
string _num09 = "123456789";
string no = $"{Utils.CreatSaltString(7, _num09)}";
for (int i = 0; i < 10; i++)
{
List sheets = new List();
bool hasCurrFrom = false;
string cipherSQL = $"select value c.id from c where c.contest!=null and c.activityId='{_activityId}' and c.contest.type=1 and c.contest.cipher='{no}' ";
var cipherResult = await client.GetContainer(Constant.TEAMModelOS, Constant.Teacher).GetList(cipherSQL, $"ActivityEnroll-{_activityId}");
if (cipherResult.list.IsNotEmpty() && cipherResult.list.Count>0) {
hasCurrFrom = true;
}
if (hasCurrFrom)
{
if (i == 9)
{
string msg = $"{_option.Location},ActivityService/GenCipher\n 组队口令生成异常,重复生成次数超过10次";
await _dingDing.SendBotMsg($"OS,{_option.Location},{msg}", GroupNames.醍摩豆服務運維群組);
throw new Exception(msg);
}
else
{
no = $"{Utils.CreatSaltString(7, _num09)}";
}
}
else { break; }
}
return no;
}
public static async Task> TeacherActivityList(AzureCosmosFactory _azureCosmos,AzureStorageFactory _azureStorage, JsonElement request, string tmdid)
{
List activities = new List();
HashSet inviteActivityIds = new HashSet();
string yearSql = $" and c.year={DateTimeOffset.Now.Year}";
if (request.TryGetProperty("year", out JsonElement _year) && int.TryParse($"{_year}",out int year ))
{
yearSql = $" and c.year={year}";
}
//先获取邀请制的
string sqlInvite = $"select value c from c join t in c.inviteTeachers where t.id='{tmdid}' and c.pk='ActivityTeacher'";
var result = await _azureCosmos.GetCosmosClient().GetContainer(Constant.TEAMModelOS, Constant.Common).GetList(sqlInvite);
inviteActivityIds= result.list.Select(z => z.id).ToHashSet();
if (inviteActivityIds.Count>0)
{
string sqlActivity = $"select value c from c where c.id in ({string.Join(",", inviteActivityIds.Select(z => $"'{z}'"))}) {yearSql} ";
var resultActivity = await _azureCosmos.GetCosmosClient().GetContainer(Constant.TEAMModelOS, Constant.Common).GetList(sqlInvite, "Activity");
if (resultActivity.list.IsNotEmpty())
{
activities.AddRange(resultActivity.list);
}
}
Teacher teacher = await _azureCosmos.GetCosmosClient().GetContainer(Constant.TEAMModelOS, Constant.Teacher).ReadItemAsync(tmdid, new PartitionKey("Base"));
string schoolOwnerIn = string.Empty;
string schoolIdIn = string.Empty;
if (teacher.schools.IsNotEmpty())
{
schoolIdIn = $"and i.id in ({string.Join(",", teacher.schools.Select(z => $"'{z.schoolId}'"))})";
schoolOwnerIn= $"and c.owner in ({string.Join(",", teacher.schools.Select(z => $"'{z.schoolId}'"))})";
}
//获取开放的
{
//完全开放 所有的学校
string sqlOpen = $"select value c from c where c.scope='public' and (c.publish=1 or c.publish=2 ) and( ARRAY_LENGTH(c.invitedSchools)=0 or IS_DEFINED(c.invitedSchools) = false ) {yearSql} ";
var resultOpen = await _azureCosmos.GetCosmosClient().GetContainer(Constant.TEAMModelOS, Constant.Common).GetList(sqlOpen, "Activity");
activities.AddRange(resultOpen.list);
if (!string.IsNullOrWhiteSpace(schoolIdIn))
{ //部分学校
string sqlSchool = $"select value c from c join i in c.confirmedSchools where c.scope='public' and c.joinMode='enroll' and (c.publish=1 or c.publish=2 ) and i.status=1 {yearSql} {schoolIdIn} ";
var resultSchool = await _azureCosmos.GetCosmosClient().GetContainer(Constant.TEAMModelOS, Constant.Common).GetList(sqlSchool, "Activity");
activities.AddRange(resultSchool.list);
}
}
string areaOwnerIn = string.Empty;
var hasAreaSchools = teacher.schools.FindAll(z => !string.IsNullOrWhiteSpace(z.areaId));
if (hasAreaSchools.IsNotEmpty())
{
areaOwnerIn = $"and c.owner in ({string.Join(",", hasAreaSchools.Select(z => $"'{z.areaId}'"))})";
schoolIdIn = $"and i.id in ({string.Join(",", hasAreaSchools.Select(z => $"'{z.schoolId}'"))})";
}
//获取所有区级的
if (!string.IsNullOrWhiteSpace(areaOwnerIn) && !string.IsNullOrEmpty(schoolIdIn))
{
string sqlOpen = $"select value c from c join i in c.confirmedSchools where c.scope='area' and c.joinMode='enroll' and (c.publish=1 or c.publish=2 ) and i.status=1 {yearSql} {areaOwnerIn} {schoolIdIn} ";
var resultOpen = await _azureCosmos.GetCosmosClient().GetContainer(Constant.TEAMModelOS, Constant.Common).GetList(sqlOpen, "Activity");
activities.AddRange(resultOpen.list);
}
//获取所有学校的
if (!string.IsNullOrWhiteSpace(schoolOwnerIn))
{
string sqlSchool = $"select value c from c where c.scope='school' and c.joinMode='enroll' and (c.publish=1 or c.publish=2 ) {yearSql} {schoolOwnerIn} ";
var resultSchool = await _azureCosmos.GetCosmosClient().GetContainer(Constant.TEAMModelOS, Constant.Common).GetList(sqlSchool, "Activity");
activities.AddRange(resultSchool.list);
}
activities.ForEach(z =>
{
var (blob_uri, blob_sas) = _azureStorage.GetBlobContainerSAS(z.owner, BlobContainerSasPermissions.Read);
z.sas=blob_sas;
});
if (activities.IsNotEmpty())
{
string sql = $"select value c from c where c.pk='ActivityEnroll' and contains(c.code,'ActivityEnroll-') and c.id='{tmdid}' and c.activityId in ({string.Join(",", activities.Select(z => $"'{z.id}'"))})";
var resultEnroll = await _azureCosmos.GetCosmosClient().GetContainer(Constant.TEAMModelOS, Constant.Teacher).GetList(sql);
foreach (var enroll in resultEnroll.list)
{
var activityDto = activities.Find(z => z.id.Equals(enroll.activityId));
if (activityDto!=null)
{
if (enroll.contest!=null && !string.IsNullOrWhiteSpace(enroll.contest.cipher))
{
activityDto.contestSign=1;
activityDto.signTime=enroll.contest.enrollTime;
activityDto.contestType=enroll.contest.type;
}
if (enroll.upload!=null && (enroll.upload.files.IsNotEmpty() || enroll.upload.sokrates.IsNotEmpty()))
{
activityDto.contestUpload=1;
activityDto.uploadTime=enroll.upload.uploadTime;
activityDto.uploadType=enroll.upload.type;
}
}
}
}
return activities;
}
public static async Task<(ReviewRule reviewRule, int invalidCode, string msg)> UpsertReviewRule(ReviewRuleTree reviewRuleTree,Activity activity, Contest contest, AzureCosmosFactory _azureCosmos)
{
var nodes = new List();
nodes= TreeToList(reviewRuleTree.trees, nodes);
ReviewRule reviewRule = new ReviewRule() {
id= activity.id,
code="ReviewRule-disposable",
pk="ReviewRule",
name=reviewRuleTree.name,
desc=reviewRuleTree.desc,
owner=activity.owner,
type="disposable",
configs=nodes,
sourceName=activity.name,
taskCount=reviewRuleTree.taskCount,
scoreRule=reviewRuleTree.scoreRule,
distribute=reviewRuleTree.distribute,
scoreDetail=reviewRuleTree.scoreDetail,
};
//代码顺序不能动
var checkReult = CheckReviewRule(reviewRule, contest);
if (checkReult.invalidCode==200) {
await _azureCosmos.GetCosmosClient().GetContainer(Constant.TEAMModelOS, Constant.Normal).UpsertItemAsync(reviewRule, new Azure.Cosmos.PartitionKey(reviewRule.code));
if (reviewRuleTree.upsertAsTemplate==1)
{
reviewRule.code="ReviewRule-template";
reviewRule.type="template";
await _azureCosmos.GetCosmosClient().GetContainer(Constant.TEAMModelOS, Constant.Normal).UpsertItemAsync(reviewRule, new Azure.Cosmos.PartitionKey(reviewRule.code));
}
}
return (reviewRule,checkReult.invalidCode,checkReult.msg);
}
public static (int invalidCode, string msg) CheckReviewRule(ReviewRule reviewRule,Contest contest)
{
int invalidCode = -1;
string msg = "";
if (reviewRule.taskCount<=0) {
invalidCode=28;
msg="作品分配次数至少一次!";
}
if (reviewRule.taskCount==1 && reviewRule.scoreRule.Equals("only"))
{
invalidCode=200;
}
else
{
invalidCode=21;//分配次数一次,必须匹配only
msg="分配次数1次,必须匹配【默认统分】规则";
}
if (reviewRule.taskCount>=2 && (reviewRule.scoreRule.Equals("avg")||reviewRule.scoreRule.Equals("top")))
{
invalidCode=200;
}
else {
invalidCode=22;//分配次数2次,必须匹配avg,top
msg="分配次数2次,必须匹配【按平均分】,【按最高分】";
}
if (reviewRule.taskCount>=3 && (reviewRule.scoreRule.Equals("avg")||reviewRule.scoreRule.Equals("top")||reviewRule.scoreRule.Equals("rmLowAvg")||reviewRule.scoreRule.Equals("rmTopAvg")))
{
invalidCode=200;
}
else
{
invalidCode=23;//分配次数2次,必须匹配avg,top,rmLowAvg,rmTopAvg
msg="分配次数3次,必须匹配必须匹配【按平均分】,【按最高分】,【去掉最低分的平均分】,【去掉最高分的平均分】";
}
if (reviewRule.taskCount>=4 && (reviewRule.scoreRule.Equals("avg")||reviewRule.scoreRule.Equals("top")||reviewRule.scoreRule.Equals("rmLowAvg")||reviewRule.scoreRule.Equals("rmTopAvg")||reviewRule.scoreRule.Equals("rmLowTopAvg")))
{
invalidCode=200;
}
else
{
invalidCode=24;//分配次数2次,必须匹配avg,top,rmLowAvg,rmTopAvg,rmLowTopAvg
msg="分配次数4次,必须匹配必须匹配【按平均分】,【按最高分】,【去掉最低分的平均分】,【去掉最高分的平均分】,【去掉最高分和最低分的平均分】";
}
if (invalidCode==200) {
if (!string.IsNullOrWhiteSpace(reviewRule.distribute))
{
if (reviewRule.distribute.Equals("period"))
{
var period = contest.sign?.fields?.Find(z => z.field.Equals("period"));
if (period!= null)
{
invalidCode = 200;
}
else
{
invalidCode=25;
msg="作品分配匹配规则为【学段】,但报名填写表单未配置。";
}
}
else if (reviewRule.distribute.Equals("subject"))
{
var subject = contest.sign?.fields?.Find(z => z.field.Equals("subject"));
if (subject!= null)
{
invalidCode = 200;
}
else
{
invalidCode=26;
msg="作品分配匹配规则为【学科】,但报名填写表单未配置。";
}
}
else if (reviewRule.distribute.Equals("periodAndSubject"))
{
var period = contest.sign?.fields?.Find(z => z.field.Equals("period"));
var subject = contest.sign?.fields?.Find(z => z.field.Equals("subject"));
if (subject!= null && period!= null)
{
invalidCode = 200;
}
else
{
invalidCode=27;
msg="作品分配匹配规则为【学段,学科】,但报名填写表单未配置。";
}
}
else {
invalidCode=30;
msg=$"作品分配匹配规则未识别【{reviewRule.distribute}】。";
}
}
else {
invalidCode=29;
msg="作品分配匹配规则不能为空。";
}
}
return (invalidCode,msg);
}
public static List TreeToList(List trees, List nodes) {
trees = trees.OrderBy(x => x.order).ToList();
List list = new List();
trees.ForEach(x => {
List cids = new List();
if (x.children.IsNotEmpty())
{
x.children.ForEach(y => cids.Add(y.id));
}
var node = new RuleConfig
{
id = x.id,
pid = x.pid,
cids= cids,
label = x.label,
desc = x.desc,
score = x.score,
order = x.order,
};
list.Add(node);
});
nodes.AddRange(list);
foreach (RuleConfigTree tree in trees)
{
if (null != tree.children && tree.children.Count > 0)
{
TreeToList(tree.children, nodes);
}
}
return nodes;
}
public static List ListToTree(List noes)
{
List list = noes.ToJsonString().ToObject>();
var res = from r in list group r by r.id into g select g;
Dictionary blockDict = new Dictionary();
foreach (var s in res)
{
blockDict.TryAdd(s.First().id, s.First());
}
return GetChild(list, blockDict);
}
private static List GetChild(List list, Dictionary dict)
{
List trees = new List();
trees = trees.OrderBy(x => x.order).ToList();
foreach (RuleConfigTree node in list)
{
bool flag = dict.TryGetValue(node.pid, out RuleConfigTree syllabus);
if (flag && syllabus != null)
{
syllabus.children.Add(node);
}
else
{
trees.Add(node);
}
}
return trees;
}
}
}