- 配置.env文件支持环境变量管理 - 集成MyBatis Plus ORM框架并配置数据库连接 - 实现JWT认证和Spring Security安全配置 - 添加全局异常处理机制和统一响应结果封装 - 配置CORS跨域资源共享支持 - 实现用户认证API包括登录、注册、刷新token功能 - 开发完整的药品管理系统包含分类、药品、库存管理 - 实现出入库管理功能包括供应商、客户管理 - 添加角色权限管理和菜单配置 - 实现仪表盘统计和过期预警功能 - 配置分页查询和数据验证功能 ```
131 lines
6.0 KiB
Vue
131 lines
6.0 KiB
Vue
<script setup>
|
||
import { ref, reactive, onMounted } from 'vue'
|
||
import { useRouter } from 'vue-router'
|
||
import { getStockOutList, getStockOutById, auditStockOut } from '@/api/stockOut'
|
||
import { Search, Refresh, Plus } from '@element-plus/icons-vue'
|
||
import { ElMessage, ElMessageBox } from 'element-plus'
|
||
|
||
const router = useRouter()
|
||
const query = reactive({ page: 1, size: 10, recordNo: '' })
|
||
const tableData = ref([])
|
||
const total = ref(0)
|
||
const loading = ref(false)
|
||
const detailVisible = ref(false)
|
||
const detailRecord = ref({})
|
||
const detailItems = ref([])
|
||
|
||
const statusMap = { 0: { type: 'warning', text: '待审核' }, 1: { type: 'success', text: '已出库' }, 2: { type: 'info', text: '已取消' } }
|
||
const typeMap = { 1: '销售出库', 2: '领用出库', 3: '报损出库', 4: '退货出库' }
|
||
|
||
async function loadData() {
|
||
loading.value = true
|
||
try {
|
||
const r = await getStockOutList(query)
|
||
tableData.value = r.data?.records || []
|
||
total.value = r.data?.total || 0
|
||
} finally { loading.value = false }
|
||
}
|
||
|
||
function handleCreate() { router.push('/stock-out/add') }
|
||
async function handleView(row) {
|
||
try {
|
||
const r = await getStockOutById(row.id)
|
||
detailRecord.value = r.data || row
|
||
detailItems.value = r.data?.details || []
|
||
detailVisible.value = true
|
||
} catch { ElMessage.error('获取详情失败') }
|
||
}
|
||
|
||
async function handleAudit(row) {
|
||
await ElMessageBox.confirm(`确认审核通过出库单 ${row.recordNo}?审核后库存将自动扣减。`, '审核确认', { type: 'success' })
|
||
await auditStockOut(row.id, { status: 1 })
|
||
ElMessage.success('审核通过,库存已扣减')
|
||
loadData()
|
||
}
|
||
|
||
async function handleReject(row) {
|
||
await ElMessageBox.confirm(`确认驳回出库单 ${row.recordNo}?`, '驳回确认', { type: 'warning' })
|
||
await auditStockOut(row.id, { status: 2 })
|
||
ElMessage.success('已驳回')
|
||
loadData()
|
||
}
|
||
|
||
onMounted(loadData)
|
||
</script>
|
||
|
||
<template>
|
||
<div class="page-container">
|
||
<div class="search-bar">
|
||
<el-input v-model="query.recordNo" placeholder="出库单号" clearable style="width:200px" @keyup.enter="loadData" />
|
||
<el-button type="primary" :icon="Search" @click="loadData">搜索</el-button>
|
||
<el-button :icon="Refresh" @click="query.recordNo='';loadData()">重置</el-button>
|
||
</div>
|
||
<div class="tool-bar">
|
||
<el-button type="primary" v-permission="'stock-out:add'" :icon="Plus" @click="handleCreate">新建出库单</el-button>
|
||
</div>
|
||
|
||
<el-table :data="tableData" border stripe v-loading="loading">
|
||
<el-table-column prop="recordNo" label="出库单号" width="160" />
|
||
<el-table-column prop="customerName" label="客户" min-width="160">
|
||
<template #default="{ row }">{{ row.customerName || '-' }}</template>
|
||
</el-table-column>
|
||
<el-table-column prop="outType" label="类型" width="110">
|
||
<template #default="{ row }">{{ typeMap[row.outType] || '未知' }}</template>
|
||
</el-table-column>
|
||
<el-table-column prop="totalAmount" label="总金额" width="120">
|
||
<template #default="{ row }">¥{{ row.totalAmount }}</template>
|
||
</el-table-column>
|
||
<el-table-column prop="outDate" label="出库日期" width="120" />
|
||
<el-table-column prop="status" label="状态" width="100" align="center">
|
||
<template #default="{ row }">
|
||
<el-tag :type="statusMap[row.status]?.type || 'info'" size="small">
|
||
{{ statusMap[row.status]?.text || '未知' }}
|
||
</el-tag>
|
||
</template>
|
||
</el-table-column>
|
||
<el-table-column prop="remark" label="备注" min-width="150" show-overflow-tooltip />
|
||
<el-table-column label="操作" width="220" fixed="right">
|
||
<template #default="{ row }">
|
||
<div class="table-actions">
|
||
<el-button size="small" @click="handleView(row)">查看</el-button>
|
||
<template v-if="row.status === 0">
|
||
<el-button size="small" type="success" v-permission="'stock-out:audit'" @click="handleAudit(row)">通过</el-button>
|
||
<el-button size="small" type="danger" @click="handleReject(row)">驳回</el-button>
|
||
</template>
|
||
</div>
|
||
</template>
|
||
</el-table-column>
|
||
</el-table>
|
||
|
||
<div style="display:flex;justify-content:flex-end;margin-top:16px">
|
||
<el-pagination
|
||
v-model:current-page="query.page" v-model:page-size="query.size"
|
||
:total="total" :page-sizes="[10,20,50]"
|
||
layout="total,sizes,prev,pager,next"
|
||
@current-change="loadData" @size-change="query.page=1;loadData()"
|
||
/>
|
||
</div>
|
||
|
||
<el-dialog v-model="detailVisible" title="出库单详情" width="750px">
|
||
<el-descriptions :column="3" border>
|
||
<el-descriptions-item label="出库单号">{{ detailRecord.recordNo }}</el-descriptions-item>
|
||
<el-descriptions-item label="客户">{{ detailRecord.customerName || '-' }}</el-descriptions-item>
|
||
<el-descriptions-item label="出库日期">{{ detailRecord.outDate }}</el-descriptions-item>
|
||
<el-descriptions-item label="类型">{{ typeMap[detailRecord.outType] }}</el-descriptions-item>
|
||
<el-descriptions-item label="总金额">¥{{ detailRecord.totalAmount }}</el-descriptions-item>
|
||
<el-descriptions-item label="状态">
|
||
<el-tag :type="statusMap[detailRecord.status]?.type" size="small">{{ statusMap[detailRecord.status]?.text }}</el-tag>
|
||
</el-descriptions-item>
|
||
</el-descriptions>
|
||
<h4 style="margin:16px 0 8px">药品明细</h4>
|
||
<el-table :data="detailItems" border size="small" max-height="300">
|
||
<el-table-column prop="medicineName" label="药品" min-width="160" />
|
||
<el-table-column prop="batchNo" label="批号" width="120" />
|
||
<el-table-column prop="quantity" label="数量" width="80" />
|
||
<el-table-column prop="unitPrice" label="单价" width="90"><template #default="{row}">¥{{row.unitPrice}}</template></el-table-column>
|
||
<el-table-column prop="totalPrice" label="小计" width="100"><template #default="{row}">¥{{row.totalPrice}}</template></el-table-column>
|
||
</el-table>
|
||
</el-dialog>
|
||
</div>
|
||
</template>
|