
using Tiobon.Core.IServices;
using Tiobon.Core.Model.Models;
using Tiobon.Core.Services.BASE;
using Tiobon.Core.IRepository.Base;
using Tiobon.Core.Common.Caches;
using Tiobon.Core.Common;
using Tiobon.Core.Model;
using Newtonsoft.Json.Linq;
using SqlSugar;
using Newtonsoft.Json;
using System.Data;
using Microsoft.AspNetCore.Http;
using Tiobon.Core.Common.UserManager;
using Tiobon.Core.Common.Helper;
using AgileObjects.AgileMapper;
using static Tiobon.Core.Model.Consts;

namespace Tiobon.Core.Services;

/// <summary>
/// 课程 (服务)
/// </summary>
public class Ghre_CourseServices : BaseServices<Ghre_Course, Ghre_CourseDto, InsertGhre_CourseInput, EditGhre_CourseInput>, IGhre_CourseServices
{
    private readonly IBaseRepository<Ghre_Course> _dal;
    private IGhre_CourseClassServices _ghre_CourseClassServices;
    private IGhre_CourseSnapServices _ghre_CourseSnapServices;
    public Ghre_CourseServices(IBaseRepository<Ghre_Course> dal,
        ICaching caching,
        IGhre_CourseClassServices ghre_CourseClassServices,
        IGhre_CourseSnapServices ghre_CourseSnapServices)
    {
        this._dal = dal;
        base.BaseDal = dal;
        _ghre_CourseClassServices = ghre_CourseClassServices;
        _ghre_CourseSnapServices = ghre_CourseSnapServices;
        base._caching = caching;
    }

