210 lines
9.8 KiB
C#
210 lines
9.8 KiB
C#
|
|
using CYQ.Data.Cache;
|
|||
|
|
using Newtonsoft.Json;
|
|||
|
|
using pili_sdk;
|
|||
|
|
using Song.ServiceInterfaces;
|
|||
|
|
using System;
|
|||
|
|
using System.Collections.Generic;
|
|||
|
|
using System.Dynamic;
|
|||
|
|
using System.IO;
|
|||
|
|
using System.Linq;
|
|||
|
|
using System.Runtime.InteropServices.ComTypes;
|
|||
|
|
using System.Text;
|
|||
|
|
using System.Threading.Tasks;
|
|||
|
|
using Taurus.Core;
|
|||
|
|
using Taurus.Mvc;
|
|||
|
|
using Taurus.Mvc.Attr;
|
|||
|
|
using WeiSha.Common;
|
|||
|
|
|
|||
|
|
namespace PeiXun.Controllers.BasicInfo
|
|||
|
|
{
|
|||
|
|
public class OutLineAPIController : Controller
|
|||
|
|
{
|
|||
|
|
[Token]
|
|||
|
|
[HttpGet]
|
|||
|
|
// 章节的状态
|
|||
|
|
public void state()
|
|||
|
|
{
|
|||
|
|
int olid = Query<int>("olid");
|
|||
|
|
|
|||
|
|
string token = Query<string>("token").TrimStart("xyl:".ToCharArray());
|
|||
|
|
Song.Entities.Accounts acc = DistributedCache.Instance.Get<Song.Entities.Accounts>(token);
|
|||
|
|
|
|||
|
|
dynamic obj = new ExpandoObject();
|
|||
|
|
obj.code = 1;
|
|||
|
|
obj.msg = "success";
|
|||
|
|
|
|||
|
|
Dictionary<string, object> dic = new Dictionary<string, object>();
|
|||
|
|
//Song.Entities.Accounts acc = Song.Extend.LoginState.Accounts.CurrentUser;
|
|||
|
|
//dic.Add("isLogin", acc != null); //学员是否登录
|
|||
|
|
//
|
|||
|
|
Song.Entities.Outline outline = Business.Do<IOutline>().OutlineSingle(olid);
|
|||
|
|
if (outline == null)
|
|||
|
|
{
|
|||
|
|
obj.code = 0;
|
|||
|
|
obj.msg = "章节不存在";
|
|||
|
|
//throw new Exception("章节不存在");
|
|||
|
|
obj.data = dic;
|
|||
|
|
Write(JsonConvert.SerializeObject(obj));
|
|||
|
|
return;
|
|||
|
|
}
|
|||
|
|
dic.Add("Name", outline.Ol_Name);
|
|||
|
|
Song.Entities.Course course = Business.Do<ICourse>().CourseSingle(outline.Cou_ID);
|
|||
|
|
if (course == null)
|
|||
|
|
{
|
|||
|
|
obj.code = 0;
|
|||
|
|
obj.msg = "课程不存在";
|
|||
|
|
obj.data = dic;
|
|||
|
|
Write(JsonConvert.SerializeObject(obj));
|
|||
|
|
return;
|
|||
|
|
//throw new Exception("课程不存在");
|
|||
|
|
}
|
|||
|
|
dic.Add("Course", course.Cou_Name);
|
|||
|
|
Song.Entities.Organization orgin;
|
|||
|
|
//是否限制在桌面应用中打开
|
|||
|
|
dic.Add("DeskAllow", this.getDeskallow(course, outline, out orgin));
|
|||
|
|
//是否在切换浏览器时继续播放
|
|||
|
|
dic.Add("SwitchPlay", this.getSwitchPlay(course, acc, orgin));
|
|||
|
|
//是否免费,或是限时免费
|
|||
|
|
if (course.Cou_IsLimitFree)
|
|||
|
|
{
|
|||
|
|
DateTime freeEnd = course.Cou_FreeEnd.AddDays(1).Date;
|
|||
|
|
if (!(course.Cou_FreeStart <= DateTime.Now && freeEnd >= DateTime.Now))
|
|||
|
|
course.Cou_IsLimitFree = false;
|
|||
|
|
}
|
|||
|
|
//是否可以学习,是否购买
|
|||
|
|
bool isStudy = false, isBuy = false, canStudy = false;
|
|||
|
|
if (acc != null)
|
|||
|
|
{
|
|||
|
|
isStudy = Business.Do<ICourse>().Study(course.Cou_ID, acc.Ac_ID);
|
|||
|
|
isBuy = course.Cou_IsFree || course.Cou_IsLimitFree ? true : Business.Do<ICourse>().IsBuy(course.Cou_ID, acc.Ac_ID);
|
|||
|
|
//学习记录
|
|||
|
|
Song.Entities.LogForStudentStudy studyLog = Business.Do<IStudent>().LogForStudySingle(acc.Ac_ID, outline.Ol_ID);
|
|||
|
|
dic.Add("StudyTime", studyLog != null ? studyLog.Lss_StudyTime : 0);
|
|||
|
|
dic.Add("PlayTime", studyLog != null ? studyLog.Lss_PlayTime : 0);
|
|||
|
|
}
|
|||
|
|
dic.Add("isStudy", isStudy);
|
|||
|
|
dic.Add("isBuy", isBuy);
|
|||
|
|
//是否可以学习,如果是免费或已经选修便可以学习,否则当前课程允许试用且当前章节是免费的,也可以学习
|
|||
|
|
canStudy = isBuy || (isStudy && outline.Ol_IsUse && outline.Ol_IsFinish && course.Cou_IsTry && outline.Ol_IsFree);
|
|||
|
|
dic.Add("canStudy", canStudy);
|
|||
|
|
//是否有知识库
|
|||
|
|
int knlCount = Business.Do<IKnowledge>().KnowledgeOfCount(-1, course.Cou_ID, -1, true);
|
|||
|
|
dic.Add("isKnl", knlCount > 0 && canStudy);
|
|||
|
|
|
|||
|
|
//是否有视频,是否为外链视频
|
|||
|
|
|
|||
|
|
List<Song.Entities.Accessory> videos = Business.Do<IAccessory>().GetAll(outline.Ol_UID, "CourseVideo");
|
|||
|
|
bool existVideo = videos.Count > 0;
|
|||
|
|
dic.Add("videoId", videos[0].As_Id);
|
|||
|
|
dic.Add("outerVideo", existVideo && (videos.Count > 0 && videos[0].As_IsOuter)); //站外视频,包括其它网站的视频,或是视频播放链接
|
|||
|
|
dic.Add("otherVideo", existVideo && (videos.Count > 0 && videos[0].As_IsOther)); //其它视频平台的链接
|
|||
|
|
if (videos.Count > 0)
|
|||
|
|
{
|
|||
|
|
string videoUrl = existVideo ? videos[0].As_FileName : string.Empty; //视频地址
|
|||
|
|
//如果是内部链接
|
|||
|
|
if (existVideo && !videos[0].As_IsOuter)
|
|||
|
|
{
|
|||
|
|
videoUrl = Upload.Get[videos[0].As_Type].Virtual + videoUrl;
|
|||
|
|
string ext = System.IO.Path.GetExtension(videoUrl).ToLower();
|
|||
|
|
if (ext == ".flv") videoUrl = Path.ChangeExtension(videoUrl, ".mp4");
|
|||
|
|
}
|
|||
|
|
dic.Add("urlVideo", canStudy ? videoUrl : string.Empty);
|
|||
|
|
outline.Ol_IsLive = false;
|
|||
|
|
}
|
|||
|
|
//直播
|
|||
|
|
bool isLive = outline.Ol_IsLive, isLiving = false;
|
|||
|
|
if (outline.Ol_IsLive)
|
|||
|
|
{
|
|||
|
|
string urlVideo = string.Empty;
|
|||
|
|
if (canStudy)
|
|||
|
|
{
|
|||
|
|
//查询直播状态
|
|||
|
|
pili_sdk.pili.StreamStatus status = Pili.API<pili_sdk.IStream>().Status(outline.Ol_LiveID);
|
|||
|
|
if (status != null)
|
|||
|
|
{
|
|||
|
|
pili_sdk.pili.Stream stream = status.Stream;
|
|||
|
|
string proto = Business.Do<ILive>().GetProtocol; //协议,http还是https
|
|||
|
|
urlVideo = string.Format("{0}://{1}/{2}/{3}.m3u8", proto, stream.LiveHlsHost, stream.HubName, stream.Title);
|
|||
|
|
isLiving = status.Status == "connected"; //正在直播
|
|||
|
|
existVideo = isLiving ? false : existVideo;
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
//直播播放地址
|
|||
|
|
if (!dic.ContainsKey("urlVideo"))
|
|||
|
|
dic.Add("urlVideo", urlVideo);
|
|||
|
|
//直播开始或结束
|
|||
|
|
dic.Add("LiveStart", DateTime.Now > outline.Ol_LiveTime);
|
|||
|
|
dic.Add("LiveOver", outline.Ol_LiveTime.AddMinutes(outline.Ol_LiveSpan) < DateTime.Now);
|
|||
|
|
}
|
|||
|
|
dic.Add("isLive", outline.Ol_IsLive); //是否为直播章节
|
|||
|
|
dic.Add("isLiving", isLiving && canStudy); //是否在直播中
|
|||
|
|
dic.Add("existVideo", existVideo && canStudy);
|
|||
|
|
|
|||
|
|
//是否有课程内容
|
|||
|
|
bool isContext = !string.IsNullOrWhiteSpace(outline.Ol_Intro);
|
|||
|
|
dic.Add("isContext", isContext && canStudy);
|
|||
|
|
//是否有试题
|
|||
|
|
bool isQues = Business.Do<IOutline>().OutlineIsQues(outline.Ol_ID, true);
|
|||
|
|
dic.Add("isQues", isQues && canStudy);
|
|||
|
|
//是否有附件
|
|||
|
|
int accessCount = Business.Do<IAccessory>().OfCount(outline.Ol_UID, "Course");
|
|||
|
|
dic.Add("isAccess", accessCount > 0 && canStudy);
|
|||
|
|
//啥都没有(视频,内容,附件,试题,都没有)
|
|||
|
|
bool isNull = !(existVideo || isLive || isContext || isQues || isQues || accessCount > 0);
|
|||
|
|
dic.Add("isNull", isNull || !canStudy);
|
|||
|
|
|
|||
|
|
|
|||
|
|
|
|||
|
|
obj.data = dic;
|
|||
|
|
Write(JsonConvert.SerializeObject(obj));
|
|||
|
|
}
|
|||
|
|
/// <summary>
|
|||
|
|
/// 判断是否必须在桌面应用中学习
|
|||
|
|
/// </summary>
|
|||
|
|
/// <returns>如果为true,则必须在课面应用中学习</returns>
|
|||
|
|
private bool getDeskallow(Song.Entities.Course course, Song.Entities.Outline ol, out Song.Entities.Organization organ)
|
|||
|
|
{
|
|||
|
|
//当前机构
|
|||
|
|
organ = Business.Do<IOrganization>().OrganSingle(course.Org_ID);
|
|||
|
|
|
|||
|
|
//自定义配置项
|
|||
|
|
WeiSha.Common.CustomConfig config = CustomConfig.Load(organ.Org_Config);
|
|||
|
|
//是否限制在桌面应用中学习
|
|||
|
|
bool studyFordesk = config["StudyForDeskapp"].Value.Boolean ?? false; //课程学习需要在桌面应用打开
|
|||
|
|
bool freeFordesk = config["FreeForDeskapp"].Value.Boolean ?? false; //免费课程和试用章节除外
|
|||
|
|
if (!WeiSha.Common.Browser.IsDestopApp)
|
|||
|
|
{
|
|||
|
|
if (!freeFordesk)
|
|||
|
|
{
|
|||
|
|
return studyFordesk && !WeiSha.Common.Browser.IsDestopApp;
|
|||
|
|
}
|
|||
|
|
else
|
|||
|
|
{
|
|||
|
|
if (course.Cou_IsFree || course.Cou_IsLimitFree) return false;
|
|||
|
|
if (ol.Ol_IsFree) return false;
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
return true && !WeiSha.Common.Browser.IsDestopApp;
|
|||
|
|
}
|
|||
|
|
/// <summary>
|
|||
|
|
/// 判断当前课程是否允许切换浏览器时视频暂停
|
|||
|
|
/// </summary>
|
|||
|
|
/// <param name="course"></param>
|
|||
|
|
/// <param name="acc"></param>
|
|||
|
|
/// <param name="organ"></param>
|
|||
|
|
/// <returns>true,则允许浏览器失去焦点时,视频仍然播放</returns>
|
|||
|
|
private bool getSwitchPlay(Song.Entities.Course course, Song.Entities.Accounts acc, Song.Entities.Organization organ)
|
|||
|
|
{
|
|||
|
|
if (acc == null) return false;
|
|||
|
|
//自定义配置项
|
|||
|
|
WeiSha.Common.CustomConfig config = CustomConfig.Load(organ.Org_Config);
|
|||
|
|
bool isstop = config["IsSwitchPlay"].Value.Boolean ?? false;
|
|||
|
|
if (isstop) return true;
|
|||
|
|
//如果机构设置中为false,继续判断学员组的设置
|
|||
|
|
Song.Entities.StudentSort sort = Business.Do<IStudent>().SortSingle(acc.Sts_ID);
|
|||
|
|
if (sort == null || !sort.Sts_IsUse) return isstop;
|
|||
|
|
return sort.Sts_SwitchPlay;
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
}
|