This commit is contained in:
728
2023-02-08 15:15:04 +08:00
parent 2706894fac
commit a0074e882e
4 changed files with 145 additions and 10 deletions

View File

@ -2,7 +2,7 @@ import { utc_etag } from "../ont/utc.ts"
import { pas, Pas, pas_clear, pas_code, pas_issue } from "./pas.ts"
import { pre_agd, pre_soc, pre_usr, pre_usract } from "./pre.ts"
import { is_re, pro_agd, pro_rec, pro_soc, pro_usr } from "./pro.ts"
import { put_usr } from "./put.ts"
import { put_soc, put_soc_res, put_soc_uid, put_usr } from "./put.ts"
// deno-lint-ignore no-explicit-any
type Ret<T extends (...args: any) => any> = Awaited<ReturnType<T>>
@ -75,9 +75,15 @@ export async function pos(
case "put": {
p.etag = utc_etag()
const { uid, sid, aid, nam, adm1, adm2, intro } = json
if (p.pas && typeof nam === "string" && typeof adm1 === "string" && typeof adm2 === "string" && typeof intro === "string")
const { uid, sid, aid, nam, adm1, adm2, intro, sec, uid_max, res, pro } = json
if (p.pas && typeof nam === "string" && typeof adm1 === "string" && typeof adm2 === "string" && typeof intro === "string") {
if (typeof uid === "number") return put_usr(p.pas, uid, { nam, adm1, adm2, intro })
else if (typeof sid === "number" && typeof sec === "object" && typeof uid_max === "number")
return put_soc(p.pas, sid, { nam, adm1, adm2, intro, sec, uid_max })
} else if (p.pas && typeof sid === "number" && (typeof res === "boolean" || typeof pro === "boolean")) {
if (typeof res === "boolean") return put_soc_res(p.pas, sid, res)
else if (typeof pro === "boolean" && typeof uid === "number") return put_soc_uid(p.pas, sid, uid, pro)
}
break
}
}

View File

