零件采购订单管理详情打印界面调整
零件采购收货预估总价 输入选中 回车总价下一行
This commit is contained in:
parent
8dab672f74
commit
18782d730d
@ -208,6 +208,7 @@
|
||||
<el-button type="primary" @click="doPrint">打印</el-button>
|
||||
</template>
|
||||
</el-dialog>
|
||||
<Print ref="printRef"/>
|
||||
</template>
|
||||
<script setup lang="ts">
|
||||
import { DICT_TYPE } from '@/utils/dict'
|
||||
@ -227,7 +228,7 @@ import * as PurchaseOrderNoApi from '@/api/heli/purchaseorderno'
|
||||
import * as PurchaseOrderNoDetailApi from '@/api/heli/purchaseordernodetail'
|
||||
import {ref} from "vue";
|
||||
import {update} from "lodash-es";
|
||||
|
||||
import Print from './print.vue'
|
||||
const dialogVisible = ref(false) // 弹窗的是否展示
|
||||
const formLoading = ref(false) // 表单的加载中:1)修改时的数据加载;2)提交的按钮禁用
|
||||
const formData = ref({
|
||||
@ -303,13 +304,31 @@ const isPrint = async () => {
|
||||
printLoading.value = true
|
||||
try {
|
||||
var newVar = await PurchaseOrderNoApi.isPrint(query.id);
|
||||
console.log(newVar)
|
||||
openPrintDialog(newVar)
|
||||
//日期 客户名 模具名 件号 零件名称 材料 规格 数量 单价 总价格 要求日期
|
||||
//createTime brief projectSubCode blueprintNo boomName compositionName matSpec purchaseAmount unitPrice estimatedPrice requireTime
|
||||
const data = newVar.purchaseOrderNoDetailList?.map((item,idx) => ({
|
||||
编号:idx + 1,
|
||||
日期: formatDate(item.createTime),
|
||||
客户名: item.brief,
|
||||
模具名: item.projectSubCode,
|
||||
件号: item.blueprintNo,
|
||||
零件名称: item.boomName,
|
||||
材料: item.compositionName,
|
||||
规格: item.matSpec,
|
||||
数量: item.purchaseAmount,
|
||||
单价: item.unitPrice,
|
||||
总价格: item.estimatedPrice,
|
||||
要求日期: formatDate(item.requireTime),
|
||||
})) || [];
|
||||
console.log(data)
|
||||
// openPrintDialog(newVar)
|
||||
printRef.value?.open(data,newVar.purchaseNo)
|
||||
} finally {
|
||||
printLoading.value = false
|
||||
}
|
||||
|
||||
}
|
||||
const printRef = ref<InstanceType<typeof Print>>();
|
||||
const updateFrom = async (row) => {
|
||||
console.log(row)
|
||||
|
||||
|
||||
@ -92,7 +92,7 @@ v-model="queryParams.supplierName" placeholder="供应商" clearable @keyup.ente
|
||||
<el-card class="hl-incard">
|
||||
<el-form ref="subFormRef" :model="list" v-loading="formLoading" label-width="0" >
|
||||
<el-table
|
||||
v-loading="loading" :data="list" :stripe="true" :show-overflow-tooltip="true" class="hl-table" ref="multipleTable" @selection-change="handleSelectionChange">
|
||||
v-loading="loading" :data="list" :stripe="true" :show-overflow-tooltip="true" class="hl-table" ref="multipleTableRef" @selection-change="handleSelectionChange">
|
||||
<el-table-column type="selection" width="55" />
|
||||
<el-table-column label="收货状态" align="center" prop="receivingStatus" min-width="120">
|
||||
<template #default="scope">
|
||||
@ -119,7 +119,12 @@ v-model="queryParams.supplierName" placeholder="供应商" clearable @keyup.ente
|
||||
<template #header><span class="hl-table_header">*</span>预估总价(元)</template>
|
||||
<template #default="scope">
|
||||
<el-form-item :prop="`${scope.$index}.estimatedPrice`" class="mb-0px!">
|
||||
<el-input-number style="width: 100%" v-model="scope.row.estimatedPrice" placeholder="预估总价" :min="0" :precision="2" />
|
||||
<el-input-number
|
||||
style="width: 100%" v-model="scope.row.estimatedPrice" placeholder="预估总价" :min="0" :precision="2"
|
||||
@input="(val)=>handleInput(val,scope.row)"
|
||||
@keyup.enter="(e)=>handleEnter(e,scope.row)"
|
||||
:id="'estimatedPrice'+scope.row.id"
|
||||
/>
|
||||
</el-form-item>
|
||||
</template>
|
||||
</el-table-column>
|
||||
@ -159,7 +164,7 @@ import { ElTable } from 'element-plus'
|
||||
import {useUserStore} from "@/store/modules/user";
|
||||
import {dateFormatter1} from "@/utils/formatTime";
|
||||
import * as PurchaseOrderNoDetailApi from "@/api/heli/purchaseordernodetail";
|
||||
defineOptions({ name: 'purchaseordernopartReceived' })
|
||||
defineOptions({ name: 'PurchaseordernopartReceived' })
|
||||
const userStore = useUserStore()
|
||||
const username = userStore.getUser.nickname
|
||||
const message = useMessage() // 消息弹窗
|
||||
@ -205,7 +210,36 @@ const queryParams = reactive({
|
||||
})
|
||||
const queryFormRef = ref() // 搜索的表单
|
||||
const exportLoading = ref(false) // 导出的加载中
|
||||
const handleInput = (val: number, row: PurchaseOrderNoDetailApi.PurchaseOrderNoDetailVO) => {
|
||||
console.log(val, 'val');
|
||||
//输入判断当前行是否选中如无将当前行选中
|
||||
if (multipleSelection.value.indexOf(row) == -1) {
|
||||
multipleSelection.value.push(row);
|
||||
multipleTableRef.value.toggleRowSelection(row)
|
||||
|
||||
};
|
||||
|
||||
}
|
||||
const handleEnter = (e: KeyboardEvent, row: PurchaseOrderNoDetailApi.PurchaseOrderNoDetailVO) => {
|
||||
//敲下回车时切换到下一行的预估总价 如果为0.00将其=null
|
||||
console.log(e, 'e');
|
||||
//判断当前行是否为最后一行如为最后一行则不切换
|
||||
if (list.value.indexOf(row) == list.value.length - 1) {
|
||||
return
|
||||
}
|
||||
const index = list.value.findIndex((item) => item.id == row.id)
|
||||
//切换到下一行
|
||||
const input = document.getElementById("estimatedPrice" + list.value[index + 1].id);
|
||||
if (input) {
|
||||
input.focus();
|
||||
if (list.value[index + 1].estimatedPrice == 0.00) {
|
||||
list.value[index + 1].estimatedPrice = ''
|
||||
}
|
||||
}
|
||||
console.log(input, 'input');
|
||||
|
||||
|
||||
}
|
||||
/** 查询列表 */
|
||||
const getList = async () => {
|
||||
loading.value = true
|
||||
@ -241,16 +275,17 @@ const resetQuery = () => {
|
||||
queryFormRef.value.resetFields()
|
||||
handleQuery()
|
||||
}
|
||||
const multipleTable: any = ref<InstanceType<typeof ElTable>>()
|
||||
const multipleTableRef: any = ref<InstanceType<typeof ElTable>>()
|
||||
const multipleSelection: any = ref([])
|
||||
|
||||
const handleSelectionChange = (val: PurchaseOrderApi.PurchaseOrderVO[]) => {
|
||||
multipleTable.value = val
|
||||
multipleSelection.value = val
|
||||
|
||||
}
|
||||
const receiveGood = async (row) => {
|
||||
multipleTable.value=[]
|
||||
multipleTable.value.push(row)
|
||||
multipleTableRef.value.clearSelection()
|
||||
multipleTableRef.value.toggleRowSelection(row)
|
||||
multipleSelection.value.indexOf(row) == -1 && multipleSelection.value.push(row) ;
|
||||
receiveGoods();
|
||||
}
|
||||
|
||||
@ -258,7 +293,7 @@ const receiveGood = async (row) => {
|
||||
const receiveGoods = async () => {
|
||||
try {
|
||||
|
||||
const list = multipleTable.value|| []; // 安全获取数据
|
||||
const list = multipleSelection.value|| []; // 安全获取数据
|
||||
// 1. 检查空数据
|
||||
if (!list || list.length==null||list.length==0) {
|
||||
message.error("采购单信息未选择,请确认");
|
||||
|
||||
@ -0,0 +1,386 @@
|
||||
<template>
|
||||
<el-dialog v-model="dialogVisible" title="" width="80%" append-to-body>
|
||||
<div class="print-wrap">
|
||||
<div class="header header-grid">
|
||||
<div class="cell company-title">
|
||||
<span class="company">杭州合立模具有限公司</span>
|
||||
<span class="title">委外工单及送货单</span>
|
||||
</div>
|
||||
<div class="cell audit"> 审核:<span class="sign-space"></span> </div>
|
||||
<div class="cell handler"> 委外加工经手人:<span class="sign-space"></span> </div>
|
||||
<div class="cell receiver"> 收货人:<span class="sign-space"></span> </div>
|
||||
<div class="cell order-no"> 订单编号:<span class="sign-space">{{ purchaseNo }}</span> </div>
|
||||
</div>
|
||||
|
||||
<table class="sheet" border="1" cellspacing="0" cellpadding="0">
|
||||
<!-- 固定列宽,总计 100% -->
|
||||
<colgroup>
|
||||
<col style="width: 4%" />
|
||||
<col style="width: 9%" />
|
||||
<col style="width: 7.5%" />
|
||||
<col style="width: 19%" />
|
||||
<col style="width: 5.5%" />
|
||||
<col style="width: 12%" />
|
||||
<col style="width: 6%" />
|
||||
<col style="width: 12.5%" />
|
||||
<col style="width: 5%" />
|
||||
<col style="width: 5%" />
|
||||
<col style="width: 6%" />
|
||||
<col style="width: 8.5%" />
|
||||
</colgroup>
|
||||
<thead>
|
||||
<tr>
|
||||
<th>编号</th>
|
||||
<th>日期</th>
|
||||
<th>客户名</th>
|
||||
<th>模具名</th>
|
||||
<th>件号</th>
|
||||
<th>零件名称</th>
|
||||
<th>材料</th>
|
||||
<th>规格</th>
|
||||
<th>数量</th>
|
||||
<th>单价</th>
|
||||
<th>总价格</th>
|
||||
<th>要求日期</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr v-for="row in rows" :key="row['编号']">
|
||||
<td>{{ row['编号'] }}</td>
|
||||
<td>{{ fmtDate(row['日期']) }}</td>
|
||||
<td class="text-left">{{ row['客户名'] }}</td>
|
||||
<td class="text-left">{{ row['模具名'] }}</td>
|
||||
<td class="text-left">{{ row['件号'] }}</td>
|
||||
<td class="text-left">{{ row['零件名称'] }}</td>
|
||||
<td>{{ row['材料'] }}</td>
|
||||
<td class="spec text-left">{{ row['规格'] }}</td>
|
||||
<td class="num">{{ row['数量'] }}</td>
|
||||
<td class="num">{{ row['单价'] }}</td>
|
||||
<td class="num">{{ row['总价格'] }}</td>
|
||||
<td>{{ fmtDate(row['要求日期']) }}</td>
|
||||
</tr>
|
||||
<tr class="sum-row">
|
||||
<td colspan="8" class="sum-label">合计</td>
|
||||
<td class="num sum-value">{{ sumQuantity }}</td>
|
||||
<td></td>
|
||||
<td class="num sum-value">{{ sumTotal }}</td>
|
||||
<td></td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
<div class="footer-sign sign-row">
|
||||
<div class="sign-item">
|
||||
<span class="label">合立经手人:</span>
|
||||
<span class="name">{{ duEmpName }}</span>
|
||||
</div>
|
||||
<div class="sign-item"> 审核人:<span class="sign-space"></span> </div>
|
||||
<div class="sign-item"> 委外加工经手人:<span class="sign-space"></span> </div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<template #footer>
|
||||
<el-button @click="dialogVisible = false">关闭</el-button>
|
||||
<el-button type="primary" @click="onPrint">打印</el-button>
|
||||
</template>
|
||||
</el-dialog>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { ref, computed } from 'vue'
|
||||
import dayjs from 'dayjs'
|
||||
import { useUserStore } from '@/store/modules/user'
|
||||
const userStore = useUserStore();
|
||||
const userName = userStore.getUser.nickname//nickname
|
||||
console.log(userStore,`userStore`);
|
||||
|
||||
// 精确浮点数加法函数
|
||||
const floatAdd = (a, b) => {
|
||||
var c, d, e;
|
||||
if (undefined === a || null === a || "" === a || isNaN(a)) { a = 0; }
|
||||
if (undefined === b || null === b || "" === b || isNaN(b)) { b = 0; }
|
||||
try {
|
||||
c = a.toString().split(".")[1].length;
|
||||
} catch (f) {
|
||||
c = 0;
|
||||
}
|
||||
try {
|
||||
d = b.toString().split(".")[1].length;
|
||||
} catch (f) {
|
||||
d = 0;
|
||||
}
|
||||
e = Math.pow(10, Math.max(c, d));
|
||||
return (floatMul(a, e) + floatMul(b, e)) / e;
|
||||
};
|
||||
|
||||
// 精确浮点数乘法函数
|
||||
const floatMul = (a, b) => {
|
||||
var c = 0,
|
||||
d = a.toString(),
|
||||
e = b.toString();
|
||||
try {
|
||||
c += d.split(".")[1].length;
|
||||
} catch (f) {}
|
||||
try {
|
||||
c += e.split(".")[1].length;
|
||||
} catch (f) {}
|
||||
return Number(d.replace(".", "")) * Number(e.replace(".", "")) / Math.pow(10, c);
|
||||
}
|
||||
|
||||
const dialogVisible = ref(false)
|
||||
const rows = ref<Record<string, any>[]>([])
|
||||
|
||||
const nowDate = dayjs().format('YYYY-MM-DD')
|
||||
const duEmpName = computed(() => userName)
|
||||
|
||||
// 计算总数量
|
||||
const sumQuantity = computed(() => {
|
||||
return rows.value.reduce((acc, cur) => {
|
||||
return floatAdd(acc, Number(cur['数量']) || 0)
|
||||
}, 0)
|
||||
})
|
||||
|
||||
// 计算总价格
|
||||
const sumTotal = computed(() => {
|
||||
return rows.value.reduce((acc, cur) => {
|
||||
return floatAdd(acc, Number(cur['总价格']) || 0)
|
||||
}, 0)
|
||||
})
|
||||
|
||||
const fmtDate = (v: any) => (v ? dayjs(v).format('YYYY-MM-DD') : '')
|
||||
const purchaseNo = ref('')
|
||||
const { query } = useRoute()
|
||||
import * as PurchaseOrderNoApi from '@/api/heli/purchaseorderno'
|
||||
/**
|
||||
*
|
||||
* @param data 打印数据
|
||||
* @param str 采购订单号=订单编号
|
||||
*/
|
||||
const open = (data: Record<string, any>[],str: string) => {
|
||||
rows.value = Array.isArray(data) ? data : []
|
||||
dialogVisible.value = true;
|
||||
purchaseNo.value = str;
|
||||
console.log(query.id);
|
||||
|
||||
}
|
||||
defineExpose({ open })
|
||||
|
||||
// onPrint()
|
||||
const onPrint = () => {
|
||||
const printNode = document.querySelector('.print-wrap') as HTMLElement
|
||||
if (!printNode) return
|
||||
const iframe = document.createElement('iframe')
|
||||
iframe.setAttribute('style', 'width:0;height:0;position:absolute;left:-9999px;top:-9999px;')
|
||||
document.body.appendChild(iframe)
|
||||
|
||||
const doc = iframe.contentWindow!.document
|
||||
|
||||
doc.open()
|
||||
doc.title = ''
|
||||
doc.write(`
|
||||
<style>
|
||||
/* 针式打印纸规格:241mm×140mm,撕边后222mm */
|
||||
@page { size: 241mm 140mm; margin: 5mm; }
|
||||
|
||||
body {
|
||||
font-family: Arial, "Microsoft YaHei", sans-serif;
|
||||
color:#000;
|
||||
margin: 5px;
|
||||
font-size: 12px;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
/* 打印区域适配撕边后的有效宽度 */
|
||||
.print-wrap {
|
||||
width: 100%;
|
||||
height: 118mm; /* 130mm - 12mm上下边距 */
|
||||
}
|
||||
|
||||
.header.header-grid {
|
||||
display: flex;
|
||||
justify-content: flex-start;
|
||||
align-items: center;
|
||||
column-gap: 12px;
|
||||
margin-bottom: 8px;
|
||||
}
|
||||
.header.header-grid .company-title {
|
||||
font-size: 12px;
|
||||
text-align: left;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 8px;
|
||||
}
|
||||
.header.header-grid .audit,
|
||||
.header.header-grid .handler,
|
||||
.header.header-grid .receiver,
|
||||
.header.header-grid .order-no{
|
||||
font-size: 12px;
|
||||
text-align: right;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: flex-end;
|
||||
}
|
||||
.order-no{
|
||||
margin-left: 12px;
|
||||
}
|
||||
/* 合计行样式 */
|
||||
.sum-row {
|
||||
border-top: 2px solid #000;
|
||||
font-weight: bold;
|
||||
}
|
||||
.sum-label {
|
||||
text-align: right;
|
||||
font-weight: bold;
|
||||
}
|
||||
.sum-value {
|
||||
font-weight: bold;
|
||||
}
|
||||
/* 合计行样式 */
|
||||
.sum-row {
|
||||
border-top: 2px solid #000;
|
||||
font-weight: bold;
|
||||
}
|
||||
.sum-label {
|
||||
text-align: right;
|
||||
font-weight: bold;
|
||||
}
|
||||
.sum-value {
|
||||
font-weight: bold;
|
||||
}
|
||||
.sign-space {
|
||||
display: inline-block;
|
||||
width: 50px;
|
||||
height: 18px;
|
||||
margin-left: 4px;
|
||||
}
|
||||
|
||||
.sheet { width:100%; border-collapse:collapse; font-size:12px; table-layout: fixed; }
|
||||
.sheet th, .sheet td { border:1px solid #333; padding:4px 0px; text-align:center; line-height:1; vertical-align: middle; }
|
||||
.sheet thead th { background:#f5f7fa; font-weight:600; }
|
||||
.sheet .text-left { text-align:left; padding-left:6px; }
|
||||
.sheet .spec { word-break: break-word; white-space: normal; }
|
||||
.sheet .num { text-align:right; padding-right:6px; }
|
||||
.sheet tfoot .sum-label, .sheet tfoot .sum-value { font-weight:700; }
|
||||
.sheet tfoot .sum-row td { border-top: 2px solid #000; }
|
||||
|
||||
.sign-row { display:flex; justify-content:flex-start; margin-top:12px; font-size:12px;gap:30px }
|
||||
.sign-item { display: flex; align-items: center; }
|
||||
.sign-item .label { margin-right: 4px; }
|
||||
</style>
|
||||
`)
|
||||
doc.write(printNode.outerHTML)
|
||||
doc.close()
|
||||
|
||||
iframe.contentWindow!.focus()
|
||||
iframe.contentWindow!.print()
|
||||
setTimeout(() => document.body.removeChild(iframe), 500)
|
||||
PurchaseOrderNoApi.updateIsPrint(query.id);
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped lang="less">
|
||||
.print-wrap {
|
||||
/* 预览时也按目标纸张尺寸展示,便于校对 */
|
||||
width: 100%;
|
||||
min-height: 140mm;
|
||||
background: #fff;
|
||||
}
|
||||
|
||||
.header.header-grid {
|
||||
display: flex;
|
||||
justify-content: flex-start;
|
||||
align-items: center;
|
||||
column-gap: 12px;
|
||||
}
|
||||
|
||||
.header.header-grid .company-title {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 8px;
|
||||
}
|
||||
|
||||
.header.header-grid .company {
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.header.header-grid .title {
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.header.header-grid .audit,
|
||||
.header.header-grid .handler,
|
||||
.header.header-grid .receiver
|
||||
.header.header-grid .order-no{
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: flex-end;
|
||||
}
|
||||
|
||||
/* 签字空间样式 */
|
||||
.sign-space {
|
||||
display: inline-block;
|
||||
width: 70px;
|
||||
height: 18px;
|
||||
|
||||
margin-left: 4px;
|
||||
}
|
||||
|
||||
.sheet {
|
||||
margin-top: 8px;
|
||||
table-layout: fixed;
|
||||
border-collapse: collapse;
|
||||
font-size: 12px;
|
||||
width: 100%;
|
||||
|
||||
th,
|
||||
td {
|
||||
padding: 6px 4px;
|
||||
text-align: center;
|
||||
line-height: 1.3;
|
||||
vertical-align: middle;
|
||||
}
|
||||
|
||||
thead th {
|
||||
background: #f5f7fa;
|
||||
font-weight: 600;
|
||||
}
|
||||
|
||||
.text-left {
|
||||
text-align: left;
|
||||
padding-left: 6px;
|
||||
}
|
||||
|
||||
.spec {
|
||||
word-break: break-word;
|
||||
white-space: normal;
|
||||
}
|
||||
|
||||
.num {
|
||||
text-align: right;
|
||||
padding-right: 6px;
|
||||
}
|
||||
|
||||
tfoot .sum-row td {
|
||||
border-top: 2px solid #000;
|
||||
}
|
||||
}
|
||||
|
||||
.footer-sign.sign-row {
|
||||
display: flex;
|
||||
justify-content: flex-start;
|
||||
margin-top: 12px;
|
||||
gap: 30px;
|
||||
}
|
||||
|
||||
.sign-item {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.sign-item .label {
|
||||
margin-right: 4px;
|
||||
}
|
||||
|
||||
.sign-item .name {
|
||||
// font-weight: bold;
|
||||
}
|
||||
</style>
|
||||
Loading…
Reference in New Issue
Block a user