member-credit-ledger.js 1.9 KB

1234567891011121314
  1. async function memberCreditPreview(context,input,payload){
  2. requireRole(context,['ops-manager']);const target=await memberTarget(context,input,text(input.objectId||input.targetId));
  3. return(await enrollmentSql('SELECT xs_credit_plan($1,$2,$3::jsonb) result',[pointerId(target.get('company')),target.id,JSON.stringify(payload)])).result;
  4. }
  5. async function memberLedger(context,input){
  6. const target=await memberTarget(context,input,text(input.objectId||input.targetId)),co=pointerId(target.get('company')),uid=number(target.get('legacyUserId'));
  7. const page=Math.max(1,Math.floor(number(input.page,1))),size=[20,50,100].includes(number(input.pageSize))?number(input.pageSize):20;
  8. const from=text(input.dateFrom),to=text(input.dateTo);for(const d of [from,to])if(d&&!/^\d{4}-\d{2}-\d{2}$/.test(d))fail(400,'日期格式无效');if(from&&to&&from>to)fail(400,'开始日期不能晚于结束日期');
  9. const result=await Psql.one(`WITH grouped AS (
  10. SELECT "groupId",max("happenedAt") at,jsonb_agg(to_jsonb(l) ORDER BY account,id) lines FROM xs_member_ledger l WHERE company=$1 AND "studentId"=$2 GROUP BY "groupId"
  11. ), filtered AS (SELECT * FROM grouped WHERE ($3='' OR EXISTS(SELECT 1 FROM jsonb_array_elements(lines) v WHERE v->>'account'=$3)) AND ($4='' OR EXISTS(SELECT 1 FROM jsonb_array_elements(lines) v WHERE v->>'kind'=$4)) AND ($5='' OR at>=NULLIF($5,'')::date::timestamp AT TIME ZONE 'Asia/Shanghai') AND ($6='' OR at<(NULLIF($6,'')::date+1)::timestamp AT TIME ZONE 'Asia/Shanghai'))
  12. SELECT (SELECT md5(COALESCE(string_agg(lines::text,'' ORDER BY "groupId"),'')) FROM filtered) version,(SELECT count(*)::int FROM filtered) total,COALESCE((SELECT jsonb_agg(to_jsonb(p)) FROM (SELECT * FROM filtered ORDER BY at DESC NULLS LAST,"groupId" DESC LIMIT $7 OFFSET $8) p),'[]') items`,[co,uid,text(input.account),text(input.kind),from,to,size,(page-1)*size]);
  13. return{...result,page,pageSize:size};
  14. }