    public async Task<ServicePageResult<Ghre_CourseDto>> QueryList(QueryBody filter, string status, List<long> ids)
    {
        RefAsync<int> totalCount = 0;
        string sql = @"SELECT *
                        FROM (SELECT A.*,
                                     D.SceneName + ' (' + D.SceneNo + ')' CourseSceneName,
                                     E.CourseWareName + ' (' + E.CourseWareNo + ')' CourseWareName,
                                     F.StaffName + ' (' + F.StaffNo + ')' ManagerStaffName,
                                     G.UserName CreateName,
                                     H.UserName UpdateName,
                                     CASE A.InOrOut
                                        WHEN 'In' THEN F.StaffName
                                        WHEN 'Out' THEN J.TeacherName
                                     END TeacherName,
                                     ISNULL (A.UpdateTime, A.CreateTime) CreateTime1
                              FROM Ghre_Course A
                                   LEFT JOIN Ghre_CourseScene D ON A.CourseSceneId = D.Id
                                   LEFT JOIN Ghre_CourseWare E ON A.CourseWareId = E.Id
                                   LEFT JOIN Ghra_Staff F ON A.ManagerId = F.StaffID
                                   LEFT JOIN Ghrs_User G ON A.CreateBy = G.UserId
                                   LEFT JOIN Ghrs_User H ON A.UpdateBy = H.UserId
                                   LEFT JOIN Ghra_Staff I ON A.TeacherId = I.StaffID
                                   LEFT JOIN Ghre_Teacher J ON A.SchoolTeacherId = I.StaffID
                              WHERE A.IsEnable = 1) A";

        if (string.IsNullOrWhiteSpace(filter.orderBy))
            filter.orderBy = "CreateTime1 DESC";

        string conditions = " WHERE 1=1";


        if (!string.IsNullOrWhiteSpace(status))
            conditions += $" AND Status ='{status}'";
        if (ids != null && ids.Any())
            conditions += $" AND Id IN({string.Join(",", ids)})";


        if (filter.jsonParam != null)
            foreach (JProperty jProperty in filter.jsonParam.Properties())
            {
                var name = jProperty.Name;
                var value = jProperty.Value.ToString();
                if (name == "page" || name == "pageSize")
                    continue;

                if (!string.IsNullOrWhiteSpace(value))
                {
                    var jsonParam = JsonConvert.DeserializeObject<JsonParam>(value);

                    if (name == "CourseNoOrName")
                    {
                        conditions += $" AND ( CourseNo LIKE '%{jsonParam.columnValue}%' OR CourseName LIKE '%{jsonParam.columnValue}%')";
                        continue;
                    }

                    switch (jsonParam.operationKey)
                    {
                        case "Include":
                            conditions += $" AND {name} LIKE '%{jsonParam.columnValue}%'";
                            break;
                        case "NotInclude":
                            conditions += $" AND {name} NOT LIKE '%{jsonParam.columnValue}%'";
                            break;
                        case "IsNull":
                            conditions += $" AND {name} IS NULL";
                            break;
                        case "NotNull":
                            conditions += $" AND {name} IS NOT NULL";
                            break;
                        case "Equal":
                            conditions += $" AND {name} ='{jsonParam.columnValue}'";
                            break;
                        case "NotEqual":
                            conditions += $" AND {name} !='{jsonParam.columnValue}'";
                            break;
                        case "GreaterOrEqual"://大于等于
                            conditions += $" AND {name} >='{jsonParam.columnValue}'";
                            break;
                        case "Greater"://大于
                            conditions += $" AND {name} >'{jsonParam.columnValue}'";
                            break;
                        case "LessOrEqual"://小于等于
                            conditions += $" AND {name} <='{jsonParam.columnValue}'";
                            break;
                        case "Less"://小于
                            conditions += $" AND {name} <'{jsonParam.columnValue}'";
                            break;
                        case "EqualAny":// 
                            if (jsonParam.columnValue != null)
                            {
                                var ids1 = JsonHelper.JsonToObj<List<string>>(jsonParam.columnValue.ToString());

                                conditions += $" AND {name} IN ({string.Join(",", ids1.Select(id => "'" + id + "'"))})";
                            }
                            break;
                        case "NotEqualAny":// 
                            if (jsonParam.columnValue != null)
                            {
                                var ids1 = JsonHelper.JsonToObj<List<string>>(jsonParam.columnValue.ToString());

                                conditions += $" AND ({name} NOT IN ({string.Join(",", ids1.Select(id => "'" + id + "'"))}) OR {name} IS NULL)";
                            }
                            break;
                        default:
                            break;
                    }
                }
            }
        if (filter.pageSize == 0)
            filter.pageSize = 10000;
        sql += conditions;
        var data = await Db.SqlQueryable<Ghre_CourseDto>(sql)
            .OrderBy(filter.orderBy)
            .ToPageListAsync(filter.pageNum, filter.pageSize, totalCount);

        var classsIds1 = data.Select(x => x.CourseClassId).Distinct().ToList();
        var classsIds = new List<long>();

        classsIds1.ForEach(x =>
        {
            if (!string.IsNullOrWhiteSpace(x))
            {
                var courseClassIds = JsonConvert.DeserializeObject<List<long>>(x);
                classsIds = classsIds.Concat(courseClassIds).ToList();
            }
        });
        classsIds = classsIds.Distinct().ToList();
        var classs = await _ghre_CourseClassServices.Query(x => classsIds.Contains(x.Id));

        data.ForEach(async x =>
        {
            x.ChargeMethodLabel = await GetParaLabel("CourseChargeMethod", x.ChargeMethod);
            x.InOrOutLabel = await GetParaLabel("CourseInOrOut", x.InOrOut);
            x.IsOPenLabel = x.IsOPen == true ? "是" : "否";
            var courseClass = classs.Where(a => x.CourseClassId.Contains(a.Id.ToString())).ToList();
            x.CourseClassName = string.Join(",", courseClass.Select(a => a.ClassName + " (" + a.ClassNo + ")"));
        });

        return new ServicePageResult<Ghre_CourseDto>(filter.pageNum, totalCount, filter.pageSize, data);
    }

