// 仅供本地视觉 QA:使用模拟认证服务,绝不调用真实修改密码接口。 // 运行:node scripts/tests/passwordDialogPreview.mjs import { createServer } from 'vite' import vue from '@vitejs/plugin-vue' import { fileURLToPath } from 'node:url' const root = fileURLToPath(new URL('../../', import.meta.url)) const previewEntry = ` import { createApp, h, ref } from 'vue' import { createI18n } from 'vue-i18n' import { ElButton, ElSelect, ElOption } from 'element-plus' import '/src/assets/styles/el-light.scss' import '/src/assets/styles/el-dark.scss' import '/src/assets/styles/el-ui.scss' import Dialog from '/src/components/core/layouts/art-header-bar/ChangePasswordDialog.vue' import zh from '/src/locales/langs/zh.json' import en from '/src/locales/langs/en.json' const i18n = createI18n({ legacy: false, locale: 'zh', messages: { zh, en } }) window.passwordPreviewRequests = [] window.passwordPreviewResult = 'success' createApp({ setup() { const visible = ref(false) const dark = ref(false) return () => h('main', { style: 'padding:24px;font-family:sans-serif' }, [ h('h2', '修改密码弹窗 · 离线验证'), h('p', '此页面不连接真实接口。密码输入仅用于本地模拟验证。'), h(ElButton, { onClick: () => visible.value = true }, () => '修改密码'), h(ElButton, { onClick: () => { dark.value = !dark.value document.documentElement.classList.toggle('dark', dark.value) } }, () => '切换主题'), h(ElButton, { onClick: () => { i18n.global.locale.value = i18n.global.locale.value === 'zh' ? 'en' : 'zh' } }, () => '切换语言'), h(ElSelect, { modelValue: window.passwordPreviewResult, 'onUpdate:modelValue': (value) => window.passwordPreviewResult = value, style: 'width:140px;margin-left:12px' }, () => ['success', 'error'].map(value => h(ElOption, { value, label: value }))), h(Dialog, { modelValue: visible.value, 'onUpdate:modelValue': value => visible.value = value }) ]) } }).use(i18n).mount('#app') ` const server = await createServer({ root, configFile: false, resolve: { alias: { '@': fileURLToPath(new URL('../../src', import.meta.url)), '@styles': fileURLToPath(new URL('../../src/assets/styles', import.meta.url)) } }, optimizeDeps: { noDiscovery: true, include: ['vue', 'element-plus', 'vue-i18n'] }, css: { preprocessorOptions: { scss: { additionalData: '@use "@styles/variables.scss" as *; @use "@styles/mixin.scss" as *;' } } }, server: { host: '127.0.0.1', port: 5198, strictPort: true }, plugins: [ { name: 'offline-password-preview', enforce: 'pre', resolveId(id) { if (id === '/__password-preview.js') return '\0password-preview-entry' if (id.endsWith('/api/modules/auth')) return '\0password-preview-auth' }, load(id) { if (id === '\0password-preview-entry') return previewEntry if (id === '\0password-preview-auth') { return `export const AuthService = { async changePassword(params) { window.passwordPreviewRequests.push(params) await new Promise(resolve => setTimeout(resolve, 500)) return window.passwordPreviewResult === 'error' ? { code: 1001, msg: '旧密码错误(模拟)' } : { code: 0, msg: 'ok' } } }` } }, configureServer(viteServer) { viteServer.middlewares.use((req, res, next) => { if (req.url !== '/') return next() res.setHeader('Content-Type', 'text/html; charset=utf-8') res.end( '