黄伟杰 2 days ago
commit f15eb001cb

@ -700,6 +700,11 @@ export default {
exportName: '产品库存.xls'
},
In: {
all: '全部',
waitIn: '待入库',
rejected: '已驳回',
auditing: '审核中',
inStock: '已入库',
no: '入库单号',
product: '产品',
inTime: '入库时间',
@ -762,6 +767,11 @@ export default {
addItem: '添加入库产品'
},
Out: {
all: '全部',
waitOut: '待出库',
rejected: '已驳回',
auditing: '审核中',
outStock: '已出库',
no: '出库单号',
customer: '客户',
product: '产品',
@ -907,6 +917,13 @@ export default {
stockCountExceededWarning: '数量不能超出可用库存,已自动调整为可用库存数量'
},
Check: {
all: '全部',
waitSubmit: '待提交',
rejected: '已驳回',
auditing: '审核中',
approved: '审核通过',
checked: '已盘点',
unchecked: '未盘点',
no: '盘点单号',
product: '产品',
checkTime: '盘点时间',
@ -1045,6 +1062,11 @@ export default {
exportName: '产品库存明细.xls'
},
Move: {
all: '全部',
waitSubmit: '待提交',
rejected: '已驳回',
auditing: '审核中',
approved: '审核通过',
no: '调拨单号',
product: '产品',
moveTime: '调度时间',
@ -1117,6 +1139,10 @@ export default {
validatorStatusRequired: '状态不能为空'
},
Pallet: {
all: '全部',
idle: '空闲',
occupied: '占用',
scrapped: '报废',
code: '托盘编码',
palletType: '托盘类型',
specification: '规格',

@ -1,5 +1,13 @@
<template>
<ContentWrap>
<!-- 统计卡片 -->
<div class="stock-check__header">
<div v-for="card in statusCards" :key="card.key" class="stock-check__stat"
:class="{ 'is-active': currentStatusKey === card.key }" @click="changeStatus(card.key, card.statusValue, card.checkStatusValue)">
<div class="stock-check__stat-title">{{ card.label }}</div>
<div class="stock-check__stat-value">{{ card.value }}</div>
</div>
</div>
<el-form
ref="queryFormRef"
:model="queryParams"
@ -42,7 +50,7 @@
class="!w-240px"
/>
</el-form-item>
<el-form-item :label="t('ErpStock.Check.status')" prop="status">
<el-form-item :label="t('ErpStock.Check.status')" prop="status" v-show="showAllFilters">
<el-select
v-model="queryParams.status"
:placeholder="t('ErpStock.Check.placeholderStatus')"
@ -57,6 +65,13 @@
/>
</el-select>
</el-form-item>
<el-form-item v-if="filterCount > 3">
<el-button type="text" class="text-primary" @click="toggleFilters">
<Icon :icon="showAllFilters ? 'ep:arrow-up' : 'ep:arrow-down'" class="mr-5px" />
{{ showAllFilters ? t('FactoryModeling.FactoryStructure.collapseText') :
t('FactoryModeling.FactoryStructure.expandText') }}
</el-button>
</el-form-item>
<el-form-item>
<el-button @click="handleQuery">
<Icon icon="ep:search" class="mr-5px" />
@ -295,6 +310,37 @@ const updatePlanTableMaxHeight = async () => {
const warehouseList = ref<WarehouseVO[]>([])
const selectionList = ref<StockCheckVO[]>([])
const queryFormRef = ref()
const currentStatusKey = ref('all')
const counters = reactive({
allCount: 0,
waitSubmitCount: 0,
rejectedCount: 0,
auditingCount: 0,
approvedCount: 0,
checkedCount: 0,
uncheckedCount: 0
})
const statusCards = computed(() => [
{ key: 'all', label: t('ErpStock.Check.all'), value: counters.allCount, statusValue: undefined, checkStatusValue: undefined },
{ key: 'waitSubmit', label: t('ErpStock.Check.waitSubmit'), value: counters.waitSubmitCount, statusValue: 0, checkStatusValue: undefined },
{ key: 'rejected', label: t('ErpStock.Check.rejected'), value: counters.rejectedCount, statusValue: 1, checkStatusValue: undefined },
{ key: 'auditing', label: t('ErpStock.Check.auditing'), value: counters.auditingCount, statusValue: 10, checkStatusValue: undefined },
{ key: 'approved', label: t('ErpStock.Check.approved'), value: counters.approvedCount, statusValue: 20, checkStatusValue: undefined },
{ key: 'checked', label: t('ErpStock.Check.checked'), value: counters.checkedCount, statusValue: undefined, checkStatusValue: 1 },
{ key: 'unchecked', label: t('ErpStock.Check.unchecked'), value: counters.uncheckedCount, statusValue: undefined, checkStatusValue: 0 }
])
const changeStatus = (key: string, statusValue: number | undefined, checkStatusValue: number | undefined) => {
currentStatusKey.value = key
queryParams.status = statusValue
queryParams.checkStatus = checkStatusValue
handleQuery()
}
const showAllFilters = ref(false)
const filterCount = 4
const toggleFilters = () => {
showAllFilters.value = !showAllFilters.value
updatePlanTableMaxHeight()
}
const formRef = ref()
const submitDialogVisible = ref(false)
const submitLoading = ref(false)
@ -322,7 +368,8 @@ const queryParams = reactive({
no: undefined as string | undefined,
warehouseId: undefined as number | undefined,
checkTime: [] as string[],
status: undefined as number | undefined
status: undefined as number | undefined,
checkStatus: undefined as number | undefined
})
const getList = async () => {
@ -331,6 +378,13 @@ const getList = async () => {
const data = await StockCheckApi.getStockCheckPage(queryParams)
list.value = data?.list || []
total.value = data?.total || 0
counters.allCount = Number(data?.allCount ?? data?.total ?? 0)
counters.waitSubmitCount = Number(data?.waitSubmitCount ?? 0)
counters.rejectedCount = Number(data?.rejectedCount ?? 0)
counters.auditingCount = Number(data?.auditingCount ?? 0)
counters.approvedCount = Number(data?.approvedCount ?? 0)
counters.checkedCount = Number(data?.checkedCount ?? 0)
counters.uncheckedCount = Number(data?.uncheckedCount ?? 0)
} finally {
loading.value = false
updatePlanTableMaxHeight()
@ -353,6 +407,7 @@ const handleQuery = () => {
}
const resetQuery = () => {
currentStatusKey.value = 'all'
queryFormRef.value?.resetFields()
handleQuery()
}
@ -478,3 +533,44 @@ onBeforeUnmount(() => {
window.removeEventListener('resize', updatePlanTableMaxHeight)
})
</script>
<style scoped lang="scss">
.stock-check__header {
display: grid;
grid-template-columns: repeat(7, minmax(0, 1fr));
gap: 12px;
width: 100%;
margin-bottom: 16px;
}
.stock-check__stat {
padding: 16px 18px;
border: 1px solid var(--el-border-color-light);
border-radius: 12px;
cursor: pointer;
transition: box-shadow 0.2s ease;
background: #fff;
&:hover {
box-shadow: 0 10px 24px rgba(64, 158, 255, 0.12);
}
&.is-active {
border-color: var(--el-color-primary);
box-shadow: 0 10px 24px rgba(64, 158, 255, 0.12);
}
}
.stock-check__stat-title {
color: var(--el-text-color-regular);
font-size: 14px;
}
.stock-check__stat-value {
margin-top: 8px;
color: var(--el-text-color-primary);
font-size: 28px;
font-weight: 700;
line-height: 1;
}
</style>

@ -3,9 +3,16 @@
<template v-if="!formVisible">
<ContentWrap>
<!-- 搜索工作栏 -->
<el-form
class="-mb-15px"
:model="queryParams"
<div class="stock-in__header">
<div v-for="card in statusCards" :key="card.key" class="stock-in__stat"
:class="{ 'is-active': currentStatusKey === card.key }" @click="changeStatus(card.key, card.statusList)">
<div class="stock-in__stat-title">{{ card.label }}</div>
<div class="stock-in__stat-value">{{ card.value }}</div>
</div>
</div>
<el-form
class="-mb-15px"
:model="queryParams"
ref="queryFormRef"
:inline="true"
label-width="auto"
@ -374,6 +381,26 @@ const inTypeToInfoKey = (inType: string) => {
}
const activeName = ref('')
const queryFormRef = ref() //
const currentStatusKey = ref('all')
const counters = reactive({
allCount: 0,
waitInCount: 0,
rejectedCount: 0,
auditingCount: 0,
inStockCount: 0
})
const statusCards = computed(() => [
{ key: 'all', label: t('ErpStock.In.all'), value: counters.allCount, statusList: [] },
{ key: 'waitIn', label: t('ErpStock.In.waitIn'), value: counters.waitInCount, statusList: [0] },
{ key: 'rejected', label: t('ErpStock.In.rejected'), value: counters.rejectedCount, statusList: [1] },
{ key: 'auditing', label: t('ErpStock.In.auditing'), value: counters.auditingCount, statusList: [10] },
{ key: 'inStock', label: t('ErpStock.In.inStock'), value: counters.inStockCount, statusList: [20] }
])
const changeStatus = (key: string, statusList: number[]) => {
currentStatusKey.value = key
queryParams.statusList = statusList
handleQuery()
}
const exportLoading = ref(false) //
const showAllFilters = ref(false)
const DEFAULT_STATUS_LIST = [0, 1, 10]
@ -426,6 +453,11 @@ const getList = async () => {
const data = await StockInApi.getStockInPage(buildQueryParams())
list.value = data.list
total.value = data.total
counters.allCount = Number(data?.allCount ?? data?.total ?? 0)
counters.waitInCount = Number(data?.waitInCount ?? 0)
counters.rejectedCount = Number(data?.rejectedCount ?? 0)
counters.auditingCount = Number(data?.auditingCount ?? 0)
counters.inStockCount = Number(data?.inStockCount ?? 0)
} finally {
loading.value = false
updatePlanTableMaxHeight()
@ -451,6 +483,7 @@ const handleQuery = () => {
/** 重置按钮操作 */
const resetQuery = () => {
useInitialStatusFilter.value = false
currentStatusKey.value = 'all'
queryFormRef.value.resetFields()
queryParams.statusList = []
queryParams.inType = activeName.value || stockInTypeOptions.value[0]?.value
@ -602,3 +635,44 @@ const handleTabClick = (tab: TabsPaneContext) => {
handleQuery()
}
</script>
<style scoped lang="scss">
.stock-in__header {
display: grid;
grid-template-columns: repeat(5, minmax(0, 1fr));
gap: 12px;
width: 100%;
margin-bottom: 16px;
}
.stock-in__stat {
padding: 16px 18px;
border: 1px solid var(--el-border-color-light);
border-radius: 12px;
cursor: pointer;
transition: box-shadow 0.2s ease;
background: #fff;
&:hover {
box-shadow: 0 10px 24px rgba(64, 158, 255, 0.12);
}
&.is-active {
border-color: var(--el-color-primary);
box-shadow: 0 10px 24px rgba(64, 158, 255, 0.12);
}
}
.stock-in__stat-title {
color: var(--el-text-color-regular);
font-size: 14px;
}
.stock-in__stat-value {
margin-top: 8px;
color: var(--el-text-color-primary);
font-size: 28px;
font-weight: 700;
line-height: 1;
}
</style>

@ -1,6 +1,14 @@
<template>
<ContentWrap>
<!-- 统计卡片 -->
<div class="stock-move__header">
<div v-for="card in statusCards" :key="card.key" class="stock-move__stat"
:class="{ 'is-active': currentStatusKey === card.key }" @click="changeStatus(card.key, card.statusValue)">
<div class="stock-move__stat-title">{{ card.label }}</div>
<div class="stock-move__stat-value">{{ card.value }}</div>
</div>
</div>
<!-- 搜索工作栏 -->
<el-form
class="-mb-15px"
@ -34,7 +42,7 @@
/>
</el-select>
</el-form-item>
<el-form-item :label="t('ErpStock.Move.moveTime')" prop="moveTime">
<el-form-item :label="t('ErpStock.Move.moveTime')" prop="moveTime" v-show="showAllFilters">
<el-date-picker
v-model="queryParams.moveTime"
value-format="YYYY-MM-DD HH:mm:ss"
@ -45,7 +53,7 @@
class="!w-240px"
/>
</el-form-item>
<el-form-item :label="t('ErpStock.Move.fromWarehouse')" prop="fromWarehouseId">
<el-form-item :label="t('ErpStock.Move.fromWarehouse')" prop="fromWarehouseId" v-show="showAllFilters">
<el-select
v-model="queryParams.fromWarehouseId"
clearable
@ -61,7 +69,7 @@
/>
</el-select>
</el-form-item>
<el-form-item :label="t('ErpStock.Move.creator')" prop="creator">
<el-form-item :label="t('ErpStock.Move.creator')" prop="creator" v-show="showAllFilters">
<el-select
v-model="queryParams.creator"
clearable
@ -77,7 +85,7 @@
/>
</el-select>
</el-form-item>
<el-form-item :label="t('ErpStock.Move.status')" prop="status">
<el-form-item :label="t('ErpStock.Move.status')" prop="status" v-show="showAllFilters">
<el-select v-model="queryParams.status" :placeholder="t('ErpStock.Move.placeholderStatus')" clearable class="!w-240px">
<el-option
v-for="dict in getIntDictOptions(DICT_TYPE.ERP_AUDIT_STATUS)"
@ -96,6 +104,13 @@
class="!w-240px"
/>
</el-form-item> -->
<el-form-item v-if="filterCount > 3">
<el-button type="text" class="text-primary" @click="toggleFilters">
<Icon :icon="showAllFilters ? 'ep:arrow-up' : 'ep:arrow-down'" class="mr-5px" />
{{ showAllFilters ? t('FactoryModeling.FactoryStructure.collapseText') :
t('FactoryModeling.FactoryStructure.expandText') }}
</el-button>
</el-form-item>
<el-form-item>
<el-button @click="handleQuery"><Icon icon="ep:search" class="mr-5px" /> {{ t('common.query') }}</el-button>
<el-button @click="resetQuery"><Icon icon="ep:refresh" class="mr-5px" /> {{ t('common.reset') }}</el-button>
@ -324,6 +339,32 @@ const queryParams = reactive({
creator: undefined
})
const queryFormRef = ref() //
const currentStatusKey = ref('all')
const counters = reactive({
allCount: 0,
waitSubmitCount: 0,
rejectedCount: 0,
auditingCount: 0,
approvedCount: 0
})
const statusCards = computed(() => [
{ key: 'all', label: t('ErpStock.Move.all'), value: counters.allCount, statusValue: undefined },
{ key: 'waitSubmit', label: t('ErpStock.Move.waitSubmit'), value: counters.waitSubmitCount, statusValue: 0 },
{ key: 'rejected', label: t('ErpStock.Move.rejected'), value: counters.rejectedCount, statusValue: 1 },
{ key: 'auditing', label: t('ErpStock.Move.auditing'), value: counters.auditingCount, statusValue: 10 },
{ key: 'approved', label: t('ErpStock.Move.approved'), value: counters.approvedCount, statusValue: 20 }
])
const changeStatus = (key: string, statusValue: number | undefined) => {
currentStatusKey.value = key
queryParams.status = statusValue
handleQuery()
}
const showAllFilters = ref(false)
const filterCount = 6
const toggleFilters = () => {
showAllFilters.value = !showAllFilters.value
updatePlanTableMaxHeight()
}
const exportLoading = ref(false) //
const productList = ref<ProductVO[]>([]) //
const warehouseList = ref<WarehouseVO[]>([]) //
@ -363,6 +404,11 @@ const getList = async () => {
const data = await StockMoveApi.getStockMovePage(queryParams)
list.value = data.list
total.value = data.total
counters.allCount = Number(data?.allCount ?? data?.total ?? 0)
counters.waitSubmitCount = Number(data?.waitSubmitCount ?? 0)
counters.rejectedCount = Number(data?.rejectedCount ?? 0)
counters.auditingCount = Number(data?.auditingCount ?? 0)
counters.approvedCount = Number(data?.approvedCount ?? 0)
} finally {
loading.value = false
updatePlanTableMaxHeight()
@ -377,6 +423,7 @@ const handleQuery = () => {
/** 重置按钮操作 */
const resetQuery = () => {
currentStatusKey.value = 'all'
queryFormRef.value.resetFields()
handleQuery()
}
@ -503,3 +550,44 @@ onBeforeUnmount(() => {
// TODO
// TODO
</script>
<style scoped lang="scss">
.stock-move__header {
display: grid;
grid-template-columns: repeat(5, minmax(0, 1fr));
gap: 12px;
width: 100%;
margin-bottom: 16px;
}
.stock-move__stat {
padding: 16px 18px;
border: 1px solid var(--el-border-color-light);
border-radius: 12px;
cursor: pointer;
transition: box-shadow 0.2s ease;
background: #fff;
&:hover {
box-shadow: 0 10px 24px rgba(64, 158, 255, 0.12);
}
&.is-active {
border-color: var(--el-color-primary);
box-shadow: 0 10px 24px rgba(64, 158, 255, 0.12);
}
}
.stock-move__stat-title {
color: var(--el-text-color-regular);
font-size: 14px;
}
.stock-move__stat-value {
margin-top: 8px;
color: var(--el-text-color-primary);
font-size: 28px;
font-weight: 700;
line-height: 1;
}
</style>

@ -2,6 +2,14 @@
<div class="dv-repair-page">
<template v-if="!formVisible">
<ContentWrap>
<!-- 统计卡片 -->
<div class="stock-out__header">
<div v-for="card in statusCards" :key="card.key" class="stock-out__stat"
:class="{ 'is-active': currentStatusKey === card.key }" @click="changeStatus(card.key, card.statusList)">
<div class="stock-out__stat-title">{{ card.label }}</div>
<div class="stock-out__stat-value">{{ card.value }}</div>
</div>
</div>
<!-- 鎼滅储宸ヤ綔鏍?-->
<el-form
class="-mb-15px"
@ -384,6 +392,26 @@ const getProductCategoryType = () => {
}
const activeName = ref('')
const queryFormRef = ref() // ?
const currentStatusKey = ref('all')
const counters = reactive({
allCount: 0,
waitOutCount: 0,
rejectedCount: 0,
auditingCount: 0,
outStockCount: 0
})
const statusCards = computed(() => [
{ key: 'all', label: t('ErpStock.Out.all'), value: counters.allCount, statusList: [] },
{ key: 'waitOut', label: t('ErpStock.Out.waitOut'), value: counters.waitOutCount, statusList: [0] },
{ key: 'rejected', label: t('ErpStock.Out.rejected'), value: counters.rejectedCount, statusList: [1] },
{ key: 'auditing', label: t('ErpStock.Out.auditing'), value: counters.auditingCount, statusList: [10] },
{ key: 'outStock', label: t('ErpStock.Out.outStock'), value: counters.outStockCount, statusList: [20] }
])
const changeStatus = (key: string, statusList: number[]) => {
currentStatusKey.value = key
queryParams.statusList = statusList
handleQuery()
}
const exportLoading = ref(false) //
const showAllFilters = ref(false)
const DEFAULT_STATUS_LIST = [0, 1, 10]
@ -445,6 +473,11 @@ const getList = async () => {
const data = await StockOutApi.getStockOutPage(buildQueryParams())
list.value = data.list
total.value = data.total
counters.allCount = Number(data?.allCount ?? data?.total ?? 0)
counters.waitOutCount = Number(data?.waitOutCount ?? 0)
counters.rejectedCount = Number(data?.rejectedCount ?? 0)
counters.auditingCount = Number(data?.auditingCount ?? 0)
counters.outStockCount = Number(data?.outStockCount ?? 0)
} finally {
loading.value = false
updatePlanTableMaxHeight()
@ -469,6 +502,7 @@ const handleQuery = () => {
/** 閲嶇疆鎸夐挳鎿嶄綔 */
const resetQuery = async () => {
useInitialStatusFilter.value = false
currentStatusKey.value = 'all'
queryFormRef.value.resetFields()
queryParams.statusList = []
queryParams.outType = activeName.value || stockOutTypeOptions.value[0]?.value
@ -622,3 +656,44 @@ const handleTabClick = async (tab: TabsPaneContext) => {
handleQuery()
}
</script>
<style scoped lang="scss">
.stock-out__header {
display: grid;
grid-template-columns: repeat(5, minmax(0, 1fr));
gap: 12px;
width: 100%;
margin-bottom: 16px;
}
.stock-out__stat {
padding: 16px 18px;
border: 1px solid var(--el-border-color-light);
border-radius: 12px;
cursor: pointer;
transition: box-shadow 0.2s ease;
background: #fff;
&:hover {
box-shadow: 0 10px 24px rgba(64, 158, 255, 0.12);
}
&.is-active {
border-color: var(--el-color-primary);
box-shadow: 0 10px 24px rgba(64, 158, 255, 0.12);
}
}
.stock-out__stat-title {
color: var(--el-text-color-regular);
font-size: 14px;
}
.stock-out__stat-value {
margin-top: 8px;
color: var(--el-text-color-primary);
font-size: 28px;
font-weight: 700;
line-height: 1;
}
</style>

@ -1,5 +1,13 @@
<template>
<ContentWrap>
<!-- 统计卡片 -->
<div class="pallet__header">
<div v-for="card in statusCards" :key="card.key" class="pallet__stat"
:class="{ 'is-active': currentStatusKey === card.key }" @click="changeStatus(card.key, card.statusValue)">
<div class="pallet__stat-title">{{ card.label }}</div>
<div class="pallet__stat-value">{{ card.value }}</div>
</div>
</div>
<el-form class="-mb-15px" :model="queryParams" ref="queryFormRef" :inline="true" label-width="auto">
<el-form-item :label="t('ErpStock.Pallet.code')" prop="code">
<el-input v-model="queryParams.code" :placeholder="t('ErpStock.Pallet.placeholderCode')" clearable
@ -151,6 +159,24 @@ const queryParams = reactive({
planCode: undefined
})
const queryFormRef = ref()
const currentStatusKey = ref('all')
const counters = reactive({
allCount: 0,
idleCount: 0,
occupiedCount: 0,
scrappedCount: 0
})
const statusCards = computed(() => [
{ key: 'all', label: t('ErpStock.Pallet.all'), value: counters.allCount, statusValue: undefined },
{ key: 'idle', label: t('ErpStock.Pallet.idle'), value: counters.idleCount, statusValue: 1 },
{ key: 'occupied', label: t('ErpStock.Pallet.occupied'), value: counters.occupiedCount, statusValue: 2 },
{ key: 'scrapped', label: t('ErpStock.Pallet.scrapped'), value: counters.scrappedCount, statusValue: 3 }
])
const changeStatus = (key: string, statusValue: number | undefined) => {
currentStatusKey.value = key
queryParams.status = statusValue
handleQuery()
}
const showAllFilters = ref(false)
const filterCount = 6
const warehouseList = ref<any[]>([])
@ -185,6 +211,10 @@ const getList = async () => {
const data = await PalletApi.getPalletPage(queryParams)
list.value = data.list ?? []
total.value = data.total ?? 0
counters.allCount = Number(data?.allCount ?? data?.total ?? 0)
counters.idleCount = Number(data?.idleCount ?? 0)
counters.occupiedCount = Number(data?.occupiedCount ?? 0)
counters.scrappedCount = Number(data?.scrappedCount ?? 0)
} finally {
loading.value = false
updatePlanTableMaxHeight()
@ -210,6 +240,7 @@ const handleQuery = () => {
}
const resetQuery = () => {
currentStatusKey.value = 'all'
queryFormRef.value.resetFields()
handleQuery()
}
@ -240,3 +271,44 @@ onBeforeUnmount(() => {
window.removeEventListener('resize', updatePlanTableMaxHeight)
})
</script>
<style scoped lang="scss">
.pallet__header {
display: grid;
grid-template-columns: repeat(4, minmax(0, 1fr));
gap: 12px;
width: 100%;
margin-bottom: 16px;
}
.pallet__stat {
padding: 16px 18px;
border: 1px solid var(--el-border-color-light);
border-radius: 12px;
cursor: pointer;
transition: box-shadow 0.2s ease;
background: #fff;
&:hover {
box-shadow: 0 10px 24px rgba(64, 158, 255, 0.12);
}
&.is-active {
border-color: var(--el-color-primary);
box-shadow: 0 10px 24px rgba(64, 158, 255, 0.12);
}
}
.pallet__stat-title {
color: var(--el-text-color-regular);
font-size: 14px;
}
.pallet__stat-value {
margin-top: 8px;
color: var(--el-text-color-primary);
font-size: 28px;
font-weight: 700;
line-height: 1;
}
</style>

Loading…
Cancel
Save