    public async Task<ServiceResult<int>> QueryDeptID(int StaffID)
    {
        string sql = $"SELECT A.DeptID from Ghra_Staff A LEFT JOIN Ghro_Dept B ON A.DeptID = B.DeptID WHERE A.StaffID='{StaffID}'";

        int id = await Db.Ado.GetIntAsync(sql);
        return ServiceResult<int>.OprateSuccess("查询成功！", id);

    }
    public async Task<ServiceResult<CommonSelect>> QueryTeacher(long? linkId)
    {
        var result = new CommonSelect();
        JArray TableColumn = new JArray();
        JArray DT_TablePageInfoT1 = new JArray();
        JArray DT_TableDataT1 = new JArray();
        JObject searchItem = new JObject();
        JObject item;
        DataTable dt;
        string sql;

        searchItem = [
            new JProperty("defaultHidden", true),
            new JProperty("field","value"),
            new JProperty("label","讲师ID"),
        ];
        TableColumn.Add(searchItem);
        searchItem = [
            new JProperty("field","label"),
            new JProperty("label","讲师名称"),
        ];
        TableColumn.Add(searchItem);

        sql = "SELECT Id, TeacherNo , TeacherName FROM Ghre_Teacher WHERE IsEnable=1 ";

        if (linkId != null)
            sql += $"AND SchoolId ='{linkId}'";
        dt = await Db.Ado.GetDataTableAsync(sql);

        for (int i = 0; i < dt.Rows.Count; i++)
        {
            item = [
                new JProperty("value",long.Parse(dt.Rows[i]["Id"].ToString())),
                new JProperty("label",dt.Rows[i]["TeacherNo"].ToString()+"-"+dt.Rows[i]["TeacherName"].ToString())
                ];
            DT_TableDataT1.Add(item);
        }

        item = [
            new JProperty("ListMax",100),
                    new JProperty("ListMin",10),
                    new JProperty("PageNum",1),
                    new JProperty("PageSize",99999),
                    new JProperty("TotalCount",dt.Rows.Count),
                    new JProperty("UIType","Auto")
            ];
        DT_TablePageInfoT1.Add(item);

        result.JM_TableColumnT1.TableColumn = TableColumn;
        result.DT_TableDataT1 = DT_TableDataT1;
        result.DT_TablePageInfoT1 = DT_TablePageInfoT1;
        return new ServiceResult<CommonSelect>() { Success = true, Message = "查询成功", Data = result, };

    }

    public override async Task<ServiceFormResult<Ghre_CourseDto>> QueryForm(QueryForm body)
    {
        var result = await base.QueryForm(body);
        string examPaperId = result.result.DT_TableDataT1[0].ExamPaperId;
        if (!string.IsNullOrWhiteSpace(examPaperId))
            result.result.DT_TableDataT1[0].ExamPaperIds = JsonConvert.DeserializeObject<List<long>>(examPaperId);

        string courseClassId = result.result.DT_TableDataT1[0].CourseClassId;
        if (!string.IsNullOrWhiteSpace(courseClassId))
            result.result.DT_TableDataT1[0].CourseClassIds = JsonConvert.DeserializeObject<List<long>>(courseClassId);

        else result.result.DT_TableDataT1[0].ExamPaperIds = new List<long>();

        if (body.doType == "Copy")
        {
            result.result.DT_TableDataT1[0].CourseNo = null;
            result.result.DT_TableDataT1[0].CourseName = null;
        }
        return result;

    }


