643 lines
22 KiB
TypeScript
643 lines
22 KiB
TypeScript
import type { Fund, Id, Md, Work } from "../../src/eid/typ.ts"
|
||
import type { Pas, PasCode, Pos, PreUsr } from "../../src/pra/pos.ts"
|
||
import type { DocC, DocD, DocU } from "../../src/db.ts"
|
||
import type * as Q from "../../src/pra/que.ts"
|
||
import { is_aut, is_md, lim_aud, lim_aut, lim_lit, lim_md, lim_md_pin, lim_sup, lim_url, lim_wsl } from "../../src/eid/is.ts"
|
||
import { is_pre_usr, is_pro_usr, is_re, is_ref, is_rej, is_sec, is_uid } from "../../src/pra/con.ts"
|
||
import { nav, navhash, navnid, navpas } from "./nav.ts"
|
||
import { acct, btn, cover, goal, idnam, meta, putpro, putrel, re, rec as srec, rel, rolref, seladm, txt, ida, wsllit, label } from "./section.ts"
|
||
import { bind, main, pas_a, pos, PosB, que, utc_refresh } from "./template.ts"
|
||
import { is_actid, is_goal, is_img, is_msg, is_nam, is_nbr, is_url, } from "../../src/eid/is.ts"
|
||
import { utc_medium, utc_short } from "../../src/ont/utc.ts"
|
||
|
||
export function pas(
|
||
) {
|
||
if (nav.pas) { navhash(`${nav.pas.uid}`); return }
|
||
if (navhash("pas")) return
|
||
|
||
navnid()
|
||
main.innerHTML = ""
|
||
const t = bind("pas")
|
||
|
||
const send = async () => {
|
||
if (!is_nbr(t.nbr.value)) return alert("无效手机号")
|
||
t.nbr.readOnly = t.send.disabled = true
|
||
const sent = await pos<PasCode>("pas", { nbr: t.nbr.value, sms: location.hostname === "ismist.cn" })
|
||
if (sent) {
|
||
const utc = sent.utc ? `\n上次发送:${utc_medium(sent.utc)}` : ""
|
||
t.hint.innerText = `验证码已发送,可多次使用\n一小时内不再重复发送${utc}`
|
||
t.pas.classList.remove("none")
|
||
} else {
|
||
t.hint.innerText = `手机号未注册\n输入居住地与注册激活码\n激活码只能使用一次,确认手机号无误`
|
||
seladm(t)
|
||
t.adm.classList.remove("none")
|
||
t.pre.classList.remove("none")
|
||
}
|
||
}
|
||
t.send.addEventListener("click", send)
|
||
|
||
t.act.addEventListener("click", async () => {
|
||
if (!is_actid(t.actid.value)) return alert("无效激活码")
|
||
t.actid.readOnly = t.act.disabled = t.adm1.disabled = t.adm2.disabled = true
|
||
const uid = await pos<PreUsr>("pre", { actid: t.actid.value, nbr: t.nbr.value, adm1: t.adm1.value, adm2: t.adm2.value })
|
||
if (uid) {
|
||
await send()
|
||
t.pas.classList.remove("none")
|
||
} else {
|
||
t.actid.readOnly = t.act.disabled = t.adm1.disabled = t.adm2.disabled = false
|
||
alert("无效激活码")
|
||
}
|
||
})
|
||
|
||
t.issue.addEventListener("click", async () => {
|
||
if (!t.code.checkValidity()) return alert("无效验证码")
|
||
t.code.readOnly = t.issue.disabled = true
|
||
const p = await pos<Pas>("pas", { nbr: t.nbr.value, code: parseInt(t.code.value) })
|
||
if (!p) {
|
||
t.code.readOnly = t.issue.disabled = false
|
||
return alert("无效验证码")
|
||
}
|
||
navpas(p)
|
||
usr(p.uid)
|
||
})
|
||
|
||
main.append(t.bind)
|
||
|
||
}
|
||
|
||
export type Usr = Omit<NonNullable<Q.Usr>, "unam" | "snam" | "anam"> & {
|
||
unam: Map<Id["_id"], Id["nam"]>,
|
||
snam: Map<Id["_id"], Id["nam"]>,
|
||
anam: Map<Id["_id"], Id["nam"]>,
|
||
}
|
||
export async function usr(
|
||
uid: number
|
||
) {
|
||
if (navhash(`${uid}`)) return
|
||
|
||
const q = await que<Q.Usr>(`usr?uid=${uid}`)
|
||
if (!q) return idn(`${uid}`, "用户")
|
||
const u: Usr = { ...q, unam: new Map(q.unam), snam: new Map(q.snam), anam: new Map(q.anam) }
|
||
const froze = is_rej(u) && !(nav.pas && (nav.pas.uid === u._id || is_pre_usr(nav.pas)))
|
||
|
||
navnid()
|
||
main.innerHTML = ""
|
||
const t = bind("usr")
|
||
|
||
idnam(t, `${uid}`, froze ? "" : u.nam, meta(t, u, u.aut))
|
||
rolref(t.rolref, u)
|
||
re(t, u)
|
||
srec(t, "uid", u, froze)
|
||
|
||
if (froze) [t.nam, t.intro].forEach(el => el.classList.add("froze"))
|
||
else t.intro.innerText = u.intro
|
||
|
||
if (nav.pas) {
|
||
if (nav.pas.uid === uid) {
|
||
pas_a.innerText = u.nam
|
||
t.put.addEventListener("click", () => putid("用户", u))
|
||
t.pas.addEventListener("click", async () => {
|
||
await pos("pas", { uid: nav.pas!.uid })
|
||
navpas(null)
|
||
})
|
||
for (const a of ["aud", "aut"] as const) {
|
||
const el = t[`pre${a}`]
|
||
if (is_aut(nav.pas.aut, "sup")) el.addEventListener("click", () => put(`${uid}`, el.innerText, {
|
||
nam: { p1: "用户名:" }, val: {}, p: "pre",
|
||
b: p => p.p1 && is_nam(p.p1) ? { nam: p.p1, aut: a } : null,
|
||
a: "无效用户名,或已达上限",
|
||
r: async () => { await navpas(); aut() },
|
||
})); else el.remove()
|
||
}
|
||
if (is_aut(nav.pas.aut) || is_sec(nav.pas)) t.preusr.addEventListener("click", () => pre("用户"))
|
||
else t.preusr.remove()
|
||
if (is_aut(nav.pas.aut, "aut")) {
|
||
t.presoc.addEventListener("click", () => pre("小组"))
|
||
t.preagd.addEventListener("click", () => pre("活动"))
|
||
} else[t.presoc, t.preagd].forEach(el => el.remove())
|
||
t.prefund.addEventListener("click", () => put(`${uid}`, t.prefund.innerText, {
|
||
nam: { p1: `订单号:(6-${lim_url} 个字符)` }, val: {}, p: "pre",
|
||
b: p => p.p1 && is_actid(p.p1) ? { actid: p.p1 } : null,
|
||
a: "无效订单号,或订单号已被使用",
|
||
r: () => usr(uid)
|
||
}))
|
||
wsllit(t)
|
||
t.putpro.remove()
|
||
} else {
|
||
[t.pos, t.pre, t.wsllit].forEach(el => el.remove())
|
||
putpro(t, "uid", u, is_pro_usr(nav.pas, "rej", u._id) ? () => usr(u._id) : undefined)
|
||
}
|
||
} else[t.pos, t.pre, t.wsllit, t.putpro].forEach(el => el.remove())
|
||
|
||
main.append(t.bind)
|
||
}
|
||
|
||
function doc<T>(
|
||
q: "soc" | "agd",
|
||
adm: string,
|
||
) {
|
||
const [a1, a2] = (adm).split("-")
|
||
if (a2) {
|
||
navnid(q, a1, a2)
|
||
return que<T[]>(`${q}?adm2=${a2}`)
|
||
} else if (a1) {
|
||
navnid(q, a1)
|
||
return que<T[]>(`${q}?adm1=${a1}`)
|
||
} else {
|
||
navnid(q)
|
||
return que<T[]>(q)
|
||
}
|
||
}
|
||
|
||
export type Soc = Omit<NonNullable<Q.Soc>, "unam"> & {
|
||
unam: Map<Id["_id"], Id["nam"]>,
|
||
}
|
||
export async function soc(
|
||
sidadm?: number | string
|
||
) {
|
||
if (navhash(typeof sidadm === "number" ? `s${sidadm}` : `soc${sidadm ?? ""}`)) return
|
||
let ss: Q.Soc[]
|
||
if (typeof sidadm === "number") {
|
||
ss = [await que<Q.Soc>(`soc?sid=${sidadm}`)]
|
||
navnid()
|
||
} else ss = await doc<Q.Soc>("soc", sidadm ?? "")
|
||
|
||
ss = ss.filter(s => s)
|
||
if (typeof sidadm === "number" && ss.length === 0) return idn(`s${sidadm}`, "小组")
|
||
|
||
main.innerHTML = ""
|
||
for (const d of ss) {
|
||
if (!d) continue
|
||
|
||
const s: Soc = { ...d, unam: new Map(d.unam) }
|
||
const froze = s.rej.length > 0 && !(nav.pas && (is_sec(nav.pas, { sid: s._id }) || is_aut(nav.pas.aut)))
|
||
|
||
const t = bind("soc")
|
||
idnam(t, `s${s._id}`, s.nam, meta(t, s))
|
||
rel(t, s)
|
||
srec(t, "sid", s, froze)
|
||
|
||
if (froze) [t.nam, t.intro].forEach(el => el.classList.add("froze"))
|
||
else t.intro.innerText = s.intro
|
||
|
||
if (nav.pas) {
|
||
if (is_aut(nav.pas.aut, "aut") || is_sec(nav.pas, { sid: s._id }))
|
||
t.put.addEventListener("click", () => putid("小组", s))
|
||
else t.put.remove()
|
||
putrel(t, "sid", s, async () => { await navpas(); soc(s._id) })
|
||
if (is_aut(nav.pas.aut, "aud")) putpro(t, "sid", s, () => soc(s._id))
|
||
else t.putpro.remove()
|
||
} else {
|
||
t.pos.remove()
|
||
t.putrel.remove()
|
||
t.putpro.remove()
|
||
}
|
||
|
||
main.append(t.bind)
|
||
}
|
||
}
|
||
|
||
export type Agd = Omit<NonNullable<Q.Agd>, "unam"> & {
|
||
unam: Map<Id["_id"], Id["nam"]>,
|
||
}
|
||
export async function agd(
|
||
aidadm?: number | string
|
||
) {
|
||
if (navhash(typeof aidadm === "number" ? `a${aidadm}` : `agd${aidadm ?? ""}`)) return
|
||
let aa: Q.Agd[]
|
||
if (typeof aidadm === "number") {
|
||
aa = [await que<Q.Agd>(`agd?aid=${aidadm}`)]
|
||
navnid()
|
||
} else aa = await doc<Q.Agd>("agd", aidadm ?? "")
|
||
|
||
aa = aa.filter(a => a)
|
||
if (typeof aidadm === "number" && aa.length === 0) return idn(`a${aidadm}`, "活动")
|
||
|
||
main.innerHTML = ""
|
||
for (const d of aa) {
|
||
if (!d) continue
|
||
|
||
const a: Agd = { ...d, unam: new Map(d.unam) }
|
||
const froze = a.rej.length > 0 && !(nav.pas && (is_sec(nav.pas, { aid: a._id }) || is_aut(nav.pas.aut)))
|
||
|
||
const t = bind("agd")
|
||
idnam(t, `a${a._id}`, a.nam, meta(t, a))
|
||
rel(t, a)
|
||
cover(t, a)
|
||
acct(t, a)
|
||
goal(t.goal, a)
|
||
srec(t, "aid", a, froze)
|
||
|
||
if (froze) [t.nam, t.intro].forEach(el => el.classList.add("froze"))
|
||
else t.intro.innerText = a.intro
|
||
|
||
if (nav.pas) {
|
||
if (is_aut(nav.pas.aut, "aut") || is_sec(nav.pas, { aid: a._id }))
|
||
t.put.addEventListener("click", () => putid("活动", a))
|
||
else t.put.remove()
|
||
if (is_sec(nav.pas, { aid: a._id })) {
|
||
t.putimg.addEventListener("click", () => put(`a${a._id}`, t.putimg.innerText, {
|
||
nam: { p1: "图片名:(2-16 个中文字符)", p2: "图片外链:(最长 128 个字符,或留空以删除图片)" }, val: {}, p: "put",
|
||
b: p => {
|
||
if (!p.p1 || !is_nam(p.p1)) return null
|
||
let img = a.img.filter(m => m.nam !== p.p1)
|
||
if (p.p2 && p.p2.length > 0) img = [{ nam: p.p1, src: p.p2 }, ...img]
|
||
return is_img(img) ? { aid: a._id, img } : null
|
||
},
|
||
a: "无效输入,或图片数已达上限(9张)",
|
||
r: () => agd(a._id),
|
||
}))
|
||
t.putgoal.addEventListener("click", () => put(`a${a._id}`, t.putgoal.innerText, {
|
||
nam: { p1: "目标名:(2-16 个中文字符)", p2: "目标进度:(0- 100,或留空以删除目标)" }, val: {}, p: "put",
|
||
b: p => {
|
||
if (!p.p1 || !is_nam(p.p1)) return null
|
||
let g = a.goal.filter(m => m.nam !== p.p1)
|
||
if (p.p2 && p.p2.length > 0) g = [{ nam: p.p1, pct: parseInt(p.p2) }, ...g]
|
||
return is_goal(g) ? { aid: a._id, goal: g } : null
|
||
},
|
||
a: "无效输入,或目标数已达上限(9个)",
|
||
r: () => agd(a._id),
|
||
}))
|
||
t.prevideo.addEventListener("click", () => put(`a${a._id}`, t.prevideo.innerText, {
|
||
nam: { p1: "视频标题:(2-256 个字符)", p2: "视频外链:(最长 128 个字符)" }, val: {}, p: "pre",
|
||
b: p => {
|
||
if (!p.p1 || !p.p2 || !is_msg(p.p1) || !is_url(p.p2)) return null
|
||
return { aid: a._id, nam: p.p1, src: p.p2 }
|
||
},
|
||
a: "无效输入\n视频标题为 2-256 个字符\n视频外链最长 128 个字符",
|
||
r: () => agd(a._id),
|
||
}))
|
||
} else {
|
||
t.putimg.remove()
|
||
t.putgoal.remove()
|
||
t.prevideo.remove()
|
||
}
|
||
if (is_uid(nav.pas, { aid: a._id })) t.prework.addEventListener("click", () => put(`a${a._id}`, t.prework.innerText, {
|
||
nam: { pa: "工作日志" }, val: {}, p: "pre", b: p => {
|
||
if (!p.pa || !is_msg(p.pa)) return null
|
||
return { aid: a._id, msg: p.pa.trim() }
|
||
},
|
||
a: "无效输入\n工作日志为 2-256 个字符",
|
||
r: () => agd(a._id),
|
||
})); else t.prework.remove()
|
||
putrel(t, "aid", a, async () => { await navpas(); agd(a._id) })
|
||
if (is_aut(nav.pas.aut, "aud")) putpro(t, "aid", a, () => agd(a._id))
|
||
else t.putpro.remove()
|
||
} else {
|
||
t.pos.remove()
|
||
t.putrel.remove()
|
||
t.putpro.remove()
|
||
}
|
||
|
||
main.append(t.bind)
|
||
}
|
||
}
|
||
|
||
export type Rec = Omit<NonNullable<Q.Rec>, "unam" | "anam"> & {
|
||
unam: Map<Id["_id"], Id["nam"]>,
|
||
anam: Map<Id["_id"], Id["nam"]>,
|
||
}
|
||
|
||
export function rec(
|
||
c: "work" | "fund",
|
||
r: Rec,
|
||
d: Rec["rec"][0],
|
||
): DocumentFragment {
|
||
const t = bind("rec")
|
||
const aid = d._id.aid
|
||
t.unam.innerText = r.unam.get(d._id.uid)!
|
||
t.unam.href = `#${d._id.uid}`
|
||
t.anam.innerText = r.anam.get(aid)!
|
||
t.anam.href = `#a${aid}`
|
||
t.meta.innerText = utc_short(d._id.utc)
|
||
if (c === "work") {
|
||
const w = d as Work
|
||
const froze = !is_re(w) && !(nav.pas && (
|
||
w._id.uid === nav.pas.uid
|
||
|| is_sec(nav.pas, { aid }) || is_uid(nav.pas, { aid })
|
||
|| is_aut(nav.pas.aut, "aut")
|
||
))
|
||
if (is_rej(w)) {
|
||
t.meta.innerText += "(反对者达两名,不公示)";
|
||
[t.meta, t.msg].forEach(el => el.classList.add("rej2"))
|
||
} else if (!is_ref(w)) {
|
||
t.meta.innerText += "(推荐人未达两名,不公示)";
|
||
[t.meta, t.msg].forEach(el => el.classList.add("ref2"))
|
||
}
|
||
if (w.ref.length !== 0 && w._id.uid === nav.pas?.uid) t.meta.innerText += "(有推荐人,不可编辑)"
|
||
if (!froze) switch (w.work) {
|
||
case "work": {
|
||
t.msg.innerText = w.msg
|
||
break
|
||
} case "video": {
|
||
t.msg.innerText = "发布了视频:"
|
||
const a = t.msg.appendChild(document.createElement("a"))
|
||
a.innerText = w.nam
|
||
a.href = w.src
|
||
break
|
||
}
|
||
}
|
||
ida(t.rej, w.rej.map(uid => [`${uid}`, r.unam.get(uid)!]))
|
||
ida(t.ref, w.ref.map(uid => [`${uid}`, r.unam.get(uid)!]))
|
||
if (nav.pas) {
|
||
const refresh = async () => {
|
||
const q = await que<Q.Rec>(`rec?c=work&uid=${w._id.uid}&aid=${w._id.aid}&utc=${w._id.utc}`)
|
||
if (q) t.rec.replaceWith(rec(c, { ...q, unam: new Map(q.unam), anam: new Map(q.anam) }, q.rec[0]))
|
||
}
|
||
putpro(t, "workid", w, refresh)
|
||
if (!is_uid(nav.pas, { aid })) t.putrej.remove()
|
||
if (!is_sec(nav.pas, { aid })) t.putref.remove()
|
||
if (w.ref.length === 0 && w._id.uid === nav.pas.uid) {
|
||
const nam = w.work === "work" ? { pa: "工作日志" } : { p1: "视频标题:(2-256 个字符)", p2: "视频外链:(最长 128 个字符)" }
|
||
const val = w.work === "work" ? { pa: w.msg } : { p1: w.nam, p2: w.src }
|
||
const b = w.work === "work" ? (p: Put) => {
|
||
if (!p.pa || !is_msg(p.pa)) return null
|
||
return { workid: w._id, msg: p.pa.trim() }
|
||
} : (p: Put) => {
|
||
if (!p.p1 || !p.p2 || !is_msg(p.p1) || !is_url(p.p2)) return null
|
||
return { workid: w._id, nam: p.p1, src: p.p2 }
|
||
}
|
||
const a = w.work === "work" ? "无效输入\n工作日志为 2-256 个字符" : "无效输入\n视频标题为 2-256 个字符\n视频外链最长 128 个字符"
|
||
t.put.addEventListener("click", () => put(`a${w._id.aid}`, r.anam.get(w._id.aid)!, {
|
||
nam, val, p: "put", b, a,
|
||
d: () => pos("put", { workid: w._id }),
|
||
r: () => usr(w._id.uid)
|
||
}))
|
||
} else t.put.remove()
|
||
} else t.putpro.remove()
|
||
} else if (c === "fund") {
|
||
const f = d as Fund
|
||
const amount = f.fund > 0 ? `提供支持:+${f.fund}\n` : ""
|
||
t.msg.innerText = `${amount}${f.msg}`
|
||
t.re.remove()
|
||
}
|
||
return t.bind
|
||
}
|
||
|
||
export async function aut(
|
||
) {
|
||
if (navhash("aut")) return
|
||
const d = await que<Q.Aut>("aut")
|
||
const q = { ...d, unam: new Map(d.unam) }
|
||
const ht = (uid?: Usr["_id"][]) => uid ? uid.map(u => [`${u}`, q.unam.get(u)!] as [string, string]) : []
|
||
|
||
navnid()
|
||
main.innerHTML = ""
|
||
const t = bind("aut")
|
||
|
||
if (nav.pas && (["sup", "aud"] as const).some(a => is_aut(nav.pas!.aut, a))) {
|
||
label(t.sup, `(${q.aut.sup?.length ?? 0}/${lim_sup},不公示)`, true); ida(t.sup, ht(q.aut.sup))
|
||
label(t.aud, `(${q.aut.aud?.length ?? 0}/${lim_aud},不公示)`, true); ida(t.aud, ht(q.aut.aud))
|
||
} else[t.sup, t.aud].forEach(el => el.parentElement?.remove())
|
||
label(t.aut, `(${q.aut.aut?.length ?? 0}/${lim_aut})`, true); ida(t.aut, ht(q.aut.aut))
|
||
label(t.wsl, `(${q.aut.wsl?.length ?? 0}/${lim_wsl})`, true); ida(t.wsl, ht(q.aut.wsl))
|
||
label(t.lit, `(${q.aut.lit?.length ?? 0}/${lim_lit})`, true); ida(t.lit, ht(q.aut.lit))
|
||
|
||
main.append(t.bind)
|
||
}
|
||
|
||
export async function md(
|
||
c: "wsl" | "lit",
|
||
id: Md["_id"],
|
||
op: "one" | "many" | "continue",
|
||
) {
|
||
nav.cont = null
|
||
if (op === "one" && navhash(`${c}${id}`)) return
|
||
if ((op === "many" || op === "continue") && navhash(c)) return
|
||
const f = op === "one" ? "" : `&f`
|
||
const q = await que<Q.Md>(`md?${c}id=${id}${f}`)
|
||
|
||
if (op === "one" && (!q || q.md.length === 0)) return idn(`${c}${id}`, "文章")
|
||
if (op !== "continue") { navnid(); main.innerHTML = "" }
|
||
if (!q) return
|
||
|
||
const { marked } = await import("https://cdn.jsdelivr.net/npm/marked@latest/lib/marked.esm.js")
|
||
const unam = new Map(q.unam)
|
||
for (const m of q.md) {
|
||
const t = bind("md")
|
||
idnam(t, `${c}${m._id}`, `${m.nam}${m.pin ? "【置顶】" : ""}`)
|
||
t.utc.innerText = utc_medium(m.utc)
|
||
t.utcp.innerText = utc_medium(m.utcp)
|
||
ida(t.unam, [[`${m.uid}`, unam.get(m.uid)!]])
|
||
t.md.innerHTML = marked.parse(m.md)
|
||
if (op === "one") t.md.classList.add("full")
|
||
else setTimeout(() => {
|
||
if (t.md.scrollHeight > t.md.clientHeight) {
|
||
t.md.innerHTML += "<button>... 阅读全文</button>"
|
||
t.md.addEventListener("click", () => t.md.classList.add("full"))
|
||
} else t.md.classList.add("full")
|
||
}, 50)
|
||
if (nav.pas && m.uid === nav.pas.uid && is_aut(nav.pas.aut, c)) {
|
||
if (!is_rej(nav.pas)) {
|
||
t.put.addEventListener("click", () => put(
|
||
`${c}${m._id}`, "编辑文章", {
|
||
nam: { p1: "标题:(2-16个中文字符)", pa: "正文 Markdown" },
|
||
val: { p1: m.nam, pa: m.md }, lim_pa: lim_md, p: "put",
|
||
b: p => {
|
||
if (!p.p1 || !p.pa || !is_nam(p.p1) || !is_md(p.pa)) return null
|
||
return { [`${c}id`]: m._id, nam: p.p1, md: p.pa.trim() }
|
||
},
|
||
a: `无效输入\n标题为 2-16 个中文字符\n正文最长 ${lim_md} 个字符`,
|
||
d: () => pos<DocD>("put", { [`${c}id`]: m._id }),
|
||
r: r => r === undefined ? md(c, 0, "many") : md(c, m._id, "one"),
|
||
}))
|
||
btn(t.putpin, m.pin ? `取消置顶` : "置顶", {
|
||
pos: () => pos<DocU>("put", { [`${c}id`]: m._id, pin: !m.pin }),
|
||
refresh: () => md(c, 0, "many"),
|
||
alert: `最多置顶 ${lim_md_pin} 篇文章`,
|
||
})
|
||
} else[t.put, t.putpin].forEach(el => el.disabled = true)
|
||
} else[t.put, t.putpin].forEach(el => el.remove())
|
||
main.append(t.bind)
|
||
}
|
||
|
||
if (op !== "one") setTimeout(() => {
|
||
nav.cont = q.md.length === 0 ? null : () => md(c, q.md[q.md.length - 1]._id, "continue")
|
||
}, 100)
|
||
}
|
||
|
||
function pre(
|
||
nam: "用户" | "小组" | "活动",
|
||
) {
|
||
if (!nav.pas) return
|
||
navnid()
|
||
main.innerHTML = ""
|
||
const t = bind("pre")
|
||
|
||
idnam(t, `${nav.pas.uid}`, `添加${nam}`)
|
||
seladm(t)
|
||
|
||
// deno-lint-ignore no-explicit-any
|
||
let p: () => any
|
||
let r: (id: Id["_id"]) => void
|
||
switch (nam) {
|
||
case "用户": {
|
||
t.pnam.parentElement?.remove()
|
||
p = () => ({ nbr: t.nbr.value, adm1: t.adm1.value, adm2: t.adm2.value })
|
||
r = usr
|
||
break
|
||
} case "小组": {
|
||
t.nbr.parentElement?.remove()
|
||
p = () => ({ snam: t.pnam.value, adm1: t.adm1.value, adm2: t.adm2.value })
|
||
r = soc
|
||
break
|
||
} case "活动": {
|
||
t.nbr.parentElement?.remove()
|
||
p = () => ({ anam: t.pnam.value, adm1: t.adm1.value, adm2: t.adm2.value })
|
||
r = agd
|
||
break
|
||
}
|
||
}
|
||
|
||
btn(t.pre, t.pre.innerText, {
|
||
pos: () => pos<DocC<Id["_id"]>>("pre", p()),
|
||
alert: `无效输入\n或${nam === "用户" ? "手机号" : "名称"}已被占用`,
|
||
refresh: r,
|
||
})
|
||
t.cancel.addEventListener("click", () => usr(nav.pas!.uid))
|
||
|
||
main.append(t.bind)
|
||
}
|
||
|
||
export type Put = { p1?: string, p2?: string, pa?: string }
|
||
export function put(
|
||
id: string,
|
||
nam: string,
|
||
p: {
|
||
nam: Put,
|
||
val: Put,
|
||
lim_pa?: number,
|
||
p: Pos,
|
||
b: (p: Put) => PosB | null,
|
||
a: string,
|
||
d?: () => Promise<DocD>, // deno-lint-ignore no-explicit-any
|
||
r: (r?: any) => void,
|
||
}
|
||
) {
|
||
if (!nav.pas) return
|
||
|
||
main.innerHTML = ""
|
||
const t = bind("put")
|
||
|
||
idnam(t, id, nam)
|
||
if (p.nam.p1) { label(t.p1, p.nam.p1); t.p1.value = p.val.p1 ?? "" } else t.p1.parentElement!.remove()
|
||
if (p.nam.p2) { label(t.p2, p.nam.p2); t.p2.value = p.val.p2 ?? "" } else t.p2.parentElement!.remove()
|
||
if (p.lim_pa) t.pa.maxLength = p.lim_pa
|
||
if (p.nam.pa) txt(t.pa, p.nam.pa, p.val.pa ?? ""); else t.pa.parentElement!.remove()
|
||
if (p.d) t.putn.addEventListener("click", async () => {
|
||
if (!confirm("确认删除?")) return
|
||
await p.d!()
|
||
p.r()
|
||
}); else t.putn.remove()
|
||
t.put.addEventListener("click", async () => {
|
||
const b = p.b({
|
||
...p.nam.p1 ? { p1: t.p1.value } : {},
|
||
...p.nam.p2 ? { p2: t.p2.value } : {},
|
||
...p.nam.pa ? { pa: t.pa.value } : {},
|
||
})
|
||
if (b === null) return alert(p.a)
|
||
const r = await pos(p.p, b)
|
||
if (r === null) return alert(p.a)
|
||
setTimeout(() => p.r(r), utc_refresh)
|
||
})
|
||
t.cancel.addEventListener("click", () => p.r())
|
||
|
||
main.append(t.bind)
|
||
}
|
||
|
||
function putid(
|
||
nam: "用户" | "小组" | "活动",
|
||
id: Usr | Soc | Agd,
|
||
) {
|
||
if (!nav.pas) return
|
||
navnid()
|
||
main.innerHTML = ""
|
||
const t = bind("putid")
|
||
|
||
idnam(t, `${id._id}`, `编辑${nam}信息`)
|
||
t.pnam.value = id.nam
|
||
seladm(t, id.adm1, id.adm2)
|
||
txt(t.intro, "简介", id.intro)
|
||
|
||
const pid = () => ({ nam: t.pnam.value, adm1: t.adm1.value, adm2: t.adm2.value, })
|
||
const paut = () => ({ uidlim: parseInt(t.uidlim.value) })
|
||
const psoc = () => ({ intro: t.intro.value.trim(), reslim: parseInt(t.reslim.value) })
|
||
const pagd = () => ({
|
||
account: t.account.value.trim(), budget: parseInt(t.budget.value),
|
||
fund: parseInt(t.fund.value), expense: parseInt(t.expense.value)
|
||
}) // deno-lint-ignore no-explicit-any
|
||
let p: () => any[]
|
||
let r
|
||
switch (nam) {
|
||
case "用户": {
|
||
[t.uidlim, t.reslim, t.account, t.budget, t.fund, t.expense].forEach(el => el.parentElement?.remove())
|
||
t.meta.remove()
|
||
p = () => [{ uid: id._id, ...pid(), intro: t.intro.value.trim() }]
|
||
r = () => usr(id._id)
|
||
break
|
||
} case "小组": {
|
||
[t.account, t.budget, t.fund, t.expense].forEach(el => el.parentElement?.remove())
|
||
const s = id as Soc
|
||
t.uidlim.value = `${s.uidlim}`
|
||
t.reslim.value = `${s.reslim}`
|
||
const [isaut, issec] = [is_aut(nav.pas.aut, "aut"), is_sec(nav.pas, { sid: id._id })]
|
||
t.pnam.readOnly = t.adm1.disabled = t.adm2.disabled = t.uidlim.readOnly = !isaut
|
||
t.intro.readOnly = t.reslim.readOnly = !issec
|
||
p = () => [
|
||
...isaut ? [{ sid: id._id, ...pid(), ...paut() }] : [],
|
||
...issec ? [{ sid: id._id, ...psoc() }] : [],
|
||
]
|
||
r = () => soc(id._id)
|
||
break
|
||
} case "活动": {
|
||
const a = id as Agd
|
||
t.uidlim.value = `${a.uidlim}`
|
||
t.reslim.value = `${a.reslim}`
|
||
t.account.value = a.account
|
||
t.budget.value = `${a.budget}`
|
||
t.fund.value = `${a.fund}`
|
||
t.expense.value = `${a.expense}`
|
||
const [isaut, issec] = [is_aut(nav.pas.aut, "aut"), is_sec(nav.pas, { aid: id._id })]
|
||
t.pnam.readOnly = t.adm1.disabled = t.adm2.disabled = t.uidlim.readOnly = !isaut;
|
||
[t.intro, t.reslim, t.account, t.budget, t.fund, t.expense].forEach(el => el.readOnly = !issec)
|
||
p = () => [
|
||
...isaut ? [{ aid: id._id, ...pid(), ...paut() }] : [],
|
||
...issec ? [{ aid: id._id, ...psoc(), ...pagd() }] : [],
|
||
]
|
||
r = () => agd(id._id)
|
||
break
|
||
}
|
||
}
|
||
if (nam === "用户" || !is_aut(nav.pas.aut, "aut") || !is_re(nav.pas)) t.putn.remove()
|
||
else btn(t.putn, `删除${nam}`, {
|
||
confirm: `确认要删除${nam}?`,
|
||
pos: () => pos<DocD>("put", { [nam === "小组" ? "sid" : "aid"]: id._id }),
|
||
alert: `${nam === "小组" ? "小组仍有志愿者" : "活动仍有工作日志或支持记录"}`,
|
||
refresh: () => nam === "小组" ? soc() : agd(),
|
||
})
|
||
btn(t.put, t.put.innerText, {
|
||
pos: async () => {
|
||
const rs = await Promise.all(p().map(b => pos<DocU>("put", b)))
|
||
return rs.some(r => r === null) ? null : 1
|
||
},
|
||
alert: "无效输入\n或名称已被占用",
|
||
refresh: r,
|
||
})
|
||
t.cancel.addEventListener("click", r)
|
||
|
||
main.append(t.bind)
|
||
}
|
||
|
||
export function idn(
|
||
id: string, nam: string
|
||
) {
|
||
navnid()
|
||
main.innerHTML = ""
|
||
|
||
const t = bind("idn")
|
||
t.id.innerText = id
|
||
t.meta.innerText = `ismist#${id} 是无效${nam}`
|
||
|
||
main.append(t.bind)
|
||
}
|