Files
xh-medical-sign-web/clinical-web/scripts/login.cjs
T
yelan 81922d774f feat(文档库): 打通模板正文真实模式并新增渲染验证
模板列表接口不返回正文,展示、编辑与发起签署前需再取版本详情获取 contentHtml,
为此新增 getTemplateContent、createTemplateWithContent、updateTemplateContent 与
deleteTemplate(归档),并在签署端按 contentSha256 缓存正文快照。

同时新增 scripts/login.cjs 与 scripts/verify-pages.cjs,通过真实登录与 CDP
渲染截图、断言关键内容并收集运行时错误,并补充 .gitignore、eslint 忽略与文档说明。
2026-09-17 14:10:45 +08:00

106 lines
3.5 KiB
JavaScript
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.
/**
* 登录并保存会话,供页面渲染验证脚本复用。
*
* 为什么不 stub 接口:MEDISIGN 后端对无效 token 返回 401,
* utils/request.ts 的响应拦截器收到 401 会 clearAuthStorage() + 跳登录页,
* 伪造会话很容易被踢出去。走真实登录最省事。
*
* 验证码是强制的(不传会报「验证码错误或已过期」)。用法:
*
* node scripts/login.cjs # 第一步:抓验证码图片
* (用看图工具认出图片里的数字)
* node scripts/login.cjs 5274 # 第二步:带验证码登录,写 .session.json
*
* 结果写到 scripts/.session.json(已在 .gitignore 里,不会提交 token)。
*
* 文件用 .cjs 后缀:package.json 里的 "type": "module" 会把 .js 当 ES 模块,
* 而这里用 require 更简单,所以显式声明成 CommonJS。
*
* 依赖:Node 18+(内置 fetch)。无需额外安装依赖。
*/
const fs = require('fs')
const path = require('path')
const BASE_URL = process.env.VERIFY_BASE_URL || 'http://127.0.0.1:5173'
const USERNAME = process.env.VERIFY_USERNAME || 'admin'
const PASSWORD = process.env.VERIFY_PASSWORD || 'admin'
const OUT_DIR = __dirname
const CAPTCHA_JSON = path.join(OUT_DIR, '.captcha.json')
const CAPTCHA_PNG = path.join(OUT_DIR, '.captcha.png')
const SESSION_FILE = path.join(OUT_DIR, '.session.json')
async function fetchCaptcha() {
const res = await fetch(`${BASE_URL}/api/v1/auth/captcha`)
const json = await res.json()
if (json.code !== '0' && json.code !== 0) {
throw new Error('获取验证码失败: ' + json.message)
}
const { captchaId, imageBase64 } = json.data
fs.writeFileSync(CAPTCHA_JSON, JSON.stringify(json))
fs.writeFileSync(
CAPTCHA_PNG,
Buffer.from(String(imageBase64).replace(/^data:image\/\w+;base64,/, ''), 'base64'),
)
console.log('验证码已保存,请打开图片认出里面的数字:')
console.log(' ' + CAPTCHA_PNG)
console.log('captchaId = ' + captchaId)
console.log('')
console.log('然后执行: node scripts/login.cjs <识别出的数字>')
}
async function login(captchaCode) {
if (!fs.existsSync(CAPTCHA_JSON)) {
throw new Error('没有找到验证码,请先执行 node scripts/login.cjs 抓取验证码')
}
const { data } = JSON.parse(fs.readFileSync(CAPTCHA_JSON, 'utf8'))
const res = await fetch(`${BASE_URL}/api/v1/auth/login`, {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({
username: USERNAME,
password: PASSWORD,
captchaId: data.captchaId,
captchaCode,
}),
})
const json = await res.json()
if (json.code !== '0' && json.code !== 0) {
throw new Error(
'登录失败: ' + json.message + '(验证码可能已过期,重新执行 node scripts/login.cjs)',
)
}
fs.writeFileSync(SESSION_FILE, JSON.stringify(json.data, null, 2))
console.log('登录成功')
console.log(
' 用户 = ' + json.data.user.displayName + ' (' + json.data.user.username + ')',
)
console.log(' campusId = ' + json.data.user.campusId)
console.log(' dataScope = ' + json.data.user.dataScope)
console.log(' permissions = ' + json.data.user.permissions.length + ' 项')
console.log(' 会话已写入 ' + SESSION_FILE)
}
async function main() {
const captchaCode = process.argv[2]
if (captchaCode) {
await login(captchaCode.trim())
} else {
await fetchCaptcha()
}
}
main().catch((err) => {
console.error(err.message)
process.exit(1)
})