    public async Task<ServiceResult> UpdateStatus(long[] ids, string status)
    {
        if (status != Consts.DIC_COURSE_STATUS.RELEASED && status != Consts.DIC_COURSE_STATUS.DISABLED && status != Consts.DIC_COURSE_STATUS.DRAFT)
            throw new Exception("无效的状态");

        HttpRequest request = UserContext.Context.Request;
        var api = request.Path.ObjToString().TrimEnd('/').ToLower();
        var ip = GetUserIp(UserContext.Context);

        var entities = new List<Ghre_Course>();
        foreach (var id in ids)
        {
            if (id == null || !BaseDal.Any(id))
                continue;

            var entity = await BaseDal.QueryById(id);

            #region 关联数据有效性验证
            if (entity.Status == Consts.DIC_COURSE_STATUS.DRAFT && status == Consts.DIC_COURSE_STATUS.RELEASED)
            {
                if (!entity.CourseClassId.IsNull())
                {
                    var CourseClassIds = JsonConvert.DeserializeObject<List<long>>(entity.CourseClassId);
                    if (CourseClassIds != null && CourseClassIds.Any())
                    {
                        for (int i = 0; i < CourseClassIds.Count; i++)
                        {
                            if (!await Db.Queryable<Ghre_CourseClass>().AnyAsync(x => x.Id == CourseClassIds[i]))
                                throw new Exception($"课程关联的课程分类已失效，请修正数据后继续发布！");
                        }
                    }
                }

                if (!entity.CourseSceneId.IsNull())
                    if (!await Db.Queryable<Ghre_CourseScene>().AnyAsync(x => x.Id == entity.CourseSceneId))
                        return ServiceResult.OprateFailed($"课程关联的课程场景已失效，请修正数据后继续发布！");

                if (!entity.ExamPaperId.IsNull())
                {
                    var ExamPaperIds = JsonConvert.DeserializeObject<List<long>>(entity.ExamPaperId);
                    if (ExamPaperIds != null && ExamPaperIds.Any())
                    {
                        for (int i = 0; i < ExamPaperIds.Count; i++)
                        {
                            if (!await Db.Queryable<Ghre_ExamPaper>().AnyAsync(x => x.Id == ExamPaperIds[0] && x.Status == DIC_EXAM_PAPER_STATUS.RELEASED))
                                return ServiceResult.OprateFailed($"课程关联的试卷已失效，请修正数据后继续发布！");
                        }
                    }
                }
            }
            #endregion

            if (entity.Status == Consts.DIC_COURSE_STATUS.RELEASED)
            {
                var examPaper = await Db.Queryable<Ghre_ExamPaper>().FirstAsync(x => x.LinkId == id && x.LinkType == "CourseId" && x.Status != Consts.DIC_COURSE_STATUS.DISABLED);
                if (examPaper != null)
                    return ServiceResult.OprateFailed($"课程【{entity.CourseName}({entity.CourseNo})】已与试卷【{examPaper.PaperName}({examPaper.PaperName})】关联，暂不可{(status == Consts.DIC_COURSE_STATUS.DRAFT ? "取消发布" : "停用")}");

            }

            BasePoco ent = entity;
            ent.UpdateIP = ip;
            ent.UpdateProg = api;
            if (status == Consts.DIC_COURSE_STATUS.RELEASED || status == Consts.DIC_COURSE_STATUS.DISABLED || status == Consts.DIC_COURSE_STATUS.DRAFT)
            {
                entity.Status = status;
                entities.Add(entity);
            }

            #region 生成课程快照
            if (status == Consts.DIC_COURSE_STATUS.RELEASED)
            {
                var sql = $"UPDATE Ghre_CourseSnap SET IsEnable = 0 WHERE CourseId = '{id}' AND IsEnable = 1";
                await Db.Ado.ExecuteCommandAsync(sql);
                var entity1 = Mapper.Map(entity).ToANew<InsertGhre_CourseSnapInput>();
                var courseClassIds = JsonConvert.DeserializeObject<List<long>>(entity1.CourseClassId);
                var classs = await _ghre_CourseClassServices.Query(x => courseClassIds.Contains(x.Id));
                entity1.CourseClass = string.Join("、", classs.Select(o => o.ClassName));
                entity1.CourseClass1 = string.Join("、", classs.Select(o => o.ClassName + "(" + o.ClassNo + ")"));
                entity1.CourseId = id;
                await _ghre_CourseSnapServices.Add(entity1);
            }
            #endregion
        }

        var result = await BaseDal.Update(entities);
        if (status == Consts.DIC_COURSE_STATUS.RELEASED)
            return ServiceResult.OprateSuccess("发布成功！");
        else if (status == Consts.DIC_COURSE_STATUS.DRAFT)
            return ServiceResult.OprateSuccess("已启用成功，请进入草稿箱查看！");
        else
            return ServiceResult.OprateSuccess("停用成功！");

    }

