ismism/ismism.ts/ui/bind/article.ts
2023-03-21 20:59:45 +08:00

643 lines
22 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

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)
}