index.vue 11.3 KB
<template>
	<div class="NCC-common-layout">
		<div class="NCC-common-layout-center">
			<!-- 产品查询条件 -->
			<el-row class="NCC-common-search-box" :gutter="16">
				<el-form @submit.native.prevent>
					<el-col :span="6">
						<el-form-item label="产品名称">
							<el-input v-model="productQuery.productName" placeholder="产品名称" clearable />
						</el-form-item>
					</el-col>
					<el-col :span="6">
						<el-form-item label="产品类别">
							<el-input v-model="productQuery.productCategory" placeholder="产品类别" clearable />
						</el-form-item>
					</el-col>
					<el-col :span="6">
						<el-form-item label="上架状态">
							<el-select v-model="productQuery.onShelfStatus" placeholder="上架状态" clearable>
								<el-option label="上架" :value="1" />
								<el-option label="下架" :value="0" />
							</el-select>
						</el-form-item>
					</el-col>
					<el-col :span="6">
						<el-form-item>
							<el-button type="primary" icon="el-icon-search" @click="searchProduct()">查询</el-button>
							<el-button icon="el-icon-refresh-right" @click="resetProduct()">重置</el-button>
						</el-form-item>
					</el-col>
				</el-form>
			</el-row>
			<!-- 产品列表 -->
			<div class="NCC-common-layout-main NCC-flex-main">
				<div class="NCC-common-head">
					<div>
						<el-button type="primary" icon="el-icon-plus" @click="addProduct()">新增产品</el-button>
						<el-button type="primary" icon="el-icon-plus" @click="addInventory()">添加库存</el-button>
						<el-button type="primary" icon="el-icon-plus" @click="addUsage()">添加使用记录</el-button>
						<el-button type="success" icon="el-icon-document" @click="viewApplicationList()">申请列表</el-button>
						<el-button type="info" icon="el-icon-data-analysis" @click="viewStatistics()">门店领取统计</el-button>
						<el-button type="primary" icon="el-icon-printer" @click="viewPendingDelivery()">待领取统计</el-button>
					</div>
					<div class="NCC-common-head-right">
						<el-tooltip effect="dark" content="刷新" placement="top">
							<el-link icon="icon-ym icon-ym-Refresh NCC-common-head-icon" :underline="false"
								@click="initProductData()" />
						</el-tooltip>
						<screenfull isContainer />
					</div>
				</div>
				<NCC-table v-loading="productLoading" :data="productList"
					:header-cell-style="{ background: '#f5f7fa', color: '#606266' }">
					<!-- <el-table-column label="产品ID" align="center">
						<template slot-scope="scope">
							<div class="product-id-info">
								<i class="el-icon-postcard product-id-icon"></i>
								<span class="text-nowrap">{{ scope.row.id || '无' }}</span>
							</div>
						</template>
					</el-table-column> -->
					<el-table-column label="产品名称" width="180" align="center" prop="productName"/>
					<el-table-column label="价格" align="center">
						<template slot-scope="scope">
							<div class="price-info">
								<i class="el-icon-coin price-icon"></i>
								<span class="text-nowrap">¥{{ formatMoney(scope.row.averagePrice) }}</span>
							</div>
						</template>
					</el-table-column>
					<el-table-column label="库存" align="center" prop="currentInventory"/>
					<el-table-column label="产品类别" align="center" prop="productCategory"/>
					<el-table-column label="归属部门" align="center" prop="departmentName">
						<template slot-scope="scope">
							<div class="department-info">
								<span class="text-nowrap">{{ scope.row.departmentName || '无' }}</span>
							</div>
						</template>
					</el-table-column>

					<el-table-column label="标准单位" align="center" prop="standardUnit"/>
					<el-table-column label="上架状态" align="center" prop="onShelfStatus">
						<template slot-scope="scope">
							<div class="shelf-status-info">
								<el-tag :type="scope.row.onShelfStatus === 1 ? 'success' : 'info'" size="small">
									{{ scope.row.onShelfStatus === 1 ? '上架' : '下架' }}
								</el-tag>
							</div>
						</template>
					</el-table-column>
					<el-table-column label="统计分类" align="center" prop="statisticsCategory"/>
					<el-table-column label="归属仓库" align="center" prop="warehouse">
						<template slot-scope="scope">
							<div class="warehouse-info">
								<i class="el-icon-office-building warehouse-icon"></i>
								<span class="text-nowrap">{{ scope.row.warehouse || '无' }}</span>
							</div>
						</template>
					</el-table-column>
					<el-table-column label="供应商名称" align="center" prop="supplierName"/>
					<!-- <el-table-column label="合同签订日期" align="center" prop="contractSignDate"/>
					<el-table-column label="合同结束日期" align="center" prop="contractEndDate"/>
					<el-table-column label="备注" align="center" prop="remark"/> -->
					<el-table-column label="操作" width="280" align="left" fixed="right">
						<template slot-scope="scope">
							<div class="action-buttons">
								<el-button v-if="scope.row.onShelfStatus === 1" type="text" icon="el-icon-view" @click="viewDetail(scope.row)"
									class="view-btn">
									查看详情
								</el-button>
								<el-button type="text" @click="toggleShelf(scope.row)">
									{{ scope.row.onShelfStatus === 1 ? '下架' : '上架' }}
								</el-button>
								<el-button v-if="scope.row.onShelfStatus === 1" type="text" icon="el-icon-edit" @click="editProduct(scope.row)"
									class="edit-btn">
									编辑
								</el-button>
							</div>
						</template>
					</el-table-column>
				</NCC-table>
				<pagination :total="productTotal" :page.sync="productQuery.currentPage"
					:limit.sync="productQuery.pageSize" @pagination="initProductData" />
			</div>
		</div>
		<!-- 产品表单弹窗 -->
		<ProductForm v-if="productFormVisible" ref="ProductForm" @refresh="refreshProduct" />
		<!-- 产品详情弹窗(库存和使用记录) -->
		<ProductDetailDialog v-if="detailDialogVisible" ref="ProductDetailDialog" @refresh="refreshProduct" />
		<!-- 添加使用记录弹窗(多产品) -->
		<UsageMultiForm v-if="usageMultiFormVisible" ref="UsageMultiForm" @refresh="refreshProduct" />
		<!-- 添加库存弹窗 -->
		<InventoryForm v-if="inventoryFormVisible" ref="InventoryForm" @refresh="refreshProduct" />
	</div>