    public override async Task<long> Add(InsertGhre_CourseInput entity)
    {
        entity.ExamPaperId = JsonHelper.ObjToJson(entity.ExamPaperIds);
        entity.CourseClassId = JsonHelper.ObjToJson(entity.CourseClassIds);
        entity.Status = Consts.DIC_COURSE_STATUS.DRAFT;
        entity.DefaultCoverImageName = entity.DefaultCoverImageName ?? "defaultCourseCover1";
        entity.UseDefaultCoverImage = entity.UseDefaultCoverImage ?? true;

        if (entity.InOrOut == "In")
        {
            var teacher = await Db.Queryable<Ghre_Teacher>().FirstAsync(x => x.StaffId == entity.TeacherId);
            if (!teacher.IsNull())
            {
                entity.SchoolTeacherId = teacher.Id;
                //entity.SchoolId = teacher.SchoolId;
            }
        }
        return await base.Add(entity);
    }

    public override async Task<bool> Update(long Id, EditGhre_CourseInput editModel)
    {

        editModel.ExamPaperId = JsonHelper.ObjToJson(editModel.ExamPaperIds);
        editModel.CourseClassId = JsonHelper.ObjToJson(editModel.CourseClassIds);


        if (!editModel.CourseClassId.IsNull())
        {
            var CourseClassIds = JsonConvert.DeserializeObject<List<long>>(editModel.CourseClassId);
            if (CourseClassIds != null && CourseClassIds.Any())
            {
                for (int i = 0; i < CourseClassIds.Count; i++)
                {
                    if (!await Db.Queryable<Ghre_CourseClass>().AnyAsync(x => x.Id == CourseClassIds[i]))
                        throw new Exception($"课程关联的课程分类已失效，请修正数据后继续发布！");
                }
            }
        }

        if (!editModel.CourseSceneId.IsNull())
            if (!await Db.Queryable<Ghre_CourseScene>().AnyAsync(x => x.Id == editModel.CourseSceneId))
                throw new Exception($"课程关联的课程场景已失效，请修正数据后继续发布！");

        if (!editModel.ExamPaperId.IsNull())
        {
            var ExamPaperIds = JsonConvert.DeserializeObject<List<long>>(editModel.ExamPaperId);
            if (ExamPaperIds != null && ExamPaperIds.Any())
            {
                for (int i = 0; i < ExamPaperIds.Count; i++)
                {
                    if (!await Db.Queryable<Ghre_ExamPaper>().AnyAsync(x => x.Id == ExamPaperIds[i] && x.Status == DIC_EXAM_PAPER_STATUS.RELEASED))
                        throw new Exception($"课程关联的试卷已失效，请修正数据后继续发布！");
                }
            }
        }

        return await base.Update(Id, editModel);
    }

