提交
This commit is contained in:
1 parent
42ad896456
commit
6b2147aa46
66 files changed
+617071
-28046
No files matched your search
@@ -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;
|
||||
|
||||
@@ -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>
|
||||
@@ -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>
|
||||
Reference in new issue
Block a user