1
This commit is contained in:
parent
32fffa4f89
commit
3dce3646e1
Binary file not shown.
|
Before Width: | Height: | Size: 107 KiB |
Binary file not shown.
|
Before Width: | Height: | Size: 86 KiB |
Binary file not shown.
|
Before Width: | Height: | Size: 86 KiB |
@ -8,6 +8,8 @@ import type {
|
||||
GridApi,
|
||||
GridReadyEvent,
|
||||
ICellRendererParams,
|
||||
IGroupCellRendererParams,
|
||||
IRowNode,
|
||||
ValueFormatterParams
|
||||
} from 'ag-grid-community'
|
||||
import { AG_GRID_LOCALE_CN } from '@ag-grid-community/locale'
|
||||
@ -74,21 +76,19 @@ const groupedServiceGroups = ref<string[]>([])
|
||||
const syncGroupedRowsRender = async () => {
|
||||
await nextTick()
|
||||
const api = gridApi.value
|
||||
if (!api) return
|
||||
if (!api || api.isDestroyed?.()) return
|
||||
if (isWholeProcessGroupedMode.value) {
|
||||
api.expandAll()
|
||||
}
|
||||
api.refreshClientSideRowModel('group')
|
||||
api.resetRowHeights()
|
||||
api.refreshCells({ force: true })
|
||||
api.redrawRows()
|
||||
setTimeout(() => {
|
||||
const liveApi = gridApi.value
|
||||
if (!liveApi) return
|
||||
if (!liveApi || liveApi.isDestroyed?.()) return
|
||||
if (isWholeProcessGroupedMode.value) {
|
||||
liveApi.expandAll()
|
||||
}
|
||||
liveApi.resetRowHeights()
|
||||
liveApi.refreshCells({ force: true })
|
||||
liveApi.redrawRows()
|
||||
}, 16)
|
||||
@ -100,6 +100,15 @@ const toServiceId = (value: unknown): number | null => {
|
||||
return parsed
|
||||
}
|
||||
|
||||
const getDictRowMergeKey = (row: Pick<WorkContentRow, 'content' | 'serviceid' | 'serviceGroup'>) => {
|
||||
const content = String(row.content || '').trim()
|
||||
const serviceid = toServiceId(row.serviceid)
|
||||
if (serviceid != null) return `sid:${serviceid}|content:${content}`
|
||||
const groupName = String(row.serviceGroup || '').trim()
|
||||
if (groupName) return `group:${groupName}|content:${content}`
|
||||
return `content:${content}`
|
||||
}
|
||||
|
||||
|
||||
|
||||
const loadProjectIndustryId = async () => {
|
||||
@ -156,17 +165,7 @@ const buildDefaultRowsFromDict = async (): Promise<WorkContentRow[]> => {
|
||||
} else {
|
||||
filtered = entries.filter(e => e.serviceid === sid)
|
||||
}
|
||||
console.log('[WorkContentGrid][init-group]', {
|
||||
storageKey: props.storageKey,
|
||||
dictMode: props.dictMode,
|
||||
serviceId: sid,
|
||||
industryId,
|
||||
groupedBy,
|
||||
matchedWholeProcessGroup,
|
||||
groupedServiceIds,
|
||||
groupedEnabled: isWholeProcessGroupedMode.value,
|
||||
filteredCount: filtered.length
|
||||
})
|
||||
|
||||
} else if (props.dictMode === 'additional') {
|
||||
filtered = entries.filter(e => e.serviceid === -1 && props.storageKey.split('-').at(-1) =='2')
|
||||
} else {
|
||||
@ -202,7 +201,7 @@ const buildDefaultRowsFromDict = async (): Promise<WorkContentRow[]> => {
|
||||
serviceGroup,
|
||||
serviceid: toServiceId(entry.serviceid),
|
||||
remark: '',
|
||||
checked: false,
|
||||
checked: true,
|
||||
custom: false,
|
||||
path: isWholeProcessGroupedMode.value && serviceGroup
|
||||
? [serviceGroup, content]
|
||||
@ -255,6 +254,7 @@ const loadFromStore = async () => {
|
||||
const persistedRows = state.detailRows.map(item => ({
|
||||
...item,
|
||||
type: item.custom ? '自定义' : (item.type || '基本工作'),
|
||||
checked: item.custom ? false : item.checked !== false,
|
||||
serviceid: toServiceId(item.serviceid),
|
||||
path: Array.isArray(item.path) && item.path.length ? item.path : ['自定义', item.content || '未命名']
|
||||
})) as WorkContentRow[]
|
||||
@ -280,16 +280,16 @@ const loadFromStore = async () => {
|
||||
if (defaultRows.length > 0) {
|
||||
const persistedCustomRows = persistedRows.filter(item => item.custom)
|
||||
const persistedDictRows = persistedRows.filter(item => !item.custom)
|
||||
const persistedByContent = new Map(
|
||||
persistedDictRows.map(item => [String(item.content || '').trim(), item])
|
||||
const persistedByKey = new Map(
|
||||
persistedDictRows.map(item => [getDictRowMergeKey(item), item])
|
||||
)
|
||||
const mergedDictRows = defaultRows.map(item => {
|
||||
const key = String(item.content || '').trim()
|
||||
const old = persistedByContent.get(key)
|
||||
const key = getDictRowMergeKey(item)
|
||||
const old = persistedByKey.get(key)
|
||||
if (!old) return item
|
||||
return {
|
||||
...item,
|
||||
checked: Boolean(old.checked),
|
||||
checked: old.checked !== false,
|
||||
remark: String(old.remark || ''),
|
||||
type: old.type || item.type
|
||||
}
|
||||
@ -318,6 +318,60 @@ const handleCheckedToggle = (id: string, checked: boolean) => {
|
||||
saveToStore()
|
||||
}
|
||||
|
||||
const getGroupCheckableRows = (node?: IRowNode<WorkContentRow> | null) => {
|
||||
if (!node) return []
|
||||
return (node.allLeafChildren || [])
|
||||
.map(item => item.data)
|
||||
.filter((item): item is WorkContentRow => Boolean(item && !isAddTriggerRow(item) && !item.custom))
|
||||
}
|
||||
|
||||
const handleGroupCheckedToggle = (node: IRowNode<WorkContentRow>, checked: boolean) => {
|
||||
const groupRows = getGroupCheckableRows(node)
|
||||
if (groupRows.length === 0) return
|
||||
const targetIds = new Set(groupRows.map(item => item.id))
|
||||
let changed = false
|
||||
for (const row of rowData.value) {
|
||||
if (!targetIds.has(row.id)) continue
|
||||
if (row.checked === checked) continue
|
||||
row.checked = checked
|
||||
changed = true
|
||||
}
|
||||
if (!changed) return
|
||||
gridApi.value?.refreshCells({ force: true })
|
||||
gridApi.value?.redrawRows()
|
||||
saveToStore()
|
||||
}
|
||||
|
||||
const groupRowRendererParams = computed<IGroupCellRendererParams<WorkContentRow> | undefined>(() => {
|
||||
if (!isWholeProcessGroupedMode.value) return undefined
|
||||
return {
|
||||
suppressCount: true,
|
||||
innerRenderer: (params: ICellRendererParams<WorkContentRow>) => {
|
||||
const wrapper = document.createElement('div')
|
||||
wrapper.className = 'work-content-group-row'
|
||||
const checkbox = document.createElement('input')
|
||||
checkbox.type = 'checkbox'
|
||||
checkbox.className = 'work-content-group-check'
|
||||
const rows = getGroupCheckableRows(params.node)
|
||||
const checkedCount = rows.filter(item => item.checked).length
|
||||
checkbox.checked = rows.length > 0 && checkedCount === rows.length
|
||||
checkbox.indeterminate = checkedCount > 0 && checkedCount < rows.length
|
||||
checkbox.disabled = rows.length === 0
|
||||
checkbox.addEventListener('mousedown', event => event.stopPropagation())
|
||||
checkbox.addEventListener('click', event => event.stopPropagation())
|
||||
checkbox.addEventListener('change', event => {
|
||||
event.stopPropagation()
|
||||
handleGroupCheckedToggle(params.node, checkbox.checked)
|
||||
})
|
||||
const label = document.createElement('span')
|
||||
label.className = 'work-content-group-label'
|
||||
label.textContent = String(params.valueFormatted || params.value || params.node.key || '')
|
||||
wrapper.append(checkbox, label)
|
||||
return wrapper
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
const contentCellRenderer = (params: ICellRendererParams<WorkContentRow>) => {
|
||||
const data = params.data
|
||||
if (!data) return ''
|
||||
@ -649,7 +703,7 @@ const confirmDeleteRow = () => {
|
||||
:getDataPath="getDataPath"
|
||||
:groupDefaultExpanded="isWholeProcessGroupedMode ? -1 : 0"
|
||||
:groupDisplayType="isWholeProcessGroupedMode ? 'groupRows' : undefined"
|
||||
:groupRowRendererParams="isWholeProcessGroupedMode ? { suppressCount: true } : undefined"
|
||||
:groupRowRendererParams="groupRowRendererParams"
|
||||
:animateRows="true"
|
||||
:localeText="AG_GRID_LOCALE_CN"
|
||||
:tooltipShowDelay="500"
|
||||
@ -728,4 +782,26 @@ const confirmDeleteRow = () => {
|
||||
height: 14px;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
:deep(.work-content-group-row) {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 8px;
|
||||
}
|
||||
|
||||
:deep(.work-content-group-check) {
|
||||
width: 14px;
|
||||
height: 14px;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
:deep(.work-content-group-check:disabled) {
|
||||
cursor: not-allowed;
|
||||
opacity: 0.5;
|
||||
}
|
||||
|
||||
:deep(.work-content-group-label) {
|
||||
min-width: 0;
|
||||
word-break: break-word;
|
||||
}
|
||||
</style>
|
||||
|
||||
@ -615,7 +615,7 @@ onMounted(() => {
|
||||
class="text-sm font-semibold text-foreground cursor-pointer select-none transition-colors hover:text-primary">
|
||||
{{ props.title }}
|
||||
</h3>
|
||||
<div class="flex items-center gap-2">
|
||||
<!-- <div class="flex items-center gap-2">
|
||||
<span class=" text-xs text-muted-foreground">简要计算</span>
|
||||
<SwitchRoot
|
||||
class="cursor-pointer peer h-5 w-9 shrink-0 rounded-full border border-transparent bg-muted shadow-sm transition-colors data-[state=checked]:bg-primary"
|
||||
@ -623,7 +623,7 @@ onMounted(() => {
|
||||
<SwitchThumb
|
||||
class="block h-4 w-4 translate-x-0.5 rounded-full bg-background shadow transition-transform data-[state=checked]:translate-x-4" />
|
||||
</SwitchRoot>
|
||||
</div>
|
||||
</div> -->
|
||||
</div>
|
||||
|
||||
<div :class="agGridWrapClass">
|
||||
|
||||
@ -620,6 +620,7 @@ export const useZxFwPricingStore = defineStore('zxFwPricing', () => {
|
||||
if (!targetServiceId) return false
|
||||
|
||||
const nextValue = toFiniteNumberOrNull(params.value)
|
||||
|
||||
let changed = false
|
||||
const updatedRows = current.detailRows.map(row => {
|
||||
if (String(row.id || '') !== targetServiceId) return row
|
||||
@ -674,6 +675,8 @@ export const useZxFwPricingStore = defineStore('zxFwPricing', () => {
|
||||
if (isSameState(current, nextState)) return false
|
||||
contracts.value[contractId] = nextState
|
||||
contractLoaded.value[contractId] = true
|
||||
const targetRow = nextState.detailRows.find(row => String(row.id || '') === targetServiceId)
|
||||
|
||||
return true
|
||||
}
|
||||
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user