    #region 获取通用列表下拉
    /// <summary>
    /// 获取通用列表下拉
    /// </summary>
    /// <param name="type"></param>
    /// <returns></returns>
    public async Task<ServiceResult<CommonSelect>> GetSelectAsync(long? linkId, string keyWords)
    {
        var result = new CommonSelect();
        var TableColumn = new JArray();
        var DT_TablePageInfoT1 = new JArray();
        var DT_TableDataT1 = new JArray();
        var searchItem = new JObject();
        JObject item;
        DataTable dt;
        string sql;
        searchItem = [
            new JProperty("defaultHidden", true),
                new JProperty("field","value"),
                new JProperty("label","课程ID"),
            ];
        TableColumn.Add(searchItem);
        searchItem = [
            new JProperty("field","label"),
                new JProperty("label","课程名称"),
            ];
        TableColumn.Add(searchItem);

        sql = $"SELECT Id,  CourseNo , CourseName FROM Ghre_Course WHERE Status ='{Consts.DIC_COURSE_STATUS.RELEASED}' AND IsEnable=1";
        if (!string.IsNullOrWhiteSpace(keyWords))
            sql += $"AND ( CourseNo like '%{keyWords}%' or CourseName like '%{keyWords}%')";

        if (linkId.HasValue)
            sql += $" AND CourseSceneId='{linkId}'";
        sql += $"  ORDER BY UpdateTime DESC, CreateTime DESC";
        dt = await Db.Ado.GetDataTableAsync(sql);

        for (int i = 0; i < dt.Rows.Count; i++)
        {
            item = [
                new JProperty("value",long.Parse(dt.Rows[i]["Id"].ToString())),
                    new JProperty("label", dt.Rows[i]["CourseName"].ToString() + "("+dt.Rows[i]["CourseNo"].ToString()+")")
                ];
            DT_TableDataT1.Add(item);
        }

        item = [
            new JProperty("ListMax",100),
                new JProperty("ListMin",10),
                new JProperty("PageNum",1),
                new JProperty("PageSize",99999),
                new JProperty("TotalCount",dt.Rows.Count),
                new JProperty("UIType","Auto")
            ];
        DT_TablePageInfoT1.Add(item);
        result.JM_TableColumnT1.TableColumn = TableColumn;
        result.DT_TableDataT1 = DT_TableDataT1;
        result.DT_TablePageInfoT1 = DT_TablePageInfoT1;
        return new ServiceResult<CommonSelect>() { Success = true, Message = "查询成功", Data = result, };
    }
    #endregion


    public async Task<ServiceResult<string>> ExportExcel(QueryExport body, string status)
    {
        QueryBody filter = new QueryBody();
        filter.pageNum = 1;
        filter.pageSize = 1000000;
        filter.langId = body.langId;

        var condition = "1=1";
        var ids = new List<long>();
        if (body.exportSet.SelectRowKeys != null && body.exportSet.SelectRowKeys.Any())
            ids = body.exportSet.SelectRowKeys;

        var data = await QueryList(filter, status, ids);


        string sql = $@"SELECT *
                            FROM Ghrs_PageSettingQuery
                            WHERE     IsEnable = 1
                                  AND PageNo = '{body.menuName}'
                                  AND (defaultHidden = 'false' or defaultHidden is null)
                            ORDER BY SortNo ASC";

        var columns = await Db.Ado.SqlQueryAsync<QueryExportColumn>(sql);

        var fieldDescs = new Dictionary<string, string>();
        if (body.exportSet.ExFields.Any())
            body.exportSet.ExFields.ForEach(x =>
            {
                if (columns.Any(o => o.field == x))
                    fieldDescs.Add(x, columns.FirstOrDefault(o => o.field == x)?.label);
            });
        else
            fieldDescs = columns.ToDictionary(item => item.field, item => item.label);
        var dt = ToDataTable(data.result.DT_TableDataT1, fieldDescs, null);
        // 获取所有列名
        var dtColumns = dt.Columns;

        var id = SnowFlakeSingle.instance.getID();
        var physicsPath = $"{Environment.CurrentDirectory}{Path.DirectorySeparatorChar}wwwroot";
        var path = $"{$"{Path.DirectorySeparatorChar}files{Path.DirectorySeparatorChar}export{Path.DirectorySeparatorChar}{id}{Path.DirectorySeparatorChar}"}";
        if (!Directory.Exists(physicsPath + path))
            Directory.CreateDirectory(physicsPath + path);

        path = path + body.exportSet.TitleName + ".xlsx";
        NPOIHelper.ExportExcel(dt, null, "sheet1", physicsPath + path);
        return ServiceResult<string>.OprateSuccess("导出成功", path);
    }

