|
|
@@ -0,0 +1,439 @@
|
|
|
+<template>
|
|
|
+ <ele-modal
|
|
|
+ :title="title"
|
|
|
+ :visible.sync="visible"
|
|
|
+ :before-close="handleClose"
|
|
|
+ :close-on-click-modal="false"
|
|
|
+ :close-on-press-escape="false"
|
|
|
+ append-to-body
|
|
|
+ width="75%"
|
|
|
+ :maxable="true"
|
|
|
+ >
|
|
|
+ <el-card shadow="never">
|
|
|
+ <el-descriptions>
|
|
|
+ <el-descriptions-item label="创建时间">{{ formData.createTime }}</el-descriptions-item>
|
|
|
+ <!-- <el-descriptions-item label="创建人">{{ formData.createUser }}</el-descriptions-item> -->
|
|
|
+ <el-descriptions-item label="物品编码">{{ formData.productCode }}</el-descriptions-item>
|
|
|
+ <el-descriptions-item label="名称">{{ formData.productName }}</el-descriptions-item>
|
|
|
+ <el-descriptions-item label="批次号">{{ formData.batchNo }}</el-descriptions-item>
|
|
|
+ <!-- <el-descriptions-item label="规格">{{ formData.spec }}</el-descriptions-item> -->
|
|
|
+ <!-- <el-descriptions-item label="型号">{{ formData.model }}</el-descriptions-item> -->
|
|
|
+ <!-- <el-descriptions-item label="牌号">{{ formData.certificateNumber }}</el-descriptions-item> -->
|
|
|
+ </el-descriptions>
|
|
|
+ <div style="margin-top: 12px">
|
|
|
+ <ele-pro-table
|
|
|
+ ref="eleTable"
|
|
|
+ row-key="outInDetailId"
|
|
|
+ :columns="tableColumns"
|
|
|
+ :datasource="datasource"
|
|
|
+ height="calc(100vh - 405px)"
|
|
|
+ full-height="calc(100vh - 116px)"
|
|
|
+ tool-class="ele-toolbar-form"
|
|
|
+ :pageSize="20"
|
|
|
+ @selection-change="handleSelectionChange"
|
|
|
+ :initLoad="false"
|
|
|
+ @done="onDone"
|
|
|
+ >
|
|
|
+ <template v-slot:measureQuantity="{ row }">
|
|
|
+ <el-input
|
|
|
+ v-model="row.measureQuantity"
|
|
|
+ placeholder="请输入"
|
|
|
+ :disabled="readonlyMode"
|
|
|
+ @input="(value) => inputNum(value, row)"
|
|
|
+ ></el-input>
|
|
|
+ </template>
|
|
|
+ <template v-slot:purpose="{ row }">
|
|
|
+ <el-input
|
|
|
+ v-model="row.purpose"
|
|
|
+ placeholder="请输入"
|
|
|
+ :disabled="readonlyMode"
|
|
|
+ ></el-input>
|
|
|
+ </template>
|
|
|
+ <template v-slot:certificateNumber="{ row, $index }">
|
|
|
+ <div>
|
|
|
+ <el-input
|
|
|
+ v-model="row.certificateNumber"
|
|
|
+ placeholder="请输入"
|
|
|
+ :disabled="readonlyMode"
|
|
|
+ @blur="validateCertificate(row, $index)"
|
|
|
+ :class="{ 'is-error': row.certificateError }"
|
|
|
+ ></el-input>
|
|
|
+ <div v-if="row.certificateError" class="el-form-item__error">
|
|
|
+ {{ row.certificateError }}
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ </template>
|
|
|
+ </ele-pro-table>
|
|
|
+ </div>
|
|
|
+ </el-card>
|
|
|
+ <div class="btns" v-if="title != '详情'">
|
|
|
+ <el-button type="primary" size="small" @click="handleSave"
|
|
|
+ >确认</el-button
|
|
|
+ >
|
|
|
+ <el-button size="small" @click="handleClose">取消</el-button>
|
|
|
+ </div>
|
|
|
+ </ele-modal>
|
|
|
+</template>
|
|
|
+<script>
|
|
|
+ import storageApi from '@/api/warehouseManagement';
|
|
|
+ import { getCode } from '@/api/codeManagement/index.js';
|
|
|
+ import { re } from 'mathjs';
|
|
|
+ export default {
|
|
|
+ props: {},
|
|
|
+ data() {
|
|
|
+ return {
|
|
|
+ visible: false,
|
|
|
+ title: '',
|
|
|
+ formData: {
|
|
|
+ code: '',
|
|
|
+ sourceType: '',
|
|
|
+ remark: ''
|
|
|
+ },
|
|
|
+ columns: [
|
|
|
+ {
|
|
|
+ columnKey: 'selection',
|
|
|
+ type: 'selection',
|
|
|
+ width: 45,
|
|
|
+ align: 'center'
|
|
|
+ },
|
|
|
+ {
|
|
|
+ columnKey: 'index',
|
|
|
+ type: 'index',
|
|
|
+ width: 50,
|
|
|
+ align: 'center',
|
|
|
+ label: '序号',
|
|
|
+ showOverflowTooltip: true,
|
|
|
+ fixed: 'left'
|
|
|
+ },
|
|
|
+ {
|
|
|
+ prop: 'batchNo',
|
|
|
+ label: '批次号',
|
|
|
+ align: 'center',
|
|
|
+ width: 100
|
|
|
+ },
|
|
|
+ {
|
|
|
+ prop: 'categoryCode',
|
|
|
+ label: '物品编码',
|
|
|
+ align: 'center',
|
|
|
+ showOverflowTooltip: true,
|
|
|
+ width: 100
|
|
|
+ },
|
|
|
+ {
|
|
|
+ slot: 'categoryName',
|
|
|
+ prop: 'categoryName',
|
|
|
+ label: '物品名称',
|
|
|
+ align: 'center',
|
|
|
+ showOverflowTooltip: true,
|
|
|
+ minWidth: 160
|
|
|
+ },
|
|
|
+ {
|
|
|
+ prop: 'inventoryCycle',
|
|
|
+ label: '存货周期(天)',
|
|
|
+ align: 'center',
|
|
|
+ width: 120,
|
|
|
+ showOverflowTooltip: true
|
|
|
+ },
|
|
|
+ {
|
|
|
+ prop: 'brandNum',
|
|
|
+ label: '牌号',
|
|
|
+ align: 'center',
|
|
|
+ showOverflowTooltip: true
|
|
|
+ },
|
|
|
+ {
|
|
|
+ prop: 'categoryModel',
|
|
|
+ label: '型号',
|
|
|
+ align: 'center',
|
|
|
+ width: 120,
|
|
|
+ showOverflowTooltip: true
|
|
|
+ },
|
|
|
+ {
|
|
|
+ prop: 'specification',
|
|
|
+ label: '规格',
|
|
|
+ align: 'center',
|
|
|
+ width: 120,
|
|
|
+ showOverflowTooltip: true
|
|
|
+ },
|
|
|
+ {
|
|
|
+ prop: 'supplierName',
|
|
|
+ label: '供应商',
|
|
|
+ showOverflowTooltip: true,
|
|
|
+ width: 130,
|
|
|
+ align: 'center'
|
|
|
+ },
|
|
|
+ {
|
|
|
+ prop: 'level',
|
|
|
+ label: '级别',
|
|
|
+ showOverflowTooltip: true
|
|
|
+ },
|
|
|
+ {
|
|
|
+ prop: 'certificateNumber',
|
|
|
+ slot: 'certificateNumber',
|
|
|
+ label: '合格证号',
|
|
|
+ showOverflowTooltip: true,
|
|
|
+ width: 160
|
|
|
+ },
|
|
|
+ {
|
|
|
+ prop: 'originalMeasureQuantity',
|
|
|
+ label: '库存数量',
|
|
|
+ sortable: 'custom',
|
|
|
+ showOverflowTooltip: true,
|
|
|
+ width: 130,
|
|
|
+ align: 'center'
|
|
|
+ },
|
|
|
+ {
|
|
|
+ prop: 'measureQuantity',
|
|
|
+ slot: 'measureQuantity',
|
|
|
+ label: '计量数量',
|
|
|
+ sortable: 'custom',
|
|
|
+ showOverflowTooltip: true,
|
|
|
+ width: 130,
|
|
|
+ align: 'center'
|
|
|
+ },
|
|
|
+ {
|
|
|
+ prop: 'measureUnit',
|
|
|
+ label: '计量单位',
|
|
|
+ align: 'center'
|
|
|
+ },
|
|
|
+ {
|
|
|
+ prop: 'weight',
|
|
|
+ label: '重量',
|
|
|
+ showOverflowTooltip: true
|
|
|
+ },
|
|
|
+ {
|
|
|
+ prop: 'weightUnit',
|
|
|
+ label: '重量单位',
|
|
|
+ showOverflowTooltip: true
|
|
|
+ },
|
|
|
+ {
|
|
|
+ prop: 'purpose',
|
|
|
+ slot: 'purpose',
|
|
|
+ label: '用途',
|
|
|
+ showOverflowTooltip: true,
|
|
|
+ width: 130
|
|
|
+ }
|
|
|
+ ],
|
|
|
+ rules: {
|
|
|
+ sourceType: [
|
|
|
+ { required: true, message: '请选择申请类型', trigger: 'change' }
|
|
|
+ ]
|
|
|
+ },
|
|
|
+ loading: false,
|
|
|
+ selectionList: [],
|
|
|
+ ids: [],
|
|
|
+ detailJnVOList: []
|
|
|
+ };
|
|
|
+ },
|
|
|
+ computed: {
|
|
|
+ readonlyMode() {
|
|
|
+ return this.title === '详情';
|
|
|
+ },
|
|
|
+ tableColumns() {
|
|
|
+ return this.title === '详情'
|
|
|
+ ? this.columns.filter((c) => c.type !== 'selection')
|
|
|
+ : this.columns;
|
|
|
+ }
|
|
|
+ },
|
|
|
+
|
|
|
+ methods: {
|
|
|
+ async datasource({ page, where, limit }) {
|
|
|
+ if (this.readonlyMode) {
|
|
|
+ return (this.detailJnVOList || []).map((item) => ({
|
|
|
+ ...item,
|
|
|
+ originalMeasureQuantity:
|
|
|
+ item.originalMeasureQuantity ?? item.measureQuantity,
|
|
|
+ certificateError: ''
|
|
|
+ }));
|
|
|
+ }
|
|
|
+ const res = await storageApi.getBatchList({ ...where, page, limit });
|
|
|
+
|
|
|
+ const data = res.list.map((item) => {
|
|
|
+ item.originalMeasureQuantity = item.measureQuantity;
|
|
|
+ item.certificateError = '';
|
|
|
+ item.outInDetailId = item.id;
|
|
|
+ delete item.id;
|
|
|
+
|
|
|
+ return {
|
|
|
+ ...item
|
|
|
+ };
|
|
|
+ });
|
|
|
+ return data;
|
|
|
+ },
|
|
|
+ reload(where) {
|
|
|
+ this.$nextTick(() => {
|
|
|
+ if (this.$refs.eleTable && this.$refs.eleTable.reload)
|
|
|
+ this.$refs.eleTable.reload({ page: 1, where: where });
|
|
|
+ });
|
|
|
+ },
|
|
|
+ onDone() {
|
|
|
+ this.$nextTick(() => {
|
|
|
+ this.$refs.eleTable.setSelectedRowKeys(this.ids);
|
|
|
+ });
|
|
|
+
|
|
|
+ if (this.detailJnVOList.length > 0) {
|
|
|
+ let list = this.$refs.eleTable.getData();
|
|
|
+
|
|
|
+ for (let i = 0; i < list.length; i++) {
|
|
|
+ for (let j = 0; j < this.detailJnVOList.length; j++) {
|
|
|
+ if (
|
|
|
+ list[i].outInDetailId == this.detailJnVOList[j].outInDetailId
|
|
|
+ ) {
|
|
|
+ this.$set(
|
|
|
+ list[i],
|
|
|
+ 'certificateNumber',
|
|
|
+ this.detailJnVOList[j].certificateNumber
|
|
|
+ );
|
|
|
+ this.$set(
|
|
|
+ list[i],
|
|
|
+ 'measureQuantity',
|
|
|
+ this.detailJnVOList[j].measureQuantity
|
|
|
+ );
|
|
|
+ this.$set(list[i], 'purpose', this.detailJnVOList[j].purpose);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ },
|
|
|
+ resetData() {
|
|
|
+ this.formData = {
|
|
|
+ code: '',
|
|
|
+ sourceType: '',
|
|
|
+ remark: ''
|
|
|
+ };
|
|
|
+ this.detailJnVOList = [];
|
|
|
+ },
|
|
|
+ validateCertificate(row, index) {
|
|
|
+ let list = this.$refs.eleTable.getData();
|
|
|
+ if (!row.certificateNumber || row.certificateNumber.trim() === '') {
|
|
|
+ this.$set(list[index], 'certificateError', '证书号不能为空');
|
|
|
+ } else {
|
|
|
+ this.$set(list[index], 'certificateError', '');
|
|
|
+ }
|
|
|
+ },
|
|
|
+ async open(type, row) {
|
|
|
+ this.resetData();
|
|
|
+ this.visible = true;
|
|
|
+ this.title =
|
|
|
+ type == 'add' ? '新增' : type == 'detail' ? '详情' : '编辑';
|
|
|
+
|
|
|
+ if (type == 'add') {
|
|
|
+ const code = await getCode('Storage_application');
|
|
|
+ this.formData.code = code;
|
|
|
+ } else if (row?.id) {
|
|
|
+ await this.getDraftDetail(row.id);
|
|
|
+ }
|
|
|
+ await this.reload();
|
|
|
+ },
|
|
|
+ async getDraftDetail(id) {
|
|
|
+ const res = await storageApi.getUnlockDetails(id);
|
|
|
+ if (res) {
|
|
|
+ console.log(res, '详情');
|
|
|
+ this.$set(this, 'formData', res);
|
|
|
+
|
|
|
+ this.tab
|
|
|
+
|
|
|
+ this.ids =
|
|
|
+ res.detailJnVOList?.map((item) => item.outInDetailId) || [];
|
|
|
+ this.detailJnVOList = res.detailJnVOList || [];
|
|
|
+ }
|
|
|
+ },
|
|
|
+ inputNum(value, row) {
|
|
|
+ const num = value.replace(/[^\d.]/g, '');
|
|
|
+ const oldValue = row.originalMeasureQuantity;
|
|
|
+
|
|
|
+ if (num > oldValue) {
|
|
|
+ this.$set(row, 'measureQuantity', oldValue);
|
|
|
+ } else {
|
|
|
+ this.$set(row, 'measureQuantity', num);
|
|
|
+ }
|
|
|
+ },
|
|
|
+ handleSelectionChange(selection) {
|
|
|
+ console.log(selection, '勾选');
|
|
|
+ if (this.title === '新增' && selection.length > 1) {
|
|
|
+ const last = selection[selection.length - 1];
|
|
|
+ this.selectionList = [last];
|
|
|
+ this.$nextTick(() => {
|
|
|
+ if (this.$refs.eleTable && this.$refs.eleTable.setSelectedRowKeys) {
|
|
|
+ this.$refs.eleTable.setSelectedRowKeys([last.outInDetailId]);
|
|
|
+ }
|
|
|
+ });
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ this.selectionList = selection;
|
|
|
+ },
|
|
|
+ handleClose() {
|
|
|
+ this.visible = false;
|
|
|
+ this.resetData();
|
|
|
+ },
|
|
|
+ handleSave() {
|
|
|
+ this.$refs.formName.validate(async (valid) => {
|
|
|
+ if (valid) {
|
|
|
+ if (this.selectionList.length == 0)
|
|
|
+ return this.$message.warning('请选择入库物品');
|
|
|
+
|
|
|
+ let isValid = true;
|
|
|
+ this.selectionList.forEach((item) => {
|
|
|
+ if (!item.certificateNumber?.trim()) {
|
|
|
+ isValid = false;
|
|
|
+ this.$set(item, 'certificateError', '证书号不能为空');
|
|
|
+ }
|
|
|
+ });
|
|
|
+ if (!isValid) {
|
|
|
+ this.$message.error('请填写所有必填项');
|
|
|
+ return;
|
|
|
+ }
|
|
|
+
|
|
|
+ let postData = {
|
|
|
+ type: 1,
|
|
|
+ code: this.formData.code,
|
|
|
+ sourceType: this.formData.sourceType,
|
|
|
+ detailJnAddPOList: this.selectionList,
|
|
|
+ id: this.title == '编辑' ? this.formData.id : null
|
|
|
+ };
|
|
|
+ this.loading = true;
|
|
|
+ storageApi
|
|
|
+ .saveStoragejn(postData)
|
|
|
+ .then(async (res) => {
|
|
|
+ if (res == 0) {
|
|
|
+ try {
|
|
|
+ this.$message.success('保存成功');
|
|
|
+ this.loading = false;
|
|
|
+ this.visible = false;
|
|
|
+ this.$emit('success');
|
|
|
+ } catch (error) {
|
|
|
+ this.visible = false;
|
|
|
+ console.log('失败', error);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ })
|
|
|
+ .catch((err) => {
|
|
|
+ console.log('申请失败', err);
|
|
|
+ this.loading = false;
|
|
|
+ this.visible = false;
|
|
|
+ });
|
|
|
+ } else {
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+ });
|
|
|
+ }
|
|
|
+ }
|
|
|
+ };
|
|
|
+</script>
|
|
|
+
|
|
|
+<style lang="scss" scoped>
|
|
|
+ .btns {
|
|
|
+ text-align: center;
|
|
|
+ padding: 10px 0;
|
|
|
+ }
|
|
|
+
|
|
|
+ .el-form-item__error {
|
|
|
+ color: red;
|
|
|
+ font-size: 12px;
|
|
|
+ line-height: 1;
|
|
|
+ padding-top: 4px;
|
|
|
+ position: relative;
|
|
|
+ }
|
|
|
+
|
|
|
+ .is-error .el-input__inner {
|
|
|
+ border-color: red;
|
|
|
+ }
|
|
|
+</style>
|