refactor(ui): 优化股票管理界面样式和功能

- 移除调试用的 console.log 语句
- 调整按钮样式,使用 vxe-button 替换原生按钮
- 添加打印功能并优化查询逻辑
- 统一列渲染逻辑,提升代码可维护性
This commit is contained in:
user 2025-03-25 09:50:09 +08:00
parent 4c87eaa302
commit 68ca3823bc
5 changed files with 93 additions and 51 deletions

View File

@ -82,18 +82,18 @@
@sort-change="changeOrder"
>
<vxe-column
v-for="col in columns.filter(col => col.visible !== false)"
:key="col.field"
:field="col.field"
:title="col.title"
:sortable="col.sortable"
:tree-node="col.treeNode"
:width="col.width"
v-for="column in columns.filter(col => col.visible !== false)"
:key="column.field"
:field="column.field"
:title="column.title"
:sortable="column.sortable"
:tree-node="column.treeNode"
:width="column.width"
>
<template #default="{ row }" v-if="col.field === 'status'">
<template #default="{ row }" v-if="column.field === 'status'">
{{ statusDicts.find(s => s.number === String(row.status))?.name || row.status }}
</template>
<template #default="{ row }" v-else-if="col.title === $t('entity.action.actions')">
<template #default="{ row }" v-else-if="column.title === $t('entity.action.actions')">
<div class="btn-group">
<router-link :to="{ name: 'DictEdit', params: { id: row.id } }" class="btn btn-primary btn-sm">
<font-awesome-icon icon="pencil-alt" />

View File