    #region 获取公开课查询条件
    public async Task<ServiceResult<CoursePublicSearch>> QueryPublicSearchFields(QueryBody body)
    {
        var entity = new CoursePublicSearch();
        string sql = @"SELECT Langkey field,
                       CASE {2}
                          WHEN 1 THEN isnull (Value01, LangValue)
                          WHEN 2 THEN isnull (Value02, LangValue)
                          WHEN 3 THEN isnull (Value03, LangValue)
                          WHEN 4 THEN isnull (Value04, LangValue)
                          WHEN 5 THEN isnull (Value05, LangValue)
                          WHEN 6 THEN isnull (Value06, LangValue)
                          WHEN 7 THEN isnull (Value07, LangValue)
                          WHEN 8 THEN isnull (Value08, LangValue)
                          WHEN 9 THEN isnull (Value09, LangValue)
                          WHEN 10 THEN isnull (Value10, LangValue)
                       END label
                FROM Ghrs_LangKey
                WHERE     IsEnable = 1
                      AND (LangKey LIKE 'GHR_Page%' OR LangKey LIKE 'GHR_Common%')";
        sql = string.Format(sql, body.menuName, App.User.ID, body.langId);
        entity.DT_PageMutiMsg = await Db.Ado.SqlQueryAsync<DT_PageMutiMsg>(sql);
        entity.SearchFields.Add(new CoursePublicSearchField()
        {
            label = "课程编号/名称",
            field = "CourseNoOrName",
            elementType = "Input",
            editable = true,
            required = false,
            multipleSelect = false,
        });
        entity.SearchFields.Add(new CoursePublicSearchField()
        {
            label = "课程分类",
            field = "CourseClassId",
            elementType = "ApiSelect",
            dataSource = "CommonList_TrainingCourseClass",
            editable = true,
            required = false,
            multipleSelect = false,
        });
        entity.SearchFields.Add(new CoursePublicSearchField()
        {
            label = "课程场景",
            field = "CourseSceneId",
            elementType = "ApiSelect",
            dataSource = "CommonList_TrainingCourseScene",
            editable = true,
            required = false,
            multipleSelect = false,
        });
        entity.SearchFields.Add(new CoursePublicSearchField()
        {
            label = "是否学过",
            field = "HasStudy",
            elementType = "ApiSelect",
            dataSource = "TBParaDetail_Train_CourseIsOpen",
            editable = true,
            required = false,
            multipleSelect = false,
        });
        return ServiceResult<CoursePublicSearch>.OprateSuccess("", entity);
    }
    #endregion

