20260911173133

This commit is contained in:
oneao committed 2026-09-11 17:31:34 +08:00
1 parent 3838ed74b1
commit f3ad727f1c
60 files changed
+4971 -6621

No files matched your search

@@ -1,21 +1,23 @@
/**
* 字段定义面板参与勾选接线测试:
* - 虚拟字段 __form/__list/__query 由配置草稿物化(内置 checkbox 的勾选态)
* - change 事件按列路由:参与列 → updateXxxConfig(携带 toggle 后的配置),普通列 → update(字段)
* - update 事件剥离 __ 虚拟字段,不污染字段草稿
* 字段定义面板参与勾选接线测试(V2:界面配置为 s_module_schema JSON):
* - 虚拟字段 __form/__list/__query 由 view/edit/query JSON 物化(内置 checkbox 的勾选态)
* - change 事件按列路由:参与列 → 对应配置 JSON(update:viewSchema/editSchema/querySchema),
* 普通列 → 字段模型(update:modelValue)
* - 字段派生虚拟字段在提交前由 stripInternalKeys 剥离,不污染保存
*/
import { mount } from '@vue/test-utils'
import { beforeAll, describe, expect, it, vi } from 'vitest'
import { beforeAll, describe, expect, it } from 'vitest'
import { createPinia, setActivePinia } from 'pinia'
import { nextTick } from 'vue'
import { registerFeature, useAreaSelection } from 'stk-table-vue'
import ModuleFieldsPanel from '@/views/module/module-management/components/ModuleFieldsPanel.vue'
import ModuleFieldsPanel from '@/views/module/module-management/ModuleFieldsPanel.vue'
import { stripInternalKeys } from '@/utils/dataChanges'
// 与 main.js 一致:注册 stk-table 的按需 feature
registerFeature(useAreaSelection)
// jsdom 无布局,容器 clientWidth 为 0 时 StkTable 走默认宽度并启用虚拟列裁剪,
// 只渲染首列——patch 成宽容器让全部列(含参与勾选列)真实渲染
// 只渲染首列——patch 成宽容器让全部列真实渲染
beforeAll(() => {
Object.defineProperty(HTMLElement.prototype, 'clientWidth', {
configurable: true,
@@ -25,45 +27,30 @@ beforeAll(() => {
})
})
vi.mock('@/services/api', () => ({
loadDataApi: vi.fn(),
saveObjectApi: vi.fn(),
nextIdApi: vi.fn(),
describeApi: vi.fn(),
}))
function makeFields() {
return [
{ b_field: 'amount', b_name: '金额', b_type: 'money', b_canuse: 1, b_i18n: null },
{ b_field: 'remark', b_name: '备注', b_type: 'textarea', b_canuse: 1, b_i18n: null },
]
}
const fields = [
{ b_id: '10', b_field: 'amount', b_name: '金额', b_type: 'money', b_canuse: 1, b_i18n: null },
{ b_id: '11', b_field: 'remark', b_name: '备注', b_type: 'textarea', b_canuse: 1, b_i18n: null },
]
const listConfig = [
{ b_id: 'v1', b_field_id: '10', b_visible: 1 },
{ b_id: 'v2', b_field_id: '11', b_visible: 0 }, // 大文本默认隐藏
]
const editConfig = [{ b_id: 'e1', b_field_id: '10', b_visible: 1 }]
const queryConfig = [] // 均未生成查询行
// 行内 checkbox 顺序 = 参与三列 + 启用列(普通编辑列不渲染 checkbox)
const FORM = 0
const LIST = 1
const QUERY = 2
function mountPanel(props = {}) {
return mount(ModuleFieldsPanel, {
function mountPanel() {
const localFields = makeFields()
const wrapper = mount(ModuleFieldsPanel, {
props: {
moduleId: 'm1',
moduleCode: 'demo',
fields: fields.map((f) => ({ ...f })),
editConfig: editConfig.map((r) => ({ ...r })),
listConfig: listConfig.map((r) => ({ ...r })),
queryConfig: queryConfig.map((r) => ({ ...r })),
moduleType: 'data',
modelValue: localFields,
// amount 已参与表单与列表;查询未配置
editSchema: { schemaVersion: 1, children: [{ field: 'amount', span: 24 }] },
viewSchema: { schemaVersion: 1, columns: [{ field: 'amount', width: 110 }] },
querySchema: { schemaVersion: 1, quick: [], groups: [] },
i18n: [],
module: { b_id: 'demo' },
loading: false,
...props,
},
attachTo: document.body,
})
return { wrapper, localFields }
}
async function settle() {
@@ -71,57 +58,64 @@ async function settle() {
await new Promise((r) => setTimeout(r, 100))
}
function rowCheckboxes(wrapper, rowIndex) {
return wrapper.findAll('.stk-tbody-main tr')[rowIndex].findAll('input[type="checkbox"]')
}
describe('ModuleFieldsPanel 参与勾选', () => {
it('虚拟字段按配置草稿物化:amount 表单/列表参与、查询未配置', async () => {
it('虚拟字段按配置 JSON 物化:amount 表单/列表参与、查询未配置', async () => {
setActivePinia(createPinia())
const wrapper = mountPanel()
const { wrapper, localFields } = mountPanel()
await settle()
const boxes = rowCheckboxes(wrapper, 0)
expect(boxes.length).toBe(4) // __form / __list / __query / b_canuse
expect(boxes[FORM].element.checked).toBe(true)
expect(boxes[LIST].element.checked).toBe(true)
expect(boxes[QUERY].element.checked).toBe(false)
expect(localFields[0].__form).toBe(1)
expect(localFields[0].__list).toBe(1)
expect(localFields[0].__query).toBe(0)
expect(localFields[1].__form).toBe(0)
wrapper.unmount()
})
it('勾选查询列 → emit updateQueryConfig,生成默认查询行(b_canuse=1)', async () => {
it('勾选查询列 → emit update:querySchema,生成默认查询条件', async () => {
setActivePinia(createPinia())
const wrapper = mountPanel()
await settle()
await rowCheckboxes(wrapper, 0)[QUERY].setValue(true)
const events = wrapper.emitted('updateQueryConfig')
expect(events).toHaveLength(1)
const rows = events[0][0]
expect(rows).toHaveLength(1)
expect(rows[0].b_field_id).toBe('10')
expect(rows[0].b_canuse).toBe(1)
expect(rows[0].b_component).toBe('number')
wrapper.unmount()
})
it('普通列 change → emit update,且剥离 __ 虚拟字段', async () => {
setActivePinia(createPinia())
const wrapper = mountPanel()
const { wrapper, localFields } = mountPanel()
await settle()
const table = wrapper.findComponent({ name: 'FmsTable' })
table.vm.$emit(
'change',
{ ...fields[0], __form: 1, __list: 1, __query: 0 },
{ dataIndex: 'b_name' },
'新名称',
)
table.vm.$emit('change', localFields[0], { dataIndex: '__query' })
await nextTick()
const events = wrapper.emitted('update')
expect(events).toBeTruthy()
const events = wrapper.emitted('update:querySchema')
expect(events?.length).toBeGreaterThan(0)
const schema = events.at(-1)[0]
const condition = schema.groups[0].conditions[0]
expect(condition.field).toBe('amount')
expect(condition.operator).toBe('eq')
expect(condition.component).toBe('number')
wrapper.unmount()
})
it('取消列表参与 → emit update:viewSchema 移除该字段节点', async () => {
setActivePinia(createPinia())
const { wrapper, localFields } = mountPanel()
await settle()
const table = wrapper.findComponent({ name: 'FmsTable' })
table.vm.$emit('change', localFields[0], { dataIndex: '__list' })
await nextTick()
const events = wrapper.emitted('update:viewSchema')
expect(events?.length).toBeGreaterThan(0)
const schema = events.at(-1)[0]
expect((schema.columns || []).map((n) => n.field)).not.toContain('amount')
wrapper.unmount()
})
it('普通列 change → emit update:modelValue,派生虚拟字段可由 stripInternalKeys 剥离', async () => {
setActivePinia(createPinia())
const { wrapper, localFields } = mountPanel()
await settle()
const table = wrapper.findComponent({ name: 'FmsTable' })
table.vm.$emit('change', localFields[0], { dataIndex: 'b_name' })
await nextTick()
const events = wrapper.emitted('update:modelValue')
expect(events?.length).toBeGreaterThan(0)
const emitted = events.at(-1)[0]
expect(emitted[0].b_id).toBe('10')
expect('__form' in emitted[0]).toBe(false)
expect('__list' in emitted[0]).toBe(false)
expect('__query' in emitted[0]).toBe(false)
expect(emitted[0].b_field).toBe('amount')
const stripped = stripInternalKeys(emitted[0])
expect('__form' in stripped).toBe(false)
expect('__list' in stripped).toBe(false)
expect('__query' in stripped).toBe(false)
wrapper.unmount()
})
})