@ -73,7 +73,6 @@ export default defineComponent({
const save = async () => {
isSaving.value = true;
try {
console.log(stock.value);
if (stock.value.id) {
await axios.put(`api/stocks/${stock.value.id}`, stock.value);
alertService.showInfo(t$('jewpmsApp.stock.updated', { param: stock.value.name }));

View File

@ -90,6 +90,8 @@ export default defineComponent({
{
title: $t('entity.action.actions'),
sortable: false,
with: 500,
slots: { default: 'active' },
},
];
@ -97,14 +99,24 @@ export default defineComponent({
if (filterParams.value[field]) {
filterParams.value[field].value = null;
}
handleSyncList();
queryMethod();
};
const handleFilter = () => {
showFilter.value = !showFilter.value;
page.currentPage = 1; // 重置页码
queryMethod();
};
handleSyncList();
const handlePrint = () => {
if (tableRef.value) tableRef.value.print();
};
// 处理输入框变化
const handleInputChange = () => {
if (showFilter.value) {
queryMethod();
}
console.log('fhandleInputChange');
};
const sort = () => {
@ -118,10 +130,10 @@ export default defineComponent({
const pageChange: VxePagerEvents.PageChange = ({ pageSize, currentPage }) => {
page.currentPage = currentPage;
page.pageSize = pageSize;
handleSyncList();
queryMethod();
};
const handleSyncList = async () => {
const queryMethod = async () => {
isFetching.value = true;
try {
const [stocksRes, statusDictsRes] = await Promise.all([
@ -168,6 +180,7 @@ export default defineComponent({
if (table && toolbar) {
table.connect(toolbar);
}
//tableRef.value.print();
});
const prepareDelete = row => {
@ -180,7 +193,7 @@ export default defineComponent({
await axios.delete(`api/stocks/${removeRow.value.id}`);
alertService.showInfo($t('jewpmsApp.stock.deleted'));
removeRow.value.id = null;
handleSyncList();
queryMethod();
if (deleteDialog.value) deleteDialog.value.hide();
} catch (e) {
alertService.showHttpError(e);
@ -190,14 +203,10 @@ export default defineComponent({
const changeOrder = ({ property, order }) => {
propOrder.value = property;
reverse.value = order === 'desc';
handleSyncList();
queryMethod();
};
const queryMethod = () => {
handleSyncList();
};
handleSyncList();
queryMethod();
return {
columns,
@ -208,11 +217,12 @@ export default defineComponent({
page,
propOrder,
reverse,
handleSyncList,
handleFilter,
handlePrint,
prepareDelete,
deleteStock,
removeRow,
deleteDialog,
operatorSelect,
changeOrder,
statusDicts,
@ -221,6 +231,7 @@ export default defineComponent({
pageChange,
clearInput,
queryMethod,
handleInputChange,
};
},
});

View File

@ -1,6 +1,6 @@
<template>
<div>
<vxe-toolbar ref="toolbarRef" import export print custom :refresh="{ queryMethod }">
<vxe-toolbar ref="toolbarRef" custom :refresh="{ queryMethod }">
<template #buttonPrefix>
<h5 class="jh-entity-heading">
<font-awesome-icon icon="warehouse" />
@ -8,19 +8,21 @@
</h5>
</template>
<template #toolPrefix>
<div class="btn-group">
<button class="btn btn-sm btn-secondary" v-on:click="handleSyncList" :disabled="isFetching" data-cy="entitySyncListButton">
<font-awesome-icon icon="sync" :spin="isFetching" />
<span class="d-none d-md-inline" v-text="$t('entity.action.refresh')"></span>
</button>
<button class="btn btn-sm btn-warning" v-on:click="handleFilter" data-cy="entityFilterButton">
<div class="vxe-group">
<vxe-button class="btn-md-circle btn-secondary">
<router-link :to="{ name: 'StockCreate' }" data-cy="entityCreateButton">
<font-awesome-icon icon="plus" />
<span class="d-none d-md-inline" v-text="$t('entity.action.new')"></span>
</router-link>
</vxe-button>
<vxe-button class="btn-md-circle" v-on:click="handleFilter" data-cy="entityFilterButton">
<font-awesome-icon icon="filter" />
<span class="d-none d-md-inline" v-text="$t('entity.action.filter')"></span>
</button>
<router-link class="btn btn-sm btn-primary" :to="{ name: 'StockCreate' }" data-cy="entityCreateButton">
<font-awesome-icon icon="plus" />
<span class="d-none d-md-inline" v-text="$t('entity.action.new')"></span>
</router-link>
</vxe-button>
<vxe-button class="btn-md-circle" v-on:click="handlePrint" data-cy="entityFilterButton">
<font-awesome-icon icon="print" />
<span class="d-none d-md-inline" v-text="$t('entity.action.print')"></span>
</vxe-button>
</div>
</template>
</vxe-toolbar>
@ -31,7 +33,7 @@
<label class="form-control-label" for="filter-number">{{ $t('jewpmsApp.stock.number') }}</label>
<b-input-group class="form-control-group">
<b-form-select id="filter-number-op" v-model="filterParams.number.op" :options="operatorSelect"></b-form-select>
<b-form-input id="filter-number-name" v-model="filterParams.number.value"></b-form-input>
<b-form-input id="filter-number-name" v-model="filterParams.number.value" @change="handleInputChange"></b-form-input>
<div v-if="filterParams.number.value" class="clear-icon" @click="clearInput('number')">
<font-awesome-icon icon="times" />
</div>
@ -41,7 +43,7 @@
<label class="form-control-label" for="filter-name">{{ $t('jewpmsApp.stock.name') }}</label>
<b-input-group class="form-control-group">
<b-form-select id="filter-name-op" v-model="filterParams.name.op" :options="operatorSelect"></b-form-select>
<b-form-input id="filter-name-name" v-model="filterParams.name.value"></b-form-input>
<b-form-input id="filter-name-name" v-model="filterParams.name.value" @change="handleInputChange"></b-form-input>
<div v-if="filterParams.name.value" class="clear-icon" @click="clearInput('name')">
<font-awesome-icon icon="times" />
</div>
@ -51,14 +53,17 @@
<label class="form-control-label" for="filter-property">{{ $t('jewpmsApp.stock.property') }}</label>
<b-input-group class="form-control-group">
<b-form-select id="filter-op" v-model="filterParams.property.op" :options="operatorSelect"></b-form-select>
<b-form-input id="filter-number" v-model="filterParams.property.value"></b-form-input>
<b-form-input id="filter-number" v-model="filterParams.property.value" @change="handleInputChange"></b-form-input>
<div v-if="filterParams.property.value" class="clear-icon" @click="clearInput('property')">
<font-awesome-icon icon="times" />
</div>
</b-input-group>
</div>
<div class="form-group">
<label class="form-control-label">{{ $t('jewpmsApp.stock.status') }}</label>
<b-input-group class="form-control-group">
<b-form-select id="filter-op" v-model="filterParams.status.op" :options="operatorSelect"></b-form-select>
<b-form-select id="filter-status" v-model="filterParams.status.value">
<b-form-select id="filter-status" v-model="filterParams.status.value" @change="handleInputChange">
<option :value="null">{{ $t('entity.action.select') }}</option>
<option v-for="dict in statusDicts" :key="dict.number" :value="dict.number">{{ dict.name }}</option>
</b-form-select>
@ -73,7 +78,6 @@
ref="tableRef"
:import-config="{}"
:export-config="{}"
:print-config="{}"
:custom-config="{}"
v-if="stocks && stocks.length > 0"
:data="stocks"
@ -87,18 +91,18 @@
:field="column.field"
:title="$t(column.title)"
:sortable="column.sortable"
/>
<vxe-column :title="$t('entity.action.actions')" width="160">
<template #default="{ row }">
<div class="btn-group">
<router-link :to="{ name: 'StockEdit', params: { id: row.id } }" class="btn btn-primary btn-sm">
<font-awesome-icon icon="pencil-alt" />
<span class="d-none d-md-inline" v-text="$t('entity.action.edit')"></span>
</router-link>
<button type="button" class="btn btn-danger btn-sm" v-b-modal.deleteDialog @click="prepareDelete(row)">
<font-awesome-icon icon="times" />
<span class="d-none d-md-inline" v-text="$t('entity.action.delete')"></span>
</button>
>
<template #default="{ row }" v-if="column.field === 'status'">
{{ statusDicts.find(s => s.number === String(row.status))?.name || row.status }}
</template>
<template #default="{ row }" v-else-if="column.title === $t('entity.action.actions')">
<div class="vxe-group">
<vxe-button class="btn-circle">
<router-link :to="{ name: 'StockEdit', params: { id: row.id } }">
<font-awesome-icon icon="pencil-alt" />
</router-link>
</vxe-button>
<vxe-button class="btn-circle text-danger" icon="vxe-icon-delete" @click="prepareDelete(row)"></vxe-button>
</div>
</template>
</vxe-column>

View File

@ -16,6 +16,10 @@
padding: 0;
}
.vxe-group {
display: flex;
}
.btn-group {
display: flex;
gap: 0.5rem;
@ -119,3 +123,27 @@
color: #999;
gap: 0.5rem;
}
.btn-circle {
border-radius: 50% !important;
width: 34px;
height: 34px;
padding: 0 8px !important;
}
/* 默认(小屏幕手机)样式:圆形按钮 */
.btn-md-circle {
border-radius: 50% !important;
width: 34px;
height: 34px;
padding: 0 8px !important;
}
/* 大屏幕PC样式微圆角按钮 */
@media (min-width: 768px) {
.btn-md-circle {
border-radius: 5px !important;
width: auto;
height: auto;
}
}