</template>

<script>
import request from '@/utils/request'
import ProductForm from './product-form.vue'
import ProductDetailDialog from './product-detail-dialog.vue'
import UsageMultiForm from './usage-multi-form.vue'
import InventoryForm from './inventory-form.vue'

export default {
	components: { ProductForm, ProductDetailDialog, UsageMultiForm, InventoryForm },
	data() {
		return {
			// 产品相关
			productList: [],
			productLoading: false,
			productTotal: 0,
			productQuery: {
				currentPage: 1,
				pageSize: 20,
				productName: undefined,
				productCategory: undefined,
				onShelfStatus: undefined
			},
			productFormVisible: false,
			detailDialogVisible: false,
			usageMultiFormVisible: false,
			inventoryFormVisible: false
		}
	},
	created() {
		this.initProductData()
	},
	methods: {
		// 产品相关方法
		initProductData() {
			this.productLoading = true
			let query = { ...this.productQuery }
			// 移除空值
			Object.keys(query).forEach(key => {
				if (query[key] === undefined || query[key] === null || query[key] === '') {
					delete query[key]
				}
			})
			request({
				url: '/api/Extend/LqProduct/GetList',
				method: 'GET',
				data: query
			}).then(res => {
				if (res.code == 200 && res.data) {
					this.productList = res.data.list || []
					this.productTotal = res.data.pagination ? res.data.pagination.total : 0
				} else {
					this.productList = []
					this.productTotal = 0
				}
				this.productLoading = false
			}).catch(() => {
				this.productLoading = false
				this.productList = []
				this.productTotal = 0
			})
		},
		searchProduct() {
			this.productQuery.currentPage = 1
			this.initProductData()
		},
		resetProduct() {
			this.productQuery = {
				currentPage: 1,
				pageSize: 20,
				productName: undefined,
				productCategory: undefined,
				onShelfStatus: undefined
			}
			this.initProductData()
		},
		addProduct() {
			this.productFormVisible = true
			this.$nextTick(() => {
				this.$refs.ProductForm.init()
			})
		},
		editProduct(row) {
			this.productFormVisible = true
			this.$nextTick(() => {
				this.$refs.ProductForm.init(row.id)
			})
		},
		viewDetail(row) {
			this.detailDialogVisible = true
			this.$nextTick(() => {
				this.$refs.ProductDetailDialog.init(row.id, row)
				this.$forceUpdate()
			})
		},
		toggleShelf(row) {
			const status = row.onShelfStatus === 1 ? 0 : 1
			const statusText = status === 1 ? '上架' : '下架'
			this.$confirm(`确定要${statusText}该产品吗?`, '提示', {
				type: 'warning'
			}).then(() => {
				request({
					url: '/api/Extend/LqProduct/ToggleShelf',
					method: 'PUT',
					data: {
						productId: row.id,
						onShelfStatus: status
					}
				}).then(res => {
					this.$message({
						type: 'success',
						message: res.msg || `${statusText}成功`,
						onClose: () => {
							this.initProductData()
						}
					})
				})
			}).catch(() => { })
		},
		refreshProduct() {
			this.productFormVisible = false
			this.usageMultiFormVisible = false
			this.inventoryFormVisible = false
			this.initProductData()
		},
		addInventory() {
			this.inventoryFormVisible = true
			this.$nextTick(() => {
				// 从列表页调用,不传产品ID,只显示上架产品
				this.$refs.InventoryForm.init()
			})
		},
		addUsage() {
			this.usageMultiFormVisible = true
			this.$nextTick(() => {
				this.$refs.UsageMultiForm.init()
			})
		},
		viewApplicationList() {
			this.$router.push({
				path: '/lqInventory/application-list',
				query: {}
			})
		},
		viewStatistics() {
			this.$router.push({
				path: '/lqInventory/store-receive-statistics',
				query: {}
			})
		},
		viewPendingDelivery() {
			this.$router.push({
				path: '/lqInventory/warehouse-pending-delivery',
				query: {}
			})
		},
		// 工具方法
		formatMoney(amount) {
			if (!amount && amount !== 0) return '0.00'
			return Number(amount).toFixed(2)
		}
	}
}
</script>

