Compare commits
2 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 1360a44e01 | |||
| 86c05e71a2 |
@@ -1,5 +1,10 @@
|
|||||||
import { createApp } from 'vue'
|
import { createApp } from 'vue'
|
||||||
import '@/styles/main.css'
|
import '@/styles/main.css'
|
||||||
|
// 命令式调用的组件样式必须在这里显式引入:ElMessage / ElMessageBox 由函数调用触发,
|
||||||
|
// 不出现在任何模板里,ElementPlusResolver 的按需注入看不到它们。漏掉时弹窗没有定位
|
||||||
|
// 与遮罩样式,会渲染成普通块元素贴到文档左上角、与页头文字叠在一起。
|
||||||
|
import 'element-plus/es/components/message/style/css'
|
||||||
|
import 'element-plus/es/components/message-box/style/css'
|
||||||
|
|
||||||
import App from '@/App.vue'
|
import App from '@/App.vue'
|
||||||
import router from '@/router'
|
import router from '@/router'
|
||||||
|
|||||||
@@ -448,7 +448,9 @@ async function pushToPythonQueue() {
|
|||||||
// 后端返回的 groups 为空时推送出去,Python 端没有可执行批次会一直停在执行中
|
// 后端返回的 groups 为空时推送出去,Python 端没有可执行批次会一直停在执行中
|
||||||
const guard = checkQueuePayload(payload, {
|
const guard = checkQueuePayload(payload, {
|
||||||
expectedType: 'appearance-patent-run',
|
expectedType: 'appearance-patent-run',
|
||||||
requiredDataKeys: ['taskId', 'api_key'],
|
// api_key 不列为必填:密钥已服务端化,本地无明文时由服务端按 uid 兜底
|
||||||
|
// (Java AppearancePatentTaskService.readApiKey),列必填会把这类用户全部拦下
|
||||||
|
requiredDataKeys: ['taskId'],
|
||||||
nonEmptyArrayKeys: ['groups'],
|
nonEmptyArrayKeys: ['groups'],
|
||||||
})
|
})
|
||||||
if (!(await passGuard(guard))) return
|
if (!(await passGuard(guard))) return
|
||||||
|
|||||||
@@ -528,7 +528,9 @@ async function pushToPythonQueue() {
|
|||||||
// 入队前最后一道闸:缺字段或含 NaN 的 payload 到 Python 侧会变成 None,任务卡住
|
// 入队前最后一道闸:缺字段或含 NaN 的 payload 到 Python 侧会变成 None,任务卡住
|
||||||
const guard = checkQueuePayload(payload, {
|
const guard = checkQueuePayload(payload, {
|
||||||
expectedType: 'similar-asin-run',
|
expectedType: 'similar-asin-run',
|
||||||
requiredDataKeys: ['taskId', 'api_key', 'aliprice_usename', 'aliprice_pwd'],
|
// api_key 不列为必填:密钥已服务端化,本地无明文时由服务端按 uid 兜底
|
||||||
|
// (Java SimilarAsinPayloadSupport.readApiKey),列必填会把这类用户全部拦下
|
||||||
|
requiredDataKeys: ['taskId', 'aliprice_usename', 'aliprice_pwd'],
|
||||||
})
|
})
|
||||||
if (!(await passGuard(guard))) return
|
if (!(await passGuard(guard))) return
|
||||||
await activateSimilarAsinTask(taskId)
|
await activateSimilarAsinTask(taskId)
|
||||||
|
|||||||
@@ -0,0 +1,57 @@
|
|||||||
|
import { test } from 'node:test'
|
||||||
|
import assert from 'node:assert/strict'
|
||||||
|
import { readFileSync, readdirSync } from 'node:fs'
|
||||||
|
import { fileURLToPath } from 'node:url'
|
||||||
|
import { resolve, dirname } from 'node:path'
|
||||||
|
|
||||||
|
const here = dirname(fileURLToPath(import.meta.url))
|
||||||
|
const repoRoot = resolve(here, '..')
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Element Plus 组件名 → 按需样式目录(ElMessageBox → message-box)。
|
||||||
|
* 与 element-plus/es/components/<目录>/style/css 的目录名一致。
|
||||||
|
*/
|
||||||
|
function styleDirOf(component: string) {
|
||||||
|
return component.replace(/^El/, '').replace(/([a-z0-9])([A-Z])/g, '$1-$2').toLowerCase()
|
||||||
|
}
|
||||||
|
|
||||||
|
/** 扫 src 下所有「显式 from 'element-plus' 具名导入的 El* 组件」及其出处 */
|
||||||
|
function explicitElementPlusImports(): Map<string, string[]> {
|
||||||
|
const used = new Map<string, string[]>()
|
||||||
|
for (const file of readdirSync(resolve(repoRoot, 'src'), { recursive: true }) as string[]) {
|
||||||
|
if (!/\.(ts|vue)$/.test(file)) continue
|
||||||
|
const source = readFileSync(resolve(repoRoot, 'src', file), 'utf-8')
|
||||||
|
for (const match of source.matchAll(/import\s+(?!type\b)\{([^}]*)\}\s*from\s*['"]element-plus['"]/g)) {
|
||||||
|
for (const raw of match[1].split(',')) {
|
||||||
|
const name = raw.trim().split(/\s+as\s+/)[0].trim()
|
||||||
|
if (!/^El[A-Z]/.test(name)) continue
|
||||||
|
const files = used.get(name) || []
|
||||||
|
if (!files.includes(file)) files.push(file)
|
||||||
|
used.set(name, files)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return used
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 显式 import 的 EP 组件不会被 ElementPlusResolver 注入样式(resolver 只处理
|
||||||
|
* 模板里未解析的组件和自动导入的标识符),漏在入口引入样式就会出现
|
||||||
|
* 「弹窗跑到文档左上角、和页头文字叠在一起」这类无定位样式的故障。
|
||||||
|
*/
|
||||||
|
test('test_element_plus_explicit_imports_have_on_demand_style', () => {
|
||||||
|
const entry = readFileSync(resolve(repoRoot, 'src/main.ts'), 'utf-8')
|
||||||
|
// 锚定行首:注释掉的 import 不算数
|
||||||
|
const styleDirs = [
|
||||||
|
...entry.matchAll(/^import\s+['"]element-plus\/es\/components\/([\w-]+)\/style\/css['"]/gm),
|
||||||
|
].map((match) => match[1])
|
||||||
|
|
||||||
|
for (const [component, files] of explicitElementPlusImports()) {
|
||||||
|
const dir = styleDirOf(component)
|
||||||
|
assert.ok(
|
||||||
|
styleDirs.includes(dir),
|
||||||
|
`${component} 在 ${files.join('、')} 被显式 import,按需样式不会自动注入;` +
|
||||||
|
`请在 src/main.ts 增加 import 'element-plus/es/components/${dir}/style/css'`,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
})
|
||||||
Reference in New Issue
Block a user