This commit is contained in:
728
2023-02-07 16:28:41 +08:00
parent 4d0aabece7
commit dd21ad4135
7 changed files with 145 additions and 70 deletions

View File

@ -17,7 +17,7 @@ const [uid1] = await Promise.all([
exp: new Date("2023-06-31").getTime(),
act: "usrnbr", uid: 1
}),
aut_c({ _id: 1, p: ["pre_usr", "pro_usr", "pro_soc", "pro_agd"] })
aut_c({ _id: 1, p: ["pre_usr", "pre_soc", "pre_agd", "pro_usr", "pro_soc", "pro_agd"] })
])
const [uid2] = await Promise.all([
usr_c("11111111112", [1, 2], "江苏", "苏州"),
@ -26,7 +26,7 @@ const [uid2] = await Promise.all([
exp: new Date("2023-06-31").getTime(),
act: "usrnbr", uid: 2
}),
aut_c({ _id: 2, p: ["pre_usr", "pro_usr", "pro_soc", "pro_agd"] })
aut_c({ _id: 2, p: ["pre_usr", "pre_soc", "pre_agd", "pro_usr", "pro_soc", "pro_agd"] })
])
await Promise.all([
usr_u(uid1!, { $set: { nam: "未明子" } }),

View File

@ -27,7 +27,7 @@ export function not_nam(
export function is_intro(
intro?: null | Id["intro"]
) {
return typeof intro === "string" && intro.length <= 4096
return typeof intro === "string" && intro.length <= 2048
}
export function not_intro(
intro?: null | Id["intro"]

View File

@ -1,6 +1,6 @@
import { utc_etag } from "../ont/utc.ts"
import { pas, Pas, pas_clear, pas_code, pas_issue } from "./pas.ts"
import { pre_usr, pre_usract } from "./pre.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"
@ -50,10 +50,15 @@ export async function pos(
case "pre": {
p.etag = utc_etag()
const { actid, nbr, adm1, adm2 } = json
if (typeof nbr === "string" && typeof adm1 === "string" && typeof adm2 === "string")
if (typeof actid === "string") return pre_usract(actid, nbr, adm1, adm2)
else if (p.pas) return pre_usr(p.pas, nbr, adm1, adm2)
const { actid, nbr, snam, anam, adm1, adm2, intro } = json
if (typeof adm1 === "string" && typeof adm2 === "string")
if (typeof nbr === "string") {
if (typeof actid === "string") return pre_usract(actid, nbr, adm1, adm2)
else if (p.pas) return pre_usr(p.pas, nbr, adm1, adm2)
} else if (p.pas && typeof intro == "string") {
if (typeof snam === "string") return pre_soc(p.pas, snam, adm1, adm2, intro)
else if (typeof anam === "string") return pre_agd(p.pas, anam, adm1, adm2, intro)
}
break
}

View File

@ -1,10 +1,12 @@
import { Act, Usr } from "../eid/typ.ts"
import { Act, Soc, Usr, Agd } from "../eid/typ.ts"
import { act_u, act_r } from "../eid/act.ts"
import { usr_c, usr_u } from "../eid/usr.ts"
import { is_id } from "../eid/id.ts"
import { DocC } from "../db.ts"
import { not_aut, Pas } from "./pas.ts"
import { not_pro } from "./pro.ts"
import { soc_c } from "../eid/soc.ts"
import { agd_c } from "../eid/agd.ts"
export async function pre_usract(
actid: Act["_id"],
@ -38,3 +40,23 @@ export async function pre_usr(
if (not_aut(pas, pre_usr.name) || not_pro(pas)) return null
return await usr_c(nbr, [pas.id.uid], adm1, adm2)
}
export async function pre_soc(
pas: Pas,
nam: Soc["nam"],
adm1: string,
adm2: string,
intro: string,
): DocC<Soc["_id"]> {
if (not_aut(pas, pre_soc.name) || not_pro(pas)) return null
return await soc_c(nam, [pas.id.uid], adm1, adm2, intro)
}
export async function pre_agd(
pas: Pas,
nam: Agd["nam"],
adm1: string,
adm2: string,
intro: string,
): DocC<Soc["_id"]> {
if (not_aut(pas, pre_agd.name) || not_pro(pas)) return null
return await agd_c(nam, [pas.id.uid], adm1, adm2, intro)
}

View File

@ -1,6 +1,6 @@
// deno-lint-ignore-file no-window-prefix
import type { DocC, DocU } from "../src/db.ts"
import type { Aut } from "../src/eid/typ.ts"
import type { Aut, Id } from "../src/eid/typ.ts"
import { adm, adm1_def, adm2_def } from "../src/ont/adm.ts"
import { utc_medium } from "../src/ont/utc.ts"
import type { Pas } from "../src/pra/pas.ts"
@ -91,15 +91,15 @@ function idanchor(
})
}
function paspre(
function pasact(
) {
const [paspre_t, [
const [pasact_t, [
nbr_e, send_e,
adm_e, adm1_e, adm2_e,
pre_e, actid_e, act_e,
pas_e, code_e, issue_e,
hint_e,
]] = bind("paspre", [
]] = bind("pasact", [
"nbr", "send",
"adm", "adm1", "adm2",
"pre", "actid", "act",
@ -164,7 +164,7 @@ function paspre(
})
})
main.append(paspre_t)
main.append(pasact_t)
}
async function usr(
@ -185,7 +185,8 @@ async function usr(
intro_e,
soc_e,
rec_e,
pos_e, put_e, pas_e, preusr_e,
pos_e, put_e, pas_e,
pre_e, preusr_e, presoc_e, preagd_e,
pro_e, prorej_e, proref_e,
]] = bind("usr", [
"idnam", "id", "nam",
@ -193,7 +194,8 @@ async function usr(
"intro",
"soc",
"rec",
"pos", "put", "pas", "preusr",
"pos", "put", "pas",
"pre", "preusr", "presoc", "preagd",
"pro", "prorej", "proref",
]) as [DocumentFragment, [
HTMLAnchorElement, HTMLElement, HTMLElement,
@ -201,6 +203,7 @@ async function usr(
HTMLParagraphElement,
HTMLParagraphElement,
HTMLElement,
HTMLElement, HTMLButtonElement, HTMLButtonElement,
HTMLElement, HTMLButtonElement, HTMLButtonElement, HTMLButtonElement,
HTMLElement, HTMLButtonElement, HTMLButtonElement,
]]
@ -233,7 +236,7 @@ async function usr(
if (pas) {
if (pas.id.uid === uid) {
pos_e.classList.remove("none")
pro_e.remove()
put_e.addEventListener("click", () => putusr(u))
pas_e.addEventListener("click", async () => {
await pos("pas", { uid })
@ -243,80 +246,113 @@ async function usr(
location.href = `#pas`
})
if (not_aut(pas, "pre_usr")) preusr_e.remove()
else preusr_e.addEventListener("click", preusr)
} else pos_e.classList.add("none")
const prorej = !u.rej.includes(pas.id.uid)
const proref = !u.ref.includes(pas.id.uid)
prorej_e.innerText = prorej ? "反对" : "取消反对"
proref_e.innerText = proref ? "推荐" : "取消推荐"
if (not_aut(pas, "pro_usr") || not_pro(pas) || pas.ref.includes(uid)) {
prorej_e.disabled = true
proref_e.disabled = true
else preusr_e.addEventListener("click", () => pre("创建用户"))
if (not_aut(pas, "pre_soc")) presoc_e.remove()
else presoc_e.addEventListener("click", () => pre("创建社团"))
if (not_aut(pas, "pre_agd")) preagd_e.remove()
else preagd_e.addEventListener("click", () => pre("创建活动"))
} else {
prorej_e.addEventListener("click", async () => {
pos_e.remove()
pre_e.remove()
const prorej = !u.rej.includes(pas.id.uid)
const proref = !u.ref.includes(pas.id.uid)
prorej_e.innerText = prorej ? "反对" : "取消反对"
proref_e.innerText = proref ? "推荐" : "取消推荐"
if (not_aut(pas, "pro_usr") || not_pro(pas) || pas.ref.includes(uid)) {
prorej_e.disabled = true
const c = await pos<DocU>("pro", { re: "rej", uid, pro: prorej })
if (c && c > 0) setTimeout(() => usr(uid), 500)
else prorej_e.disabled = false
})
proref_e.addEventListener("click", async () => {
proref_e.disabled = true
const c = await pos<DocU>("pro", { re: "ref", uid, pro: proref })
if (c && c > 0) setTimeout(() => usr(uid), 500)
else proref_e.disabled = false
})
} else {
prorej_e.addEventListener("click", async () => {
prorej_e.disabled = true
const c = await pos<DocU>("pro", { re: "rej", uid, pro: prorej })
if (c && c > 0) setTimeout(() => usr(uid), 500)
else prorej_e.disabled = false
})
proref_e.addEventListener("click", async () => {
proref_e.disabled = true
const c = await pos<DocU>("pro", { re: "ref", uid, pro: proref })
if (c && c > 0) setTimeout(() => usr(uid), 500)
else proref_e.disabled = false
})
}
}
} else {
pos_e.classList.add("none")
pro_e.classList.add("none")
pos_e.remove()
pre_e.remove()
pro_e.remove()
}
main.append(usr_t)
}
function preusr(
function pre(
nam: "创建用户" | "创建社团" | "创建活动"
) {
if (!pas) { location.href = `#paspre`; return }
if (!pas) { location.href = `#pasact`; return }
main.innerHTML = ""
const [preusr_t, [
idnam_e, id_e,
adm1_e, adm2_e, nbr_e,
const [pre_t, [
idnam_e, id_e, nam_e,
meta_e, pnam_e, nbr_e,
adm1_e, adm2_e, intro_e,
pre_e, cancel_e,
]] = bind("preusr", [
"idnam", "id",
"adm1", "adm2", "nbr",
]] = bind("pre", [
"idnam", "id", "nam",
"meta", "pnam", "nbr",
"adm1", "adm2", "intro",
"pre", "cancel",
]) as [DocumentFragment, [
HTMLAnchorElement, HTMLElement,
HTMLSelectElement, HTMLSelectElement, HTMLInputElement,
HTMLAnchorElement, HTMLElement, HTMLElement,
HTMLElement, HTMLInputElement, HTMLInputElement,
HTMLSelectElement, HTMLSelectElement, HTMLTextAreaElement,
HTMLButtonElement, HTMLButtonElement,
]]
idnam_e.href = `#${pas.id.uid}`
id_e.innerText = `${pas.id.uid}`
nam_e.innerText = nam
meta_e.innerText = `将作为推荐人${nam}`
selopt(adm1_e, adm.keys())
adm1_e.value = adm1_def
selopt(adm2_e, adm.get(adm1_def)!)
adm2_e.value = adm2_def
adm1_e.addEventListener("change", () => selopt(adm2_e, adm.get(adm1_e.value)!))
let param: () => Record<string, string>
let pf = ""
switch (nam) {
case "创建用户": {
meta_e.innerText += `\n新用户可通过手机号登录、编辑用户信息`
pnam_e.parentElement?.remove()
intro_e.parentElement?.remove()
param = () => ({ nbr: nbr_e.value, adm1: adm1_e.value, adm2: adm2_e.value })
break
} case "创建社团": case "创建活动": {
nbr_e.parentElement?.remove()
intro_e.addEventListener("input", () => {
intro_e.style.height = "auto"
intro_e.style.height = `${intro_e.scrollHeight}px`;
(intro_e.previousElementSibling as HTMLElement).innerText = `简介:(${intro_e.value.length} / 2048 个字符)`
})
param = () => ({
...nam === "创建社团" ? { snam: pnam_e.value } : { anam: pnam_e.value },
adm1: adm1_e.value, adm2: adm2_e.value, intro: intro_e.value
})
pf = nam === "创建社团" ? "s" : "a"
break
} default: { usr(pas.id.uid); return }
}
pre_e.addEventListener("click", async () => {
if (!/^1\d{10}$/.test(nbr_e.value)) { alert("无效手机号"); return }
pre_e.disabled = nbr_e.readOnly = adm1_e.disabled = adm2_e.disabled = true
const c = await pos<DocC<NonNullable<Usr>["_id"]>>("pre", {
nbr: nbr_e.value, adm1: adm1_e.value, adm2: adm2_e.value
})
if (c) usr(c)
else {
alert("创建用户失败")
pre_e.disabled = nbr_e.readOnly = adm1_e.disabled = adm2_e.disabled = false
}
const id = await pos<DocC<Id["_id"]>>("pre", param())
if (id) setTimeout(() => location.hash = `#${pf}${id}`, 500)
else alert(`${nam}失败`)
})
cancel_e.addEventListener("click", () => usr(pas!.id.uid))
main.append(preusr_t)
main.append(pre_t)
}
function putusr(
@ -396,8 +432,10 @@ function idnull(
window.addEventListener("hashchange", () => {
hash = decodeURI(window.location.hash).substring(1)
main.innerHTML = ""
if (hash === "pas") paspre()
if (hash === "pas") pasact()
else if (/^\d+$/.test(hash)) usr(parseInt(hash))
else if (hash.startsWith("s")) que("soc").then(s => main.innerText = JSON.stringify(s))
else if (hash.startsWith("a")) que("agd").then(a => main.innerText = JSON.stringify(a))
})
async function load(

View File

@ -375,7 +375,7 @@
</style>
<template id="paspre">
<template id="pasact">
<article>
<section>
<a class="idnam"><code class="id active">pas</code> <span class="nam">用户登录与激活</span></a>
@ -388,7 +388,7 @@
<button class="send">发送验证码</button>
</section>
<section class="flex adm none">
<label>居住地:</label>
<label>居住地</label>
<select class="adm1"></select>
<select class="adm2"></select>
</section>
@ -442,7 +442,11 @@
<section class="pos flex">
<button class="put">编辑</button>
<button class="pas">登出</button>
</section>
<section class="pre flex">
<button class="preusr">创建用户</button>
<button class="presoc">创建社团</button>
<button class="preagd">创建活动</button>
</section>
<section class="pro flex">
<button class="prorej">反对</button>
@ -452,15 +456,17 @@
</article>
</template>
<template id="preusr">
<template id="pre">
<article>
<section>
<a class="idnam"><code class="id active"></code> <span>创建用户</span></a>
<a class="idnam"><code class="id active"></code> <span class="nam"></span></a>
</section>
<hr>
<section class="meta">
你将作为推荐人创建用户<br>
新用户可通过下列手机号登录,编辑用户信息
<section class="meta"></section>
<hr>
<section class="flex">
<label>名称2-16个中文字符不能重复</label>
<input class="pnam" type="text" maxlength="16" required />
</section>
<section class="flex">
<label>手机号:</label>
@ -468,10 +474,14 @@
minlength="11" maxlength="11" required />
</section>
<section class="flex">
<label>居住地:</label>
<label></label>
<select class="adm1"></select>
<select class="adm2"></select>
</section>
<section>
<label>简介0 / 2048 个字符)</label>
<textarea class="intro" maxlength="2048"></textarea>
</section>
<hr>
<section class="flex">
<button class="pre">确认</button>
@ -492,7 +502,7 @@
<input class="nam" type="text" maxlength="16" required />
</section>
<section class="flex adm">
<label>居住地:</label>
<label>居住地</label>
<select class="adm1"></select>
<select class="adm2"></select>
</section>

View File

@ -165,7 +165,7 @@ http {
proxy_busy_buffers_size 256k;
proxy_cache cache;
proxy_cache_methods GET;
proxy_cache_valid any 100ms;
proxy_cache_valid any 1s;
proxy_cache_revalidate on;
proxy_cache_background_update on;
proxy_cache_lock on;