@ -1,7 +1,9 @@
import { DocU } from "../db.ts"
import { Usr } from "../eid/typ.ts"
import { usr_u } from "../eid/usr.ts"
import { Pas } from "./pas.ts"
import { soc_r, soc_u } from "../eid/soc.ts"
import { Soc, Usr } from "../eid/typ.ts"
import { usr_r, usr_u } from "../eid/usr.ts"
import { not_aut, Pas } from "./pas.ts"
import { pre_soc } from "./pre.ts"
import { not_pro } from "./pro.ts"
export async function put_usr(
@ -9,6 +11,52 @@ export async function put_usr(
uid: Usr["_id"],
u: Pick<Usr, "nam" | "adm1" | "adm2" | "intro">
): DocU {
if (not_pro(pas) || pas.id.uid !== uid) return null
if (pas.id.uid !== uid) return null
return await usr_u(uid, { $set: u })
}
export async function put_soc(
pas: Pas,
sid: Soc["_id"],
s: Pick<Soc, "nam" | "adm1" | "adm2" | "intro" | "sec" | "uid_max">,
): DocU {
if (not_aut(pas, pre_soc.name) || not_pro(pas)) return null
return await soc_u(sid, { $set: s })
}
export async function put_soc_res(
pas: Pas,
sid: Soc["_id"],
res: boolean,
): DocU {
if (not_pro(pas)) return null
const s = await soc_r(sid, { uid: 1 })
if (!s || s.uid.includes(pas.id.uid)) return null
return await soc_u(sid, res
? { $addToSet: { res: pas.id.uid } }
: { $pull: { res: pas.id.uid } }
)
}
export async function put_soc_uid(
pas: Pas,
sid: Soc["_id"],
uid: Usr["_id"],
pro: boolean,
): DocU {
if (not_pro(pas)) return null
const [s, u] = await Promise.all([
soc_r(sid, { sec: 1, uid: 1, res: 1 }),
usr_r({ _id: uid }, { rej: 1, ref: 1 }),
])
if (!s || !u) return null
if (pro && s.res.includes(uid)
&& u.rej.length < 2
&& u.ref.filter(r => s.sec.includes(r)).length >= 2
&& s.sec.includes(pas.id.uid)
) return await soc_u(sid, { $addToSet: { uid }, $pull: { res: uid } })
if (!pro && (s.uid.includes(uid) && uid === pas.id.uid
|| s.res.includes(uid) && s.sec.includes(pas.id.uid)
)) return await soc_u(sid, { $pull: { uid, res: uid } })
return null
}

View File

@ -112,7 +112,7 @@ function idmeta(
} else if (pro === "ref") {
el.idnam_e.classList.add("green")
el.proc_e.classList.add("green")
}
} else el.proc_e.classList.add("gray")
el.adm_e.innerText = `${id.adm1} ${id.adm2}`
el.utc_e.innerText = `${utc_medium(id.utc)}`
@ -334,14 +334,20 @@ async function soc(
idnam_e, id_e, nam_e,
adm_e, utc_e, rej_e, ref_e, rejc_e, refc_e, proc_e,
sec_e, uid_e, res_e, intro_e, rec_e,
put_e, putpre_e, putsec_e, putuid_e, putres_e,
pro_e, prorej_e, proref_e,
]] = bind("soc", [
"idnam", "id", "nam",
"adm", "utc", "rej", "ref", "rejc", "refc", "proc",
"sec", "uid", "res", "intro", "rec",
"put", "putpre", "putsec", "putuid", "putres",
"pro", "prorej", "proref",
]) as [DocumentFragment, [
HTMLAnchorElement, HTMLElement, HTMLElement,
HTMLElement, HTMLElement, HTMLElement, HTMLElement, HTMLElement, HTMLElement, HTMLElement,
HTMLElement, HTMLElement, HTMLElement, HTMLElement, HTMLElement
HTMLElement, HTMLElement, HTMLElement, HTMLElement, HTMLElement,
HTMLElement, HTMLButtonElement, HTMLButtonElement, HTMLButtonElement, HTMLButtonElement,
HTMLElement, HTMLButtonElement, HTMLButtonElement,
]]
idnam_e.href = `#s${s._id}`
@ -357,7 +363,71 @@ async function soc(
intro_e.innerText = s.intro
rec_e.innerText = JSON.stringify(s.nrec)
} else {
nam_e.innerText = sec_e.innerText = uid_e.innerText = res_e.innerText = intro_e.innerText = rec_e.innerText = "【冻结中】"
sec_e.innerText = uid_e.innerText = res_e.innerText = intro_e.innerText = rec_e.innerText = "【冻结中】"
}
if (pas) {
if (not_aut(pas, "pre_soc")) putpre_e.remove()
else putpre_e.disabled = true
if (!s.sec.includes(pas.id.uid)) putsec_e.remove()
else putsec_e.disabled = true
if (!s.uid.includes(pas.id.uid)) putuid_e.remove()
else putuid_e.addEventListener("click", async () => {
if (confirm("退出社团?")) {
putuid_e.disabled = true
const r = await pos<DocU>("put", { sid: s._id, uid: pas!.id.uid, pro: false })
if (r && r > 0) {
const h = `s${s._id}`
if (hash === h) soc(s._id)
else location.href = `#${h}`
} else putuid_e.disabled = false
}
})
if (s.uid.includes(pas.id.uid)) putres_e.remove()
else {
const res = !s.res.includes(pas.id.uid)
putres_e.innerText = res ? "申请加入" : "取消申请"
if (!res || pub && s.res.length < s.res_max) putres_e.addEventListener("click", async () => {
putres_e.disabled = true
const r = await pos<DocU>("put", { sid: s._id, res })
if (r && r > 0) {
const h = `s${s._id}`
if (hash === h) soc(s._id)
else location.href = `#${h}`
} else putuid_e.disabled = false
}); else putres_e.disabled = true
}
if (not_aut(pas, "pro_soc")) pro_e.remove()
else {
const prorej = !s.rej.includes(pas.id.uid)
const proref = !s.ref.includes(pas.id.uid)
prorej_e.innerText = prorej ? "反对" : "取消反对"
proref_e.innerText = proref ? "推荐" : "取消推荐"
if (not_pro(pas)) prorej_e.disabled = proref_e.disabled = true
else {
prorej_e.addEventListener("click", async () => {
prorej_e.disabled = true
const r = await pos<DocU>("pro", { re: "rej", sid: s._id, pro: prorej })
if (r && r > 0) {
const h = `s${s._id}`
if (hash === h) soc(s._id)
else location.href = `#${h}`
} else prorej_e.disabled = false
})
proref_e.addEventListener("click", async () => {
proref_e.disabled = true
const r = await pos<DocU>("pro", { re: "ref", sid: s._id, pro: proref })
if (r && r > 0) {
const h = `s${s._id}`
if (hash === h) soc(s._id)
else location.href = `#${h}`
} else proref_e.disabled = false
})
}
}
} else {
put_e.remove()
pro_e.remove()
}
main.append(soc_t)

View File

@ -507,6 +507,17 @@
<p class="rec"></p>
</section>
<hr>
<section class="put flex">
<button class="putpre">编辑</button>
<button class="putsec">管理</button>
<button class="putuid">退出</button>
<button class="putres">申请加入</button>
</section>
<section class="pro flex">
<button class="prorej">反对</button>
<button class="proref">推荐</button>
</section>
<hr>
</article>
</template>