This commit is contained in:
zlwu committed 2026-08-17 09:22:31 +08:00
1 parent 42ad896456
commit 6b2147aa46
66 files changed
+617071 -28046

No files matched your search

+66 -54
View File
@@ -130,18 +130,18 @@
</div>
<div class="list-body list-wrap">
<ListTable table-key="db-inventory"
class="list-table"
:data="tableData"
v-loading="loading"
stripe
row-key="id"
show-summary
:summary-method="getSummary"
@sort-change="handleSortChange"
@selection-change="handleSelectionChange"
@row-dblclick="handleView"
>
<div ref="inventoryTableWrapRef" class="table-scroll bx-list-table-wrap">
<ListTable table-key="db-inventory"
class="list-table"
:data="tableData"
v-loading="loading"
stripe
row-key="id"
@sort-change="handleSortChange"
@selection-change="handleSelectionChange"
@row-dblclick="handleView"
@header-dragend="() => inventoryStatsRowRef?.resync?.()"
>
<el-table-column type="selection" min-width="55" align="center" />
<el-table-column type="index" label="序号" min-width="60" align="center" header-align="center" />
<el-table-column
@@ -356,6 +356,15 @@
</template>
</el-table-column>
</ListTable>
<ListColumnStatsRow
ref="inventoryStatsRowRef"
storage-key="db-inventory-column-stats"
:columns="inventoryStatsRowColumns"
:data="tableData"
:table-wrap-el="inventoryTableWrapRef"
:get-cell-value="getInventoryStatCellValue"
/>
</div>
<div class="pagination list-pager-bar">
<div class="list-pager-selected">
@@ -512,7 +521,6 @@
* UI 模式 P02 · 复杂业务列表
* 参考:/#/crm/quote · src/views/crm/quote/index.vue
*/
import type { TableColumnCtx } from 'element-plus'
import {
Check,
Close,
@@ -529,6 +537,8 @@
import ListToolbarDateShortcuts from '@/components/core/list-toolbar-date-shortcuts/index.vue'
import ListQuickSearchInput from '@/components/business/list-quick-search-input/index.vue'
import ListToolbarEndActions from '@/components/business/list-toolbar-end-actions/index.vue'
import ListColumnStatsRow from '@/components/business/list-column-stats-row/index.vue'
import type { StatsRowColumn } from '@/utils/list-column-stats'
import { usePersistedListColumns } from '@/composables/usePersistedListColumns'
import { canDeleteByCreator, CREATOR_DELETE_TIP } from '@/utils/creator-delete'
import { syncViewRowFromFlatList } from '@/utils/view-dialog-refresh'
@@ -582,6 +592,45 @@
resetToDefault
} = usePersistedListColumns('db-inventory-list-columns', listColumnDefs)
const inventoryTableWrapRef = ref<HTMLElement | null>(null)
const inventoryStatsRowRef = ref<{ resync?: () => void } | null>(null)
const inventoryStatsRowColumns = computed((): StatsRowColumn[] => {
const cols: StatsRowColumn[] = [
{ key: '__selection', interactive: false },
{ key: '__index', interactive: false }
]
if (isColumnVisible('id')) {
cols.push({ key: 'id', interactive: true, prop: 'id' })
}
if (isColumnVisible('planNo')) {
cols.push({ key: 'planNo', interactive: true, prop: 'planNo' })
}
cols.push({ key: 'batchNo', interactive: true, prop: 'batchNo' })
for (const def of listColumnDefs) {
if (def.prop === 'id' || def.prop === 'planNo') continue
if (!isColumnVisible(def.prop)) continue
cols.push({
key: def.prop,
interactive: true,
prop: def.prop
})
}
return cols
})
const KG_TO_TON_PROPS = new Set(['netWeight', 'grossWeight', 'tareWeight', 'deduction'])
function getInventoryStatCellValue(row: InventoryRecord, prop: string): unknown {
if (KG_TO_TON_PROPS.has(prop)) {
return (Number((row as any)[prop]) || 0) / 1000
}
if (prop === 'createByName') {
return row.createByName || row.createBy || ''
}
return (row as any)?.[prop]
}
const exportLoading = ref(false)
const saving = ref(false)
const tableData = ref<InventoryRecord[]>([])
@@ -682,47 +731,6 @@
return sortProp.value === prop ? sortOrder.value : null
}
const getSummary = (param: { columns: TableColumnCtx<InventoryRecord>[]; data: InventoryRecord[] }) => {
const { columns } = param
const sums: string[] = []
columns.forEach((column, index) => {
if (column.type === 'selection') {
sums[index] = ''
return
}
if (column.type === 'index') {
sums[index] = '合计'
return
}
if (column.property === 'quantity') {
const totalQuantity = tableData.value.reduce(
(sum, row) => sum + (Number(row.quantity) || 0),
0
)
sums[index] = totalQuantity.toString()
return
}
if (
column.property === 'netWeight' ||
column.property === 'grossWeight' ||
column.property === 'tareWeight' ||
column.property === 'deduction'
) {
const prop = column.property as keyof InventoryRecord
const totalWeight = tableData.value.reduce(
(sum, row) => sum + (Number(row[prop]) || 0) / 1000,
0
)
sums[index] = totalWeight.toFixed(2)
return
}
sums[index] = ''
})
return sums
}
const compare = (
a: InventoryRecord,
b: InventoryRecord,
@@ -1175,6 +1183,10 @@
</script>
<style scoped lang="scss">
.bx-list-table-wrap {
min-width: 0;
}
.db-date-with-shortcuts {
display: flex;
align-items: center;
+59 -48
View File
@@ -130,17 +130,17 @@
</div>
<div class="list-body list-wrap">
<ListTable table-key="db-plans"
class="list-table"
:data="tableData"
v-loading="loading"
stripe
row-key="id"
show-summary
:summary-method="getSummary"
@selection-change="handleSelectionChange"
@row-dblclick="handleView"
>
<div ref="plansTableWrapRef" class="table-scroll bx-list-table-wrap">
<ListTable table-key="db-plans"
class="list-table"
:data="tableData"
v-loading="loading"
stripe
row-key="id"
@selection-change="handleSelectionChange"
@row-dblclick="handleView"
@header-dragend="() => plansStatsRowRef?.resync?.()"
>
<el-table-column type="selection" min-width="55" align="center" />
<el-table-column type="index" label="序号" min-width="60" align="center" header-align="center" />
<el-table-column
@@ -289,7 +289,16 @@
{{ row.createByName || row.createBy || '—' }}
</template>
</el-table-column>
</ListTable>
</ListTable>
<ListColumnStatsRow
ref="plansStatsRowRef"
storage-key="db-plans-column-stats"
:columns="plansStatsRowColumns"
:data="tableData"
:table-wrap-el="plansTableWrapRef"
:get-cell-value="getPlansStatCellValue"
/>
</div>
<div class="pagination list-pager-bar">
<div class="list-pager-selected">
@@ -465,7 +474,6 @@
* UI 模式 P02 · 复杂业务列表
* 参考:/#/crm/quote · src/views/crm/quote/index.vue
*/
import type { TableColumnCtx } from 'element-plus'
import {
Check,
Close,
@@ -481,6 +489,8 @@
import ListToolbarDateShortcuts from '@/components/core/list-toolbar-date-shortcuts/index.vue'
import ListQuickSearchInput from '@/components/business/list-quick-search-input/index.vue'
import ListToolbarEndActions from '@/components/business/list-toolbar-end-actions/index.vue'
import ListColumnStatsRow from '@/components/business/list-column-stats-row/index.vue'
import type { StatsRowColumn } from '@/utils/list-column-stats'
import { usePersistedListColumns } from '@/composables/usePersistedListColumns'
import DbCrmProductSelect from '@/components/business/db/DbCrmProductSelect.vue'
import DbPlanRelatedViewDialog from '@/components/business/db/DbPlanRelatedViewDialog.vue'
@@ -524,6 +534,36 @@
resetToDefault
} = usePersistedListColumns('db-plans-list-columns', listColumnDefs)
const plansTableWrapRef = ref<HTMLElement | null>(null)
const plansStatsRowRef = ref<{ resync?: () => void } | null>(null)
const plansStatsRowColumns = computed((): StatsRowColumn[] => {
const cols: StatsRowColumn[] = [
{ key: '__selection', interactive: false },
{ key: '__index', interactive: false },
{ key: 'planNo', interactive: true, prop: 'planNo' }
]
for (const def of listColumnDefs) {
if (!isColumnVisible(def.prop)) continue
cols.push({
key: def.prop,
interactive: true,
prop: def.prop === 'autoGenerate' ? 'autoGenerateEnabled' : def.prop
})
}
return cols
})
function getPlansStatCellValue(row: Plan, prop: string): unknown {
if (prop === 'executedQuantity') {
return (row.executedQuantity || 0) / 1000
}
if (prop === 'createByName') {
return row.createByName || row.createBy || ''
}
return (row as any)?.[prop]
}
const loading = ref(false)
const exportLoading = ref(false)
const saving = ref(false)
@@ -641,41 +681,6 @@
return 'info'
}
const getSummary = (param: { columns: TableColumnCtx<Plan>[]; data: Plan[] }) => {
const { columns } = param
const sums: string[] = []
columns.forEach((column, index) => {
if (column.type === 'selection') {
sums[index] = ''
return
}
if (column.type === 'index') {
sums[index] = '合计'
return
}
if (column.property === 'plannedQuantity') {
const totalPlanned = tableData.value.reduce(
(sum, row) => sum + (Number(row.plannedQuantity) || 0),
0
)
sums[index] = totalPlanned.toString()
return
}
if (column.label === '已执行量(吨)') {
const totalExecuted = tableData.value.reduce(
(sum, row) => sum + (row.executedQuantity || 0) / 1000,
0
)
sums[index] = totalExecuted.toFixed(2)
return
}
sums[index] = ''
})
return sums
}
const loadData = async () => {
loading.value = true
try {
@@ -1064,3 +1069,9 @@
loadData()
})
</script>
<style scoped lang="scss">
.bx-list-table-wrap {
min-width: 0;
}
</style>
+69 -47
View File
@@ -109,17 +109,17 @@
</div>
<div class="list-body list-wrap">
<ListTable table-key="db-weighing"
class="list-table"
:data="paginatedData"
v-loading="loading"
stripe
row-key="id"
show-summary
:summary-method="getSummary"
@selection-change="handleSelectionChange"
@row-dblclick="handleView"
>
<div ref="weighingTableWrapRef" class="table-scroll bx-list-table-wrap">
<ListTable table-key="db-weighing"
class="list-table"
:data="paginatedData"
v-loading="loading"
stripe
row-key="id"
@selection-change="handleSelectionChange"
@row-dblclick="handleView"
@header-dragend="() => weighingStatsRowRef?.resync?.()"
>
<el-table-column type="selection" min-width="55" align="center" />
<el-table-column type="index" label="序号" min-width="60" align="center" header-align="center" />
<el-table-column
@@ -306,6 +306,15 @@
</template>
</el-table-column>
</ListTable>
<ListColumnStatsRow
ref="weighingStatsRowRef"
storage-key="db-weighing-column-stats"
:columns="weighingStatsRowColumns"
:data="paginatedData"
:table-wrap-el="weighingTableWrapRef"
:get-cell-value="getWeighingStatCellValue"
/>
</div>
<div class="pagination list-pager-bar">
<div class="list-pager-selected">
@@ -506,7 +515,6 @@
* UI 模式 P02 · 复杂业务列表
* 参考:/#/crm/quote · src/views/crm/quote/index.vue
*/
import type { TableColumnCtx } from 'element-plus'
import {
Check,
Close,
@@ -520,6 +528,8 @@
import ListToolbarDateShortcuts from '@/components/core/list-toolbar-date-shortcuts/index.vue'
import ListQuickSearchInput from '@/components/business/list-quick-search-input/index.vue'
import ListToolbarEndActions from '@/components/business/list-toolbar-end-actions/index.vue'
import ListColumnStatsRow from '@/components/business/list-column-stats-row/index.vue'
import type { StatsRowColumn } from '@/utils/list-column-stats'
import { usePersistedListColumns } from '@/composables/usePersistedListColumns'
import DbCrmProductSelect from '@/components/business/db/DbCrmProductSelect.vue'
import DbRelatedViewDialog from '@/components/business/db/DbRelatedViewDialog.vue'
@@ -571,6 +581,33 @@
resetToDefault
} = usePersistedListColumns('db-weighing-list-columns', listColumnDefs)
const weighingTableWrapRef = ref<HTMLElement | null>(null)
const weighingStatsRowRef = ref<{ resync?: () => void } | null>(null)
const weighingStatsRowColumns = computed((): StatsRowColumn[] => {
const cols: StatsRowColumn[] = [
{ key: '__selection', interactive: false },
{ key: '__index', interactive: false }
]
if (isColumnVisible('inventoryDate')) {
cols.push({ key: 'inventoryDate', interactive: true, prop: 'inventoryDate' })
}
if (isColumnVisible('planNo')) {
cols.push({ key: 'planNo', interactive: true, prop: 'planNo' })
}
cols.push({ key: 'batchNo', interactive: true, prop: 'batchNo' })
for (const def of listColumnDefs) {
if (def.prop === 'inventoryDate' || def.prop === 'planNo') continue
if (!isColumnVisible(def.prop)) continue
cols.push({
key: def.prop,
interactive: true,
prop: def.prop
})
}
return cols
})
const loading = ref(false)
const exportLoading = ref(false)
const saving = ref(false)
@@ -693,6 +730,20 @@
(row.createdAt ? row.createdAt.split(' ')[0] : '') ||
''
function getWeighingStatCellValue(row: WeighingRecord, prop: string): unknown {
if (prop === 'inventoryDate') return getRecordDate(row)
if (prop === 'currentQuantity' || prop === 'netWeight') {
return (Number((row as any)[prop]) || 0) / 1000
}
if (prop === 'docStatus') {
return row.isVoided === 1 ? '已作废' : '正常'
}
if (prop === 'createByName') {
return row.createByName || row.createBy || ''
}
return (row as any)?.[prop]
}
const buildListQueryParams = (): WeighingListParams => {
const params: WeighingListParams = {}
const keyword = searchKeyword.value.trim()
@@ -709,41 +760,6 @@
return params
}
const getSummary = (param: { columns: TableColumnCtx<WeighingRecord>[] }) => {
const { columns } = param
const sums: string[] = []
columns.forEach((column, index) => {
if (column.type === 'selection') {
sums[index] = ''
return
}
if (column.type === 'index') {
sums[index] = '合计'
return
}
if (column.label === '本次量(吨)') {
const totalCurrent = paginatedData.value.reduce(
(sum, row) => sum + (row.currentQuantity || 0) / 1000,
0
)
sums[index] = totalCurrent.toFixed(2)
return
}
if (column.label === '净重(吨)') {
const totalNet = paginatedData.value.reduce(
(sum, row) => sum + (row.netWeight || 0) / 1000,
0
)
sums[index] = totalNet.toFixed(2)
return
}
sums[index] = ''
})
return sums
}
const calculateNetWeight = () => {
formData.netWeight = netWeight.value
}
@@ -1196,3 +1212,9 @@
openAddFromInventoryQuery()
})
</script>
<style scoped lang="scss">
.bx-list-table-wrap {
min-width: 0;
}
</style>