|
@@ -2493,7 +2493,7 @@ async function nodePage(input) {
|
|
|
}
|
|
}
|
|
|
async function nodeUnitPage(input,current) {
|
|
async function nodeUnitPage(input,current) {
|
|
|
const uid = await authorizeRequestedUser(current,input.userId || input.uid); const paging = pageInput(input); const bindingId = String(input.bindingId || '').trim(); let parentId = number(input.pid); let binding = null;
|
|
const uid = await authorizeRequestedUser(current,input.userId || input.uid); const paging = pageInput(input); const bindingId = String(input.bindingId || '').trim(); let parentId = number(input.pid); let binding = null;
|
|
|
- const bindingRows=await Psql.query('SELECT b.* FROM "CourseBinding" b JOIN "CommonModel" c ON c."company"=b."company" AND c."modelId"=58 AND c."itemId"=b."id" WHERE b."company"=$1 AND b."yhid"::text=$2 AND b."enrollmentStatus"=\'active\' AND c."status"=99 AND (($3<>\'\' AND (b."id"::text=$3 OR b."objectId"=$3)) OR ($3=\'\' AND b."kcid"::text=$4))',[DEFAULT_COMPANY_ID,String(uid),bindingId,String(parentId)]);
|
|
|
|
|
|
|
+ const bindingRows=await mobileUnitBindingRows(uid,bindingId,parentId,current);
|
|
|
if(bindingRows.length>1)fail(409,'该内容有多个开课分类,请选择具体开课记录');binding=bindingRows[0]||null;
|
|
if(bindingRows.length>1)fail(409,'该内容有多个开课分类,请选择具体开课记录');binding=bindingRows[0]||null;
|
|
|
if (!binding) fail(403,'该课程尚未分配给当前学员'); parentId = number(binding.kcid,parentId);
|
|
if (!binding) fail(403,'该课程尚未分配给当前学员'); parentId = number(binding.kcid,parentId);
|
|
|
if (parentId) {
|
|
if (parentId) {
|
|
@@ -2765,7 +2765,7 @@ async function appLearningOverview(input,current) {
|
|
|
Psql.query('SELECT "dqrq" AS date,COUNT(*)::int AS count FROM "DailyStudyRecord" WHERE '+dateWhere.join(' AND ')+' GROUP BY "dqrq"',dateValues),
|
|
Psql.query('SELECT "dqrq" AS date,COUNT(*)::int AS count FROM "DailyStudyRecord" WHERE '+dateWhere.join(' AND ')+' GROUP BY "dqrq"',dateValues),
|
|
|
Psql.query('SELECT "bxrq","yysj","dszt",COUNT(*)::int AS count FROM "CourseAppointment" WHERE NOT EXISTS (SELECT 1 FROM "CommonModel" cancelled WHERE cancelled."company"="CourseAppointment"."company" AND cancelled."modelId"=54 AND cancelled."itemId"="CourseAppointment"."id" AND cancelled."status"=-2) AND '+groupWhere.join(' AND ')+' GROUP BY "bxrq","yysj","dszt"',groupValues),
|
|
Psql.query('SELECT "bxrq","yysj","dszt",COUNT(*)::int AS count FROM "CourseAppointment" WHERE NOT EXISTS (SELECT 1 FROM "CommonModel" cancelled WHERE cancelled."company"="CourseAppointment"."company" AND cancelled."modelId"=54 AND cancelled."itemId"="CourseAppointment"."id" AND cancelled."status"=-2) AND '+groupWhere.join(' AND ')+' GROUP BY "bxrq","yysj","dszt"',groupValues),
|
|
|
schedulePromise,
|
|
schedulePromise,
|
|
|
- Psql.query('SELECT c."objectId",c."generalId",c."title",c."createTime",c."createdAt",b.*,b."objectId" AS "bindingObjectId",n."nodeName" AS "courseTitle" FROM "CourseBinding" b LEFT JOIN "CommonModel" c ON c."company"=$1 AND c."modelId"=58 AND c."itemId"=b."id" LEFT JOIN "Node" n ON n."company"=$1 AND n."nodeId"=CASE WHEN COALESCE(b."kcid",\'\')~\'^\\d+(?:\\.0+)?$\' THEN b."kcid"::numeric ELSE -1 END WHERE b."company"=$1 AND b."yhid"=$2 AND b."enrollmentStatus"=\'active\' AND c."status"=99 AND COALESCE(n."zstatus",99)=99 ORDER BY b."id" DESC',[DEFAULT_COMPANY_ID,String(targetId)]),
|
|
|
|
|
|
|
+ mobileReadableCourseBindings(targetId),
|
|
|
Psql.oneOrNone('SELECT c."objectId",c."generalId",c."title",c."createTime",c."createdAt",d."id",d."pl",d."con",d."djq",d."ygg",d."dqrq",d."dsid",d."fxrl",d."xxqs",d."szmdid",d."userId",d."learned" FROM "DailyStudyRecord" d LEFT JOIN "CommonModel" c ON c."company"=$1 AND c."modelId"=56 AND c."itemId"=d."id" WHERE d."company"=$1 AND d."userId"=$2 AND COALESCE(NULLIF(d."xxqs",\'\'),\'[]\')<>\'[]\' ORDER BY COALESCE(c."createTime",c."createdAt",d."updatedAt",d."createdAt") DESC LIMIT 1',[DEFAULT_COMPANY_ID,targetId])
|
|
Psql.oneOrNone('SELECT c."objectId",c."generalId",c."title",c."createTime",c."createdAt",d."id",d."pl",d."con",d."djq",d."ygg",d."dqrq",d."dsid",d."fxrl",d."xxqs",d."szmdid",d."userId",d."learned" FROM "DailyStudyRecord" d LEFT JOIN "CommonModel" c ON c."company"=$1 AND c."modelId"=56 AND c."itemId"=d."id" WHERE d."company"=$1 AND d."userId"=$2 AND COALESCE(NULLIF(d."xxqs",\'\'),\'[]\')<>\'[]\' ORDER BY COALESCE(c."createTime",c."createdAt",d."updatedAt",d."createdAt") DESC LIMIT 1',[DEFAULT_COMPANY_ID,targetId])
|
|
|
]);
|
|
]);
|
|
|
const normalizedRecords=records.map(appOverviewStudyRow),normalizedLatestReading=appOverviewStudyRow(latestReading),readingMap=await appOverviewReadingMap(normalizedLatestReading?[...normalizedRecords,normalizedLatestReading]:normalizedRecords,targetId),attachReading=(row)=>{if(!row)return row;const reading=readingMap.get(String(row.GeneralID));return reading?{...row,...reading}:row;};
|
|
const normalizedRecords=records.map(appOverviewStudyRow),normalizedLatestReading=appOverviewStudyRow(latestReading),readingMap=await appOverviewReadingMap(normalizedLatestReading?[...normalizedRecords,normalizedLatestReading]:normalizedRecords,targetId),attachReading=(row)=>{if(!row)return row;const reading=readingMap.get(String(row.GeneralID));return reading?{...row,...reading}:row;};
|
|
@@ -2780,7 +2780,7 @@ async function appStudentCompanionOverview(input,current,uid,p) {
|
|
|
let base=merged.filter((row)=>history?(row.cancelled===true||number(row.dszt)>=30):row.cancelled!==true);if(search)base=base.filter((row)=>(String(row.Title||'')+' '+String(row.Title2||'')+' '+String(row.plxm||'')).toLocaleLowerCase('zh-CN').includes(search));if(month)base=base.filter((row)=>companionDateKey(row).startsWith(month+'-'));
|
|
let base=merged.filter((row)=>history?(row.cancelled===true||number(row.dszt)>=30):row.cancelled!==true);if(search)base=base.filter((row)=>(String(row.Title||'')+' '+String(row.Title2||'')+' '+String(row.plxm||'')).toLocaleLowerCase('zh-CN').includes(search));if(month)base=base.filter((row)=>companionDateKey(row).startsWith(month+'-'));
|
|
|
const dateMap=new Map();for(const row of base){const date=companionDateKey(row);if(!date)continue;const value=dateMap.get(date)||{date,finished:0,planned:0};if(number(row.dszt)>=30&&row.cancelled!==true)value.finished++;else if(row.cancelled!==true)value.planned++;dateMap.set(date,value);}const dates=[...dateMap.values()].sort((left,right)=>left.date.localeCompare(right.date));
|
|
const dateMap=new Map();for(const row of base){const date=companionDateKey(row);if(!date)continue;const value=dateMap.get(date)||{date,finished:0,planned:0};if(number(row.dszt)>=30&&row.cancelled!==true)value.finished++;else if(row.cancelled!==true)value.planned++;dateMap.set(date,value);}const dates=[...dateMap.values()].sort((left,right)=>left.date.localeCompare(right.date));
|
|
|
let filtered=base;if(input.dateStart)filtered=filtered.filter((row)=>companionDateKey(row)>=String(input.dateStart));if(input.dateEnd)filtered=filtered.filter((row)=>companionDateKey(row)<=String(input.dateEnd));if(input.filter==='finished')filtered=filtered.filter((row)=>number(row.dszt)>=30&&row.cancelled!==true);if(input.filter==='pending')filtered=filtered.filter((row)=>number(row.dszt)<30&&row.cancelled!==true&&companionDateKey(row)<today);filtered.sort((left,right)=>{const order=(companionDateKey(left)+' '+String(left.yysj||left.sdsd||'')).localeCompare(companionDateKey(right)+' '+String(right.yysj||right.sdsd||''));return history?-order:order;});
|
|
let filtered=base;if(input.dateStart)filtered=filtered.filter((row)=>companionDateKey(row)>=String(input.dateStart));if(input.dateEnd)filtered=filtered.filter((row)=>companionDateKey(row)<=String(input.dateEnd));if(input.filter==='finished')filtered=filtered.filter((row)=>number(row.dszt)>=30&&row.cancelled!==true);if(input.filter==='pending')filtered=filtered.filter((row)=>number(row.dszt)<30&&row.cancelled!==true&&companionDateKey(row)<today);filtered.sort((left,right)=>{const order=(companionDateKey(left)+' '+String(left.yysj||left.sdsd||'')).localeCompare(companionDateKey(right)+' '+String(right.yysj||right.sdsd||''));return history?-order:order;});
|
|
|
- const total=filtered.length,offset=(p.index-1)*p.size,schedules=filtered.slice(offset,offset+p.size),courses=await Psql.query('SELECT c."generalId",c."title",b.*,b."objectId" AS "bindingObjectId",n."nodeName" AS "courseTitle" FROM "CourseBinding" b JOIN "CommonModel" c ON c."company"=b."company" AND c."modelId"=58 AND c."itemId"=b."id" LEFT JOIN "Node" n ON n."company"=b."company" AND n."nodeId"::text=b."kcid" WHERE b."company"=$1 AND b."yhid"=$2 AND b."enrollmentStatus"=\'active\' AND c."status"=99 AND COALESCE(n."zstatus",99)=99 ORDER BY b."id" DESC',[DEFAULT_COMPANY_ID,String(uid)]),scopes=['courses','appointments'],live=withLegacyAppointmentVersion(await appLiveVersionSnapshot(uid,scopes,current),scopes,legacyAppointmentSync);
|
|
|
|
|
|
|
+ const total=filtered.length,offset=(p.index-1)*p.size,schedules=filtered.slice(offset,offset+p.size),courses=await mobileReadableCourseBindings(uid),scopes=['courses','appointments'],live=withLegacyAppointmentVersion(await appLiveVersionSnapshot(uid,scopes,current),scopes,legacyAppointmentSync);
|
|
|
return{schedules,courses:courses.map(appOverviewCourseRow),page:mobilePageMeta(total,p),dates,studentOptions:[],...mobileSource(),...live};
|
|
return{schedules,courses:courses.map(appOverviewCourseRow),page:mobilePageMeta(total,p),dates,studentOptions:[],...mobileSource(),...live};
|
|
|
}
|
|
}
|
|
|
async function appCompanionOverview(input,current) {
|
|
async function appCompanionOverview(input,current) {
|
|
@@ -2803,7 +2803,7 @@ async function appCompanionOverview(input,current) {
|
|
|
if(input.filter==='pending'){clauses.push('a."dszt"::numeric<30 AND COALESCE(c."status",99)<>-2');add(date+'<?',appOverviewToday());}
|
|
if(input.filter==='pending'){clauses.push('a."dszt"::numeric<30 AND COALESCE(c."status",99)<>-2');add(date+'<?',appOverviewToday());}
|
|
|
const where=clauses.join(' AND '),count=await Psql.one('SELECT COUNT(*)::int total'+join+' WHERE '+where,args);
|
|
const where=clauses.join(' AND '),count=await Psql.one('SELECT COUNT(*)::int total'+join+' WHERE '+where,args);
|
|
|
const rows=await Psql.query('SELECT c."generalId",c."title",c."createTime",c."status" AS "commonStatus",a.*,n."nodeName" AS "courseTitle"'+join+' LEFT JOIN "Node" n ON n."company"=a."company" AND n."nodeId"::text=a."kcid" WHERE '+where+' ORDER BY a."yysj" '+(history?'DESC':'ASC')+',a."id" DESC LIMIT $'+(args.length+1)+' OFFSET $'+(args.length+2),[...args,p.size,(p.index-1)*p.size]);
|
|
const rows=await Psql.query('SELECT c."generalId",c."title",c."createTime",c."status" AS "commonStatus",a.*,n."nodeName" AS "courseTitle"'+join+' LEFT JOIN "Node" n ON n."company"=a."company" AND n."nodeId"::text=a."kcid" WHERE '+where+' ORDER BY a."yysj" '+(history?'DESC':'ASC')+',a."id" DESC LIMIT $'+(args.length+1)+' OFFSET $'+(args.length+2),[...args,p.size,(p.index-1)*p.size]);
|
|
|
- const courses=coach?[]:await Psql.query('SELECT c."generalId",c."title",b.*,b."objectId" AS "bindingObjectId",n."nodeName" AS "courseTitle" FROM "CourseBinding" b JOIN "CommonModel" c ON c."company"=b."company" AND c."modelId"=58 AND c."itemId"=b."id" LEFT JOIN "Node" n ON n."company"=b."company" AND n."nodeId"::text=b."kcid" WHERE b."company"=$1 AND b."yhid"=$2 AND b."enrollmentStatus"=\'active\' AND c."status"=99 AND COALESCE(n."zstatus",99)=99 ORDER BY b."id" DESC',[DEFAULT_COMPANY_ID,String(uid)]);
|
|
|
|
|
|
|
+ const courses=coach?[]:await mobileReadableCourseBindings(uid);
|
|
|
const live=await appLiveVersionSnapshot(uid,['courses','appointments'],current);return {schedules:rows.map(appOverviewScheduleRow),courses:courses.map(appOverviewCourseRow),page:mobilePageMeta(count.total,p),dates,studentOptions,...mobileSource(),...live};
|
|
const live=await appLiveVersionSnapshot(uid,['courses','appointments'],current);return {schedules:rows.map(appOverviewScheduleRow),courses:courses.map(appOverviewCourseRow),page:mobilePageMeta(count.total,p),dates,studentOptions,...mobileSource(),...live};
|
|
|
}
|
|
}
|
|
|
async function appAccountOverview(input,current) {
|
|
async function appAccountOverview(input,current) {
|