myERP/src/views/purchase/index.vue

528 lines
16 KiB
Vue
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<template>
<div class="pageBox">
<!-- <div class="searchBox">
<div class="row">
<span class="span">商品名称</span>
<div class="right"><el-input v-model="goods_name" class="wid100" clearable></el-input></div>
</div>
<div class="row">
<el-button type="primary" @click="handleSearch"><el-icon><Search /></el-icon>&nbsp;筛选</el-button>
</div>
</div> -->
<el-card shadow="never">
<div class="opaBox">
<el-button type="primary" @click="handleAdd"><el-icon><Plus /></el-icon>&nbsp;新增</el-button>
<!-- <el-button type="warning" @click="handleExport"><span class="iconfont icon-daochu"></span>&nbsp;导出</el-button> -->
</div>
<el-table :data="goodsList" style="width: 100%" border v-loading="loading">
<el-table-column prop="id" label="ID" width="80" align="center" />
<el-table-column prop="type" label="采购类型" align="center">
<template #default="scope">
<span>{{ Type[scope.row.type] }}</span>
</template>
</el-table-column>
<el-table-column prop="supplier.name" label="供应商" align="center" />
<el-table-column prop="warehouse.name" label="仓库" align="center" />
<el-table-column prop="batch_number" label="批次" align="center" />
<el-table-column label="采购单" align="center" min-width="150">
<template #default="scope">
<div class="imgBox">
<el-image :z-index="9999" v-for="(item, index) in scope.row.images" :key="index" :src="item" :hide-on-click-modal="true" :preview-src-list="[item]" fit="cover" :preview-teleported="true" />
</div>
</template>
</el-table-column>
<el-table-column prop="attachments" label="附件">
<template #default="scope">
<div class="imgBox">
<a :href="scope.row.attachments" target="_blank" style="word-break: break-all;">{{scope.row.attachments}}</a>
</div>
</template>
</el-table-column>
<el-table-column prop="in_put_time" label="入仓时间" align="center" />
<el-table-column prop="purchasing_agent" label="采购人" align="center" />
<el-table-column prop="admin_user.username" label="创建人" align="center" />
<el-table-column prop="note" label="备注" align="center" />
<el-table-column prop="created_at" label="创建时间" align="center" />
</el-table>
<div class="page-pagination">
<el-pagination
:current-page="page"
background
layout="prev, pager, next, sizes, total"
:total="total"
:page-sizes="[10, 50, 100]"
:page-size="pageSize"
@size-change="handleSizeChange"
@current-change="handleCurrentChange"></el-pagination>
</div>
</el-card>
<el-dialog v-model="showDialog" width="900px" title="新增" @close="resetForm">
<el-form label-position="right" label-width="110px">
<el-form-item label="采购类型:">
<el-radio-group v-model="itemInfo.type">
<el-radio label="default">默认</el-radio>
</el-radio-group>
</el-form-item>
<el-form-item label="供应商:">
<el-select v-model="itemInfo.supplier_id" placeholder="请选择" clearable filterable>
<el-option v-for="it in suppliersList" :key="it.id" :label="it.name" :value="it.id" />
</el-select>
</el-form-item>
<el-form-item label="仓库:">
<el-select v-model="itemInfo.warehouse_id" placeholder="请选择" clearable filterable>
<el-option v-for="it in warehouseList" :key="it.id" :label="it.name" :value="it.id" />
</el-select>
</el-form-item>
<el-form-item label="采购人:">
<el-input v-model="itemInfo.purchasing_agent" clearable></el-input>
</el-form-item>
<el-form-item label="入仓时间:">
<el-date-picker
v-model="itemInfo.in_put_time"
type="datetime"
format="YYYY-MM-DD HH:mm:ss"
value-format="YYYY-MM-DD HH:mm:ss"
placeholder="选择日期"
clearable>
</el-date-picker>
</el-form-item>
<el-form-item label="批次号:">
<el-input v-model="itemInfo.batch_number" clearable></el-input>
</el-form-item>
<el-form-item label="采购单:">
<el-upload
ref="uploadRef"
action="/api/upload/img"
:headers="headers"
:on-remove="handleImgRemove"
:on-error="handleUploadError"
:on-preview="handlePreview"
:on-success="handleImgSuccess"
:file-list="imgsList"
:show-file-list="true"
list-type="picture-card"
accept=".png,.jpg,.gif">
<el-icon><Plus /></el-icon>
</el-upload>
</el-form-item>
<el-form-item label="附件:">
<el-upload
action="/api/upload/file"
:on-success="handleFileSuccess"
:on-remove="handleFileRemove"
:before-upload="handleBeforeUpload"
:on-error="handleUploadError"
:on-preview="previewFile"
:headers="headers"
:file-list="fileList"
:show-file-list="true">
<el-button type="primary">上传附件</el-button>
<template #tip>
<div class="el-upload__tip">请上传zip、pdf、excel、docdocx格式附件最大限制为 4 M</div>
</template>
</el-upload>
</el-form-item>
<el-form-item label="备注:">
<el-input v-model="itemInfo.note" type="textarea" :rows="4"></el-input>
</el-form-item>
</el-form>
<div v-for="(item, i) in skusList" :key="i" class="skuBox">
<div class="tit">采购商品{{ i + 1 }}</div>
<el-form label-width="110px" :inline="true">
<!-- <el-form-item label="所属商品:">
<el-select v-model="item.goods_id" placeholder="请选择" clearable filterable style="width: 220px;" @change="changeGoods(item)">
<el-option v-for="it in allGoodsList" :key="it.id" :label="it.title" :value="it.id" />
</el-select>
</el-form-item> -->
<el-form-item label="商品/规格:" style="width: 100%;">
<el-select v-model="item.sku_id" placeholder="请选择" clearable filterable style="width: 680px;">
<el-option v-for="it in guigeList" :key="it.id" :label="it.goods && it.goods.title + ' - ' + it.title" :value="it.id" />
</el-select>
</el-form-item>
<el-form-item label="采购数量:">
<el-input-number v-model="item.num" :min="0" style="width: 270px;" />
</el-form-item>
<el-form-item label="采购成本:">
<el-input placeholder="采购成本" v-model="item.cost" clearable style="width: 270px;"></el-input>
</el-form-item>
<el-form-item label="生产日期:">
<el-date-picker
v-model="item.production_date"
type="date"
format="YYYY-MM-DD"
value-format="YYYY-MM-DD"
placeholder="选择日期"
style="width: 270px;"
clearable>
</el-date-picker>
</el-form-item>
<el-form-item label="出厂日期:">
<el-date-picker
v-model="item.factory_date"
type="date"
format="YYYY-MM-DD"
value-format="YYYY-MM-DD"
placeholder="选择日期"
style="width: 270px;"
clearable>
</el-date-picker>
</el-form-item>
<el-form-item label="有效期类型:">
<el-radio-group v-model="item.validity_type" style="width: 270px;">
<el-radio label="day">天</el-radio>
<el-radio label="month">月</el-radio>
<el-radio label="year">年</el-radio>
<el-radio label="none">长期</el-radio>
</el-radio-group>
</el-form-item>
<el-form-item label="有效时间:">
<el-input-number v-model="item.validity" :min="0" style="width: 270px;" />
</el-form-item>
<el-form-item label="批次号:">
<el-input placeholder="批次号" v-model="item.batch_number" clearable style="width: 270px;"></el-input>
</el-form-item>
<el-form-item label=" ">
<el-button type="danger" @click="handleSkuDelete(i)" size="small"><el-icon><Delete /></el-icon>&nbsp;删除</el-button>
</el-form-item>
</el-form>
</div>
<el-form label-position="right" label-width="110px">
<el-form-item label="">
<el-button type="success" @click="toAddSku()">增加采购商品</el-button>
</el-form-item>
</el-form>
<template #footer>
<span class="dialog-footer">
<el-button @click="showDialog = false">取消</el-button>
<el-button type="primary" @click="commitOpa()" :loading="opa_loading">确定</el-button>
</span>
</template>
</el-dialog>
<!-- 预览图片 -->
<el-dialog v-model="picVisible" center width="800px">
<img :src="dialogImageUrl" style="max-width: 700px; margin: 0 auto;display: block;" />
</el-dialog>
</div>
</template>
<script>
import { onMounted, reactive, toRefs, ref, nextTick } from "vue"
import { get, post } from "@/api/request"
import { Search, Plus, Edit, ZoomIn, Delete } from '@element-plus/icons'
import { ElMessage, ElMessageBox } from 'element-plus'
import { parseErrors } from 'components/common'
export default {
components: {
Search, Plus, Edit, ZoomIn, Delete
},
setup() {
const data = reactive({
goodsList: [],
page: 1,
pageSize: 10,
total: 0,
loading: false,
pickerTime: [],
showDialog: false,
opa_loading: false,
headers: {
Authorization: localStorage.getItem('token'),
'Shop-Id': localStorage.getItem('shopId') || ''
},
picVisible: false,
dialogImageUrl: '',
imgsList: [],
fileList: [],
Type: {
'default': '默认'
},
warehouseList: [],
suppliersList: [],
guigeList: [],
itemInfo: {},
skusList: [],
qaFileList: [],
allGoodsList: [],
})
function handleSearch() {
data.page = 1
fetchData()
}
const fetchData = () => {
data.loading = true
let params = {
page: data.page,
pageSize: data.pageSize,
service_id: data.service_id,
start_date: data.pickerTime ? data.pickerTime[0] : '',
end_date: data.pickerTime ? data.pickerTime[1] : ''
}
get(`/api/purchases`, params).then((res) => {
data.goodsList = res.data
data.total = res.meta.total
data.loading = false
}).catch(() => {
data.loading = false
})
}
function handleCurrentChange(e) {
data.page = e
fetchData()
}
function handleSizeChange(e) {
data.page = 1
data.pageSize = e
fetchData()
}
function handleAdd() {
data.imgsList = []
data.qaFileList = []
data.skusList = []
data.itemInfo = {
type: 'default'
}
data.showDialog = true
}
function commitOpa() {
if(!data.skusList.length) {
ElMessage({ type: 'info', message: '请添加采购商品' })
return
}
data.opa_loading = true
let imgs = []
data.imgsList.forEach((it) => {
imgs.push(it.url)
})
let params = {
...data.itemInfo
}
params.goodsSkus = data.skusList
params.images = imgs
params.attachments = data.qaFileList.length ? data.qaFileList[0].url : ''
post(`/api/purchases`, params).then(() => {
data.page = 1
fetchData()
ElMessage({ type: 'success', message: '新增成功' })
data.showDialog = false
data.opa_loading = false
}).catch((err) => {
data.opa_loading = false
parseErrors(err.response.data.errors)
})
}
function handleImgRemove(res, ress) {
data.replyImg = ress
}
function handleUploadError(err) {
if(JSON.parse(err.message) && JSON.parse(err.message).message) {
ElMessage({ type: 'error', message: JSON.parse(err.message).message })
}
}
function handlePreview(File) {
data.dialogImageUrl = File.url
data.picVisible = true
}
function handleImgSuccess(res) {
data.imgsList.push({url: res.data.link})
}
function handleFileSuccess(res, ress) {
if (res.code === 0) {
data.qaFileList = [{ name: ress.name, url: res.data.link }]
}
}
function handleFileRemove(res, ress) {
data.qaFileList = ress
}
function previewFile(File) {
window.open(File.response.data.link)
}
const handleBeforeUpload = (file) => {
let type = file.name.indexOf('.pdf') !== -1 || file.name.indexOf('.doc') !== -1 || file.name.indexOf('.docx') !== -1 || file.name.indexOf('.zip') !== -1 || file.name.indexOf('.xlsx') !== -1
if (type) {
const isLt4M = file.size / 1024 / 1024 < 4
if (!isLt4M) {
ElMessage.error('附件上传大小不能超过 4MB!')
return false
}
} else {
ElMessage.error('上传文件格式不正确')
return false
}
}
function handleSkuDelete(index) {
data.skusList.splice(index, 1)
}
const uploadRef = ref(null)
const resetForm = () => {
data.imgsList = []
nextTick(() => {
uploadRef.value.clearFiles()
})
}
function toAddSku() {
let sku = {
goods_id: '',
sku_id: '',
num: 1,
cost: '',
production_date: '',
factory_date: '',
validity_type: '',
validity: '',
batch_number: ''
}
data.skusList.push(sku)
}
function getWarehouseList() {
get(`/api/all/warehouses`).then((res) => {
data.warehouseList = res.data
})
}
function getSuppliersList() {
get(`/api/suppliers`, {pageSize: 1000}).then((res) => {
data.suppliersList = res.data
})
}
function getSkusList() {
get(`/api/all/goods-skus`).then((res) => {
data.guigeList = res.data
})
}
function getAllGoodsList() {
get(`/api/all/goods`).then((res) => {
data.allGoodsList = res.data
})
}
function changeGoods(row) {
row.sku_id = ''
get(`/api/all/goods-skus`, {goods_id: row.goods_id}).then((res) => {
data.guigeList = res.data
})
}
onMounted(() => {
fetchData()
getWarehouseList()
getSuppliersList()
getSkusList()
getAllGoodsList()
})
return {
uploadRef,
...toRefs(data),
handleSearch,
handleCurrentChange,
handleSizeChange,
fetchData,
handleAdd,
commitOpa,
handleImgRemove,
handleUploadError,
handlePreview,
handleImgSuccess,
handleSkuDelete,
resetForm,
toAddSku,
handleFileSuccess,
handleFileRemove,
previewFile,
handleBeforeUpload,
getWarehouseList,
getSuppliersList,
getSkusList,
getAllGoodsList,
changeGoods
}
}
}
</script>
<style lang="scss" scoped>
.searchBox{
display: flex;
flex-wrap: wrap;
background-color: #fff;
padding: 15px 0 0 0;
border-radius: 4px;
margin-bottom: 15px;
.row{
display: flex;
align-items: center;
width: 20%;
box-sizing: border-box;
margin-bottom: 15px;
&.row1{
width: 25%;
}
.span{
display: block;
width: 80px;
font-size: 14px;
text-align: right;
box-sizing: border-box;
}
.right{
width: calc(100% - 100px);
}
.wid100{
width: 100%;
}
}
}
.opaBox{
margin-bottom: 15px;
}
.imgBox{
display: flex;
flex-wrap: wrap;
.el-image{
width: 60px;
height: 60px;
border-radius: 4px;
margin-right: 10px;
}
}
.skuBox{
border: 1px solid #e5e5e5;
border-radius: 5px;
padding: 15px 0;
margin-bottom: 15px;
background-color: #f3f3f3;
.tit{
padding-left: 40px;
font-weight: 600;
font-size: 15px;
margin-bottom: 15px;
}
}
</style>