<style lang="scss" scoped>
// 通用文本不换行样式
.text-nowrap {
	white-space: nowrap;
	overflow: hidden;
	text-overflow: ellipsis;
	max-width: 100%;
}

// 产品相关样式
.product-id-info,
.product-name-info,
.price-info,
.category-info,
.unit-info,
.shelf-status-info,
.statistics-info,
.warehouse-info,
.supplier-info {
	display: flex;
	align-items: center;
	justify-content: center;
	gap: 6px;
}

.product-id-icon,
.product-name-icon {
	color: #409EFF;
	font-size: 16px;
}

.price-icon {
	color: #67C23A;
	font-size: 16px;
}

.category-icon,
.unit-icon,
.statistics-icon {
	color: #909399;
	font-size: 16px;
}

.shelf-status-icon {
	font-size: 16px;

	&.status-on {
		color: #67C23A;
	}

	&.status-off {
		color: #909399;
	}
}

.warehouse-icon,
.supplier-icon {
	color: #409EFF;
	font-size: 16px;
}

// 操作按钮样式
.action-buttons {
	display: flex;
	align-items: center;
	gap: 8px;

	.view-btn {
		color: #409EFF;

		&:hover {
			color: #66b1ff;
		}
	}

	.edit-btn {
		color: #409EFF;

		&:hover {
			color: #66b1ff;
		}
	}
}

// 表格行悬停效果
::v-deep .el-table__row:hover {
	background-color: #f5f7fa;
}

// 表格头部样式
::v-deep .el-table__header-wrapper {
	.el-table__header {
		th {
			background-color: #f5f7fa;
			color: #606266;
			font-weight: 600;
		}
	}
}
</style>