dst patch

This commit is contained in:
728
2023-06-02 18:42:24 +08:00
parent 650c90e134
commit bb4531f16e
9 changed files with 53 additions and 17 deletions

View File

@ -1,5 +1,5 @@
import type { Agd, Dst } from "./typ.ts"
import { DocC, DocR, DocU, coll } from "../db.ts"
import type { Agd, Dst, Usr } from "./typ.ts"
import { DocC, DocD, DocR, DocU, coll } from "../db.ts"
import { is_dstid, is_id, is_json, is_lim, lim_rd } from "./is.ts"
export async function dst_c(
@ -18,7 +18,7 @@ export async function dst_r(
}
export async function dst_f(
_id: { rd: Dst["_id"]["rd"], uid?: Agd["_id"] }
_id: { rd: Dst["_id"]["rd"], uid?: Usr["_id"] }
) {
if (!is_lim(_id.rd, lim_rd) || "uid" in _id && !is_id(_id.uid!)) return null
const f = {
@ -39,6 +39,19 @@ export async function dst_n(
return is_lim(_id.rd, lim_rd) ? await coll.dst.countDocuments(f) : null
}
export async function dst_a(
_id: Dst["_id"]
): DocU {
const d = await dst_r(_id)
try {
if (d) {
const { matchedCount, modifiedCount } = await coll.dst.updateOne({ _id }, { $inc: { dst: d.dst ? 1 : 2 } })
if (matchedCount > 0) return modifiedCount > 0 ? 1 : 0
else return null
} else return await dst_c({ _id, dst: 1 }) ? 1 : null
} catch { return null }
}
export async function dst_u(
rd: Dst["_id"]["rd"],
json: NonNullable<Dst["json"]>,
@ -51,3 +64,13 @@ export async function dst_u(
else return null
} catch { return null }
}
export async function dst_d(
_id: { rd: Dst["_id"]["rd"], uid: Usr["_id"] }
): DocD {
if (!is_lim(_id.rd, lim_rd) || !is_id(_id.uid)) return null
try {
const d = await coll.dst.deleteMany({ "_id.rd": _id.rd, "_id.uid": _id.uid })
return d > 0 ? 1 : 0
} catch { return null }
}

View File

@ -70,6 +70,7 @@ export type Fund = Rec & {
export type Dst = {
_id: { rd: number, aid?: Agd["_id"], uid?: Usr["_id"] },
json?: string,
dst?: number,
}
export type Aut = {

View File

@ -18,8 +18,9 @@ export type Pas = {
aut: Aut["aut"],
sid: Rol,
aid: Rol,
redst: boolean,
limdst: number,
dst: Agd["_id"][],
dst: [Agd["_id"], number][],
}
function limdst(
@ -45,8 +46,9 @@ async function pas_of_usr(
nam: u.nam,
aut: aut ? aut.aut : [],
sid, aid,
redst: dst ? dst.findIndex(d => d.dst === undefined) >= 0 : false,
limdst: limdst(fund.reduceRight((a, b) => a + b.unit, 0), work),
dst: dst ? dst.map(d => d._id.aid!) : [],
dst: dst ? dst.map(d => [d._id.aid!, d.dst ?? 1]) : [],
}
}

View File

@ -63,10 +63,13 @@ export async function pos(
if (typeof snam === "string") return pre_soc(p.pas, snam, adm1, adm2)
else if (typeof anam === "string") return pre_agd(p.pas, anam, adm1, adm2)
}
} else if (typeof rd === "number" && p.pas) {
if (typeof aid === "number" && typeof uid === "number") return pre_dst(p.pas, { rd, aid, uid })
else if (typeof aid === "number") return pre_dst(p.pas, { rd, aid })
else if (typeof uid === "number") return pre_dst(p.pas, { rd, uid })
} else if (typeof aid === "number") {
if (typeof nbr === "string" && typeof sms === "boolean" && typeof msg === "string") return pre_ord(nbr, aid, msg, sms)
else if (!p.pas) break
else if (typeof rd === "number") return pre_dst(p.pas, typeof uid === "number" ? { rd, aid, uid } : { rd, aid })
else if (typeof msg === "string") return pre_work(p.pas, aid, { msg })
else if (typeof nam === "string" && typeof src === "string") {
if (typeof utcs === "number" && typeof utce === "number")

View File

@ -1,7 +1,7 @@
import type { Act, Agd, Aut, Dst, Fund, Lit, Ord, Soc, Usr, Work, Wsl } from "../eid/typ.ts"
import type { Pas } from "./pas.ts"
import { is_pre_agd, is_pre_lit, is_pre_soc, is_pre_usr, is_pre_work, is_pre_wsl, is_pre_aut, is_pre_dst } from "./can.ts"
import { coll, DocC } from "../db.ts"
import { coll, DocC, DocU } from "../db.ts"
import { act_r, act_u } from "../eid/act.ts"
import { usr_c, usr_r, usr_u } from "../eid/usr.ts"
import { soc_c, soc_u } from "../eid/soc.ts"
@ -13,7 +13,7 @@ import { aut_c, aut_d, aut_g, aut_r, aut_u } from "../eid/aut.ts"
import { utc_d, utc_h, utc_week } from "../ont/utc.ts"
import { nord_f, ord_c, ord_d } from "../eid/ord.ts"
import { smssend } from "../ont/sms.ts"
import { dst_c } from "../eid/dst.ts"
import { dst_a, dst_c, dst_d } from "../eid/dst.ts"
export async function pre_usr(
pa: { pas: Pas } | { actid: Act["_id"] },
@ -133,9 +133,11 @@ export async function pre_fund(
export async function pre_dst(
pas: Pas,
dstid: Dst["_id"],
): DocC<Dst["_id"]> {
if (dstid.uid !== pas.uid && !is_pre_dst(pas)) return null
return await dst_c({ _id: dstid })
): DocU {
if (!dstid.uid && is_pre_dst(pas)) return await dst_c({ _id: dstid }) ? 1 : null
if (dstid.uid === pas.uid && pas.redst && !dstid.aid) return await dst_d({ rd: dstid.rd, uid: dstid.uid })
if (dstid.uid === pas.uid && is_id(dstid.aid!) && is_lim(pas.dst.reduceRight((a, b) => a + b[1], 1), pas.limdst)) return await dst_a(dstid)
return null
}
export async function pre_aut(

View File

@ -106,7 +106,7 @@ Deno.test("pre", async () => {
pos({ jwt }, "pre", json({ rd: lim_rd, aid: 1 })),
pos({ jwt }, "pre", json({ rd: lim_rd, aid: 2 })),
])
assertEquals([{ rd: lim_rd, aid: 1 }, { rd: lim_rd, aid: 2 }], dst)
assertEquals([1, 1], dst)
await Promise.all([
usr_d(1), usr_d(2), soc_d(1), agd_d(1),
...ord.filter(ordid => ordid !== null).map(ordid => ord_d(ordid!)),

View File

@ -586,7 +586,11 @@ export async function dst(
goal(t.goal, q.rd.goal.map((g, n) => ({ nam: `${g}\n${q.rd?.prize[n] ?? ""}`, pct: Math.round(100 * Math.min(1, q.rd!.sale / g)) })))
}
label(t.idl, `(共${q.dst.length}个)`, true)
ida(t.idl, q.dst.map(d => [`a${d.aid}`, `a${d.aid} ${q.anam.get(d.aid)}${d.ndst}票)` + (nav.pas && nav.pas?.dst.includes(d.aid) ? "(已投)" : "")]), "id")
ida(t.idl, q.dst.map(d => {
const n = nav.pas && nav.pas?.dst.find(t => t[0] === d.aid)
const c = n ? `(已投${n[1]}票)` : ""
return [`a${d.aid}`, `a${d.aid} ${q.anam.get(d.aid)}${d.ndst}票)${c}`]
}), "id")
if (nav.pas && is_aut(nav.pas.aut, "aut")) {
t.put.addEventListener("click", () => put("dst", t.put.innerText, {
@ -612,8 +616,9 @@ export async function dst(
}))
} else[t.put, t.preaid].forEach(el => el.remove())
if (nav.pas) {
if (nav.pas.dst.length < nav.pas.limdst) t.preuid.addEventListener("click", () => put("dst", "投票", {
if (nav.pas.dst.reduceRight((a, b) => a + b[1], 0) < nav.pas.limdst || nav.pas.redst) t.preuid.addEventListener("click", () => put("dst", "投票", {
nam: { p1: "参赛活动IDa1" }, val: {}, p: "pre", b: p => {
if (p.p1 === "dst") return { rd: lim_rd, uid: nav.pas!.uid }
const aid = parseInt(p.p1?.substring(1) ?? "")
if (q.dst.findIndex(d => d.aid === aid) < 0) return null
return { rd: lim_rd, aid, uid: nav.pas!.uid }

View File

@ -125,7 +125,7 @@ export function meta(
if ("dst" in t) {
if (nav.pas && nav.pas.uid === id._id)
t.dst.innerText = `\n\n票数${nav.pas.dst.length}/${nav.pas.limdst} (已投/可投)`
t.dst.innerText = `\n\n票数${nav.pas.dst.reduceRight((a, b) => a + b[1], 0)}/${nav.pas.limdst} (已投/可投)`
else t.dst.remove()
}
return cls

View File

@ -1,4 +1,4 @@
import type { Ord, Rec } from "../../src/eid/typ.ts"
import type { Dst, Ord, Rec } from "../../src/eid/typ.ts"
import type { Pos } from "../../src/pra/pos.ts"
import type { Agd } from "./article.ts"
@ -18,7 +18,7 @@ export async function que<T>(
return r.json() as T
}
export type PosB = Record<string, string | number | boolean | Agd["img"] | Agd["goal"] | Ord["_id"] | Rec["_id"]>
export type PosB = Record<string, string | number | boolean | Agd["img"] | Agd["goal"] | Ord["_id"] | Rec["_id"]> | Dst["_id"]
export async function pos<T>(
p: Pos,
b: PosB,