Commit 0d7b48e1 by qinjianhui

feat: 页面样式修改

parent bb6917a9
...@@ -3,9 +3,27 @@ description ...@@ -3,9 +3,27 @@ description
glob glob
alwaysApply: true alwaysApply: true
--- ---
## 技术栈 ## 技术栈
Vue3 + Element Plus + Pinia + Axios + TypeScript + Vite Vue3 + Element Plus + Pinia + Axios + TypeScript + Vite
## UI 相关编码要求
-- 当有上下两个子表时,使用 `src/components/splitDiv/splitDiv.vue` 组件,使用时注意传递对应的 props 和插槽
-- 所有按钮都需要使用 `span` 标签包裹,并添加 `class="item"` 类名
-- 所有按钮都需要使用 `type` 属性,并且值为 `primary`、`success`、`warning`、`danger`
-- 表格相关布局时,使用 `src/components/TableView.vue` 组件,使用时注意传递对应的 props 和插槽
## 接口相关
-- 所有接口统一放在 `src/api/`目录下,当模块多时,可按模块创建子目录,例如 `src/api/factoryOrderNew/xxx1`、`src/api/factoryOrderNew/xxx2`、`src/api/factoryOrderNew/xxx3`
## TS 类型定义相关
-- 所有类型定义统一放在 `src/types/`目录下,当模块多时,可按模块创建子目录,例如 `src/types/factoryOrderNew/xxx1`、`src/types/factoryOrderNew/xxx2`、`src/types/factoryOrderNew/xxx3`
## 代码编写原则 ## 代码编写原则
-- 只编写解决问题所需的最少代码 -- 只编写解决问题所需的最少代码
-- 避免冗余实现和过渡设计 -- 避免冗余实现和过渡设计
-- 实现一个复杂功能时,需要合理拆分组件,使每个文件的代码更易维护 -- 实现一个复杂功能时,需要合理拆分组件,使每个文件的代码更易维护
......
<template> <template>
<div class="batch-manage"> <div class="batch-manage">
<div class="batch-manage-filter"> <div class="batch-manage-filter">
<ElForm :inline="true" :model="filterForm" size="default"> <ElForm class="search-form" :inline="true" :model="filterForm">
<ElFormItem label="创建时间"> <ElFormItem label="创建时间">
<el-date-picker <el-date-picker
v-model="filterForm.createTimeRange" v-model="filterForm.createTimeRange"
...@@ -12,26 +12,6 @@ ...@@ -12,26 +12,6 @@
style="width: 320px" style="width: 320px"
/> />
</ElFormItem> </ElFormItem>
<ElFormItem label="开始时间">
<el-date-picker
v-model="filterForm.startTimeRange"
type="datetimerange"
value-format="YYYY-MM-DD HH:mm:ss"
start-placeholder="开始时间"
end-placeholder="结束时间"
style="width: 320px"
/>
</ElFormItem>
<ElFormItem label="完成时间">
<el-date-picker
v-model="filterForm.finishTimeRange"
type="datetimerange"
value-format="YYYY-MM-DD HH:mm:ss"
start-placeholder="开始时间"
end-placeholder="结束时间"
style="width: 320px"
/>
</ElFormItem>
<ElFormItem label="创建人"> <ElFormItem label="创建人">
<ElInput <ElInput
v-model="filterForm.creator" v-model="filterForm.creator"
...@@ -40,14 +20,6 @@ ...@@ -40,14 +20,6 @@
style="width: 120px" style="width: 120px"
/> />
</ElFormItem> </ElFormItem>
<ElFormItem label="编排组">
<ElInput
v-model="filterForm.arrangeGroup"
placeholder="编排组"
clearable
style="width: 120px"
/>
</ElFormItem>
<ElFormItem label="工艺类型"> <ElFormItem label="工艺类型">
<ElSelect <ElSelect
v-model="filterForm.craftType" v-model="filterForm.craftType"
...@@ -105,45 +77,40 @@ ...@@ -105,45 +77,40 @@
</div> </div>
<div class="batch-manage-actions"> <div class="batch-manage-actions">
<ElButton type="danger" @click="handleBatchDelete">批量删除</ElButton> <span class="item">
<ElButton type="danger" @click="handleBatchDelete">批量删除</ElButton>
</span>
</div> </div>
<div class="batch-manage-table"> <div class="batch-manage-table">
<ElTable <TableView
v-loading="loading" :paginated-data="tableData"
:data="tableData" :columns="columns"
border selectionable
style="width: 100%"
@selection-change="handleSelectionChange" @selection-change="handleSelectionChange"
> >
<ElTableColumn type="selection" width="45" /> <template #downloadStatus="{ row }">
<ElTableColumn prop="batchNo" label="批次号" min-width="120" /> <el-tag
<ElTableColumn prop="downloadStatus" label="下载状态" min-width="90" align="center"> :type="row.downloadStatus === '已下载' ? 'success' : 'info'"
<template #default="{ row }"> size="small"
<el-tag :type="row.downloadStatus === '已下载' ? 'success' : 'info'" size="small"> >
{{ row.downloadStatus || '未下载' }} {{ row.downloadStatus || '未下载' }}
</el-tag> </el-tag>
</template> </template>
</ElTableColumn> <template #operation="{ row }">
<ElTableColumn prop="orderCount" label="订单数量" min-width="90" align="center" /> <ElButton type="primary" link size="small" @click="handleView(row)">
<ElTableColumn prop="totalCount" label="全部数量" min-width="90" align="center" /> 查看
<ElTableColumn prop="creator" label="创建人" min-width="80" /> </ElButton>
<ElTableColumn prop="craftType" label="工艺类型" min-width="90" /> <ElButton
<ElTableColumn prop="timesRange" label="次数范围" min-width="90" /> type="primary"
<ElTableColumn prop="createTime" label="创建时间" min-width="160" sortable /> link
<ElTableColumn prop="createTime" label="创建时间排序" min-width="110" sortable /> size="small"
<ElTableColumn prop="extractTimes" label="提取次数排序" min-width="110" sortable /> @click="handleDownload(row)"
<ElTableColumn label="操作" min-width="200" fixed="right"> >
<template #default="{ row }"> 下载
<ElButton type="primary" link size="small" @click="handleView(row)"> </ElButton>
查看 </template>
</ElButton> </TableView>
<ElButton type="primary" link size="small" @click="handleDownload(row)">
下载
</ElButton>
</template>
</ElTableColumn>
</ElTable>
</div> </div>
<ElPagination <ElPagination
...@@ -153,7 +120,7 @@ ...@@ -153,7 +120,7 @@
background background
layout="total, sizes, prev, pager, next, jumper" layout="total, sizes, prev, pager, next, jumper"
:total="total" :total="total"
style="margin-top: 10px" style="margin: 10px auto 0"
@size-change="handlePageSizeChange" @size-change="handlePageSizeChange"
@current-change="handleCurrentPageChange" @current-change="handleCurrentPageChange"
/> />
...@@ -165,6 +132,8 @@ import { ref, reactive, onMounted } from 'vue' ...@@ -165,6 +132,8 @@ import { ref, reactive, onMounted } from 'vue'
import { ElMessage, ElMessageBox } from 'element-plus' import { ElMessage, ElMessageBox } from 'element-plus'
import { getBatchManageListApi, batchDeleteApi } from '@/api/factoryOrderNew' import { getBatchManageListApi, batchDeleteApi } from '@/api/factoryOrderNew'
import type { BatchManageData } from '@/types/api/factoryOrderNew' import type { BatchManageData } from '@/types/api/factoryOrderNew'
import type { CustomColumn } from '@/types/table'
import TableView from '@/components/TableView.vue'
const loading = ref(false) const loading = ref(false)
const tableData = ref<BatchManageData[]>([]) const tableData = ref<BatchManageData[]>([])
...@@ -173,6 +142,63 @@ const currentPage = ref(1) ...@@ -173,6 +142,63 @@ const currentPage = ref(1)
const pageSize = ref(50) const pageSize = ref(50)
const total = ref(0) const total = ref(0)
const columns: CustomColumn<BatchManageData>[] = [
{ key: 'batchNo', prop: 'batchNo', label: '批次号', minWidth: 120 },
{
key: 'downloadStatus',
prop: 'downloadStatus',
label: '下载状态',
minWidth: 90,
align: 'center',
slot: 'downloadStatus',
},
{
key: 'orderCount',
prop: 'orderCount',
label: '订单数量',
minWidth: 90,
align: 'center',
},
{
key: 'totalCount',
prop: 'totalCount',
label: '全部数量',
minWidth: 90,
align: 'center',
},
{ key: 'creator', prop: 'creator', label: '创建人', minWidth: 80 },
{ key: 'craftType', prop: 'craftType', label: '工艺类型', minWidth: 90 },
{ key: 'timesRange', prop: 'timesRange', label: '次数范围', minWidth: 90 },
{
key: 'createTime',
prop: 'createTime',
label: '创建时间',
minWidth: 160,
sortable: true,
},
{
key: 'createTimeSort',
prop: 'createTime',
label: '创建时间排序',
minWidth: 110,
sortable: true,
},
{
key: 'extractTimes',
prop: 'extractTimes',
label: '提取次数排序',
minWidth: 110,
sortable: true,
},
{
key: 'operation',
label: '操作',
minWidth: 120,
fixed: 'right',
slot: 'operation',
},
]
const filterForm = reactive({ const filterForm = reactive({
createTimeRange: [] as string[], createTimeRange: [] as string[],
startTimeRange: [] as string[], startTimeRange: [] as string[],
...@@ -220,8 +246,9 @@ const handleBatchDelete = async () => { ...@@ -220,8 +246,9 @@ const handleBatchDelete = async () => {
await batchDeleteApi(selectedRows.value.map((r) => r.id)) await batchDeleteApi(selectedRows.value.map((r) => r.id))
ElMessage.success('删除成功') ElMessage.success('删除成功')
loadData() loadData()
} catch (e: any) { } catch (e) {
ElMessage.error(e?.message || '删除失败') const err = e as Error & { message?: string }
ElMessage.error(err?.message || '删除失败')
} }
} }
...@@ -266,7 +293,8 @@ defineExpose({ refresh }) ...@@ -266,7 +293,8 @@ defineExpose({ refresh })
.batch-manage-filter { .batch-manage-filter {
flex-shrink: 0; flex-shrink: 0;
padding-bottom: 10px; width: 100%;
min-width: 0;
} }
.batch-manage-actions { .batch-manage-actions {
...@@ -278,4 +306,20 @@ defineExpose({ refresh }) ...@@ -278,4 +306,20 @@ defineExpose({ refresh })
flex: 1; flex: 1;
overflow: auto; overflow: auto;
} }
.search-form {
display: flex;
flex-wrap: wrap;
align-items: center;
gap: 0;
min-width: 0;
:deep(.el-form-item) {
margin-right: 10px;
margin-bottom: 10px;
}
:deep(.el-form-item__content) {
min-width: 0;
}
}
</style> </style>
...@@ -26,7 +26,7 @@ ...@@ -26,7 +26,7 @@
</template> </template>
<template #top_right> <template #top_right>
<img <img
v-if="item.craftCode && ['ZPZY', 'CXZY', 'THZY'].includes(item.craftCode)" v-if="item.craftCode && ['ZPZY', 'CXZY', 'THZY'].includes(item.craftCode as string)"
:src="`/images/pic/${item.craftCode}.png`" :src="`/images/pic/${item.craftCode}.png`"
width="60" width="60"
height="60" height="60"
...@@ -40,7 +40,7 @@ ...@@ -40,7 +40,7 @@
<template #info> <template #info>
<div class="card-info-grid"> <div class="card-info-grid">
<div class="card-info-row full"> <div class="card-info-row full">
<span class="info-value ellipsis" :title="item.productName || ''"> <span class="info-value ellipsis" :title="(item.productName as string) || ''">
{{ item.productName }} {{ item.productName }}
</span> </span>
</div> </div>
...@@ -60,8 +60,8 @@ ...@@ -60,8 +60,8 @@
<span class="info-label">变体SKU</span> <span class="info-label">变体SKU</span>
<span <span
class="info-value clickable ellipsis" class="info-value clickable ellipsis"
:title="item.variantSku || ''" :title="(item.variantSku as string) || ''"
@click.stop="copyText(item.variantSku || '')" @click.stop="copyText((item.variantSku as string) || '')"
> >
{{ item.variantSku }} {{ item.variantSku }}
</span> </span>
...@@ -70,8 +70,8 @@ ...@@ -70,8 +70,8 @@
<span class="info-label">库存SKU</span> <span class="info-label">库存SKU</span>
<span <span
class="info-value clickable ellipsis" class="info-value clickable ellipsis"
:title="item.thirdSkuCode || ''" :title="(item.thirdSkuCode as string) || ''"
@click.stop="copyText(item.thirdSkuCode || '')" @click.stop="copyText((item.thirdSkuCode as string) || '')"
> >
{{ item.thirdSkuCode }} {{ item.thirdSkuCode }}
</span> </span>
...@@ -108,6 +108,7 @@ ...@@ -108,6 +108,7 @@
background background
layout="total, sizes, prev, pager, next, jumper" layout="total, sizes, prev, pager, next, jumper"
:total="total" :total="total"
style="margin: 0 auto"
@size-change="$emit('page-size-change', $event)" @size-change="$emit('page-size-change', $event)"
@current-change="$emit('current-page-change', $event)" @current-change="$emit('current-page-change', $event)"
/> />
......
<template> <template>
<div class="waiting-restock"> <div class="waiting-restock">
<div class="restock-filter"> <div class="restock-filter">
<ElForm :inline="true" :model="filterForm" size="default"> <ElForm :inline="true" :model="filterForm" size="default" class="search-form">
<ElFormItem label="仓库筛选" />
<ElFormItem label="库存SKU"> <ElFormItem label="库存SKU">
<ElInput <ElInput
v-model="filterForm.stockSku" v-model="filterForm.stockSku"
...@@ -27,63 +26,133 @@ ...@@ -27,63 +26,133 @@
</div> </div>
<div class="restock-table"> <div class="restock-table">
<ElTable v-loading="loading" :data="tableData" border style="width: 100%"> <TableView
<ElTableColumn type="index" label="序号" width="60" align="center" /> v-loading="loading"
<ElTableColumn prop="warehouseName" label="仓库名称" min-width="100" /> :paginated-data="pageData"
<ElTableColumn label="SKU图片" width="80" align="center"> :columns="columns"
<template #default="{ row }"> serial-numberable
<el-image >
v-if="row.skuImage" <template #skuImage="{ row }">
:src="row.skuImage" <el-image
style="width: 50px; height: 50px" v-if="row.skuImage"
fit="contain" :src="row.skuImage"
:preview-src-list="[row.skuImage]" style="width: 50px; height: 50px"
preview-teleported fit="contain"
/> :preview-src-list="[row.skuImage]"
</template> preview-teleported
</ElTableColumn> />
<ElTableColumn prop="productName" label="商品名称" min-width="120" show-overflow-tooltip /> </template>
<ElTableColumn prop="styleNo" label="款号" min-width="80" /> <template #shortageQuantity="{ row }">
<ElTableColumn prop="stockSku" label="库存SKU" min-width="120" /> <span style="color: #f56c6c; font-weight: bold">{{ row.shortageQuantity }}</span>
<ElTableColumn prop="shortageQuantity" label="缺货数量" min-width="90" align="center"> </template>
<template #default="{ row }"> <template #availableQuantity="{ row }">
<span style="color: #f56c6c; font-weight: bold">{{ row.shortageQuantity }}</span> <span :style="{ color: (row.availableQuantity || 0) < 0 ? '#f56c6c' : '' }">
</template> {{ row.availableQuantity }}
</ElTableColumn> </span>
<ElTableColumn prop="availableQuantity" label="可用数量" min-width="90" align="center"> </template>
<template #default="{ row }"> <template #operation="{ row }">
<span :style="{ color: (row.availableQuantity || 0) < 0 ? '#f56c6c' : '' }"> <ElButton type="primary" link size="small" @click="handleRestockCheck(row)">
{{ row.availableQuantity }} 补货校验
</span> </ElButton>
</template> </template>
</ElTableColumn> </TableView>
<ElTableColumn prop="stockQuantity" label="库存数量" min-width="90" align="center" />
<ElTableColumn prop="occupiedQuantity" label="占用数量" min-width="90" align="center" />
<ElTableColumn label="操作" width="120" align="center" fixed="right">
<template #default="{ row }">
<ElButton
type="primary"
link
size="small"
@click="handleRestockCheck(row)"
>
补货校验
</ElButton>
</template>
</ElTableColumn>
</ElTable>
</div> </div>
<ElPagination
v-model:current-page="currentPage"
v-model:page-size="pageSize"
:page-sizes="[50, 100, 200, 300]"
background
layout="total, sizes, prev, pager, next, jumper"
:total="total"
style="margin: 10px auto 0;"
@size-change="handlePageSizeChange"
@current-change="handleCurrentPageChange"
/>
</div> </div>
</template> </template>
<script setup lang="ts"> <script setup lang="ts">
import { ref, reactive, onMounted } from 'vue' import { computed, ref, reactive, onMounted } from 'vue'
import { ElMessage } from 'element-plus' import { ElMessage } from 'element-plus'
import { getRestockListApi, restockCheckApi } from '@/api/factoryOrderNew' import { getRestockListApi, restockCheckApi } from '@/api/factoryOrderNew'
import type { RestockData } from '@/types/api/factoryOrderNew' import type { RestockData } from '@/types/api/factoryOrderNew'
import type { CustomColumn } from '@/types/table'
import TableView from '@/components/TableView.vue'
const loading = ref(false) const loading = ref(false)
const tableData = ref<RestockData[]>([]) const allData = ref<RestockData[]>([])
const currentPage = ref(1)
const pageSize = ref(50)
const total = ref(0)
const pageData = computed(() => {
const start = (currentPage.value - 1) * pageSize.value
return allData.value.slice(start, start + pageSize.value)
})
const columns: CustomColumn<RestockData>[] = [
{
key: 'warehouseName',
prop: 'warehouseName',
label: '仓库名称',
minWidth: 100,
},
{
key: 'skuImage',
label: 'SKU图片',
width: 100,
align: 'center',
slot: 'skuImage',
},
{
key: 'productName',
prop: 'productName',
label: '商品名称',
minWidth: 120,
showOverflowTooltip: true,
},
{ key: 'styleNo', prop: 'styleNo', label: '款号', minWidth: 80 },
{ key: 'stockSku', prop: 'stockSku', label: '库存SKU', minWidth: 120 },
{
key: 'shortageQuantity',
prop: 'shortageQuantity',
label: '缺货数量',
minWidth: 90,
align: 'center',
slot: 'shortageQuantity',
},
{
key: 'availableQuantity',
prop: 'availableQuantity',
label: '可用数量',
minWidth: 90,
align: 'center',
slot: 'availableQuantity',
},
{
key: 'stockQuantity',
prop: 'stockQuantity',
label: '库存数量',
minWidth: 90,
align: 'center',
},
{
key: 'occupiedQuantity',
prop: 'occupiedQuantity',
label: '占用数量',
minWidth: 90,
align: 'center',
},
{
key: 'operation',
label: '操作',
width: 120,
align: 'center',
fixed: 'right',
slot: 'operation',
},
]
const filterForm = reactive({ const filterForm = reactive({
stockSku: '', stockSku: '',
...@@ -97,35 +166,50 @@ const loadData = async () => { ...@@ -97,35 +166,50 @@ const loadData = async () => {
stockSku: filterForm.stockSku || undefined, stockSku: filterForm.stockSku || undefined,
styleNo: filterForm.styleNo || undefined, styleNo: filterForm.styleNo || undefined,
}) })
tableData.value = res.data || [] allData.value = res.data || []
total.value = allData.value.length
} catch (_e) { } catch (_e) {
tableData.value = [] allData.value = []
total.value = 0
} finally { } finally {
loading.value = false loading.value = false
} }
} }
const handleSearch = () => { const handleSearch = () => {
currentPage.value = 1
loadData() loadData()
} }
const handleReset = () => { const handleReset = () => {
filterForm.stockSku = '' filterForm.stockSku = ''
filterForm.styleNo = '' filterForm.styleNo = ''
currentPage.value = 1
loadData() loadData()
} }
const handlePageSizeChange = (size: number) => {
pageSize.value = size
currentPage.value = 1
}
const handleCurrentPageChange = (page: number) => {
currentPage.value = page
}
const handleRestockCheck = async (row: RestockData) => { const handleRestockCheck = async (row: RestockData) => {
try { try {
await restockCheckApi(row.id) await restockCheckApi(row.id)
ElMessage.success('补货校验成功') ElMessage.success('补货校验成功')
loadData() loadData()
} catch (e: any) { } catch (e) {
ElMessage.error(e?.message || '补货校验失败') const err = e as Error & { message?: string }
ElMessage.error(err?.message || '补货校验失败')
} }
} }
const refresh = () => { const refresh = () => {
currentPage.value = 1
loadData() loadData()
} }
...@@ -153,4 +237,20 @@ defineExpose({ refresh }) ...@@ -153,4 +237,20 @@ defineExpose({ refresh })
flex: 1; flex: 1;
overflow: auto; overflow: auto;
} }
.search-form {
display: flex;
flex-wrap: wrap;
align-items: center;
gap: 0;
min-width: 0;
:deep(.el-form-item) {
margin-right: 10px;
margin-bottom: 10px;
}
:deep(.el-form-item__content) {
min-width: 0;
}
}
</style> </style>
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment