出入库统计,优化
This commit is contained in:
@@ -22,7 +22,9 @@ import org.springframework.web.bind.annotation.*;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
import javax.validation.constraints.NotEmpty;
|
||||
import javax.validation.constraints.NotNull;
|
||||
import org.springframework.format.annotation.DateTimeFormat;
|
||||
import java.util.Arrays;
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
@@ -46,6 +48,13 @@ public class GearStockIoOrderController extends BaseController {
|
||||
ExcelUtil.exportExcel(list, "出入库单据", GearStockIoOrderVo.class, response);
|
||||
}
|
||||
|
||||
@GetMapping("/materialFlow")
|
||||
public R<IGearStockIoOrderService.MaterialFlowResp> materialFlow(@NotNull(message = "物料ID不能为空") @RequestParam Long itemId,
|
||||
@RequestParam(required = false) @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss") Date startTime,
|
||||
@RequestParam(required = false) @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss") Date endTime) {
|
||||
return R.ok(stockIoOrderService.queryMaterialFlow(itemId, startTime, endTime));
|
||||
}
|
||||
|
||||
@GetMapping("/{orderId}")
|
||||
public R<GearStockIoOrderVo> getInfo(@NotNull(message = "主键不能为空") @PathVariable Long orderId) {
|
||||
return R.ok(stockIoOrderService.queryById(orderId));
|
||||
|
||||
@@ -6,8 +6,11 @@ import com.gear.oa.domain.bo.GearStockIoOrderBo;
|
||||
import com.gear.oa.domain.bo.GearStockIoOrderWithDetailBo;
|
||||
import com.gear.oa.domain.vo.GearStockIoOrderVo;
|
||||
import com.gear.oa.domain.vo.GearStockIoOrderWithDetailVo;
|
||||
import com.fasterxml.jackson.annotation.JsonFormat;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
import java.util.Collection;
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
|
||||
public interface IGearStockIoOrderService {
|
||||
@@ -29,4 +32,31 @@ public interface IGearStockIoOrderService {
|
||||
void confirmIn(Long orderId);
|
||||
|
||||
void revoke(Long orderId, String reason);
|
||||
|
||||
MaterialFlowResp queryMaterialFlow(Long itemId, Date startTime, Date endTime);
|
||||
|
||||
@lombok.Data
|
||||
class MaterialFlowResp {
|
||||
private Long itemId;
|
||||
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
|
||||
private Date startTime;
|
||||
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
|
||||
private Date endTime;
|
||||
private BigDecimal confirmInQty;
|
||||
private BigDecimal outQty;
|
||||
private BigDecimal revokeInQty;
|
||||
private BigDecimal revokeOutQty;
|
||||
private BigDecimal netQty;
|
||||
private List<MaterialFlowRow> rows;
|
||||
}
|
||||
|
||||
@lombok.Data
|
||||
class MaterialFlowRow {
|
||||
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
|
||||
private Date time;
|
||||
private String action;
|
||||
private String orderCode;
|
||||
private String ioType;
|
||||
private BigDecimal qtyChange;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -20,6 +20,8 @@ import com.gear.oa.domain.vo.GearStockIoOrderVo;
|
||||
import com.gear.oa.domain.vo.GearStockIoOrderWithDetailVo;
|
||||
import com.gear.oa.mapper.*;
|
||||
import com.gear.oa.service.IGearStockIoOrderService;
|
||||
import com.gear.oa.service.IGearStockIoOrderService.MaterialFlowResp;
|
||||
import com.gear.oa.service.IGearStockIoOrderService.MaterialFlowRow;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
@@ -355,6 +357,129 @@ public class GearStockIoOrderServiceImpl implements IGearStockIoOrderService {
|
||||
baseMapper.updateById(update);
|
||||
}
|
||||
|
||||
@Override
|
||||
public MaterialFlowResp queryMaterialFlow(Long itemId, Date startTime, Date endTime) {
|
||||
if (itemId == null) {
|
||||
throw new ServiceException("物料ID不能为空");
|
||||
}
|
||||
List<GearStockIoOrder> confirmOrders = baseMapper.selectList(Wrappers.<GearStockIoOrder>lambdaQuery()
|
||||
.eq(GearStockIoOrder::getIoType, "I")
|
||||
.eq(GearStockIoOrder::getConfirmInFlag, "1")
|
||||
.isNotNull(GearStockIoOrder::getConfirmInTime)
|
||||
.ge(startTime != null, GearStockIoOrder::getConfirmInTime, startTime)
|
||||
.le(endTime != null, GearStockIoOrder::getConfirmInTime, endTime)
|
||||
.eq(GearStockIoOrder::getDelFlag, "0"));
|
||||
|
||||
List<GearStockIoOrder> outOrders = baseMapper.selectList(Wrappers.<GearStockIoOrder>lambdaQuery()
|
||||
.eq(GearStockIoOrder::getIoType, "O")
|
||||
.isNotNull(GearStockIoOrder::getExecuteTime)
|
||||
.ge(startTime != null, GearStockIoOrder::getExecuteTime, startTime)
|
||||
.le(endTime != null, GearStockIoOrder::getExecuteTime, endTime)
|
||||
.eq(GearStockIoOrder::getDelFlag, "0"));
|
||||
|
||||
List<GearStockIoOrder> revokeOrders = baseMapper.selectList(Wrappers.<GearStockIoOrder>lambdaQuery()
|
||||
.eq(GearStockIoOrder::getRevokeFlag, "1")
|
||||
.isNotNull(GearStockIoOrder::getRevokeTime)
|
||||
.ge(startTime != null, GearStockIoOrder::getRevokeTime, startTime)
|
||||
.le(endTime != null, GearStockIoOrder::getRevokeTime, endTime)
|
||||
.eq(GearStockIoOrder::getDelFlag, "0"));
|
||||
|
||||
Set<Long> orderIds = new HashSet<>();
|
||||
for (GearStockIoOrder o : confirmOrders) {
|
||||
if (o != null && o.getOrderId() != null) orderIds.add(o.getOrderId());
|
||||
}
|
||||
for (GearStockIoOrder o : outOrders) {
|
||||
if (o != null && o.getOrderId() != null) orderIds.add(o.getOrderId());
|
||||
}
|
||||
for (GearStockIoOrder o : revokeOrders) {
|
||||
if (o != null && o.getOrderId() != null) orderIds.add(o.getOrderId());
|
||||
}
|
||||
|
||||
Map<Long, BigDecimal> qtyMap = new HashMap<>();
|
||||
if (!orderIds.isEmpty()) {
|
||||
List<GearStockIoOrderDetail> details = detailMapper.selectList(Wrappers.<GearStockIoOrderDetail>lambdaQuery()
|
||||
.in(GearStockIoOrderDetail::getOrderId, orderIds)
|
||||
.eq(GearStockIoOrderDetail::getItemType, "material")
|
||||
.eq(GearStockIoOrderDetail::getItemId, itemId)
|
||||
.eq(GearStockIoOrderDetail::getDelFlag, "0"));
|
||||
for (GearStockIoOrderDetail d : details) {
|
||||
if (d == null || d.getOrderId() == null) continue;
|
||||
BigDecimal q = d.getQuantity() == null ? BigDecimal.ZERO : d.getQuantity();
|
||||
qtyMap.merge(d.getOrderId(), q, BigDecimal::add);
|
||||
}
|
||||
}
|
||||
|
||||
BigDecimal confirmInQty = BigDecimal.ZERO;
|
||||
BigDecimal outQty = BigDecimal.ZERO;
|
||||
BigDecimal revokeInQty = BigDecimal.ZERO;
|
||||
BigDecimal revokeOutQty = BigDecimal.ZERO;
|
||||
List<MaterialFlowRow> rows = new ArrayList<>();
|
||||
|
||||
for (GearStockIoOrder o : confirmOrders) {
|
||||
if (o == null || o.getOrderId() == null || o.getConfirmInTime() == null) continue;
|
||||
BigDecimal qty = qtyMap.getOrDefault(o.getOrderId(), BigDecimal.ZERO);
|
||||
if (qty.compareTo(BigDecimal.ZERO) <= 0) continue;
|
||||
MaterialFlowRow r = new MaterialFlowRow();
|
||||
r.setTime(o.getConfirmInTime());
|
||||
r.setAction("确认入库");
|
||||
r.setOrderCode(o.getOrderCode());
|
||||
r.setIoType(o.getIoType());
|
||||
r.setQtyChange(qty);
|
||||
rows.add(r);
|
||||
confirmInQty = confirmInQty.add(qty);
|
||||
}
|
||||
|
||||
for (GearStockIoOrder o : outOrders) {
|
||||
if (o == null || o.getOrderId() == null || o.getExecuteTime() == null) continue;
|
||||
BigDecimal qty = qtyMap.getOrDefault(o.getOrderId(), BigDecimal.ZERO);
|
||||
if (qty.compareTo(BigDecimal.ZERO) <= 0) continue;
|
||||
MaterialFlowRow r = new MaterialFlowRow();
|
||||
r.setTime(o.getExecuteTime());
|
||||
r.setAction("出库");
|
||||
r.setOrderCode(o.getOrderCode());
|
||||
r.setIoType(o.getIoType());
|
||||
r.setQtyChange(qty.negate());
|
||||
rows.add(r);
|
||||
outQty = outQty.add(qty);
|
||||
}
|
||||
|
||||
for (GearStockIoOrder o : revokeOrders) {
|
||||
if (o == null || o.getOrderId() == null || o.getRevokeTime() == null) continue;
|
||||
BigDecimal qty = qtyMap.getOrDefault(o.getOrderId(), BigDecimal.ZERO);
|
||||
if (qty.compareTo(BigDecimal.ZERO) <= 0) continue;
|
||||
MaterialFlowRow r = new MaterialFlowRow();
|
||||
r.setTime(o.getRevokeTime());
|
||||
r.setAction("撤回");
|
||||
r.setOrderCode(o.getOrderCode());
|
||||
r.setIoType(o.getIoType());
|
||||
if ("O".equalsIgnoreCase(o.getIoType())) {
|
||||
r.setQtyChange(qty);
|
||||
revokeOutQty = revokeOutQty.add(qty);
|
||||
} else if ("I".equalsIgnoreCase(o.getIoType())) {
|
||||
r.setQtyChange(qty.negate());
|
||||
revokeInQty = revokeInQty.add(qty);
|
||||
} else {
|
||||
continue;
|
||||
}
|
||||
rows.add(r);
|
||||
}
|
||||
|
||||
rows.sort(Comparator.comparing(MaterialFlowRow::getTime));
|
||||
BigDecimal net = confirmInQty.subtract(outQty).add(revokeOutQty).subtract(revokeInQty);
|
||||
|
||||
MaterialFlowResp resp = new MaterialFlowResp();
|
||||
resp.setItemId(itemId);
|
||||
resp.setStartTime(startTime);
|
||||
resp.setEndTime(endTime);
|
||||
resp.setConfirmInQty(confirmInQty);
|
||||
resp.setOutQty(outQty);
|
||||
resp.setRevokeInQty(revokeInQty);
|
||||
resp.setRevokeOutQty(revokeOutQty);
|
||||
resp.setNetQty(net);
|
||||
resp.setRows(rows);
|
||||
return resp;
|
||||
}
|
||||
|
||||
private GearStockIoOrder requireOrder(Long orderId) {
|
||||
if (orderId == null) {
|
||||
throw new ServiceException("单据ID不能为空");
|
||||
|
||||
@@ -59,3 +59,11 @@ export function revokeStockIoOrder(orderId, reason) {
|
||||
data: { reason: reason || '' }
|
||||
})
|
||||
}
|
||||
|
||||
export function getMaterialFlow(params) {
|
||||
return request({
|
||||
url: '/gear/stockIoOrder/materialFlow',
|
||||
method: 'get',
|
||||
params
|
||||
})
|
||||
}
|
||||
|
||||
@@ -29,12 +29,16 @@
|
||||
<el-col :span="1.5">
|
||||
<el-button type="warning" plain icon="Download" size="mini" @click="handleExport">导出</el-button>
|
||||
</el-col>
|
||||
<el-col :span="1.5">
|
||||
<el-button type="info" plain size="mini" @click="openFlow">统计/打印</el-button>
|
||||
</el-col>
|
||||
<right-toolbar v-model:showSearch="showSearch" @queryTable="getList" />
|
||||
</el-row>
|
||||
|
||||
<el-table v-loading="loading" :data="list" @selection-change="handleSelectionChange">
|
||||
<el-table-column type="selection" width="55" align="center" />
|
||||
<el-table-column label="单据编号" align="center" prop="orderCode" min-width="160" />
|
||||
<el-table-column label="创建时间" align="center" prop="createTime" min-width="160" />
|
||||
<el-table-column label="物料" align="center" min-width="220">
|
||||
<template #default="scope">
|
||||
<el-tooltip v-if="scope.row.materialNames && String(scope.row.materialNames).length > 16" effect="dark" placement="top">
|
||||
@@ -62,7 +66,7 @@
|
||||
<template #default="scope">
|
||||
<el-button size="mini" type="text" icon="Document" @click="showDetail(scope.row)">明细</el-button>
|
||||
<el-button size="mini" type="text" icon="CircleCheck" :disabled="scope.row.revokeFlag === '1' || scope.row.confirmInFlag === '1'" @click="handleConfirm(scope.row)">确认入库</el-button>
|
||||
<el-button size="mini" type="text" icon="RefreshLeft" :disabled="scope.row.revokeFlag === '1' || scope.row.confirmInFlag === '1'" @click="handleRevoke(scope.row)">撤回</el-button>
|
||||
<el-button size="mini" type="text" icon="RefreshLeft" :disabled="scope.row.revokeFlag === '1'" @click="handleRevoke(scope.row)">撤回</el-button>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
@@ -184,9 +188,16 @@
|
||||
<el-descriptions-item label="确认入库人">{{ detailData.order.confirmInBy || '-' }}</el-descriptions-item>
|
||||
<el-descriptions-item label="撤回人">{{ detailData.order.revokeBy || '-' }}</el-descriptions-item>
|
||||
</el-descriptions>
|
||||
<div style="margin: 12px 0;">
|
||||
<el-table :data="operationRows(detailData.order)" border style="width: 100%">
|
||||
<el-table-column label="操作" prop="action" width="120" align="center" />
|
||||
<el-table-column label="操作人" prop="user" width="140" align="center" />
|
||||
<el-table-column label="操作时间" prop="time" min-width="180" align="center" />
|
||||
</el-table>
|
||||
</div>
|
||||
<div style="margin: 12px 0; text-align: right;">
|
||||
<el-button type="success" size="small" :disabled="detailData.order.revokeFlag === '1' || detailData.order.confirmInFlag === '1'" @click="handleConfirm(detailData.order)">确认入库</el-button>
|
||||
<el-button type="danger" size="small" :disabled="detailData.order.revokeFlag === '1' || detailData.order.confirmInFlag === '1'" @click="handleRevoke(detailData.order)">撤回</el-button>
|
||||
<el-button type="danger" size="small" :disabled="detailData.order.revokeFlag === '1'" @click="handleRevoke(detailData.order)">撤回</el-button>
|
||||
</div>
|
||||
<el-table :data="detailData.details || []" border style="width: 100%">
|
||||
<el-table-column label="行号" prop="lineNo" width="70" align="center" />
|
||||
@@ -205,6 +216,90 @@
|
||||
<el-button @click="detailOpen = false">关闭</el-button>
|
||||
</template>
|
||||
</el-dialog>
|
||||
|
||||
<el-dialog title="物料出入库统计" v-model="flowOpen" width="980px" top="6vh" append-to-body>
|
||||
<el-form :inline="true" size="small" label-width="90px">
|
||||
<el-form-item label="物料">
|
||||
<RawSelector v-model="flowForm.itemId" :allowAdd="false" @change="onFlowMaterialChange" />
|
||||
</el-form-item>
|
||||
<el-form-item label="时间范围">
|
||||
<el-date-picker
|
||||
v-model="flowForm.timeRange"
|
||||
type="datetimerange"
|
||||
range-separator="至"
|
||||
start-placeholder="开始时间"
|
||||
end-placeholder="结束时间"
|
||||
value-format="YYYY-MM-DD HH:mm:ss"
|
||||
format="YYYY-MM-DD HH:mm:ss"
|
||||
style="width: 360px"
|
||||
/>
|
||||
</el-form-item>
|
||||
<el-form-item>
|
||||
<el-button type="primary" :loading="flowLoading" @click="fetchFlow">查询</el-button>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
|
||||
<div v-loading="flowLoading" style="margin-top: 10px;">
|
||||
<div ref="flowPrintContent">
|
||||
<div style="font-size: 16px; font-weight: 600; text-align: center; margin-bottom: 8px;">
|
||||
物料出入库统计
|
||||
</div>
|
||||
<div style="margin-bottom: 10px;">
|
||||
<span>物料:</span><span>{{ flowItemName || '-' }}</span>
|
||||
<span style="margin-left: 18px;">时间:</span>
|
||||
<span>{{ (flowForm.timeRange && flowForm.timeRange[0]) || '-' }}</span>
|
||||
<span> 至 </span>
|
||||
<span>{{ (flowForm.timeRange && flowForm.timeRange[1]) || '-' }}</span>
|
||||
</div>
|
||||
<el-row :gutter="10" style="margin-bottom: 10px;">
|
||||
<el-col :span="6">
|
||||
<el-card shadow="never">
|
||||
<div>确认入库</div>
|
||||
<div style="font-size: 18px; font-weight: 600;">{{ flowResult ? flowResult.confirmInQty : '-' }}</div>
|
||||
</el-card>
|
||||
</el-col>
|
||||
<el-col :span="6">
|
||||
<el-card shadow="never">
|
||||
<div>出库</div>
|
||||
<div style="font-size: 18px; font-weight: 600;">{{ flowResult ? flowResult.outQty : '-' }}</div>
|
||||
</el-card>
|
||||
</el-col>
|
||||
<el-col :span="6">
|
||||
<el-card shadow="never">
|
||||
<div>撤回入库</div>
|
||||
<div style="font-size: 18px; font-weight: 600;">{{ flowResult ? flowResult.revokeInQty : '-' }}</div>
|
||||
</el-card>
|
||||
</el-col>
|
||||
<el-col :span="6">
|
||||
<el-card shadow="never">
|
||||
<div>撤回出库</div>
|
||||
<div style="font-size: 18px; font-weight: 600;">{{ flowResult ? flowResult.revokeOutQty : '-' }}</div>
|
||||
</el-card>
|
||||
</el-col>
|
||||
</el-row>
|
||||
<el-row :gutter="10" style="margin-bottom: 10px;">
|
||||
<el-col :span="6">
|
||||
<el-card shadow="never">
|
||||
<div>净变动</div>
|
||||
<div style="font-size: 18px; font-weight: 600;">{{ flowResult ? flowResult.netQty : '-' }}</div>
|
||||
</el-card>
|
||||
</el-col>
|
||||
</el-row>
|
||||
|
||||
<el-table :data="(flowResult && flowResult.rows) || []" border style="width: 100%;">
|
||||
<el-table-column label="时间" prop="time" min-width="170" />
|
||||
<el-table-column label="动作" prop="action" width="100" />
|
||||
<el-table-column label="单号" prop="orderCode" min-width="160" />
|
||||
<el-table-column label="数量变化" prop="qtyChange" width="120" />
|
||||
</el-table>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<template #footer>
|
||||
<el-button :disabled="!flowResult" @click="printFlow">打印</el-button>
|
||||
<el-button @click="flowOpen = false">关闭</el-button>
|
||||
</template>
|
||||
</el-dialog>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
@@ -215,7 +310,8 @@ import {
|
||||
getStockIoOrderWithDetail,
|
||||
addStockIoOrderWithDetail,
|
||||
confirmInStockIoOrder,
|
||||
revokeStockIoOrder
|
||||
revokeStockIoOrder,
|
||||
getMaterialFlow
|
||||
} from '@/api/wms/stockIoOrder'
|
||||
|
||||
export default {
|
||||
@@ -250,7 +346,15 @@ export default {
|
||||
bizType: [{ required: true, message: '业务类型不能为空', trigger: 'blur' }]
|
||||
},
|
||||
detailOpen: false,
|
||||
detailData: null
|
||||
detailData: null,
|
||||
flowOpen: false,
|
||||
flowLoading: false,
|
||||
flowForm: {
|
||||
itemId: undefined,
|
||||
timeRange: []
|
||||
},
|
||||
flowItemName: '',
|
||||
flowResult: null
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
@@ -267,6 +371,30 @@ export default {
|
||||
const n = Number(val)
|
||||
return Number.isFinite(n) ? n : 0
|
||||
},
|
||||
operationRows(order) {
|
||||
const rows = []
|
||||
if (!order) return rows
|
||||
rows.push({
|
||||
action: '创建单据',
|
||||
user: order.createBy || '-',
|
||||
time: order.createTime || '-'
|
||||
})
|
||||
if (order.confirmInTime) {
|
||||
rows.push({
|
||||
action: '确认入库',
|
||||
user: order.confirmInBy || '-',
|
||||
time: order.confirmInTime || '-'
|
||||
})
|
||||
}
|
||||
if (order.revokeTime) {
|
||||
rows.push({
|
||||
action: '撤回',
|
||||
user: order.revokeBy || '-',
|
||||
time: order.revokeTime || '-'
|
||||
})
|
||||
}
|
||||
return rows
|
||||
},
|
||||
getList() {
|
||||
this.loading = true
|
||||
listStockIoOrder(this.queryParams)
|
||||
@@ -366,6 +494,75 @@ export default {
|
||||
this.buttonLoading = false
|
||||
})
|
||||
},
|
||||
openFlow() {
|
||||
this.flowOpen = true
|
||||
this.flowResult = null
|
||||
if (!this.flowForm.timeRange || this.flowForm.timeRange.length !== 2) {
|
||||
const end = new Date()
|
||||
const start = new Date(end.getTime() - 7 * 24 * 60 * 60 * 1000)
|
||||
this.flowForm.timeRange = [this.formatDateTime(start), this.formatDateTime(end)]
|
||||
}
|
||||
},
|
||||
formatDateTime(d) {
|
||||
const pad = (n) => (n < 10 ? '0' + n : String(n))
|
||||
const yyyy = d.getFullYear()
|
||||
const MM = pad(d.getMonth() + 1)
|
||||
const dd = pad(d.getDate())
|
||||
const HH = pad(d.getHours())
|
||||
const mm = pad(d.getMinutes())
|
||||
const ss = pad(d.getSeconds())
|
||||
return `${yyyy}-${MM}-${dd} ${HH}:${mm}:${ss}`
|
||||
},
|
||||
onFlowMaterialChange(material) {
|
||||
this.flowItemName = material && material.materialName ? material.materialName : ''
|
||||
},
|
||||
fetchFlow() {
|
||||
if (!this.flowForm.itemId) {
|
||||
this.$modal.msgError('请选择物料')
|
||||
return
|
||||
}
|
||||
if (!this.flowForm.timeRange || this.flowForm.timeRange.length !== 2) {
|
||||
this.$modal.msgError('请选择时间范围')
|
||||
return
|
||||
}
|
||||
this.flowLoading = true
|
||||
this.flowResult = null
|
||||
getMaterialFlow({
|
||||
itemId: this.flowForm.itemId,
|
||||
startTime: this.flowForm.timeRange[0],
|
||||
endTime: this.flowForm.timeRange[1]
|
||||
})
|
||||
.then((res) => {
|
||||
this.flowResult = res.data || null
|
||||
})
|
||||
.finally(() => {
|
||||
this.flowLoading = false
|
||||
})
|
||||
},
|
||||
printFlow() {
|
||||
const el = this.$refs.flowPrintContent
|
||||
if (!el) return
|
||||
const w = window.open('', '_blank')
|
||||
if (!w) return
|
||||
const html = `
|
||||
<html>
|
||||
<head>
|
||||
<title>物料出入库统计</title>
|
||||
<style>
|
||||
body { font-family: -apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,"Helvetica Neue",Arial,"Noto Sans","PingFang SC","Microsoft YaHei",sans-serif; padding: 12px; }
|
||||
table { border-collapse: collapse; width: 100%; }
|
||||
th, td { border: 1px solid #dcdfe6; padding: 6px 8px; font-size: 12px; }
|
||||
</style>
|
||||
</head>
|
||||
<body>${el.innerHTML}</body>
|
||||
</html>`
|
||||
w.document.open()
|
||||
w.document.write(html)
|
||||
w.document.close()
|
||||
w.focus()
|
||||
w.print()
|
||||
w.close()
|
||||
},
|
||||
submitEdit() {
|
||||
this.$refs.editFormRef.validate((valid) => {
|
||||
if (!valid) return
|
||||
|
||||
@@ -26,12 +26,16 @@
|
||||
<el-col :span="1.5">
|
||||
<el-button type="warning" plain icon="Download" size="mini" @click="handleExport">导出</el-button>
|
||||
</el-col>
|
||||
<el-col :span="1.5">
|
||||
<el-button type="info" plain size="mini" @click="openFlow">统计/打印</el-button>
|
||||
</el-col>
|
||||
<right-toolbar v-model:showSearch="showSearch" @queryTable="getList" />
|
||||
</el-row>
|
||||
|
||||
<el-table v-loading="loading" :data="list" @selection-change="handleSelectionChange">
|
||||
<el-table-column type="selection" width="55" align="center" />
|
||||
<el-table-column label="单据编号" align="center" prop="orderCode" min-width="160" />
|
||||
<el-table-column label="创建时间" align="center" prop="createTime" min-width="160" />
|
||||
<el-table-column label="物料" align="center" min-width="220">
|
||||
<template #default="scope">
|
||||
<el-tooltip v-if="scope.row.materialNames && String(scope.row.materialNames).length > 16" effect="dark" placement="top">
|
||||
@@ -166,6 +170,13 @@
|
||||
<el-descriptions-item label="责任人">{{ detailData.order.responsibleName }}</el-descriptions-item>
|
||||
<el-descriptions-item label="撤回人">{{ detailData.order.revokeBy || '-' }}</el-descriptions-item>
|
||||
</el-descriptions>
|
||||
<div style="margin: 12px 0;">
|
||||
<el-table :data="operationRows(detailData.order)" border style="width: 100%">
|
||||
<el-table-column label="操作" prop="action" width="120" align="center" />
|
||||
<el-table-column label="操作人" prop="user" width="140" align="center" />
|
||||
<el-table-column label="操作时间" prop="time" min-width="180" align="center" />
|
||||
</el-table>
|
||||
</div>
|
||||
<div style="margin: 12px 0; text-align: right;">
|
||||
<el-button type="danger" size="small" :disabled="detailData.order.revokeFlag === '1'" @click="handleRevoke(detailData.order)">撤回</el-button>
|
||||
</div>
|
||||
@@ -186,6 +197,90 @@
|
||||
<el-button @click="detailOpen = false">关闭</el-button>
|
||||
</template>
|
||||
</el-dialog>
|
||||
|
||||
<el-dialog title="物料出入库统计" v-model="flowOpen" width="980px" top="6vh" append-to-body>
|
||||
<el-form :inline="true" size="small" label-width="90px">
|
||||
<el-form-item label="物料">
|
||||
<RawSelector v-model="flowForm.itemId" :allowAdd="false" @change="onFlowMaterialChange" />
|
||||
</el-form-item>
|
||||
<el-form-item label="时间范围">
|
||||
<el-date-picker
|
||||
v-model="flowForm.timeRange"
|
||||
type="datetimerange"
|
||||
range-separator="至"
|
||||
start-placeholder="开始时间"
|
||||
end-placeholder="结束时间"
|
||||
value-format="YYYY-MM-DD HH:mm:ss"
|
||||
format="YYYY-MM-DD HH:mm:ss"
|
||||
style="width: 360px"
|
||||
/>
|
||||
</el-form-item>
|
||||
<el-form-item>
|
||||
<el-button type="primary" :loading="flowLoading" @click="fetchFlow">查询</el-button>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
|
||||
<div v-loading="flowLoading" style="margin-top: 10px;">
|
||||
<div ref="flowPrintContent">
|
||||
<div style="font-size: 16px; font-weight: 600; text-align: center; margin-bottom: 8px;">
|
||||
物料出入库统计
|
||||
</div>
|
||||
<div style="margin-bottom: 10px;">
|
||||
<span>物料:</span><span>{{ flowItemName || '-' }}</span>
|
||||
<span style="margin-left: 18px;">时间:</span>
|
||||
<span>{{ (flowForm.timeRange && flowForm.timeRange[0]) || '-' }}</span>
|
||||
<span> 至 </span>
|
||||
<span>{{ (flowForm.timeRange && flowForm.timeRange[1]) || '-' }}</span>
|
||||
</div>
|
||||
<el-row :gutter="10" style="margin-bottom: 10px;">
|
||||
<el-col :span="6">
|
||||
<el-card shadow="never">
|
||||
<div>确认入库</div>
|
||||
<div style="font-size: 18px; font-weight: 600;">{{ flowResult ? flowResult.confirmInQty : '-' }}</div>
|
||||
</el-card>
|
||||
</el-col>
|
||||
<el-col :span="6">
|
||||
<el-card shadow="never">
|
||||
<div>出库</div>
|
||||
<div style="font-size: 18px; font-weight: 600;">{{ flowResult ? flowResult.outQty : '-' }}</div>
|
||||
</el-card>
|
||||
</el-col>
|
||||
<el-col :span="6">
|
||||
<el-card shadow="never">
|
||||
<div>撤回入库</div>
|
||||
<div style="font-size: 18px; font-weight: 600;">{{ flowResult ? flowResult.revokeInQty : '-' }}</div>
|
||||
</el-card>
|
||||
</el-col>
|
||||
<el-col :span="6">
|
||||
<el-card shadow="never">
|
||||
<div>撤回出库</div>
|
||||
<div style="font-size: 18px; font-weight: 600;">{{ flowResult ? flowResult.revokeOutQty : '-' }}</div>
|
||||
</el-card>
|
||||
</el-col>
|
||||
</el-row>
|
||||
<el-row :gutter="10" style="margin-bottom: 10px;">
|
||||
<el-col :span="6">
|
||||
<el-card shadow="never">
|
||||
<div>净变动</div>
|
||||
<div style="font-size: 18px; font-weight: 600;">{{ flowResult ? flowResult.netQty : '-' }}</div>
|
||||
</el-card>
|
||||
</el-col>
|
||||
</el-row>
|
||||
|
||||
<el-table :data="(flowResult && flowResult.rows) || []" border style="width: 100%;">
|
||||
<el-table-column label="时间" prop="time" min-width="170" />
|
||||
<el-table-column label="动作" prop="action" width="100" />
|
||||
<el-table-column label="单号" prop="orderCode" min-width="160" />
|
||||
<el-table-column label="数量变化" prop="qtyChange" width="120" />
|
||||
</el-table>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<template #footer>
|
||||
<el-button :disabled="!flowResult" @click="printFlow">打印</el-button>
|
||||
<el-button @click="flowOpen = false">关闭</el-button>
|
||||
</template>
|
||||
</el-dialog>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
@@ -195,7 +290,8 @@ import {
|
||||
listStockIoOrder,
|
||||
getStockIoOrderWithDetail,
|
||||
addStockIoOrderWithDetail,
|
||||
revokeStockIoOrder
|
||||
revokeStockIoOrder,
|
||||
getMaterialFlow
|
||||
} from '@/api/wms/stockIoOrder'
|
||||
|
||||
export default {
|
||||
@@ -229,7 +325,15 @@ export default {
|
||||
bizType: [{ required: true, message: '业务类型不能为空', trigger: 'blur' }]
|
||||
},
|
||||
detailOpen: false,
|
||||
detailData: null
|
||||
detailData: null,
|
||||
flowOpen: false,
|
||||
flowLoading: false,
|
||||
flowForm: {
|
||||
itemId: undefined,
|
||||
timeRange: []
|
||||
},
|
||||
flowItemName: '',
|
||||
flowResult: null
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
@@ -246,6 +350,30 @@ export default {
|
||||
const n = Number(val)
|
||||
return Number.isFinite(n) ? n : 0
|
||||
},
|
||||
operationRows(order) {
|
||||
const rows = []
|
||||
if (!order) return rows
|
||||
rows.push({
|
||||
action: '创建单据',
|
||||
user: order.createBy || '-',
|
||||
time: order.createTime || '-'
|
||||
})
|
||||
if (order.executeTime) {
|
||||
rows.push({
|
||||
action: '出库',
|
||||
user: order.executeBy || '-',
|
||||
time: order.executeTime || '-'
|
||||
})
|
||||
}
|
||||
if (order.revokeTime) {
|
||||
rows.push({
|
||||
action: '撤回',
|
||||
user: order.revokeBy || '-',
|
||||
time: order.revokeTime || '-'
|
||||
})
|
||||
}
|
||||
return rows
|
||||
},
|
||||
getList() {
|
||||
this.loading = true
|
||||
listStockIoOrder(this.queryParams)
|
||||
@@ -324,6 +452,75 @@ export default {
|
||||
this.buttonLoading = false
|
||||
})
|
||||
},
|
||||
openFlow() {
|
||||
this.flowOpen = true
|
||||
this.flowResult = null
|
||||
if (!this.flowForm.timeRange || this.flowForm.timeRange.length !== 2) {
|
||||
const end = new Date()
|
||||
const start = new Date(end.getTime() - 7 * 24 * 60 * 60 * 1000)
|
||||
this.flowForm.timeRange = [this.formatDateTime(start), this.formatDateTime(end)]
|
||||
}
|
||||
},
|
||||
formatDateTime(d) {
|
||||
const pad = (n) => (n < 10 ? '0' + n : String(n))
|
||||
const yyyy = d.getFullYear()
|
||||
const MM = pad(d.getMonth() + 1)
|
||||
const dd = pad(d.getDate())
|
||||
const HH = pad(d.getHours())
|
||||
const mm = pad(d.getMinutes())
|
||||
const ss = pad(d.getSeconds())
|
||||
return `${yyyy}-${MM}-${dd} ${HH}:${mm}:${ss}`
|
||||
},
|
||||
onFlowMaterialChange(material) {
|
||||
this.flowItemName = material && material.materialName ? material.materialName : ''
|
||||
},
|
||||
fetchFlow() {
|
||||
if (!this.flowForm.itemId) {
|
||||
this.$modal.msgError('请选择物料')
|
||||
return
|
||||
}
|
||||
if (!this.flowForm.timeRange || this.flowForm.timeRange.length !== 2) {
|
||||
this.$modal.msgError('请选择时间范围')
|
||||
return
|
||||
}
|
||||
this.flowLoading = true
|
||||
this.flowResult = null
|
||||
getMaterialFlow({
|
||||
itemId: this.flowForm.itemId,
|
||||
startTime: this.flowForm.timeRange[0],
|
||||
endTime: this.flowForm.timeRange[1]
|
||||
})
|
||||
.then((res) => {
|
||||
this.flowResult = res.data || null
|
||||
})
|
||||
.finally(() => {
|
||||
this.flowLoading = false
|
||||
})
|
||||
},
|
||||
printFlow() {
|
||||
const el = this.$refs.flowPrintContent
|
||||
if (!el) return
|
||||
const w = window.open('', '_blank')
|
||||
if (!w) return
|
||||
const html = `
|
||||
<html>
|
||||
<head>
|
||||
<title>物料出入库统计</title>
|
||||
<style>
|
||||
body { font-family: -apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,"Helvetica Neue",Arial,"Noto Sans","PingFang SC","Microsoft YaHei",sans-serif; padding: 12px; }
|
||||
table { border-collapse: collapse; width: 100%; }
|
||||
th, td { border: 1px solid #dcdfe6; padding: 6px 8px; font-size: 12px; }
|
||||
</style>
|
||||
</head>
|
||||
<body>${el.innerHTML}</body>
|
||||
</html>`
|
||||
w.document.open()
|
||||
w.document.write(html)
|
||||
w.document.close()
|
||||
w.focus()
|
||||
w.print()
|
||||
w.close()
|
||||
},
|
||||
submitEdit() {
|
||||
this.$refs.editFormRef.validate((valid) => {
|
||||
if (!valid) return
|
||||
|
||||
@@ -49,6 +49,9 @@
|
||||
<el-col :span="1.5">
|
||||
<el-button type="warning" plain icon="Download" size="mini" @click="handleExport">导出</el-button>
|
||||
</el-col>
|
||||
<el-col :span="1.5">
|
||||
<el-button type="info" plain size="mini" @click="openFlow">统计/打印</el-button>
|
||||
</el-col>
|
||||
<right-toolbar v-model:showSearch="showSearch" @queryTable="getList" />
|
||||
</el-row>
|
||||
|
||||
@@ -56,6 +59,7 @@
|
||||
<el-table-column type="selection" width="55" align="center" />
|
||||
<el-table-column label="单据ID" align="center" prop="orderId" v-if="false" />
|
||||
<el-table-column label="单据编号" align="center" prop="orderCode" min-width="160" />
|
||||
<el-table-column label="创建时间" align="center" prop="createTime" min-width="160" />
|
||||
<el-table-column label="类型" align="center" prop="ioType" width="90">
|
||||
<template #default="scope">
|
||||
<el-tag :type="ioTypeTag(scope.row.ioType)">{{ ioTypeLabel(scope.row.ioType) }}</el-tag>
|
||||
@@ -260,6 +264,13 @@
|
||||
<el-descriptions-item label="确认入库人">{{ detailData.order.confirmInBy || '-' }}</el-descriptions-item>
|
||||
<el-descriptions-item label="撤回人">{{ detailData.order.revokeBy || '-' }}</el-descriptions-item>
|
||||
</el-descriptions>
|
||||
<div style="margin: 12px 0;">
|
||||
<el-table :data="operationRows(detailData.order)" border style="width: 100%">
|
||||
<el-table-column label="操作" prop="action" width="120" align="center" />
|
||||
<el-table-column label="操作人" prop="user" width="140" align="center" />
|
||||
<el-table-column label="操作时间" prop="time" min-width="180" align="center" />
|
||||
</el-table>
|
||||
</div>
|
||||
<el-table :data="detailData.details || []" border style="width: 100%">
|
||||
<el-table-column label="行号" prop="lineNo" width="70" align="center" />
|
||||
<el-table-column label="物料类型" prop="itemType" width="110" align="center" />
|
||||
@@ -280,6 +291,90 @@
|
||||
<el-button @click="detailOpen = false">关闭</el-button>
|
||||
</template>
|
||||
</el-dialog>
|
||||
|
||||
<el-dialog title="物料出入库统计" v-model="flowOpen" width="980px" top="6vh" append-to-body>
|
||||
<el-form :inline="true" size="small" label-width="90px">
|
||||
<el-form-item label="物料">
|
||||
<RawSelector v-model="flowForm.itemId" :allowAdd="false" @change="onFlowMaterialChange" />
|
||||
</el-form-item>
|
||||
<el-form-item label="时间范围">
|
||||
<el-date-picker
|
||||
v-model="flowForm.timeRange"
|
||||
type="datetimerange"
|
||||
range-separator="至"
|
||||
start-placeholder="开始时间"
|
||||
end-placeholder="结束时间"
|
||||
value-format="YYYY-MM-DD HH:mm:ss"
|
||||
format="YYYY-MM-DD HH:mm:ss"
|
||||
style="width: 360px"
|
||||
/>
|
||||
</el-form-item>
|
||||
<el-form-item>
|
||||
<el-button type="primary" :loading="flowLoading" @click="fetchFlow">查询</el-button>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
|
||||
<div v-loading="flowLoading" style="margin-top: 10px;">
|
||||
<div ref="flowPrintContent">
|
||||
<div style="font-size: 16px; font-weight: 600; text-align: center; margin-bottom: 8px;">
|
||||
物料出入库统计
|
||||
</div>
|
||||
<div style="margin-bottom: 10px;">
|
||||
<span>物料:</span><span>{{ flowItemName || '-' }}</span>
|
||||
<span style="margin-left: 18px;">时间:</span>
|
||||
<span>{{ (flowForm.timeRange && flowForm.timeRange[0]) || '-' }}</span>
|
||||
<span> 至 </span>
|
||||
<span>{{ (flowForm.timeRange && flowForm.timeRange[1]) || '-' }}</span>
|
||||
</div>
|
||||
<el-row :gutter="10" style="margin-bottom: 10px;">
|
||||
<el-col :span="6">
|
||||
<el-card shadow="never">
|
||||
<div>确认入库</div>
|
||||
<div style="font-size: 18px; font-weight: 600;">{{ flowResult ? flowResult.confirmInQty : '-' }}</div>
|
||||
</el-card>
|
||||
</el-col>
|
||||
<el-col :span="6">
|
||||
<el-card shadow="never">
|
||||
<div>出库</div>
|
||||
<div style="font-size: 18px; font-weight: 600;">{{ flowResult ? flowResult.outQty : '-' }}</div>
|
||||
</el-card>
|
||||
</el-col>
|
||||
<el-col :span="6">
|
||||
<el-card shadow="never">
|
||||
<div>撤回入库</div>
|
||||
<div style="font-size: 18px; font-weight: 600;">{{ flowResult ? flowResult.revokeInQty : '-' }}</div>
|
||||
</el-card>
|
||||
</el-col>
|
||||
<el-col :span="6">
|
||||
<el-card shadow="never">
|
||||
<div>撤回出库</div>
|
||||
<div style="font-size: 18px; font-weight: 600;">{{ flowResult ? flowResult.revokeOutQty : '-' }}</div>
|
||||
</el-card>
|
||||
</el-col>
|
||||
</el-row>
|
||||
<el-row :gutter="10" style="margin-bottom: 10px;">
|
||||
<el-col :span="6">
|
||||
<el-card shadow="never">
|
||||
<div>净变动</div>
|
||||
<div style="font-size: 18px; font-weight: 600;">{{ flowResult ? flowResult.netQty : '-' }}</div>
|
||||
</el-card>
|
||||
</el-col>
|
||||
</el-row>
|
||||
|
||||
<el-table :data="(flowResult && flowResult.rows) || []" border style="width: 100%;">
|
||||
<el-table-column label="时间" prop="time" min-width="170" />
|
||||
<el-table-column label="动作" prop="action" width="100" />
|
||||
<el-table-column label="单号" prop="orderCode" min-width="160" />
|
||||
<el-table-column label="数量变化" prop="qtyChange" width="120" />
|
||||
</el-table>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<template #footer>
|
||||
<el-button :disabled="!flowResult" @click="printFlow">打印</el-button>
|
||||
<el-button @click="flowOpen = false">关闭</el-button>
|
||||
</template>
|
||||
</el-dialog>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
@@ -292,7 +387,8 @@ import {
|
||||
getStockIoOrderWithDetail,
|
||||
addStockIoOrderWithDetail,
|
||||
updateStockIoOrderWithDetail,
|
||||
delStockIoOrder
|
||||
delStockIoOrder,
|
||||
getMaterialFlow
|
||||
} from '@/api/wms/stockIoOrder'
|
||||
|
||||
export default {
|
||||
@@ -355,7 +451,15 @@ export default {
|
||||
bizType: [{ required: true, message: '业务类型不能为空', trigger: 'blur' }]
|
||||
},
|
||||
detailOpen: false,
|
||||
detailData: null
|
||||
detailData: null,
|
||||
flowOpen: false,
|
||||
flowLoading: false,
|
||||
flowForm: {
|
||||
itemId: undefined,
|
||||
timeRange: []
|
||||
},
|
||||
flowItemName: '',
|
||||
flowResult: null
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
@@ -397,6 +501,37 @@ export default {
|
||||
if (v === '2') return 'success'
|
||||
return 'info'
|
||||
},
|
||||
operationRows(order) {
|
||||
const rows = []
|
||||
if (!order) return rows
|
||||
rows.push({
|
||||
action: '创建单据',
|
||||
user: order.createBy || '-',
|
||||
time: order.createTime || '-'
|
||||
})
|
||||
if (order.ioType === 'O' && order.executeTime) {
|
||||
rows.push({
|
||||
action: '出库',
|
||||
user: order.executeBy || '-',
|
||||
time: order.executeTime || '-'
|
||||
})
|
||||
}
|
||||
if (order.ioType === 'I' && order.confirmInTime) {
|
||||
rows.push({
|
||||
action: '确认入库',
|
||||
user: order.confirmInBy || '-',
|
||||
time: order.confirmInTime || '-'
|
||||
})
|
||||
}
|
||||
if (order.revokeTime) {
|
||||
rows.push({
|
||||
action: '撤回',
|
||||
user: order.revokeBy || '-',
|
||||
time: order.revokeTime || '-'
|
||||
})
|
||||
}
|
||||
return rows
|
||||
},
|
||||
getList() {
|
||||
this.loading = true
|
||||
listStockIoOrder(this.queryParams)
|
||||
@@ -514,6 +649,75 @@ export default {
|
||||
`stockIoOrder_${type}_${new Date().getTime()}.xlsx`
|
||||
)
|
||||
},
|
||||
openFlow() {
|
||||
this.flowOpen = true
|
||||
this.flowResult = null
|
||||
if (!this.flowForm.timeRange || this.flowForm.timeRange.length !== 2) {
|
||||
const end = new Date()
|
||||
const start = new Date(end.getTime() - 7 * 24 * 60 * 60 * 1000)
|
||||
this.flowForm.timeRange = [this.formatDateTime(start), this.formatDateTime(end)]
|
||||
}
|
||||
},
|
||||
formatDateTime(d) {
|
||||
const pad = (n) => (n < 10 ? '0' + n : String(n))
|
||||
const yyyy = d.getFullYear()
|
||||
const MM = pad(d.getMonth() + 1)
|
||||
const dd = pad(d.getDate())
|
||||
const HH = pad(d.getHours())
|
||||
const mm = pad(d.getMinutes())
|
||||
const ss = pad(d.getSeconds())
|
||||
return `${yyyy}-${MM}-${dd} ${HH}:${mm}:${ss}`
|
||||
},
|
||||
onFlowMaterialChange(material) {
|
||||
this.flowItemName = material && material.materialName ? material.materialName : ''
|
||||
},
|
||||
fetchFlow() {
|
||||
if (!this.flowForm.itemId) {
|
||||
this.$modal.msgError('请选择物料')
|
||||
return
|
||||
}
|
||||
if (!this.flowForm.timeRange || this.flowForm.timeRange.length !== 2) {
|
||||
this.$modal.msgError('请选择时间范围')
|
||||
return
|
||||
}
|
||||
this.flowLoading = true
|
||||
this.flowResult = null
|
||||
getMaterialFlow({
|
||||
itemId: this.flowForm.itemId,
|
||||
startTime: this.flowForm.timeRange[0],
|
||||
endTime: this.flowForm.timeRange[1]
|
||||
})
|
||||
.then((res) => {
|
||||
this.flowResult = res.data || null
|
||||
})
|
||||
.finally(() => {
|
||||
this.flowLoading = false
|
||||
})
|
||||
},
|
||||
printFlow() {
|
||||
const el = this.$refs.flowPrintContent
|
||||
if (!el) return
|
||||
const w = window.open('', '_blank')
|
||||
if (!w) return
|
||||
const html = `
|
||||
<html>
|
||||
<head>
|
||||
<title>物料出入库统计</title>
|
||||
<style>
|
||||
body { font-family: -apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,"Helvetica Neue",Arial,"Noto Sans","PingFang SC","Microsoft YaHei",sans-serif; padding: 12px; }
|
||||
table { border-collapse: collapse; width: 100%; }
|
||||
th, td { border: 1px solid #dcdfe6; padding: 6px 8px; font-size: 12px; }
|
||||
</style>
|
||||
</head>
|
||||
<body>${el.innerHTML}</body>
|
||||
</html>`
|
||||
w.document.open()
|
||||
w.document.write(html)
|
||||
w.document.close()
|
||||
w.focus()
|
||||
w.print()
|
||||
w.close()
|
||||
},
|
||||
showDetail(row) {
|
||||
this.detailOpen = true
|
||||
this.detailData = null
|
||||
|
||||
Reference in New Issue
Block a user