You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
crmeb/admin/src/views/ck/ckwarehouse/index.vue

1200 lines
45 KiB

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

<template>
<el-container style="margin-top: 10px;">
<!-- 搜索部分 -->
<el-header height="auto" style="padding: 10px 0; background-color: #fff; border-bottom: 1px solid #eaeaea;">
<SearchBlock v-model="billQuery" v-show="showSearch" size="mini" :menus="queryOption"
@change="handleQuery"></SearchBlock>
<el-col :span="1.5">
<el-button type="primary" size="small" plain icon="el-icon-plus" @click="handleAdd('bill')"
v-hasPermi="['jxc:ckcargo:add']">新增单据
</el-button>
</el-col>
<el-col :span="1.5">
<el-button
type="info"
plain
icon="el-icon-upload2"
size="small"
@click="handleImport"
>导入
</el-button>
</el-col>
<el-col :span="1.5">
<el-button
type="warning"
plain
icon="el-icon-download"
size="small"
@click="downloadTemplate"
>导出
</el-button>
</el-col>
</el-header>
<el-container>
<!-- 左侧单据部分 -->
<el-aside :width="isCollapse ? '60px' : '300px'"
style="border-right: 1px solid #eaeaea; padding: 10px;max-height: 90vh; transition: width 0.3s; position: relative;">
<div class="collapse-btn" @click="isCollapse = !isCollapse"
style="position: absolute; right: 10px; top: 10px; background: #fff; border: 1px solid #eaeaea; padding: 3px 6px; cursor: pointer; z-index: 10; border-radius: 2px;">
<span v-if="isCollapse"></span>
<span v-else></span>
</div>
<h3 v-if="!isCollapse" style="margin: 0 0 10px 0; font-size: 16px; font-weight: 500; padding-right: 30px;">
单据列表</h3>
<BillList v-if="!isCollapse" ref="billList" :params="billQuery" :showAutoOut="true" :autoSelectFirst="false" @rowClick="billClick"></BillList>
</el-aside>
<!-- 右侧商品部分 -->
<el-main style="padding: 10px;">
<!-- 导入成功确认弹窗 -->
<el-dialog
:visible.sync="importSuccessDialogVisible"
title="导入成功确认"
width="1200px"
top="50px"
custom-class="import-success-dialog"
modal
:close-on-click-modal="false"
>
<div v-html="importSuccessDialogContent"></div>
<template #footer>
<span class="dialog-footer">
<el-button @click="importSuccessDialogVisible = false">取消</el-button>
<el-button type="primary" @click="confirmImportedBills">确认</el-button>
</span>
</template>
</el-dialog>
<!-- 操作按钮 -->
<el-row :gutter="10" class="mb8">
<el-col :span="1.5">
<el-tooltip content="选择表格中的记录后新增明细" placement="top">
<el-button type="primary" size="small"
v-if="(!isCollapse && (this.selectedBill.sourceType == '1' && this.selectedBill.billStatus == '0'))" plain
icon="el-icon-plus"
@click="handleAdd('out')" v-hasPermi="['jxc:ckcargo:add']">新增明细
</el-button>
</el-tooltip>
</el-col>
<el-col :span="1.5">
<el-tooltip :content="!isCollapse ? '选择表格中的记录后删除单据' : '选择表格中的记录后删除明细'" placement="top">
<el-button type="danger" size="small"
v-if="(!isCollapse && this.selectedBill.sourceType == '1' && this.selectedBill.billStatus == '0') || (isCollapse && this.modifyData.id)" plain
icon="el-icon-delete"
@click="handleDel" v-hasPermi="['jxc:ckcargo:remove']">{{ !isCollapse ? '删除单据' : '删除明细' }}
</el-button>
</el-tooltip>
</el-col>
<el-col :span="1.5">
<el-tooltip content="选择表格中的记录后撤销" placement="top">
<el-button plain size="small"
v-if="(!isCollapse && this.selectedBill.sourceType == '1' && this.selectedBill.billStatus == '1')"
type="warning" icon="el-icon-plus" v-hasPermi="['jxc:ckcargo:add']" @click="backBill">单据撤销
</el-button>
</el-tooltip>
</el-col>
<el-col :span="1.5">
<el-tooltip content="选择表格中的记录后单据确认" placement="top">
<el-button plain size="small"
v-if="(!isCollapse && this.selectedBill.sourceType == '1' && this.selectedBill.billStatus == '0')"
type="success" icon="el-icon-plus" v-hasPermi="['jxc:ckcargo:add']" @click="confirm">单据确认
</el-button>
</el-tooltip>
</el-col>
<right-toolbar :showSearch.sync="showSearch" @queryTable="getList"></right-toolbar>
</el-row>
<!-- 商品列表 -->
<el-table v-loading="loading" highlight-current-row :data="ckcargoList" height="calc(100vh - 200px)"
@sort-change="handleSortChange"
@selection-change="handleSelectionChange" border>
<el-table-column type="selection" width="55" align="center" fixed="left"/>
<el-table-column label="单据编号" align="center" prop="billNumber" sortable='custom' min-width="100"
fixed="left"/>
<el-table-column label="仓库" align="center" prop="stockName" sortable='custom' min-width="80" fixed="left"/>
<el-table-column label="单据日期" align="center" prop="billDate" min-width="140" sortable='custom' fixed="left">
<template slot-scope="scope">
<span>{{ parseTime(scope.row.billDate, '{y}-{m}-{d}') }}</span>
</template>
</el-table-column>
<el-table-column label="商品分类" align="center" prop="className" sortable='custom' min-width="100"/>
<el-table-column label="商品编号" align="center" prop="hsCode" sortable='custom' min-width="100"/>
<el-table-column label="商品名称" align="center" prop="cargoName" sortable='custom' min-width="80"/>
<el-table-column label="规格型号" show-overflow-tooltip align="center" prop="cargoSpec" sortable='custom'
min-width="200"/>
<el-table-column label="单位" align="center" prop="unit" sortable='custom' min-width="80">
<template slot-scope="scope">
<dict-tag :options="dict.type.bm_measuring_unit" :value="scope.row.unit" />
</template>
</el-table-column>
<el-table-column label="数量" align="center" prop="cargoWt" sortable='custom' min-width="100"/>
<el-table-column label="单价" align="center" prop="unitPrice" sortable='custom' min-width="100"/>
<el-table-column label="金额" align="center" prop="cargoValue" sortable='custom' min-width="100"/>
<el-table-column label="是否自动出库" align="center" prop="autoOut" sortable='custom' min-width="100">
<template slot-scope="scope">
<el-tag>{{ scope.row.autoOut == '1' ? '是' : '否' }}</el-tag>
</template>
</el-table-column>
<el-table-column label="供应商" align="center" prop="custName" sortable='custom' min-width="150"/>
<!-- <el-table-column label="数据来源" align="center" prop="sourceType" sortable='custom' min-width="100">-->
<!-- <template slot-scope="scope">-->
<!-- <el-tag>{{-->
<!-- scope.row.sourceType == '0' ? '载货清单' : scope.row.sourceType == '2' ? '转场' : scope.row.sourceType == '3' ? '混配' : '直接入库'-->
<!-- }}-->
<!-- </el-tag>-->
<!-- </template>-->
<!-- </el-table-column>-->
<el-table-column label="状态" align="center" prop="status" sortable='custom' min-width="100">
<template slot-scope="scope">
<el-tag>{{ scope.row.billStatus == '1' ? '已确认' : '未确认' }}</el-tag>
</template>
</el-table-column>
<!-- <el-table-column label="货架名称" align="center" prop="shelfName" sortable='custom' min-width="80"/>-->
<!-- <el-table-column label="货位名称" align="center" prop="locationName" sortable='custom' min-width="80"-->
<!-- />-->
<el-table-column label="有效期至" align="center" prop="expiryDate" min-width="180" sortable='custom'>
</el-table-column>
<el-table-column label="操作" fixed="right" align="center" class-name="small-padding fixed-width" width="180px">
<template slot-scope="scope">
<el-button size="mini" type="text" icon="el-icon-check" @click="showDetail(scope.row)"
v-hasPermi="['jxc:ckcargo:edit']">查看
</el-button>
<el-button size="mini" type="text"
v-if="scope.row.billStatus == '0' && scope.row.sourceType == '1'"
icon="el-icon-edit" @click="handleUpdate(scope.row)" v-hasPermi="['jxc:ckcargo:edit']">修改
</el-button>
<el-button size="mini" type="text" v-if="scope.row.billStatus == '0' && scope.row.sourceType == '1'"
icon="el-icon-delete" @click="handleDelete(scope.row)" v-hasPermi="['jxc:ckcargo:remove']">删除
</el-button>
</template>
</el-table-column>
</el-table>
<pagination :total="total" :page.sync="queryParams.pageNum" :limit.sync="queryParams.pageSize"
@pagination="getList"/>
</el-main>
</el-container>
<!-- 添加或修改仓库入库管理对话框 -->
<el-dialog :title="title" :close-on-click-modal="false"
:visible.sync="open" fullscreen append-to-body>
<BillEdit ref="billEdit" :hideEdit="hideEdit" @close="handleClose" @refresh="refreshList"></BillEdit>
</el-dialog>
<!-- 导入对话框 -->
<el-dialog :title="upload.title" :visible.sync="upload.open" width="400px" append-to-body>
<el-upload
ref="upload"
:limit="1"
accept=".xlsx, .xls"
:headers="upload.headers"
:action="''"
:disabled="upload.isUploading"
:on-progress="handleFileUploadProgress"
:on-success="handleFileSuccess"
:auto-upload="false"
:http-request="uploadFile"
drag
>
<i class="el-icon-upload"></i>
<div class="el-upload__text">将文件拖到此处,或<em>点击上传</em></div>
<div class="el-upload__tip text-center" slot="tip">
<div class="el-upload__tip" slot="tip">
<el-checkbox v-model="upload.updateSupport"/>
是否更新已经存在的数据
</div>
<span>仅允许导入xls、xlsx格式文件。</span>
<el-link type="primary" :underline="false" style="font-size:12px;vertical-align: baseline;"
@click="importTemplate">下载模板
</el-link>
</div>
</el-upload>
<div slot="footer" class="dialog-footer">
<el-button type="primary" @click="submitFileForm">确 定</el-button>
<el-button @click="upload.open = false">取 消</el-button>
</div>
</el-dialog>
</el-container>
</template>
<script>
import {datePickerOpts} from "@/utils";
import SearchBlock from '@/components/SearchBlock';
import {
ckbillcargoListApi,
ckbillcargoDeleteApi as delCkcargo,
recallPutBill,
confirmPutBill
} from '@/api/ckbillcargo'
import BillList from '@/views/ck/ckwarehouse/components/BillList';
import BillEdit from '@/views/ck/ckwarehouse/components/BillEdit';
import {listWarehouse} from "@/api/cmwarehouse";
import {ckbillDeleteApi as delCkbill, downloadTemplate, importData} from "@/api/ckbill";
// import { listVessel } from "@/api/jxc/vessel";
export default {
name: "Ckwarehouse",
dicts: ['sys_origin_country', 'sys_trade_nature', 'sys_inbound_outbound_type', 'bm_measuring_unit'],
components: {
BillList,
BillEdit,
SearchBlock,
},
data() {
return {
// 导入成功确认弹窗
importSuccessDialogVisible: false,
importSuccessDialogContent: '',
importedBillIds: [],
//船名、航次、核注清单编号、单据日期
queryOption: [
// {
// label: '船舶名称',
// prop: 'vesselId',
// type: 'select',
// getOptions: () => this.vesselList,
// optionsProp: 'id',
// optionsLabel: 'vesselName',
// },
{
label: '单据日期',
prop: 'date',
type: 'daterange',
splitDaterange: true,
options: datePickerOpts()
},
{
label: '单据编号',
prop: 'billNumber',
type: 'text',
},
{
label: '商品名称',
prop: 'cargoName',
type: 'text',
},
{
label: '仓库名称',
prop: 'stockCode',
type: 'select',
getOptions: () => this.warehouses,
optionsProp: 'stockCode',
optionsLabel: 'stockName',
},
{
label: '是否自动出库',
prop: 'autoOut',
type: 'select',
options: [
{label: '是', value: '1'},
{label: '否', value: '0'}
],
optionLabel: 'label',
optionValue: 'value'
},
{
label: '商品编号',
prop: 'hsCode',
type: 'text',
},
],
activeName: ['1', '2', '3'],
pickerOptions: datePickerOpts(),
// 遮罩层
loading: false,
// 选中数组
ids: [],
// 选中名字
names: [],
// 非单个禁用
single: true,
// 非多个禁用
multiple: true,
// 显示搜索条件
showSearch: true,
// 总条数
total: 0,
// 有效期
queryTimeTwo: [],
// 仓库入库管理表格数据
ckcargoList: [],
warehouses: [],
// vesselList: [],
// 弹出层标题
title: "",
// 是否显示弹出层
open: false,
// 导入参数
upload: {
// 是否显示弹出层
open: false,
// 弹出层标题
title: "",
// 是否禁用上传
isUploading: false,
// 是否更新已经存在的数据
updateSupport: 0,
// 设置上传的请求头部
headers: {Authorization: "Bearer " + sessionStorage.getItem('token')},
// 上传的地址
url: process.env.VUE_APP_BASE_API + "/api/autogencode/ckbill/importData"
},
// 查询参数
queryParams: {
pageNum: 1,
pageSize: 10,
billId: null,
billDate: null,
billNumber: null,
inoutType: "1",
cargoId: null,
hsCode: null,
cargoName: null,
billNo: null,
cargoSpec: null,
originCountry: null,
custId: null,
custName: null,
opType: null,
tradType: null,
cargoNum: null,
cargoWt: null,
cargoVol: null,
stockId: null,
stockCode: null,
stockName: null,
shelfId: null,
shelfName: null,
locationId: null,
locationName: null,
cargoValue: null,
customsNo: null,
listNumber: null,
beginDate: null,
endDate: null,
cargoNumber: null,
itemNumber: null,
bookNumber: null,
expiryDate: null,
beginDateTwo: null,
endDateTwo: null,
autoOut: null,
},
// 单据查询参数
billQuery: {
billNumber: null,
cargoName: null,
stockCode: null,
stockName: null,
hsCode: null,
beginDate: null,
endDate: null,
queryTime: null,
autoOut: null,
},
// 左侧菜单折叠状态
isCollapse: true,
// 选中单据
selectedBill: {},
modifyData: {},
hideEdit: false,
};
},
created() {
listWarehouse({}).then(response => {
this.warehouses = response || [];
// 初始化时触发查询
this.getList();
}).catch(error => {
console.error('获取仓库列表失败:', error);
this.warehouses = [];
// 即使获取仓库列表失败,也要触发查询
this.getList();
});
},
methods: {
// 点击单据
billClick(row, isAutoRestore = false) {
if (row && Object.keys(row).length > 0) {
if (isAutoRestore) {
// 如果是自动恢复选中状态直接更新selectedBill和查询参数
this.selectedBill = row || {};
this.queryParams.pageNum = 1;
this.queryParams.billNumber = this.selectedBill.billNumber;
// 触发右侧的查询
this.getList();
} else {
// 检查是否点击的是当前选中的单据
if (this.selectedBill.id === row.id) {
// 取消选中状态
this.selectedBill = {};
// 清空查询参数中的单据编号
this.queryParams.pageNum = 1;
this.queryParams.billNumber = null;
} else {
// 选中新的单据
this.selectedBill = row || {};
// 更新查询参数中的单据编号
this.queryParams.pageNum = 1;
this.queryParams.billNumber = this.selectedBill.billNumber;
}
// 触发右侧的查询
this.getList();
}
} else if (!row || Object.keys(row).length === 0) {
// 清空选中状态
this.selectedBill = {};
this.queryParams.pageNum = 1;
this.queryParams.billNumber = null;
// 触发右侧的查询
this.getList();
}
},
// 刷新列表
refreshList(selectedBillId = null) {
// 只刷新左侧的单据列表,不影响顶部搜索条件和右侧列表
this.$nextTick(() => {
if (this.$refs.billList) {
this.$refs.billList.getList();
}
});
},
/** 查询仓库入库管理列表 */
getList() {
this.loading = true;
// 构建查询参数,确保日期格式正确
const params = {...this.queryParams};
// 处理日期范围参数,确保不是数组格式
if (Array.isArray(params.beginDate)) {
params.beginDate = params.beginDate[0];
}
if (Array.isArray(params.endDate)) {
params.endDate = params.endDate[1];
}
// 确保日期格式为 yyyy-MM-dd HH:mm:ss
// if (params.beginDate && typeof params.beginDate === 'object') {
// params.beginDate = this.formatDate(params.beginDate, false);
// }
// if (params.endDate && typeof params.endDate === 'object') {
// params.endDate = this.formatDate(params.endDate, true);
// }
ckbillcargoListApi(params).then(response => {
this.ckcargoList = response.list;
this.total = response.total;
this.loading = false;
}).catch(e => {
this.loading = false;
});
},
handleClose(show) {
if (this.hideEdit || !show) {
this.open = false;
return;
}
this.$confirm('关闭后未保存信息会丢失', '确认关闭?')
.then(_ => {
this.open = false;
})
.catch(_ => {
});
},
//排序
handleSortChange(col) {
// 保存当前的日期范围参数
const beginDate = this.queryParams.beginDate;
const endDate = this.queryParams.endDate;
this.$sortBy(col, this.queryParams);
// 恢复日期范围参数
this.queryParams.beginDate = beginDate;
this.queryParams.endDate = endDate;
this.getList();
},
/** 格式化日期为 yyyy-MM-dd 格式 */
formatDate(date) {
if (!date) return null;
let dateObj;
if (typeof date === 'string') {
dateObj = new Date(date);
} else if (date instanceof Date) {
dateObj = date;
} else {
return null;
}
if (isNaN(dateObj.getTime())) {
return null;
}
const year = dateObj.getFullYear();
const month = String(dateObj.getMonth() + 1).padStart(2, '0');
const day = String(dateObj.getDate()).padStart(2, '0');
return `${year}-${month}-${day}`;
},
/** 搜索按钮操作 */
handleQuery() {
this.queryParams.pageNum = 1;
// 处理日期范围参数
this.queryParams.beginDate = this.billQuery.dateBegin || null;
this.queryParams.endDate = this.billQuery.dateEnd || null;
// 将其他搜索参数复制到 queryParams 中
this.queryParams.stockCode = this.billQuery.stockCode;
this.queryParams.cargoName = this.billQuery.cargoName;
this.queryParams.billNumber = this.billQuery.billNumber;
this.queryParams.hsCode = this.billQuery.hsCode;
this.queryParams.autoOut = this.billQuery.autoOut;
// 同时刷新左侧和右侧列表
this.getList();
this.$nextTick(() => {
if (this.$refs.billList) {
this.$refs.billList.getList();
}
});
},
/** 重置按钮操作 */
resetQuery() {
this.queryTimeTwo = [];
// 清空搜索条件中的所有字段
this.$set(this.billQuery, 'billNumber', null);
this.$set(this.billQuery, 'cargoName', null);
this.$set(this.billQuery, 'stockCode', null);
this.$set(this.billQuery, 'stockName', null);
this.$set(this.billQuery, 'hsCode', null);
this.$set(this.billQuery, 'dateBegin', null);
this.$set(this.billQuery, 'dateEnd', null);
this.$set(this.billQuery, 'autoOut', null);
// 重置查询参数
this.queryParams = {
pageNum: 1,
pageSize: 10,
dateBegin: null,
dateEnd: null,
billNumber: null,
cargoName: null,
stockCode: null,
hsCode: null,
autoOut: null,
};
// 同时刷新左侧和右侧列表
this.getList();
this.$nextTick(() => {
if (this.$refs.billList) {
this.$refs.billList.getList();
}
});
},
// 多选框选中数据
handleSelectionChange(selection) {
this.ids = selection.map(item => item.id);
this.names = selection.map(item => item.id);
this.single = selection.length !== 1;
this.multiple = !selection.length;
this.modifyData = selection[0] || {};
},
handleDel() {
if (!this.isCollapse && this.selectedBill.id) {
// 左侧展开时,删除单据
const ids = [this.selectedBill.id];
const billNumber = this.selectedBill.billNumber || '选中单据';
this.$modal.confirm('是否确认删除"' + billNumber + '"的入库单据?').then(() => {
return delCkbill(ids);
}).then(() => {
// 清空选中状态和查询参数
this.selectedBill = {};
this.queryParams.billNumber = null;
// 刷新左侧单据列表
this.refreshList();
// 刷新右侧商品列表
this.getList();
this.$modal.msgSuccess("删除成功");
}).catch(() => {
});
} else if (this.ids.length > 0 || this.modifyData.id) {
// 左侧未展开时,删除明细
const ids = this.ids.length > 0 ? this.ids : [this.modifyData.id];
const billNumber = this.modifyData.billNumber || '选中数据';
this.$modal.confirm('是否确认删除"' + billNumber + '"的数据项?').then(() => {
return delCkcargo(ids);
}).then(() => {
this.getList();
this.$modal.msgSuccess("删除成功");
}).catch(() => {
});
} else {
this.$modal.msgError('请先选择要删除的记录');
return;
}
},
/** 新增按钮操作 */
handleAdd(type) {
this.hideEdit = false;
if (type === 'bill') {
this.open = true;
this.$nextTick(() => {
this.$refs.billEdit.open({type: 1});
})
return;
}
if (this.modifyData.billId && this.modifyData.billStatus == '1') {
this.$confirm('当前选中单据已确认,是否新增单据?', '温馨提示', {
confirmButtonText: '确定',
cancelButtonText: '取消',
type: 'info',
}).then(() => {
this.open = true;
this.$nextTick(() => {
this.$refs.billEdit.open({type: 1});
})
});
return;
}
this.open = true;
this.$nextTick(() => {
this.$refs.billEdit.open({type: 1, data: this.modifyData});
})
},
backBill() {
// 从选中的记录中获取单据ID
if (!this.isCollapse && this.selectedBill.id) {
// 保存当前选中的单据ID
const selectedBillId = this.selectedBill.id;
// 左侧展开时使用selectedBill
this.$confirm(`确定撤销当前单据吗?`, '温馨提示', {
confirmButtonText: '确定',
cancelButtonText: '取消',
type: 'warning',
}).then(() => {
// 撤销
this.loading = true;
recallPutBill(this.selectedBill.id).then(res => {
this.$message({
message: '撤销成功!',
type: 'success'
});
// 更新selectedBill的状态使按钮状态立即变化
this.selectedBill.billStatus = '0';
this.loading = false;
// 刷新列表并保持选中状态
this.refreshList(selectedBillId);
this.getList();
}).catch(e => {
this.loading = false;
});
});
} else if (this.modifyData.billId) {
// 左侧未展开时使用modifyData
this.$confirm(`确定撤销当前单据吗?`, '温馨提示', {
confirmButtonText: '确定',
cancelButtonText: '取消',
type: 'warning',
}).then(() => {
// 撤销
this.loading = true;
recallPutBill(this.modifyData.billId).then(res => {
this.$message({
message: '撤销成功!',
type: 'success'
});
// 更新modifyData的状态使按钮状态立即变化
this.modifyData.billStatus = '0';
this.loading = false;
this.refreshList();
}).catch(e => {
this.loading = false;
});
});
} else {
this.$modal.msgError('请先选择要撤销的单据');
}
},
confirm() {
// 从选中的记录中获取单据ID
if (!this.isCollapse && this.selectedBill.id) {
// 保存当前选中的单据ID
const selectedBillId = this.selectedBill.id;
// 左侧展开时使用selectedBill
// 检查是否自动出库
if (this.selectedBill.autoOut === '1') {
this.$confirm(`当前单据设置为自动出库,确认后将会自动生成出库单据。\n确定提交当前单据吗`, '温馨提示', {
confirmButtonText: '确定',
cancelButtonText: '取消',
type: 'warning',
}).then(() => {
// 确认单据
this.loading = true;
confirmPutBill(this.selectedBill.id).then(res => {
this.$message({
message: '提交成功!',
type: 'success'
});
// 更新selectedBill的状态使按钮状态立即变化
this.selectedBill.billStatus = '1';
this.loading = false;
// 刷新列表并保持选中状态
this.refreshList(selectedBillId);
this.getList();
}).catch(e => {
this.loading = false;
});
});
} else {
this.$confirm(`确定提交当前单据吗?`, '温馨提示', {
confirmButtonText: '确定',
cancelButtonText: '取消',
type: 'warning',
}).then(() => {
// 确认单据
this.loading = true;
confirmPutBill(this.selectedBill.id).then(res => {
this.$message({
message: '提交成功!',
type: 'success'
});
// 更新selectedBill的状态使按钮状态立即变化
this.selectedBill.billStatus = '1';
this.loading = false;
// 刷新列表并保持选中状态
this.refreshList(selectedBillId);
this.getList();
}).catch(e => {
this.loading = false;
});
});
}
} else if (this.modifyData.billId) {
// 左侧未展开时使用modifyData
// 检查是否自动出库
if (this.modifyData.autoOut === '1') {
this.$confirm(`当前单据设置为自动出库,确认后将会自动生成出库单据。\n确定提交当前单据吗`, '温馨提示', {
confirmButtonText: '确定',
cancelButtonText: '取消',
type: 'warning',
}).then(() => {
// 确认单据
this.loading = true;
confirmPutBill(this.modifyData.billId).then(res => {
this.$message({
message: '提交成功!',
type: 'success'
});
// 更新modifyData的状态使按钮状态立即变化
this.modifyData.billStatus = '1';
this.loading = false;
this.refreshList();
}).catch(e => {
this.loading = false;
});
});
} else {
this.$confirm(`确定提交当前单据吗?`, '温馨提示', {
confirmButtonText: '确定',
cancelButtonText: '取消',
type: 'warning',
}).then(() => {
// 确认单据
this.loading = true;
confirmPutBill(this.modifyData.billId).then(res => {
this.$message({
message: '提交成功!',
type: 'success'
});
// 更新modifyData的状态使按钮状态立即变化
this.modifyData.billStatus = '1';
this.loading = false;
this.refreshList();
}).catch(e => {
this.loading = false;
});
});
}
} else {
this.$modal.msgError('请先选择要确认的单据');
}
},
/** 修改按钮操作 */
handleUpdate(row) {
this.hideEdit = row.billStatus == '1';
this.open = true;
this.$nextTick(() => {
// 传递 billId单据ID而不是 id商品明细ID
this.$refs.billEdit.open({type: 0, data: {id: row.billId}});
})
},
showDetail(row) {
this.hideEdit = true;
this.open = true;
this.$nextTick(() => {
// 传递 billId单据ID而不是 id商品明细ID
const data = row.billId ? {id: row.billId} : (this.modifyData.billId ? {id: this.modifyData.billId} : null);
this.$refs.billEdit.open({type: 2, data: data});
})
},
/** 删除按钮操作 */
handleDelete(row) {
const ids = row.id || this.ids;
const names = row.id || this.names;
this.$modal.confirm('是否确认删除"' + row.billNumber + '"的数据项?').then(function () {
return delCkcargo(ids);
}).then(() => {
this.getList();
this.$modal.msgSuccess("删除成功");
}).catch(() => {
});
},
/** 导出按钮操作 */
handleExport() {
this.download('jxc/ckcargo/export', {
...this.queryParams
}, `仓库入库管理_${new Date().getTime()}.xlsx`)
},
/** 下载模板 */
downloadTemplate() {
// 调用后端API下载模板
downloadTemplate().then(blob => {
// 直接使用blob数据
const url = window.URL.createObjectURL(blob);
const link = document.createElement('a');
link.href = url;
link.setAttribute('download', `入库导入模板_${new Date().getTime()}.xlsx`);
document.body.appendChild(link);
link.click();
// 清理
document.body.removeChild(link);
window.URL.revokeObjectURL(url);
}).catch(error => {
console.error('下载模板失败:', error);
this.$modal.msgError('下载模板失败,请重试');
});
},
/** 导入按钮操作 */
handleImport() {
this.upload.title = "入库信息导入";
this.upload.open = true;
},
/** 下载模板操作 */
importTemplate() {
// 调用后端API下载模板
downloadTemplate().then(blob => {
// 直接使用blob数据
const url = window.URL.createObjectURL(blob);
const link = document.createElement('a');
link.href = url;
link.setAttribute('download', `入库导入模板_${new Date().getTime()}.xlsx`);
document.body.appendChild(link);
link.click();
// 清理
document.body.removeChild(link);
window.URL.revokeObjectURL(url);
}).catch(error => {
console.error('下载模板失败:', error);
this.$modal.msgError('下载模板失败,请重试');
});
},
// 文件上传中处理
handleFileUploadProgress(event, file, fileList) {
this.upload.isUploading = true;
},
// 文件上传成功处理
handleFileSuccess(response, file, fileList) {
this.upload.open = false;
this.upload.isUploading = false;
this.$refs.upload.clearFiles();
this.$alert("<div style='overflow: auto;overflow-x: hidden;max-height: 70vh;padding: 10px 20px 0;'>" + response.msg + "</div>", "导入结果", {dangerouslyUseHTMLString: true});
// 导入成功后刷新列表
this.refreshList();
// 同时刷新右侧商品列表
this.getList();
},
///** 提交上传文件 */
submitFileForm() {
this.$refs.upload.submit();
},
/** 确认导入的单据 */
confirmImportedBills() {
console.log('用户确认,开始确认单据');
const billIds = this.importedBillIds;
// 循环确认每个单据
const confirmPromises = billIds.map(billId => {
console.log('确认单据ID:', billId);
return confirmPutBill(billId);
});
Promise.all(confirmPromises).then(() => {
console.log('确认成功');
this.$modal.msgSuccess('单据确认成功');
// 关闭弹窗
this.importSuccessDialogVisible = false;
// 确认成功后刷新列表
this.refreshList();
this.getList();
}).catch(error => {
console.log('确认失败:', error);
this.$modal.msgError('单据确认失败:' + (error.response?.data?.message || '未知错误'));
// 关闭弹窗
this.importSuccessDialogVisible = false;
// 即使确认失败,也刷新列表
this.refreshList();
this.getList();
});
},
/** 自定义上传方法 */
uploadFile(file) {
console.log('开始导入文件:', file);
const formData = new FormData();
formData.append('file', file.file);
formData.append('updateSupport', this.upload.updateSupport);
importData(formData).then(response => {
console.log('导入响应:', response);
const data = response;
this.$modal.msgSuccess(response.message || '导入成功');
this.upload.open = false;
this.upload.fileList = [];
// 检查是否有导入的单据ID列表
console.log('检查单据ID列表:', data.billIds);
if (data.billIds && data.billIds.length > 0) {
// 显示加载提示
this.$modal.loading('正在获取单据明细...');
// 循环查询每个单据的明细
console.log('开始查询单据明细:', data.billIds);
const detailPromises = data.billIds.map(billId => {
console.log('查询单据ID:', billId);
return ckbillcargoListApi({billId: billId});
});
Promise.all(detailPromises).then(detailResponses => {
console.log('明细查询响应:', detailResponses);
// 关闭加载提示
this.$modal.closeLoading();
// 处理明细数据
const billDetails = [];
detailResponses.forEach((detailResponse, index) => {
console.log('处理明细响应:', index, detailResponse);
if (detailResponse && detailResponse && detailResponse.list) {
const billId = data.billIds[index];
const details = detailResponse.list;
billDetails.push({ billId, details });
console.log('添加单据明细:', billId, details.length);
}
});
// 生成弹窗内容
const successCount = data.message?.match(/\d+/)?.[0] || 0;
console.log('生成弹窗内容,成功数量:', successCount);
let dialogContent = `
<div style="padding: 20px;">
<h3 style="margin-bottom: 20px; color: #409EFF;">导入成功</h3>
<p style="margin-bottom: 15px;">共导入成功 ${successCount} 条单据,以下是导入的内容:</p>
`;
// 为每个单据生成明细表格
console.log('生成明细表格,单据数量:', billDetails.length);
billDetails.forEach((billDetail, index) => {
const { billId, details } = billDetail;
console.log('处理单据:', index + 1, billId, details.length);
// 获取单据编号
let billNumber = '';
if (details.length > 0) {
billNumber = details[0].billNumber || '';
}
dialogContent += `
<div style="margin-bottom: 30px;">
<h4 style="margin-bottom: 10px; color: #606266;">单据 (编号: ${billNumber || '未知'})</h4>
<div style="border: 1px solid #e4e7ed; border-radius: 4px; overflow: hidden;">
<table style="width: 100%; border-collapse: collapse;">
<thead style="background-color: #f5f7fa;">
<tr>
<th style="padding: 10px; border: 1px solid #e4e7ed; text-align: left;">商品分类</th>
<th style="padding: 10px; border: 1px solid #e4e7ed; text-align: left;">商品编号</th>
<th style="padding: 10px; border: 1px solid #e4e7ed; text-align: left;">商品名称</th>
<th style="padding: 10px; border: 1px solid #e4e7ed; text-align: left;">规格型号</th>
<th style="padding: 10px; border: 1px solid #e4e7ed; text-align: left;">单位</th>
<th style="padding: 10px; border: 1px solid #e4e7ed; text-align: left;">数量</th>
<th style="padding: 10px; border: 1px solid #e4e7ed; text-align: left;">单价</th>
<th style="padding: 10px; border: 1px solid #e4e7ed; text-align: left;">金额</th>
<th style="padding: 10px; border: 1px solid #e4e7ed; text-align: left;">供应商</th>
</tr>
</thead>
<tbody>
`;
// 生成明细行
if (details.length > 0) {
details.forEach(detail => {
// 使用后端返回的unitName字段
let unitText = detail.unitName;
dialogContent += `
<tr>
<td style="padding: 10px; border: 1px solid #e4e7ed;">${detail.productClass || detail.className || '-'}</td>
<td style="padding: 10px; border: 1px solid #e4e7ed;">${detail.cargoCode || detail.hsCode || '-'}</td>
<td style="padding: 10px; border: 1px solid #e4e7ed;">${detail.cargoName || '-'}</td>
<td style="padding: 10px; border: 1px solid #e4e7ed;">${detail.cargoSpec || '-'}</td>
<td style="padding: 10px; border: 1px solid #e4e7ed;">${unitText}</td>
<td style="padding: 10px; border: 1px solid #e4e7ed;">${detail.cargoWt || detail.num || '-'}</td>
<td style="padding: 10px; border: 1px solid #e4e7ed;">${detail.price || detail.unitPrice || '-'}</td>
<td style="padding: 10px; border: 1px solid #e4e7ed;">${detail.amount || detail.cargoValue || '-'}</td>
<td style="padding: 10px; border: 1px solid #e4e7ed;">${detail.supplierName || detail.custName || '-'}</td>
</tr>
`;
});
} else {
dialogContent += `
<tr>
<td colspan="9" style="padding: 20px; text-align: center; border: 1px solid #e4e7ed; color: #909399;">
暂无明细数据
</td>
</tr>
`;
}
dialogContent += `
</tbody>
</table>
</div>
</div>
`;
});
// 没有明细数据时的提示
if (billDetails.length === 0) {
console.log('没有明细数据');
dialogContent += `
<div style="border: 1px solid #e4e7ed; border-radius: 4px; overflow: hidden;">
<table style="width: 100%; border-collapse: collapse;">
<thead style="background-color: #f5f7fa;">
<tr>
<th style="padding: 10px; border: 1px solid #e4e7ed; text-align: left;">商品分类</th>
<th style="padding: 10px; border: 1px solid #e4e7ed; text-align: left;">商品编号</th>
<th style="padding: 10px; border: 1px solid #e4e7ed; text-align: left;">商品名称</th>
<th style="padding: 10px; border: 1px solid #e4e7ed; text-align: left;">规格型号</th>
<th style="padding: 10px; border: 1px solid #e4e7ed; text-align: left;">单位</th>
<th style="padding: 10px; border: 1px solid #e4e7ed; text-align: left;">数量</th>
<th style="padding: 10px; border: 1px solid #e4e7ed; text-align: left;">单价</th>
<th style="padding: 10px; border: 1px solid #e4e7ed; text-align: left;">金额</th>
<th style="padding: 10px; border: 1px solid #e4e7ed; text-align: left;">供应商</th>
</tr>
</thead>
<tbody>
<tr>
<td colspan="9" style="padding: 20px; text-align: center; border: 1px solid #e4e7ed; color: #909399;">
暂无明细数据
</td>
</tr>
</tbody>
</table>
</div>
`;
}
dialogContent += `
<p style="margin-top: 20px; color: #606266;"></p>
</div>
`;
//
console.log('');
console.log(':', dialogContent);
console.log('ID:', data.billIds);
//
this.importSuccessDialogContent = dialogContent;
// ID
this.importedBillIds = data.billIds;
//
this.importSuccessDialogVisible = true;
console.log(':', this.importSuccessDialogVisible);
}).catch(error => {
// 关闭加载提示
console.log('明细查询失败:', error);
this.$modal.closeLoading();
this.$modal.msgError('获取单据明细失败:' + (error.response?.data?.message || '未知错误'));
// 即使获取明细失败,也刷新列表
this.refreshList();
this.getList();
});
} else {
// 没有单据ID直接刷新列表
console.log('没有单据ID直接刷新列表');
this.refreshList();
this.getList();
}
}).catch(error => {
console.log('导入失败:', error);
this.$modal.msgError('导入失败:' + (error.response?.data?.message || '未知错误'));
}).finally(() => {
console.log('导入过程完成');
this.upload.isUploading = false;
});
}
}
};
</script>
<style scoped>
.app-container {
display: flex;
position: absolute;
left: 0;
right: 0;
bottom: 0;
top: 0;
}
.right-content {
flex: 1;
overflow: hidden;
display: flex;
flex-direction: column;
}
.search-item {
margin-bottom: 6px;
}
.table {
flex: 1;
}
.search-input {
max-width: 150px;
}
::v-deep .el-dialog.is-fullscreen {
display: flex;
flex-direction: column;
}
::v-deep .el-dialog__body {
padding-top: 0px !important;
flex: 1;
overflow: auto;
}
::v-deep .import-success-dialog {
z-index: 9999 !important;
}
::v-deep .import-success-dialog .el-dialog__body {
max-height: 500px;
overflow-y: auto;
}
</style>