fix: 修正库存查询,优化展示。

This commit is contained in:
c
2026-03-13 17:34:05 +08:00
parent 8628776104
commit 48cd47dd72
14 changed files with 463 additions and 43 deletions

View File

@@ -300,32 +300,62 @@ defineExpose({
.form-dialog {
--el-dialog-width: fit-content !important;
}
.form-dialog :deep(.el-dialog) {
overflow: hidden;
border-radius: 8px;
}
.form-dialog :deep(.el-dialog__header) {
padding: 16px 20px;
margin-right: 0;
background-color: var(--el-fill-color-light);
border-bottom: 1px solid var(--el-border-color-lighter);
}
.form-dialog :deep(.el-dialog__title) {
font-size: 16px;
font-weight: 600;
color: var(--el-text-color-primary);
}
.form-dialog :deep(.el-dialog__headerbtn) {
top: 16px;
}
.form-dialog :deep(.el-dialog__body) {
padding: 10px 20px;
max-height: 70vh;
padding: 10px 20px;
overflow-y: auto;
}
.form-item-table {
height: 40vh;
}
.upload-row {
display: flex;
align-items: center; /* 垂直居中对齐 */
gap: 12px; /* 按钮和文字的间距 */
gap: 12px;
align-items: center;
width: 100%;
}
.upload-tip-side {
margin-left: 4px;
opacity: 0.8;
font-size: 12px; /* 字体调小 */
color: var(--el-text-color-secondary); /* 使用次要文字颜色 */
font-size: 12px;
line-height: 1.4;
white-space: nowrap; /* 防止意外换行,如果空间不够可去掉 */
color: var(--el-text-color-secondary);
white-space: nowrap;
opacity: 0.8;
}
.tip-desc {
font-weight: 500;
color: var(--el-color-primary);
}
.form-dialog .el-dialog__header {
padding-bottom: 0px;
padding-bottom: 0;
}
.form-dialog .el-dialog__body {
@@ -335,15 +365,47 @@ defineExpose({
.el-dialog {
--el-dialog-margin-top: 5vh !important;
}
.table-actions {
display: flex;
align-items: center;
justify-content: space-between;
padding: 5px 0;
margin-top: 10px;
text-align: right;
padding: 5px 0;
}
.ml-2 {
margin-left: 8px;
}
.el-icon {
vertical-align: middle;
}
:deep(.el-divider__text) {
font-weight: 600;
color: var(--el-text-color-primary);
}
:deep(.el-divider__text .el-icon) {
margin-right: 6px;
}
:deep(.el-table) {
font-size: 13px;
}
:deep(.el-table th.el-table__cell) {
font-weight: 600;
background-color: var(--el-fill-color-light);
}
:deep(.el-upload) {
display: inline-flex;
}
:deep(.el-upload__input) {
display: none;
}
</style>

View File

@@ -60,9 +60,42 @@ const handleReset = () => {
<style>
.button-container {
width: 100%;
/* 核心:让行内/行内块元素(按钮)水平居中 */
text-align: center;
/* 可选:增加上下间距,避免按钮贴边 */
margin: 20px 0;
text-align: center;
}
:deep(.el-dialog) {
overflow: hidden;
border-radius: 8px;
}
:deep(.el-dialog__header) {
padding: 16px 20px;
margin-right: 0;
background-color: var(--el-fill-color-light);
border-bottom: 1px solid var(--el-border-color-lighter);
}
:deep(.el-dialog__title) {
font-size: 16px;
font-weight: 600;
color: var(--el-text-color-primary);
}
:deep(.el-dialog__headerbtn) {
top: 16px;
}
:deep(.el-dialog__body) {
padding: 20px;
}
:deep(.el-form-item) {
margin-bottom: 18px;
}
:deep(.el-form-item__label) {
font-weight: 500;
color: var(--el-text-color-regular);
}
</style>

View File

@@ -60,19 +60,65 @@ watch(() => parentParamValue.value, loadData);
<style>
.dialog-footer-container {
display: flex;
justify-content: space-between; /* 左右两端对齐 */
align-items: center;
justify-content: space-between;
width: 100%;
}
.footer-summary {
display: flex;
gap: 8px;
align-items: center;
}
.total-count {
font-size: 14px;
font-weight: 500;
color: var(--el-text-color-primary);
}
.item-dialog {
--el-dialog-width: fit-content !important;
--el-dialog-padding-primary: 20px;
}
.item-dialog :deep(.el-dialog) {
overflow: hidden;
border-radius: 8px;
}
.item-dialog :deep(.el-dialog__header) {
padding: 16px 20px;
margin-right: 0;
background-color: var(--el-fill-color-light);
border-bottom: 1px solid var(--el-border-color-lighter);
}
.item-dialog :deep(.el-dialog__title) {
font-size: 16px;
font-weight: 600;
color: var(--el-text-color-primary);
}
.item-dialog :deep(.el-dialog__headerbtn) {
top: 16px;
}
.item-dialog :deep(.el-dialog__body) {
padding: 10px 20px;
max-height: 70vh;
padding: 10px 20px;
overflow-y: auto;
}
.item-dialog :deep(.el-table) {
font-size: 13px;
}
.item-dialog :deep(.el-table th.el-table__cell) {
font-weight: 600;
background-color: var(--el-fill-color-light);
}
.item-table {
height: 60vh;
}

View File

@@ -99,3 +99,22 @@ onMounted(loadData);
<template #columns><slot name="columns"></slot></template>
</TableMain>
</template>
<style scoped>
:deep(.el-table) {
font-size: 13px;
}
:deep(.el-table th.el-table__cell) {
font-weight: 600;
background-color: var(--el-fill-color-light);
}
:deep(.el-pagination) {
justify-content: flex-end;
}
:deep(.el-pagination.is-background .el-pager li) {
font-weight: 500;
}
</style>

View File

@@ -30,9 +30,24 @@ const searcherParams = defineModel<Record<string, string>>("searcherParams");
<style>
.table-header {
display: flex;
flex-wrap: wrap;
gap: 10px;
margin-bottom: 10px;
}
.table-tool-bar {
padding-left: 10px;
}
:deep(.el-input__wrapper) {
box-shadow: 0 0 0 1px var(--el-border-color) inset;
}
:deep(.el-input__wrapper:hover) {
box-shadow: 0 0 0 1px var(--el-border-color-hover) inset;
}
:deep(.el-input__wrapper.is-focus) {
box-shadow: 0 0 0 1px var(--el-color-primary) inset;
}
</style>

View File

@@ -49,7 +49,7 @@ defineExpose({
});
</script>
<template>
<div style="height: calc(100vh - 157px); display: flex; flex-direction: column; overflow: hidden">
<div style="display: flex; flex-direction: column; height: calc(100vh - 157px); overflow: hidden">
<div style="flex: 1; overflow: hidden">
<el-table
ref="tableRef"
@@ -77,3 +77,36 @@ defineExpose({
</div>
</div>
</template>
<style scoped>
:deep(.el-table) {
font-size: 13px;
}
:deep(.el-table th.el-table__cell) {
font-weight: 600;
background-color: var(--el-fill-color-light);
}
:deep(.el-pagination) {
justify-content: flex-end;
}
:deep(.el-pagination.is-background .el-pager li) {
font-weight: 500;
}
:deep(.el-table__expand-icon) {
font-size: 14px;
color: var(--el-text-color-secondary);
transition: all 0.2s ease;
}
:deep(.el-table__expand-icon:hover) {
color: var(--el-color-primary);
}
:deep(.el-table__expand-icon--expanded) {
transform: rotate(90deg);
}
</style>

View File

@@ -199,20 +199,41 @@ defineExpose({
<style scoped>
.footer-actions {
display: flex;
gap: 12px;
align-items: center;
gap: 12px; /* 确保附加组件和按钮之间有间距 */
}
.dialog-footer-container {
display: flex;
justify-content: space-between; /* 左右两端对齐 */
align-items: center;
justify-content: space-between;
width: 100%;
}
.footer-summary {
display: flex;
gap: 8px;
align-items: center;
}
.total-count {
font-size: 14px;
font-weight: 500;
color: var(--el-text-color-primary);
}
.selected-count {
font-size: 13px;
font-weight: 500;
color: var(--el-color-primary);
}
.dialog-filter-area {
padding: 12px 16px;
margin-bottom: 16px;
padding: 10px;
background-color: var(--el-fill-color-lighter);
border-radius: 4px;
border: 1px solid var(--el-border-color-lighter);
border-radius: 6px;
}
.dialog-table-area {
@@ -223,7 +244,38 @@ defineExpose({
.dialog-footer {
display: flex;
justify-content: flex-end;
gap: 12px;
justify-content: flex-end;
}
:deep(.el-dialog) {
overflow: hidden;
border-radius: 8px;
}
:deep(.el-dialog__header) {
padding: 16px 20px;
margin-right: 0;
background-color: var(--el-fill-color-light);
border-bottom: 1px solid var(--el-border-color-lighter);
}
:deep(.el-dialog__title) {
font-size: 16px;
font-weight: 600;
color: var(--el-text-color-primary);
}
:deep(.el-dialog__headerbtn) {
top: 16px;
}
:deep(.el-table) {
font-size: 13px;
}
:deep(.el-table th.el-table__cell) {
font-weight: 600;
background-color: var(--el-fill-color-light);
}
</style>

View File

@@ -74,3 +74,41 @@ defineExpose({
/>
</div>
</template>
<style scoped>
:deep(.el-tree) {
font-size: 14px;
}
:deep(.el-tree-node__content) {
height: 32px;
border-radius: 4px;
transition: background-color 0.2s ease;
}
:deep(.el-tree-node__content:hover) {
background-color: var(--el-fill-color-light);
}
:deep(.el-tree-node.is-current > .el-tree-node__content) {
color: var(--el-color-primary);
background-color: var(--el-color-primary-light-9);
}
:deep(.el-tree-node__expand-icon) {
color: var(--el-text-color-secondary);
}
:deep(.el-tree-node__expand-icon.is-leaf) {
color: transparent;
}
p {
padding-left: 8px;
margin: 0 0 12px;
font-size: 14px;
font-weight: 600;
color: var(--el-text-color-primary);
border-left: 3px solid var(--el-color-primary);
}
</style>

View File

@@ -5,7 +5,7 @@ import BasePageableTable from "../base-pageable-table/BasePageableTable.vue";
import type { SearcherProp } from "../search-bar/SearchBarType";
import type { ToolButtonProp } from "../table-tool-bar/TableToolBarType";
import { get } from "@/common/http/request";
import { Loading } from "@element-plus/icons-vue";
import { Loading, ArrowRight } from "@element-plus/icons-vue";
const props = defineProps({
searchers: Array as PropType<SearcherProp[]>,
@@ -210,21 +210,28 @@ defineExpose({
<template #columns>
<el-table-column v-if="itemUrl || itemFieldName" type="expand" fixed="left" width="50">
<template #default="{ row }">
<div class="item-container">
<template #default="{ row, expanded }">
<div :class="['item-container', { 'is-expanded': expanded }]">
<div v-if="loadingItems[getRowKey(row)]" class="loading-state">
<el-icon class="is-loading"><Loading /></el-icon>
<span>加载中...</span>
<div class="loading-content">
<el-icon class="is-loading loading-icon"><Loading /></el-icon>
<span class="loading-text">加载中...</span>
</div>
</div>
<div v-else-if="itemDataMap[getRowKey(row)] !== undefined">
<slot name="item-content" :row="row" :item-data="itemDataMap[getRowKey(row)]">
<el-empty v-if="!itemDataMap[getRowKey(row)]" description="无明细数据" :image-size="60" />
<pre v-else>{{ JSON.stringify(itemDataMap[getRowKey(row)], null, 2) }}</pre>
<div v-if="!itemDataMap[getRowKey(row)]" class="empty-state">
<el-empty description="暂无明细数据" :image-size="60" />
</div>
<pre v-else class="json-preview">{{ JSON.stringify(itemDataMap[getRowKey(row)], null, 2) }}</pre>
</slot>
</div>
<div v-else class="empty-state">点击展开加载明细</div>
<div v-else class="expand-hint">
<el-icon class="hint-icon"><ArrowRight /></el-icon>
<span class="hint-text">点击展开查看详情</span>
</div>
</div>
</template>
</el-table-column>
@@ -238,17 +245,96 @@ defineExpose({
.item-container {
min-height: 50px;
padding: 16px;
background-color: #fafafa;
background-color: var(--el-fill-color-light);
border-radius: 4px;
transition: all 0.3s ease;
}
.loading-state,
.empty-state {
.item-container.is-expanded {
background-color: var(--el-fill-color);
box-shadow: inset 0 2px 8px rgb(0 0 0 / 8%);
}
.loading-state {
display: flex;
align-items: center;
justify-content: center;
min-height: 80px;
}
.loading-content {
display: flex;
flex-direction: column;
gap: 12px;
align-items: center;
}
.loading-icon {
font-size: 24px;
color: var(--el-color-primary);
}
.loading-text {
font-size: 13px;
color: #909399;
}
.expand-hint {
display: flex;
gap: 8px;
align-items: center;
justify-content: center;
min-height: 60px;
font-size: 13px;
color: var(--el-text-color-placeholder);
}
.hint-icon {
font-size: 14px;
transition: transform 0.3s ease;
}
.expand-hint:hover .hint-icon {
color: var(--el-color-primary);
transform: translateX(4px);
}
.hint-text {
transition: color 0.3s ease;
}
.expand-hint:hover .hint-text {
color: var(--el-color-primary);
}
.empty-state {
padding: 20px 0;
}
.json-preview {
max-height: 400px;
padding: 12px;
overflow: auto;
font-size: 12px;
line-height: 1.6;
color: var(--el-text-color-regular);
background-color: var(--el-fill-color-light);
border: 1px solid var(--el-border-color-light);
border-radius: 4px;
}
:deep(.el-table__expand-icon) {
font-size: 16px;
color: #909399;
transition: all 0.2s ease;
}
:deep(.el-table__expand-icon:hover) {
color: var(--el-color-primary);
transform: scale(1.1);
}
:deep(.el-table__expand-icon--expanded) {
transform: rotate(90deg);
}
</style>

View File

@@ -96,18 +96,54 @@ watch(treeSelect, loadData);
</div>
</div>
</template>
<style>
<style scoped>
.page-container {
display: flex;
flex-direction: row;
flex-wrap: nowrap;
}
.tree-box {
width: 17.5%;
flex-flow: row nowrap;
gap: 12px;
height: calc(100vh - 120px);
overflow: auto;
padding: 12px;
background-color: var(--el-bg-color-page);
}
.tree-box {
width: 200px;
min-width: 160px;
max-width: 260px;
height: 100%;
padding: 12px;
overflow: auto;
background-color: var(--el-bg-color);
border-radius: 8px;
box-shadow: 0 1px 4px rgb(0 0 0 / 5%);
}
.table-box {
width: 82%;
display: flex;
flex: 1;
flex-direction: column;
min-width: 0;
height: 100%;
padding: 12px;
overflow: hidden;
background-color: var(--el-bg-color);
border-radius: 8px;
box-shadow: 0 1px 4px rgb(0 0 0 / 5%);
}
:deep(.table-box > .table-header) {
flex: none;
margin-bottom: 8px;
}
:deep(.table-box > .table-main) {
flex: 1;
min-height: 0;
overflow: hidden;
}
:deep(.el-pagination) {
padding-top: 8px;
margin-top: 0;
}
</style>

View File

@@ -21,7 +21,7 @@ const addUrl = "/sys/sysrole/addSysRole";
const editUrl = "/sys/sysrole/updateSysRole";
const removeUrl = "/sys/sysrole/deleteSysRole";
const statusUrl = "/sys/sysrole/setStatus";
const treeUrl = "/sys/syspermission/getPermissionTree";
const treeUrl = "/sys/syspermission/getAllPermissionTree";
const searchers = [{ name: "roleName", type: "text" as const, placeholder: $t("_prop.systemset.sysrole.roleName") }];
const rules = reactive<FormRules>({
roleName: [{ required: true, message: $t("_message.systemset.sysrole.input_roleName"), trigger: "blur" }],

View File

@@ -23,7 +23,7 @@ const searchers = [
:searchers="searchers"
ref="tableRef"
:tree-side-url="treeSideUrl"
tree-side-node-name="id"
tree-side-node-name="value"
tree-side-param-name="productBrand"
tree-side-title="所有品牌"
>

View File

@@ -24,7 +24,7 @@ const searchers = [
:searchers="searchers"
ref="tableRef"
:tree-side-url="treeSideUrl"
tree-side-node-name="id"
tree-side-node-name="value"
tree-side-param-name="productType"
tree-side-title="所有规格"
>

View File

@@ -22,7 +22,7 @@ const searchers = [
:searchers="searchers"
ref="tableRef"
:tree-side-url="treeSideUrl"
tree-side-node-name="id"
tree-side-node-name="value"
tree-side-param-name="storeId"
tree-side-title="所有仓库"
>