    #region 获取公开课
    public async Task<ServicePageResult<CoursePublic>> QueryPublic(QueryBody filter)
    {
        RefAsync<int> totalCount = 0;
        string sql = @"SELECT A.Id,
                           A.CoverUrl,
                           A.UseDefaultCoverImage,
                           A.DefaultCoverImageName,
                           A.CourseName,
                           A.StandardHour,
                           A.CreditPoints,
                           CONVERT (VARCHAR (10), ISNULL (A.UpdateTime, A.CreateTime), 120)
                              CourseBeginTIme,
                           CONVERT
                           (VARCHAR (10),
                            dateadd (month, +3, ISNULL (A.UpdateTime, A.CreateTime)),
                            120)
                              CourseEndTIme,
                           NULL
                              ExamDate,
                           NULL
                              ExamBeginDate,
                           NULL
                              ExamEndDate,
                            CAST('0' AS BIT)
                              DisableBtn
                    FROM Ghre_Course A
                    WHERE A.IsOPen = 'true' AND A.IsEnable = 1";

        if (string.IsNullOrWhiteSpace(filter.orderBy))
            filter.orderBy = "CourseName ASC";

        string conditions = " AND 1=1";
        if (filter.jsonParam != null)
            foreach (JProperty jProperty in filter.jsonParam.Properties())
            {
                var name = jProperty.Name;
                var value = jProperty.Value.ToString();
                if (name == "page" || name == "pageSize")
                    continue;

                if (name == "CourseNoOrName")
                {
                    var jsonParam = JsonConvert.DeserializeObject<JsonParam>(value);
                    conditions += $" AND (CourseNo LIKE '%{jsonParam.columnValue}%' OR CourseName LIKE '%{jsonParam.columnValue}%')";

                    continue;
                }
                if (name == "CourseClassId")
                {
                    var jsonParam = JsonConvert.DeserializeObject<JsonParam>(value);
                    conditions += $" AND CourseClassId LIKE '%{jsonParam.columnValue}%' ";

                    continue;
                }
                //if (name == "Date")
                //{
                //    var jsonParam = JsonConvert.DeserializeObject<JsonParam1>(value);
                //    conditions += $" AND (Date BETWEEN '{jsonParam.columnValue[0]}' AND '{jsonParam.columnValue[1]}')";

                //    continue;
                //}
                //if (name == "CreditPoints")
                //{
                //    var jsonParam = JsonConvert.DeserializeObject<JsonParam>(value);

                //    switch (jsonParam.operationKey)
                //    {
                //        case "Include":
                //            sql += $" WHERE {name} LIKE '%{jsonParam.columnValue}%'";
                //            break;
                //        case "NotInclude":
                //            sql += $" WHERE {name} NOT LIKE '%{jsonParam.columnValue}%'";
                //            break;
                //        case "IsNull":
                //            sql += $" WHERE {name} IS NULL";
                //            break;
                //        case "NotNull":
                //            sql += $" WHERE {name} IS NOT NULL";
                //            break;
                //        case "Equal":
                //            sql += $" WHERE {name} ='{jsonParam.columnValue}'";
                //            break;
                //        case "NotEqual":
                //            sql += $" WHERE {name} !='{jsonParam.columnValue}'";
                //            break;
                //        case "GreaterOrEqual"://大于等于
                //            sql += $" WHERE {name} >='{jsonParam.columnValue}'";
                //            break;
                //        case "Greater"://大于
                //            sql += $" WHERE {name} >'{jsonParam.columnValue}'";
                //            break;
                //        case "LessOrEqual"://小于等于
                //            sql += $" WHERE {name} <='{jsonParam.columnValue}'";
                //            break;
                //        case "Less"://小于
                //            sql += $" WHERE {name} <'{jsonParam.columnValue}'";
                //            break;
                //        default:
                //            break;
                //    }

                //    continue;
                //}

                if (!string.IsNullOrWhiteSpace(value))
                {
                    var jsonParam = JsonConvert.DeserializeObject<JsonParam>(value);

                    switch (jsonParam.operationKey)
                    {
                        case "Include":
                            conditions += $" AND {name} LIKE '%{jsonParam.columnValue}%'";
                            break;
                        case "NotInclude":
                            conditions += $" AND {name} NOT LIKE '%{jsonParam.columnValue}%'";
                            break;
                        case "IsNull":
                            conditions += $" AND {name} IS NULL";
                            break;
                        case "NotNull":
                            conditions += $" AND {name} IS NOT NULL";
                            break;
                        case "Equal":
                            conditions += $" AND {name} ='{jsonParam.columnValue}'";
                            break;
                        case "NotEqual":
                            conditions += $" AND {name} !='{jsonParam.columnValue}'";
                            break;
                        default:
                            break;
                    }
                }
            }

        //if (ids != null && ids.Any())
        //    conditions += $" AND Id IN({string.Join(",", ids)})";

        sql += conditions;
        if (filter.pageSize == 0)
            filter.pageSize = 10000;
        var data = await Db.SqlQueryable<CoursePublic>(sql)
            .OrderBy(filter.orderBy)
            .ToPageListAsync(filter.pageNum, filter.pageSize, totalCount);

        return new ServicePageResult<CoursePublic>(filter.pageNum, totalCount, filter.pageSize, data);
    }
    #endregion
}