Files
wq-wms-java/nladmin-ui/src/views/wms/st/outbill/index.vue
2026-08-05 09:29:21 +08:00

559 lines
20 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="app-container">
<!--工具栏-->
<div class="head-container">
<div v-if="crud.props.searchToggle">
<!-- 搜索 -->
<el-form
:inline="true"
class="demo-form-inline"
label-position="right"
label-width="80px"
label-suffix=":"
>
<el-form-item label="模糊查询">
<el-input
v-model="query.bill_code"
size="mini"
clearable
placeholder="单据号"
@keyup.enter.native="crud.toQuery"
/>
</el-form-item>
<el-form-item label="物料编码">
<el-input
v-model="query.material_code"
size="mini"
clearable
placeholder="物料编码"
@keyup.enter.native="crud.toQuery"
/>
</el-form-item>
<el-form-item label="所属仓库">
<el-select
v-model="query.stor_id"
collapse-tags
clearable
size="mini"
placeholder="全部"
class="filter-item"
>
<el-option
v-for="item in storlist"
:key="item.stor_id"
:label="item.stor_name"
:value="item.stor_id"
/>
</el-select>
</el-form-item>
<el-form-item label="单据状态">
<el-select
v-model="query.bill_status"
collapse-tags
clearable
size="mini"
placeholder="单据状态"
class="filter-item"
>
<el-option
v-for="item in dict.io_bill_status"
:key="item.value"
:label="item.label"
:value="item.value"
/>
</el-select>
</el-form-item>
<el-form-item label="业务类型">
<el-select
v-model="query.bill_type"
collapse-tags
clearable
filterable
size="mini"
placeholder="业务类型"
class="filter-item"
>
<el-option
v-for="item in dict.ST_INV_OUT_TYPE"
:key="item.value"
:label="item.label"
:value="item.value"
/>
</el-select>
</el-form-item>
<el-form-item label="批次号">
<el-input
v-model="query.pcsn"
size="mini"
clearable
placeholder="批次号"
@keyup.enter.native="crud.toQuery"
/>
</el-form-item>
<el-form-item label="是否回传">
<el-select
v-model="query.is_upload"
clearable
size="mini"
placeholder="是否回传"
class="filter-item"
@change="crud.toQuery"
>
<el-option
v-for="item in dict.is_upload"
:key="item.value"
:label="item.label"
:value="item.value"
/>
</el-select>
</el-form-item>
<el-form-item label="创建时间" prop="createTime">
<el-date-picker
v-model="query.createTime"
type="daterange"
value-format="yyyy-MM-dd HH:mm:ss"
start-placeholder="开始日期"
end-placeholder="结束日期"
:default-time="['00:00:00', '23:59:59']"
@change="crud.toQuery"
/>
</el-form-item>
<rrOperation />
</el-form>
</div>
<!--如果想在工具栏加入更多按钮可以使用插槽方式 slot = 'left' or 'right'-->
<crudOperation :permission="permission">
<el-button
slot="right"
class="filter-item"
type="success"
icon="el-icon-position"
size="mini"
:disabled="dis_flag"
@click="divOpen"
>
分配
</el-button>
<el-button
slot="right"
v-permission="permission.confirm"
class="filter-item"
:loading="loadingConfirm"
type="warning"
:disabled="confirm_flag"
icon="el-icon-check"
size="mini"
@click="confirm"
>
强制确认
</el-button>
<el-button
slot="right"
class="filter-item"
type="primary"
icon="el-icon-printer"
size="mini"
@click="printBill"
>出库标签打印
</el-button>
</crudOperation>
<!--表格渲染-->
<el-table
ref="table"
v-loading="crud.loading"
size="mini"
:data="crud.data"
style="width: 100%;"
:highlight-current-row="true"
@selection-change="crud.selectionChangeHandler"
@current-change="handleCurrentChange"
@select="handleSelectionChange"
@select-all="onSelectAll"
>
<el-table-column
v-permission="['admin','checkoutbill:del','checkoutbill:edit']"
label="操作"
width="250"
align="center"
fixed="right"
>
<template slot-scope="scope">
<udOperation
:data="scope.row"
style="display: inline"
:permission="permission"
:disabled-edit="canUd(scope.row)"
:disabled-dle="canUd(scope.row)"
/>
</template>
</el-table-column>
<!-- <el-table-column :selectable="checkboxT" type="selection" width="55" />-->
<el-table-column type="selection" width="55" />
<el-table-column show-overflow-tooltip prop="bill_code" width="130" label="单据号">
<template slot-scope="scope">
<el-link type="warning" @click="toView(scope.$index, scope.row)">{{ scope.row.bill_code }}</el-link>
</template>
</el-table-column>
<el-table-column show-overflow-tooltip :formatter="stateFormat" width="80" prop="bill_status" label="单据状态" />
<el-table-column show-overflow-tooltip prop="stor_name" label="仓库" width="80" />
<el-table-column show-overflow-tooltip prop="bill_type" :formatter="bill_typeFormat" label="业务类型" />
<el-table-column show-overflow-tooltip width="100" prop="biz_date" label="业务日期" />
<el-table-column show-overflow-tooltip label="明细数" align="center" prop="detail_count" width="60" />
<el-table-column show-overflow-tooltip label="计划数量" align="center" prop="total_qty" width="100" :formatter="crud.formatNum3" />
<!-- <el-table-column show-overflow-tooltip label="实际重量" align="center" prop="plan_qty" width="100" :formatter="crud.formatNum3" />-->
<el-table-column show-overflow-tooltip label="是否回传" align="center" prop="is_upload" width="80" :formatter="formatIsUpload" />
<el-table-column show-overflow-tooltip label="备注" align="center" prop="remark" width="100" />
<el-table-column show-overflow-tooltip label="制单人" align="center" prop="input_optname" />
<el-table-column show-overflow-tooltip label="制单时间" align="center" prop="input_time" width="140" />
<el-table-column show-overflow-tooltip label="修改人" align="center" prop="update_optname" />
<el-table-column show-overflow-tooltip label="修改时间" align="center" prop="update_time" width="140" />
<el-table-column show-overflow-tooltip label="分配人" align="center" prop="dis_optname" />
<el-table-column show-overflow-tooltip label="分配时间" align="center" prop="dis_time" width="140" />
<el-table-column show-overflow-tooltip label="确认人" align="center" prop="confirm_optname" />
<el-table-column show-overflow-tooltip label="确认时间" align="center" prop="confirm_time" width="140" />
</el-table>
<!--分页组件-->
<pagination />
</div>
<AddDialog @AddChanged="querytable" />
<ViewDialog :dialog-show.sync="viewShow" :rowmst="mstrow" @AddChanged="querytable" />
<DivDialog :dialog-show.sync="divShow" :open-array="openParam" :stor-code="storCode" :rowmst="mstrow" @DivChanged="querytable" />
<el-dialog
:close-on-click-modal="false"
title="打印预览"
:visible.sync="printPreviewVisible"
width="700px"
@close="closePrintPreview"
>
<iframe ref="printIframe" src="about:blank" style="width: 100%; height: 500px; border: 1px solid #ddd;" />
<div slot="footer" class="dialog-footer">
<el-button type="info" @click="printPreviewVisible = false">取消</el-button>
<el-button type="primary" @click="doPrint">打印</el-button>
</div>
</el-dialog>
</div>
</template>
<script>
import checkoutbill from '@/views/wms/st/outbill/checkoutbill'
import CRUD, { crud, header, presenter } from '@crud/crud'
import rrOperation from '@crud/RR.operation'
import crudOperation from '@crud/CRUD.operation'
import udOperation from '@crud/UD.operation'
import pagination from '@crud/Pagination'
import AddDialog from '@/views/wms/st/outbill/AddDialog'
import DivDialog from '@/views/wms/st/outbill/DivDialog'
import ViewDialog from '@/views/wms/st/outbill/ViewDialog'
import crudBsrealstorattr from '@/views/wms/basedata/bsrealstorattr/bsrealstorattr'
import crudPurchase from '@/views/wms/pm_manage/otherIn/purchase'
import QRCode from 'qrcode'
const start = new Date()
export default {
name: 'Checkoutbill',
components: { ViewDialog, AddDialog, crudOperation, rrOperation, udOperation, pagination, DivDialog },
cruds() {
return CRUD({ title: '用户', idField: 'iostorinv_id', url: 'api/checkoutbill', crudMethod: { ...checkoutbill },
optShow: {
add: true,
edit: false,
del: false,
reset: true,
download: false
},
queryOnPresenterCreated: false
})
},
mixins: [presenter(), header(), crud()],
// 数据字典
dicts: ['io_bill_status', 'ST_CREATE_MODE', 'ST_INV_OUT_TYPE', 'is_upload', 'IS_OR_NOT'],
data() {
return {
height: document.documentElement.clientHeight - 180 + 'px;',
permission: {
add: ['admin', 'checkoutbill:add'],
edit: ['admin', 'checkoutbill:edit'],
del: ['admin', 'checkoutbill:del'],
confirm: ['admin', 'checkoutbill:confirm']
},
loadingConfirm: false,
divShow: false,
printPreviewVisible: false,
dis_flag: true,
confirm_flag: true,
business_confirm_flag: true,
outReturn_flag: true,
openParam: [],
mstrow: {},
audit_flag: true,
viewShow: false,
uploadDialogShow: false,
currentRow: null,
checkrows: [],
storlist: [],
billtypelist: [],
storCode: null
}
},
mounted: function() {
const that = this
window.onresize = function temp() {
that.height = document.documentElement.clientHeight - 180 + 'px;'
}
},
created() {
crudBsrealstorattr.getStor().then(res => {
this.storlist = res.data
})
this.initQuery()
},
methods: {
/* 搜索框创建时间默认最近一周*/
initQuery() {
const end = new Date()
const start = new Date()
const endYear = end.getFullYear()
var endMonth = end.getMonth() + 1
if (end.getMonth() + 1 < 10) {
endMonth = '0' + endMonth.toString()
}
var endDay = end.getDate()
if (end.getDate() < 10) {
endDay = '0' + endDay.toString()
}
const endDate = endYear + '-' + endMonth + '-' + endDay + ' 23:59:59'
start.setTime(start.getTime() - 3600 * 1000 * 24 * 7)
const startYear = start.getFullYear()
var startMonth = start.getMonth() + 1
if (start.getMonth() + 1 < 10) {
startMonth = '0' + startMonth.toString()
}
var startDay = start.getDate()
if (start.getDate() < 10) {
startDay = '0' + startDay.toString()
}
const startDate = startYear + '-' + startMonth + '-' + startDay + ' 00:00:00'
this.$set(this.query, 'createTime', [startDate, endDate])
this.crud.toQuery()
},
canUd(row) {
return row.bill_status !== '10'
},
toView(index, row) {
this.mstrow = row
this.viewShow = true
},
[CRUD.HOOK.beforeRefresh]() {
this.handleCurrentChange(null)
},
handleSelectionChange(val, row) {
if (val.length > 1) {
this.$refs.table.clearSelection()
this.$refs.table.toggleRowSelection(val.pop())
this.buttonChange(row)
} else if (val.length === 1) {
this.buttonChange(row)
} else {
this.handleCurrentChange(null)
}
},
onSelectAll() {
this.$refs.table.clearSelection()
this.handleCurrentChange(null)
},
doPrint() {
const iframe = this.$refs.printIframe
if (!iframe) return
iframe.contentWindow.focus()
iframe.contentWindow.print()
},
printBill() {
const selections = this.crud.selections
if (!selections || selections.length === 0 || selections.length > 1) {
this.crud.notify('请选择一条单据', CRUD.NOTIFICATION_TYPE.INFO)
return
}
const billIds = selections.map(s => s.order_no).join('、')
this.$confirm('确认打印以下单据的物料标签?\n' + billIds, '提示', {
confirmButtonText: '确定',
cancelButtonText: '取消',
type: 'warning'
}).then(() => {
this.fetchDetailsAndPrint(selections)
}).catch(() => {})
},
fetchDetailsAndPrint(selections) {
const promises = selections.map(bill => {
return checkoutbill.getOutBillDtl({ 'iostorinv_id': bill.iostorinv_id }).then(res => {
const dtlList = (res.data) || []
return dtlList.map(dtl => ({
...dtl
}))
})
})
Promise.all(promises).then(results => {
const allDtls = results.reduce((acc, cur) => acc.concat(cur), [])
if (allDtls.length === 0) {
this.crud.notify('未查询到明细数据', CRUD.NOTIFICATION_TYPE.INFO)
return
}
this.printPreviewVisible = true
this.$nextTick(() => {
this.renderPrintContent(allDtls)
})
}).catch(() => {
this.crud.notify('查询明细失败', CRUD.NOTIFICATION_TYPE.ERROR)
})
},
closePrintPreview() {
this.printPreviewVisible = false
},
async renderPrintContent(dtlList) {
const iframe = this.$refs.printIframe
if (!iframe) return
const doc = iframe.contentDocument || (iframe.contentWindow && iframe.contentWindow.document)
if (!doc) {
setTimeout(() => this.renderPrintContent(dtlList), 100)
return
}
let html = '<!DOCTYPE html><html><head><meta charset="utf-8"><style>'
html += '*{margin:0;padding:0;box-sizing:border-box}'
html += 'body{font-family:"Microsoft YaHei",Arial,sans-serif;padding:10px}'
html += '.label{page-break-after:always;padding:10px;text-align:center;}'
html += '.label:last-child{page-break-after:auto}'
html += 'h3{text-align:center;font-size:13px;margin-bottom:3px}'
html += 'table{width:463px;border-collapse:collapse;margin:0 auto;height:224px}'
html += 'td{padding:3px 5px;border:2px solid #333;font-size:17px}'
html += '.lbl{width:25%;text-align:right;background:#f9f9f9}'
html += '.val{width:45%;text-align:left}'
html += '.qr{width:30%;text-align:center;vertical-align:middle}'
html += '@media print{@page{size:auto;margin:5mm}}'
html += '</style></head><body>'
for (const dtl of dtlList) {
const orderNo = dtl.bill_code || ''
const itemNo = dtl.seq_no || ''
const skuCode = dtl.material_code || ''
const house_code = dtl.source_load_port || ''
const skuName = dtl.material_name || ''
const qty = dtl.plan_qty || ''
const assQty = dtl.assign_qty || ''
const qrText = orderNo + '#' + itemNo + '#' + skuCode + '#' + skuName + '##' + qty + '#'
const imgSrc = await QRCode.toDataURL(qrText, {
width: 300
})
html += '<div class="label">'
html += '<h3>上海诺力</h3>'
html += '<table>'
html += '<tr><td class="lbl">出库单号</td><td class="val">' + orderNo + '</td><td class="qr" rowspan="6"><img src="' + imgSrc + '" width="150" height="150" /></td></tr>'
html += '<tr><td class="lbl">行号</td><td class="val">' + itemNo + '</td></tr>'
html += '<tr><td class="lbl">物料编码</td><td class="val">' + skuCode + '</td></tr>'
html += '<tr><td class="lbl">物料名称</td><td class="val">' + skuName + '</td></tr>'
html += '<tr><td class="lbl">出库数量</td><td class="val">' + assQty + '</td></tr>'
html += '<tr><td class="lbl">用料位置</td><td class="val">' + house_code + '</td></tr>'
html += '</table></div>'
}
html += '</body></html>'
doc.open()
doc.write(html)
doc.close()
},
buttonChange(current) {
if (current !== null) {
this.currentRow = current
if (current.bill_status === '10' || current.bill_status === '20' || current.bill_status === '30' || current.bill_status === '40') {
this.dis_flag = false
} else {
this.dis_flag = true
}
if (current.bill_status === '50' || current.bill_status === '40' || current.bill_status === '30') {
this.confirm_flag = false
} else {
this.confirm_flag = true
}
if (current.bill_type === '1006' || current.bill_type === '1003') {
this.business_confirm_flag = false
} else {
this.business_confirm_flag = true
}
if (current.bill_status === '40' || current.bill_status === '30') {
this.outReturn_flag = false
} else {
this.outReturn_flag = true
}
}
},
stateFormat(row) {
return this.dict.label.io_bill_status[row.bill_status]
},
bill_typeFormat(row) {
return this.dict.label.ST_INV_OUT_TYPE[row.bill_type]
},
create_modeFormat(row) {
return this.dict.label.ST_CREATE_MODE[row.create_mode]
},
isOverdue(row) {
return this.dict.label.IS_OR_NOT[row.is_overdue]
},
handleCurrentChange(current) {
if (current === null) {
this.dis_flag = true
this.confirm_flag = true
this.outReturn_flag = true
this.currentRow = {}
}
},
checkboxT(row) {
return row.bill_status !== '99'
},
divOpen() {
checkoutbill.getOutBillDtl({ 'iostorinv_id': this.currentRow.iostorinv_id }).then(res => {
this.openParam = res.data
this.storCode = this.currentRow.stor_code
this.divShow = true
this.mstrow = this.currentRow
})
},
confirm() {
this.loadingConfirm = true
checkoutbill.confirm({ 'iostorinv_id': this.currentRow.iostorinv_id }).then(res => {
this.querytable()
this.crud.notify('出库成功!', CRUD.NOTIFICATION_TYPE.SUCCESS)
this.loadingConfirm = false
}).catch(() => {
this.loadingConfirm = false
})
},
outReturn() {
alert('点击确认按钮后,单据进行回传!')
checkoutbill.outReturn(this.currentRow).then(res => {
this.crud.notify('回传成功!', CRUD.NOTIFICATION_TYPE.SUCCESS)
this.querytable()
})
},
querytable() {
this.onSelectAll()
this.crud.toQuery()
this.handleCurrentChange(null)
},
formatIsUpload(row) {
if (row.is_upload === '0') {
return '否'
} else if (row.is_upload === '1') {
return '是'
}
},
tableChanged() {
this.crud.toQuery()
}
}
}
</script>
<style rel="stylesheet/scss" lang="scss" scoped>
::v-deep .el-dialog__body {
padding-top: 10px;
}
</style>