959 lines
29 KiB
Vue
959 lines
29 KiB
Vue
<template>
|
||
<div class="app-container">
|
||
<!-- 查询表单 - 可复用的查询组件 -->
|
||
<el-form :model="queryParams" ref="queryForm" size="small" :inline="true" v-show="showSearch" label-width="90px">
|
||
<!-- 库存日期 -->
|
||
<el-form-item label="库存日期">
|
||
<el-date-picker
|
||
v-model="dateRange"
|
||
type="daterange"
|
||
align="right"
|
||
unlink-panels
|
||
range-separator="至"
|
||
start-placeholder="开始日期"
|
||
end-placeholder="结束日期"
|
||
format="yyyy-MM-dd"
|
||
value-format="yyyy-MM-dd"
|
||
style="width: 240px"
|
||
:picker-options="pickerOptions">
|
||
</el-date-picker>
|
||
</el-form-item>
|
||
|
||
<!-- 出库类型 -->
|
||
<el-form-item label="出库类型" prop="intoType">
|
||
<el-select
|
||
v-model="queryParams.intoTypeList"
|
||
multiple
|
||
placeholder="请选择出库类型"
|
||
clearable
|
||
style="width: 200px">
|
||
<el-option
|
||
v-for="item in intoTypeOptions"
|
||
:key="item.dictValue"
|
||
:label="item.dictLabel"
|
||
:value="item.dictValue">
|
||
</el-option>
|
||
</el-select>
|
||
</el-form-item>
|
||
|
||
<!-- 货品类别 - 改为级联多选 -->
|
||
<el-form-item label="货品类别">
|
||
<el-cascader
|
||
v-model="selectedCategories"
|
||
:options="goodsCategoryOptions"
|
||
:show-all-levels="false"
|
||
:props="categoryProps"
|
||
clearable
|
||
filterable
|
||
multiple
|
||
collapse-tags
|
||
placeholder="请选择货品类别"
|
||
style="width: 200px;"
|
||
@change="handleCategoryChange">
|
||
</el-cascader>
|
||
</el-form-item>
|
||
|
||
<!-- 所属区域 -->
|
||
<el-form-item label="所属区域">
|
||
<el-cascader
|
||
v-model="selectedOrg"
|
||
:options="orgOptions"
|
||
:show-all-levels="false"
|
||
clearable
|
||
filterable
|
||
placeholder="请选择所属区域"
|
||
:props="{
|
||
checkStrictly: true,
|
||
expandTrigger: 'hover',
|
||
value: 'orgId',
|
||
label: 'orgName',
|
||
children: 'children'
|
||
}"
|
||
style="width: 200px;"
|
||
@change="handleAreaChange">
|
||
</el-cascader>
|
||
</el-form-item>
|
||
|
||
<!-- 货品仓库 -->
|
||
<el-form-item label="货品仓库" prop="warehouseId">
|
||
<el-select
|
||
v-model="queryParams.warehouseIdList"
|
||
multiple
|
||
placeholder="请选择货品仓库"
|
||
clearable
|
||
style="width: 200px"
|
||
@change="handleWarehouseChange">
|
||
<el-option
|
||
v-for="item in wareHouseOptions"
|
||
:key="item.warehouseId"
|
||
:label="item.warehouseName"
|
||
:value="item.warehouseId">
|
||
</el-option>
|
||
</el-select>
|
||
</el-form-item>
|
||
|
||
<!-- 货品名称 -->
|
||
<el-form-item label="货品名称" prop="goodsName">
|
||
<el-input
|
||
v-model="queryParams.materialName"
|
||
placeholder="请输入货品名称"
|
||
maxlength="100"
|
||
clearable
|
||
style="width: 200px"/>
|
||
</el-form-item>
|
||
<el-form-item>
|
||
<el-button type="primary" icon="el-icon-search" size="mini" @click="handleQuery">搜索</el-button>
|
||
<el-button icon="el-icon-refresh" size="mini" @click="resetQuery">重置</el-button>
|
||
</el-form-item>
|
||
</el-form>
|
||
|
||
<!-- 操作按钮栏 -->
|
||
<el-row :gutter="10" class="mb8">
|
||
<el-col :span="1.5">
|
||
<el-button
|
||
type="warning"
|
||
plain
|
||
icon="el-icon-download"
|
||
size="mini"
|
||
@click="handleExport"
|
||
>导出</el-button>
|
||
</el-col>
|
||
<el-col :span="1.5">
|
||
<el-button
|
||
type="info"
|
||
plain
|
||
icon="el-icon-printer"
|
||
size="mini"
|
||
@click="handlePrint"
|
||
>打印</el-button>
|
||
</el-col>
|
||
<right-toolbar :showSearch.sync="showSearch" @queryTable="getList"></right-toolbar>
|
||
</el-row>
|
||
|
||
<!-- 数据表格 - 使用show-summary属性 -->
|
||
<el-table
|
||
v-loading="loading"
|
||
:data="tableListData"
|
||
border
|
||
show-summary
|
||
:summary-method="getSummaries">
|
||
<el-table-column label="序号" align="center" width="60" type="index">
|
||
<template slot-scope="scope">
|
||
<span>{{(queryParams.pageNum - 1) * queryParams.pageSize + scope.$index + 1}}</span>
|
||
</template>
|
||
</el-table-column>
|
||
<el-table-column label="货品名称" align="center" prop="goodsName" width="150" :show-overflow-tooltip="true"/>
|
||
<el-table-column label="货品编码" align="center" prop="goodsCode" width="120" :show-overflow-tooltip="true"/>
|
||
<el-table-column label="货品类别" align="center" prop="goodsCategoryName" width="120" :show-overflow-tooltip="true"/>
|
||
<el-table-column label="计量单位" align="center" prop="unitName" width="100"/>
|
||
<el-table-column label="货品规格" align="center" prop="specification" width="120" :show-overflow-tooltip="true"/>
|
||
<el-table-column label="单价(元)" align="center" prop="price" width="100">
|
||
<template slot-scope="scope">
|
||
<span>{{ formatMoney((scope.row.price || 0) / 100) }}</span>
|
||
</template>
|
||
</el-table-column>
|
||
<el-table-column label="所属区域" align="center" prop="areaName" width="120" :show-overflow-tooltip="true"/>
|
||
<el-table-column label="货品仓库" align="center" prop="warehouseName" width="120" :show-overflow-tooltip="true"/>
|
||
<el-table-column label="出库类型" align="center" prop="intoType" width="120">
|
||
<template slot-scope="scope">
|
||
<span v-if="scope.row.intoType === '6'">超市出库</span>
|
||
<span v-else-if="scope.row.intoType === '1'">采购出库</span>
|
||
<span v-else-if="scope.row.intoType === '5'">即入即出</span>
|
||
<span v-else>--</span>
|
||
</template>
|
||
</el-table-column>
|
||
<el-table-column label="出库时间" align="center" prop="intoDate" width="160">
|
||
<template slot-scope="scope">
|
||
<span>{{ scope.row.intoDate ? formatDateTime(scope.row.intoDate) : '-' }}</span>
|
||
</template>
|
||
</el-table-column>
|
||
<el-table-column label="出库数量" align="center" prop="intoNum" width="100">
|
||
<template slot-scope="scope">
|
||
<span>{{ formatNumber(scope.row.intoNum) }}</span>
|
||
</template>
|
||
</el-table-column>
|
||
<el-table-column label="出库金额(元)" align="center" prop="intoAmount" width="120">
|
||
<template slot-scope="scope">
|
||
<span>{{ formatMoney((scope.row.intoAmount || 0) / 100) }}</span>
|
||
</template>
|
||
</el-table-column>
|
||
<el-table-column label="是否退单" align="center" prop="recordTypeFlag" width="120">
|
||
<template slot-scope="scope">
|
||
<span :style="scope.row.recordTypeFlag === 1 ? 'color: red' : ''">
|
||
{{ scope.row.recordTypeFlag === 1 ? '退单' : '正常' }}
|
||
</span>
|
||
</template>
|
||
</el-table-column>
|
||
<el-table-column label="结存数量" align="center" prop="balanceNum" width="100">
|
||
<template slot-scope="scope">
|
||
<span>{{ formatNumber(scope.row.balanceNum) }}</span>
|
||
</template>
|
||
</el-table-column>
|
||
<el-table-column label="结存金额(元)" align="center" prop="balanceAmount" width="120">
|
||
<template slot-scope="scope">
|
||
<span>{{ formatMoney((scope.row.balanceAmount || 0) / 100) }}</span>
|
||
</template>
|
||
</el-table-column>
|
||
<el-table-column label="领料人" align="center" prop="operatorName" width="120" :show-overflow-tooltip="true"/>
|
||
<el-table-column label="生产日期" align="center" prop="productionDate" width="120">
|
||
<template slot-scope="scope">
|
||
<span>{{ scope.row.productionDate ? formatDate(scope.row.productionDate) : '-' }}</span>
|
||
</template>
|
||
</el-table-column>
|
||
<el-table-column label="过期日期" align="center" prop="expiryDate" width="120">
|
||
<template slot-scope="scope">
|
||
<span>{{ scope.row.expiryDate ? formatDate(scope.row.expiryDate) : '-' }}</span>
|
||
</template>
|
||
</el-table-column>
|
||
<el-table-column
|
||
label="出库单号"
|
||
prop="recordId"
|
||
width="200"
|
||
align="center"
|
||
fixed="right"
|
||
class-name="blue-record-col"
|
||
:show-overflow-tooltip="true"
|
||
/>
|
||
</el-table>
|
||
|
||
<!-- 分页组件 -->
|
||
<pagination
|
||
v-show="total>0"
|
||
:total="total"
|
||
:page.sync="queryParams.pageNum"
|
||
:limit.sync="queryParams.pageSize"
|
||
@pagination="getList"
|
||
/>
|
||
</div>
|
||
</template>
|
||
|
||
<script>
|
||
// 导入区域树API
|
||
import {getTreeArea} from "@/api/canteen/canteenRecord";
|
||
// 导出库存出库相关API
|
||
import {
|
||
listInventoryIntoDetailout,
|
||
exportInventoryIntoDetail,
|
||
getWarehouseList,
|
||
getSupplierList,
|
||
getIntoTypeDict,
|
||
getGoodsCategoryDict
|
||
} from "@/api/report/inventoryInfo";
|
||
|
||
export default {
|
||
name: "InventoryIntoDetail",
|
||
dicts: [],
|
||
data() {
|
||
return {
|
||
// 合计数据
|
||
summaryData: null,
|
||
|
||
// 区域树选项
|
||
orgOptions: [],
|
||
selectedOrg: [], // 选中的区域
|
||
|
||
// 货品类别相关数据
|
||
goodsCategoryOptions: [], // 货品类别树形数据
|
||
selectedCategories: [], // 选中的货品类别路径数组
|
||
categoryProps: {
|
||
expandTrigger: 'hover',
|
||
value: 'id',
|
||
label: 'dictLabel',
|
||
children: 'children',
|
||
emitPath: true,
|
||
multiple: true
|
||
},
|
||
|
||
// 仓库下拉选项
|
||
wareHouseOptions: [],
|
||
|
||
// 供应商下拉选项
|
||
supplierOptions: [],
|
||
|
||
// 出库类型下拉选项
|
||
intoTypeOptions: [
|
||
{ dictLabel: '领取出库', dictValue: '1' },
|
||
{ dictLabel: '退货出库', dictValue: '3' },
|
||
{ dictLabel: '即入即出', dictValue: '5' },
|
||
{ dictLabel: '超市出库', dictValue: '6' }
|
||
],
|
||
|
||
// 遮罩层
|
||
loading: true,
|
||
|
||
// 显示搜索条件
|
||
showSearch: true,
|
||
|
||
// 总条数
|
||
total: 0,
|
||
|
||
// 表格数据
|
||
tableListData: [],
|
||
|
||
// 查询参数
|
||
queryParams: {
|
||
pageNum: 1,
|
||
pageSize: 10,
|
||
recordId: null, // 单据编号
|
||
intoTypeList: [], // 出库类型列表
|
||
categoryIdList: [], // 货品类别ID列表(包含所有子节点)
|
||
warehouseIdList: [], // 仓库ID列表
|
||
goodsName: null, // 货品名称
|
||
supplierIdList: [], // 供应商ID列表
|
||
areaIdList: [], // 区域ID列表
|
||
startDate: null, // 开始日期
|
||
endDate: null // 结束日期
|
||
},
|
||
|
||
// 日期范围
|
||
dateRange: this.defaultDateRange(),
|
||
|
||
// 日期选择器快捷选项
|
||
pickerOptions: {
|
||
shortcuts: [{
|
||
text: '最近一周',
|
||
onClick: (picker) => {
|
||
const end = new Date();
|
||
const start = new Date();
|
||
start.setTime(start.getTime() - 3600 * 1000 * 24 * 6);
|
||
picker.$emit('pick', [this.formatDate(start), this.formatDate(end)]);
|
||
}
|
||
}, {
|
||
text: '最近一个月',
|
||
onClick: (picker) => {
|
||
const end = new Date();
|
||
const start = new Date();
|
||
start.setTime(start.getTime() - 3600 * 1000 * 24 * 30);
|
||
picker.$emit('pick', [this.formatDate(start), this.formatDate(end)]);
|
||
}
|
||
}, {
|
||
text: '最近三个月',
|
||
onClick: (picker) => {
|
||
const end = new Date();
|
||
const start = new Date();
|
||
start.setTime(start.getTime() - 3600 * 1000 * 24 * 91);
|
||
picker.$emit('pick', [this.formatDate(start), this.formatDate(end)]);
|
||
}
|
||
}]
|
||
}
|
||
};
|
||
},
|
||
created() {
|
||
// 初始化数据
|
||
this.getTree(); // 获取区域树
|
||
this.getWareHouseData(); // 获取仓库列表
|
||
this.getSupplierData(); // 获取供应商列表
|
||
this.getGoodsCategoryData(); // 获取货品类别树
|
||
this.getList(); // 获取列表数据
|
||
},
|
||
methods: {
|
||
/**
|
||
* 自定义合计计算方法
|
||
*/
|
||
getSummaries(param) {
|
||
const { columns, data } = param;
|
||
const sums = [];
|
||
|
||
columns.forEach((column, index) => {
|
||
if (index === 0) {
|
||
// 第一列显示"合计"
|
||
sums[index] = '合计';
|
||
return;
|
||
}
|
||
|
||
// 根据列名判断需要合计的字段
|
||
const columnProp = column.property;
|
||
if (this.summaryData) {
|
||
switch(columnProp) {
|
||
case 'intoNum':
|
||
sums[index] = this.formatNumber(this.summaryData.totalInQty || 0);
|
||
break;
|
||
case 'intoAmount':
|
||
sums[index] = this.formatMoney((this.summaryData.totalInAmount || 0) / 100);
|
||
break;
|
||
/* case 'balanceNum':
|
||
sums[index] = this.formatNumber(this.summaryData.totalStockQty || 0);
|
||
break;
|
||
case 'balanceAmount':
|
||
sums[index] = this.formatMoney((this.summaryData.totalStockAmount || 0) / 100);
|
||
break; */
|
||
default:
|
||
// 其他列显示空
|
||
sums[index] = '';
|
||
break;
|
||
}
|
||
} else {
|
||
sums[index] = '';
|
||
}
|
||
});
|
||
|
||
return sums;
|
||
},
|
||
|
||
/**
|
||
* 获取货品类别树
|
||
*/
|
||
getGoodsCategoryData() {
|
||
getGoodsCategoryDict().then((response) => {
|
||
const data = response.data || response || [];
|
||
console.log('获取到的货品类别数据:', data);
|
||
|
||
// 如果后端返回的是平铺数据,需要转换为树形结构
|
||
if (data.length > 0 && !data[0].children) {
|
||
// 使用我们自己的构建树方法
|
||
this.goodsCategoryOptions = this.buildCategoryTree(data);
|
||
} else {
|
||
// 如果已经是树形结构,直接使用
|
||
this.goodsCategoryOptions = data;
|
||
}
|
||
|
||
console.log('转换后的货品类别树:', this.goodsCategoryOptions);
|
||
}).catch(error => {
|
||
console.error('获取货品类别失败:', error);
|
||
this.goodsCategoryOptions = [];
|
||
});
|
||
},
|
||
|
||
/**
|
||
* 构建货品类别树形结构
|
||
*/
|
||
buildCategoryTree(list) {
|
||
// 创建根节点(原料和商品)
|
||
const tree = [];
|
||
|
||
// 1. 原料根节点
|
||
const materialRoot = {
|
||
id: 25595457052610560,
|
||
dictLabel: "原料",
|
||
parentId: -1,
|
||
children: []
|
||
};
|
||
|
||
// 2. 商品根节点
|
||
const goodsRoot = {
|
||
id: 65595542415085568,
|
||
dictLabel: "商品",
|
||
parentId: -1,
|
||
children: []
|
||
};
|
||
|
||
// 将数据按 parent_id 分组
|
||
const map = {};
|
||
list.forEach(item => {
|
||
if (!map[item.id]) {
|
||
map[item.id] = { ...item, children: [] };
|
||
}
|
||
});
|
||
|
||
// 构建树结构
|
||
list.forEach(item => {
|
||
if (item.parentId === 25595457052610560) {
|
||
const child = { ...item, children: [] };
|
||
materialRoot.children.push(child);
|
||
map[item.id] = child;
|
||
} else if (item.parentId === 65595542415085568) {
|
||
const child = { ...item, children: [] };
|
||
goodsRoot.children.push(child);
|
||
map[item.id] = child;
|
||
} else if (item.parentId !== -1 && map[item.parentId]) {
|
||
const child = { ...item, children: [] };
|
||
if (!map[item.parentId].children) {
|
||
map[item.parentId].children = [];
|
||
}
|
||
map[item.parentId].children.push(child);
|
||
map[item.id] = child;
|
||
}
|
||
});
|
||
|
||
tree.push(materialRoot, goodsRoot);
|
||
return tree;
|
||
},
|
||
|
||
/**
|
||
* 货品类别变化时触发
|
||
*/
|
||
handleCategoryChange(values) {
|
||
if (!values || values.length === 0) {
|
||
this.queryParams.categoryIdList = [];
|
||
return;
|
||
}
|
||
let allCategoryIds = [];
|
||
values.forEach(path => {
|
||
const selectedId = path[path.length - 1];
|
||
const node = this.findCategoryNodeById(selectedId, this.goodsCategoryOptions);
|
||
if (node) {
|
||
allCategoryIds.push(...this.getAllChildCategoryIds(node));
|
||
}
|
||
});
|
||
|
||
this.queryParams.categoryIdList = Array.from(new Set(allCategoryIds));
|
||
|
||
console.log("最终传给后台的 categoryIdList =", this.queryParams.categoryIdList);
|
||
},
|
||
|
||
/**
|
||
* 查找指定ID的节点
|
||
*/
|
||
findCategoryNodeById(id, options) {
|
||
for (const node of options) {
|
||
if (node.id === id) {
|
||
return node;
|
||
}
|
||
if (node.children && node.children.length > 0) {
|
||
const found = this.findCategoryNodeById(id, node.children);
|
||
if (found) return found;
|
||
}
|
||
}
|
||
return null;
|
||
},
|
||
|
||
/**
|
||
* 获取节点及其所有子节点的ID
|
||
*/
|
||
getAllChildCategoryIds(node) {
|
||
if (!node) return [];
|
||
|
||
let ids = [node.id];
|
||
|
||
if (node.children && node.children.length > 0) {
|
||
node.children.forEach(child => {
|
||
ids = ids.concat(this.getAllChildCategoryIds(child));
|
||
});
|
||
}
|
||
|
||
return ids;
|
||
},
|
||
|
||
/**
|
||
* 获取选中的区域ID列表(包含子节点)
|
||
*/
|
||
getSelectedOrgIds() {
|
||
if (!this.selectedOrg || this.selectedOrg.length === 0) return [];
|
||
const lastValue = this.selectedOrg[this.selectedOrg.length - 1];
|
||
// 找到对应节点
|
||
let stack = [...this.orgOptions];
|
||
let node = null;
|
||
for (let val of this.selectedOrg) {
|
||
node = stack.find(item => item.orgId === val);
|
||
if (!node) break;
|
||
stack = node.children || [];
|
||
}
|
||
|
||
if (node) {
|
||
return this.getAllChildIds(node, this.orgOptions);
|
||
}
|
||
return [lastValue];
|
||
},
|
||
|
||
/**
|
||
* 递归获取节点及子节点的所有 orgId
|
||
*/
|
||
getAllChildIds(node, options) {
|
||
let ids = [node.orgId]; // 当前节点
|
||
if (node.children && node.children.length > 0) {
|
||
node.children.forEach(child => {
|
||
ids = ids.concat(this.getAllChildIds(child, options)); // 递归获取子节点
|
||
});
|
||
}
|
||
return ids;
|
||
},
|
||
|
||
/**
|
||
* 获取区域树
|
||
*/
|
||
getTree() {
|
||
getTreeArea().then(res => {
|
||
this.orgOptions = res || [];
|
||
});
|
||
},
|
||
|
||
/**
|
||
* 区域变化时触发
|
||
*/
|
||
handleAreaChange() {
|
||
// 区域变化时,重新加载仓库列表
|
||
this.queryParams.warehouseIdList = [];
|
||
this.getWareHouseData();
|
||
},
|
||
|
||
/**
|
||
* 仓库变化时触发
|
||
*/
|
||
handleWarehouseChange() {
|
||
// 可以在这里添加其他逻辑
|
||
},
|
||
|
||
/**
|
||
* 获取仓库列表
|
||
*/
|
||
getWareHouseData() {
|
||
const areaIdList = this.getSelectedOrgIds();
|
||
|
||
console.log("选中的 orgId 列表:", areaIdList, Array.isArray(areaIdList));
|
||
|
||
if (!areaIdList || !areaIdList.length) {
|
||
this.wareHouseOptions = [];
|
||
return;
|
||
}
|
||
getWarehouseList({
|
||
areaIdList: areaIdList.join(',')
|
||
}).then(res => {
|
||
this.wareHouseOptions = res.data || [];
|
||
});
|
||
},
|
||
|
||
/**
|
||
* 获取供应商列表
|
||
*/
|
||
getSupplierData() {
|
||
getSupplierList().then((response) => {
|
||
this.supplierOptions = response.data || [];
|
||
});
|
||
},
|
||
|
||
/**
|
||
* 搜索按钮操作
|
||
*/
|
||
handleQuery() {
|
||
this.queryParams.pageNum = 1;
|
||
this.getList();
|
||
},
|
||
|
||
/**
|
||
* 重置按钮操作
|
||
*/
|
||
resetQuery() {
|
||
this.dateRange = this.defaultDateRange();
|
||
this.selectedOrg = [];
|
||
this.selectedCategories = [];
|
||
this.summaryData = null;
|
||
this.queryParams = {
|
||
pageNum: 1,
|
||
pageSize: 10,
|
||
recordId: null,
|
||
intoTypeList: [],
|
||
categoryIdList: [], // 清空货品类别列表
|
||
warehouseIdList: [],
|
||
goodsName: null,
|
||
supplierIdList: [],
|
||
areaIdList: [],
|
||
startDate: null,
|
||
endDate: null
|
||
};
|
||
this.resetForm("queryForm");
|
||
this.getWareHouseData();
|
||
this.handleQuery();
|
||
},
|
||
|
||
/**
|
||
* 查询列表
|
||
*/
|
||
getList() {
|
||
this.loading = true;
|
||
|
||
// 获取选中的区域ID列表
|
||
this.queryParams.areaIdList = this.getSelectedOrgIds();
|
||
|
||
// 处理日期范围
|
||
if (this.dateRange && this.dateRange.length === 2) {
|
||
this.queryParams.startDate = this.dateRange[0];
|
||
this.queryParams.endDate = this.dateRange[1];
|
||
} else {
|
||
this.queryParams.startDate = null;
|
||
this.queryParams.endDate = null;
|
||
}
|
||
// 调用API查询
|
||
console.log('查询参数:', this.queryParams);
|
||
listInventoryIntoDetailout(this.queryParams).then(response => {
|
||
console.log('响应数据:', response);
|
||
const data = response.data || response;
|
||
this.tableListData = data.rows || [];
|
||
this.total = Number(data.total) || 0;
|
||
|
||
// 获取合计数据
|
||
this.summaryData = data.summary || null;
|
||
|
||
console.log('分页信息 - total:', this.total, 'rows:', this.tableListData.length);
|
||
console.log('合计数据:', this.summaryData);
|
||
this.loading = false;
|
||
}).catch(() => {
|
||
this.loading = false;
|
||
});
|
||
},
|
||
|
||
/**
|
||
* 导出功能
|
||
*/
|
||
handleExport() {
|
||
// 处理日期范围
|
||
let startDate = '';
|
||
let endDate = '';
|
||
|
||
if (this.dateRange && this.dateRange.length === 2) {
|
||
const start = this.dateRange[0];
|
||
const end = this.dateRange[1];
|
||
|
||
startDate = start + ' 00:00:00';
|
||
endDate = end + ' 23:59:59';
|
||
}
|
||
|
||
// 构建参数
|
||
let param = {
|
||
pageNum: this.queryParams.pageNum,
|
||
pageSize: this.queryParams.pageSize,
|
||
recordId: this.queryParams.recordId,
|
||
intoTypeList: this.queryParams.intoTypeList,
|
||
categoryIdList: this.queryParams.categoryIdList,
|
||
warehouseIdList: this.queryParams.warehouseIdList,
|
||
materialName: this.queryParams.materialName,
|
||
supplierIdList: this.queryParams.supplierIdList,
|
||
areaIdList: this.getSelectedOrgIds(),
|
||
startDate: startDate,
|
||
endDate: endDate
|
||
};
|
||
|
||
// 使用download方法(参考另一个模块)
|
||
this.$modal.confirm('是否确认导出所有库存出库明细数据项?').then(() => {
|
||
this.loading = true;
|
||
|
||
// 使用download方法
|
||
this.download(
|
||
'/smart-canteen/drp/inventoryInto/detail/outexport',
|
||
param,
|
||
`库存出库明细_${new Date().getTime()}.xlsx`
|
||
).then(() => {
|
||
this.loading = false;
|
||
this.$modal.msgSuccess("导出成功");
|
||
}).catch(error => {
|
||
this.loading = false;
|
||
console.error('导出失败:', error);
|
||
this.$modal.msgError("导出失败");
|
||
});
|
||
}).catch(() => {
|
||
// 用户取消
|
||
});
|
||
},
|
||
|
||
/**
|
||
* 打印功能
|
||
*/
|
||
handlePrint() {
|
||
// 构建打印数据
|
||
const printData = {
|
||
title: '库存出库明细表',
|
||
columns: [
|
||
{ prop: 'goodsCode', label: '货品编码', width: 120 },
|
||
{ prop: 'goodsCategoryName', label: '货品类别', width: 120 },
|
||
{ prop: 'goodsName', label: '货品名称', width: 150 },
|
||
{ prop: 'unitName', label: '计量单位', width: 100 },
|
||
{ prop: 'specification', label: '货品规格', width: 120 },
|
||
{ prop: 'price', label: '单价(元)', width: 100 },
|
||
{ prop: 'areaName', label: '所属区域', width: 120 },
|
||
{ prop: 'warehouseName', label: '货品仓库', width: 120 },
|
||
{ prop: 'intoTypeName', label: '出库类型', width: 120 },
|
||
{ prop: 'supplierName', label: '供应商', width: 150 },
|
||
{ prop: 'intoDate', label: '出库时间', width: 160 },
|
||
{ prop: 'intoNum', label: '出库数量', width: 100 },
|
||
{ prop: 'intoAmount', label: '出库金额(元)', width: 120 },
|
||
{ prop: 'recordTypeFlag', label: '关联编号', width: 100 },
|
||
{ prop: 'balanceNum', label: '结存数量', width: 100 },
|
||
{ prop: 'balanceAmount', label: '结存金额(元)', width: 120 },
|
||
{ prop: 'productionDate', label: '生产日期', width: 120 },
|
||
{ prop: 'expiryDate', label: '过期日期', width: 120 },
|
||
{ prop: 'operatorName', label: '操作人', width: 120 },
|
||
{ prop: 'recordId', label: '出库单号', width: 150 }
|
||
],
|
||
data: this.tableListData,
|
||
queryParams: this.queryParams
|
||
};
|
||
|
||
// 打开新窗口打印
|
||
const printWindow = window.open('', '_blank');
|
||
const printContent = this.generatePrintHTML(printData);
|
||
printWindow.document.write(printContent);
|
||
printWindow.document.close();
|
||
printWindow.focus();
|
||
setTimeout(() => {
|
||
printWindow.print();
|
||
printWindow.close();
|
||
}, 500);
|
||
},
|
||
|
||
/**
|
||
* 生成打印HTML
|
||
*/
|
||
generatePrintHTML(printData) {
|
||
let html = `
|
||
<!DOCTYPE html>
|
||
<html>
|
||
<head>
|
||
<meta charset="UTF-8">
|
||
<title>${printData.title}</title>
|
||
<style>
|
||
body { font-family: "Microsoft YaHei", Arial, sans-serif; margin: 20px; }
|
||
h2 { text-align: center; margin-bottom: 20px; }
|
||
table { width: 100%; border-collapse: collapse; font-size: 12px; }
|
||
th, td { border: 1px solid #000; padding: 8px; text-align: center; }
|
||
th { background-color: #f0f0f0; font-weight: bold; }
|
||
.print-info { margin-bottom: 20px; font-size: 12px; }
|
||
@media print {
|
||
@page { size: landscape; margin: 10mm; }
|
||
}
|
||
</style>
|
||
</head>
|
||
<body>
|
||
<h2>${printData.title}</h2>
|
||
<div class="print-info">
|
||
<p>打印时间:${new Date().toLocaleString()}</p>
|
||
<p>共 ${printData.data.length} 条记录</p>
|
||
</div>
|
||
<table>
|
||
<thead>
|
||
<tr>
|
||
`;
|
||
|
||
printData.columns.forEach(col => {
|
||
html += `<th>${col.label}</th>`;
|
||
});
|
||
|
||
html += `
|
||
</tr>
|
||
</thead>
|
||
<tbody>
|
||
`;
|
||
|
||
printData.data.forEach(row => {
|
||
html += '<tr>';
|
||
printData.columns.forEach(col => {
|
||
let value = row[col.prop] || '-';
|
||
if (col.prop === 'price' || col.prop === 'intoAmount' || col.prop === 'balanceAmount') {
|
||
value = this.formatMoney(value);
|
||
} else if (col.prop === 'intoNum' || col.prop === 'balanceNum') {
|
||
value = this.formatNumber(value);
|
||
} else if (col.prop === 'intoDate') {
|
||
value = value ? this.formatDateTime(value) : '-';
|
||
} else if (col.prop === 'productionDate' || col.prop === 'expiryDate') {
|
||
value = value ? this.formatDate(value) : '-';
|
||
}
|
||
html += `<td>${value}</td>`;
|
||
});
|
||
html += '</tr>';
|
||
});
|
||
|
||
html += `
|
||
</tbody>
|
||
</table>
|
||
</body>
|
||
</html>
|
||
`;
|
||
|
||
return html;
|
||
},
|
||
|
||
/**
|
||
* 默认日期范围(最近30天)
|
||
*/
|
||
defaultDateRange() {
|
||
const end = new Date();
|
||
const start = new Date();
|
||
start.setTime(start.getTime() - 30 * 24 * 60 * 60 * 1000);
|
||
return [this.formatDate(start), this.formatDate(end)];
|
||
},
|
||
|
||
/**
|
||
* 格式化日期 YYYY-MM-DD
|
||
*/
|
||
formatDate(date) {
|
||
if (!date) return '';
|
||
const d = new Date(date);
|
||
const year = d.getFullYear();
|
||
const month = String(d.getMonth() + 1).padStart(2, '0');
|
||
const day = String(d.getDate()).padStart(2, '0');
|
||
return `${year}-${month}-${day}`;
|
||
},
|
||
|
||
/**
|
||
* 格式化日期时间 YYYY-MM-DD HH:mm
|
||
*/
|
||
formatDateTime(date) {
|
||
if (!date) return '';
|
||
const d = new Date(date);
|
||
const year = d.getFullYear();
|
||
const month = String(d.getMonth() + 1).padStart(2, '0');
|
||
const day = String(d.getDate()).padStart(2, '0');
|
||
const hours = String(d.getHours()).padStart(2, '0');
|
||
const minutes = String(d.getMinutes()).padStart(2, '0');
|
||
return `${year}-${month}-${day} ${hours}:${minutes}`;
|
||
},
|
||
|
||
/**
|
||
* 格式化金额(保留两位小数)
|
||
*/
|
||
formatMoney(value) {
|
||
if (value === null || value === undefined || value === '') return '0.00';
|
||
return Number(value).toFixed(2);
|
||
},
|
||
|
||
/**
|
||
* 格式化数量
|
||
*/
|
||
formatNumber(value) {
|
||
if (value === null || value === undefined || value === '') return '0';
|
||
return Number(value);
|
||
}
|
||
}
|
||
};
|
||
</script>
|
||
|
||
<style scoped>
|
||
.app-container {
|
||
padding: 20px;
|
||
}
|
||
|
||
/* 合计行样式增强 */
|
||
::v-deep .el-table__footer-wrapper tbody td {
|
||
background-color: #f5f7fa;
|
||
font-weight: bold;
|
||
color: #303133;
|
||
}
|
||
|
||
::v-deep .el-table__footer-wrapper tbody td:first-child {
|
||
font-weight: bold;
|
||
color: #409EFF;
|
||
}
|
||
|
||
/* 表格样式 */
|
||
::v-deep .el-table__fixed-right td.blue-record-col .cell {
|
||
color: #1677ff !important;
|
||
font-weight: 600;
|
||
}
|
||
|
||
/* 调整表单样式 */
|
||
::v-deep .el-form-item {
|
||
margin-bottom: 18px;
|
||
}
|
||
|
||
/* 调整按钮样式 */
|
||
::v-deep .el-button {
|
||
margin-left: 0;
|
||
}
|
||
|
||
::v-deep .el-form-item__content {
|
||
line-height: 32px;
|
||
}
|
||
|
||
/* 调整表格样式 */
|
||
::v-deep .el-table {
|
||
margin-top: 20px;
|
||
}
|
||
|
||
::v-deep .el-table th {
|
||
background-color: #f5f7fa;
|
||
color: #303133;
|
||
}
|
||
|
||
::v-deep .el-pagination {
|
||
margin-top: 15px;
|
||
}
|
||
</style>
|