2026-04-13 17:04:38 +08:00
|
|
|
|
<template>
|
|
|
|
|
|
<div class="app-container">
|
2026-05-29 19:52:32 +08:00
|
|
|
|
<!-- 状态筛选 tabs:全部 / 加急 / 未完成 / 已完成 -->
|
|
|
|
|
|
<el-tabs v-model="statusFilter" @tab-click="onStatusTabChange" class="compact-tabs">
|
|
|
|
|
|
<el-tab-pane label="全部" name="all" />
|
|
|
|
|
|
<el-tab-pane name="urgent">
|
|
|
|
|
|
<span slot="label" style="color:#f56c6c;">
|
|
|
|
|
|
<i class="el-icon-warning-outline"></i> 加急 ({{ stat.urgent }})
|
|
|
|
|
|
</span>
|
|
|
|
|
|
</el-tab-pane>
|
|
|
|
|
|
<el-tab-pane :label="`未完成 (${stat.undone})`" name="undone" />
|
|
|
|
|
|
<el-tab-pane :label="`已完成 (${stat.done})`" name="done" />
|
|
|
|
|
|
</el-tabs>
|
|
|
|
|
|
|
|
|
|
|
|
<el-form :model="queryParams" ref="queryForm" size="mini" :inline="true" v-show="showSearch"
|
|
|
|
|
|
label-width="68px" class="compact-search">
|
|
|
|
|
|
<el-form-item label="关联需求" prop="requirementId">
|
|
|
|
|
|
<el-select v-model="queryParams.requirementId" placeholder="选择需求" filterable clearable style="width: 200px">
|
|
|
|
|
|
<el-option v-for="item in requirementList" :key="item.requirementId" :label="item.title"
|
|
|
|
|
|
:value="item.requirementId" />
|
|
|
|
|
|
</el-select>
|
|
|
|
|
|
</el-form-item>
|
2026-04-13 17:04:38 +08:00
|
|
|
|
<el-form-item label="操作时间" prop="signTime">
|
|
|
|
|
|
<el-date-picker v-model="searchTime" type="daterange" start-placeholder="开始日期" end-placeholder="结束日期"
|
2026-05-29 19:52:32 +08:00
|
|
|
|
:default-time="['00:00:00', '23:59:59']" />
|
2026-04-13 17:04:38 +08:00
|
|
|
|
</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>
|
2026-05-29 19:52:32 +08:00
|
|
|
|
<right-toolbar :showSearch.sync="showSearch" @queryTable="getList"></right-toolbar>
|
|
|
|
|
|
<el-button type="primary" size="mini" icon="el-icon-plus" class="add-purchase-btn"
|
|
|
|
|
|
@click="addDialogVisible = true">新建采购单</el-button>
|
|
|
|
|
|
<add-purchase-dialog :visible.sync="addDialogVisible" @saved="getList" />
|
|
|
|
|
|
|
|
|
|
|
|
<el-table v-loading="loading" :data="TaskList" @selection-change="handleSelectionChange" stripe size="small"
|
|
|
|
|
|
row-key="masterId" :expand-row-keys="expandedKeys"
|
|
|
|
|
|
:row-class-name="rowClassName" @expand-change="onRowExpand">
|
|
|
|
|
|
<el-table-column type="expand" width="36">
|
|
|
|
|
|
<template slot-scope="props">
|
|
|
|
|
|
<div style="padding: 10px 24px; background:#fafafa;">
|
|
|
|
|
|
<!-- 顶部:模式 + 批量入库 -->
|
|
|
|
|
|
<div style="display:flex; align-items:center; justify-content:space-between; margin-bottom:8px;">
|
|
|
|
|
|
<div style="display:flex; align-items:center; gap:8px;">
|
|
|
|
|
|
<span style="font-weight:600;">物料明细({{ (itemsMap[props.row.masterId] || []).length }} 项)</span>
|
|
|
|
|
|
<el-radio-group v-model="mode" size="mini" v-if="props.row.status === 0">
|
|
|
|
|
|
<el-radio-button label="single">单个操作</el-radio-button>
|
|
|
|
|
|
<el-radio-button label="batch">批量操作</el-radio-button>
|
|
|
|
|
|
</el-radio-group>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
<div v-if="mode === 'batch' && props.row.status === 0"
|
|
|
|
|
|
style="display:flex; align-items:center; gap:6px;">
|
|
|
|
|
|
<el-select v-model="batchStatus" size="mini" placeholder="批量设置状态" style="width:140px">
|
|
|
|
|
|
<el-option v-for="s in statusOptions" :key="s.value" :value="s.value" :label="s.label" />
|
|
|
|
|
|
</el-select>
|
|
|
|
|
|
<el-button size="mini" type="success" @click="submitComplete">执行入库</el-button>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
<el-table v-loading="itemsLoading[props.row.masterId]"
|
|
|
|
|
|
:data="itemsMap[props.row.masterId] || []" size="mini" stripe ref="warehouseTable">
|
|
|
|
|
|
<el-table-column v-if="mode === 'batch' && props.row.status === 0"
|
|
|
|
|
|
type="selection" width="44" align="center" />
|
|
|
|
|
|
<el-table-column label="物料名" prop="name" min-width="120" />
|
|
|
|
|
|
<el-table-column label="截止" prop="endTime" width="120" align="center">
|
|
|
|
|
|
<template slot-scope="s">
|
|
|
|
|
|
<template v-if="s.row.endTime != null && s.row.taskStatus !== 2">
|
|
|
|
|
|
<span v-if="dayDiff(s.row.endTime) > 3">{{ parseTime(s.row.endTime, '{y}-{m}-{d}') }}</span>
|
|
|
|
|
|
<el-tag v-else-if="dayDiff(s.row.endTime) > 0" type="warning" size="mini" effect="plain">剩{{ dayDiff(s.row.endTime) }}天</el-tag>
|
|
|
|
|
|
<el-tag v-else-if="dayDiff(s.row.endTime) === 0" type="danger" size="mini" effect="plain">今日</el-tag>
|
|
|
|
|
|
<el-tag v-else type="danger" size="mini" effect="plain">逾{{ Math.abs(dayDiff(s.row.endTime)) }}天</el-tag>
|
|
|
|
|
|
</template>
|
|
|
|
|
|
</template>
|
|
|
|
|
|
</el-table-column>
|
|
|
|
|
|
<el-table-column label="数量" prop="taskInventory" width="64" align="right" />
|
|
|
|
|
|
<el-table-column label="单位" prop="unit" width="56" />
|
|
|
|
|
|
<el-table-column label="单价" width="110" align="right">
|
|
|
|
|
|
<template slot-scope="s">
|
|
|
|
|
|
<el-input v-if="s.row.taskStatus !== 2 && props.row.status === 0"
|
|
|
|
|
|
v-model="s.row.price" size="mini" type="number" placeholder="¥" />
|
|
|
|
|
|
<span v-else>¥{{ Number(s.row.price || 0).toFixed(2) }}</span>
|
|
|
|
|
|
</template>
|
|
|
|
|
|
</el-table-column>
|
|
|
|
|
|
<el-table-column label="型号" prop="model" min-width="100" />
|
|
|
|
|
|
<el-table-column label="规格" prop="specifications" min-width="100" />
|
|
|
|
|
|
<el-table-column label="品牌" prop="brand" min-width="80" />
|
|
|
|
|
|
<el-table-column label="备注" prop="remark" min-width="140">
|
|
|
|
|
|
<template slot-scope="s">
|
|
|
|
|
|
<el-input v-model="s.row.remark" size="mini" placeholder="备注"
|
|
|
|
|
|
:disabled="s.row.taskStatus === 2 || props.row.status === 1"
|
|
|
|
|
|
@blur="updateRemark(s.row)" />
|
|
|
|
|
|
</template>
|
|
|
|
|
|
</el-table-column>
|
|
|
|
|
|
<el-table-column label="状态" prop="taskStatus" width="110" align="center">
|
|
|
|
|
|
<template slot-scope="s">
|
|
|
|
|
|
<el-tag v-if="s.row.taskStatus === 2" type="success" size="mini">完成</el-tag>
|
|
|
|
|
|
<el-select v-else-if="mode === 'single' && props.row.status === 0"
|
|
|
|
|
|
v-model="s.row.taskStatus" size="mini" placeholder="状态"
|
|
|
|
|
|
@change="handleUpdateTask(s.row)">
|
|
|
|
|
|
<el-option v-for="opt in filteredStatusOptions(s.row)" :key="opt.value"
|
|
|
|
|
|
:value="opt.value" :label="opt.label" />
|
|
|
|
|
|
</el-select>
|
|
|
|
|
|
<el-tag v-else size="mini">{{ statusLabel(s.row.taskStatus) }}</el-tag>
|
|
|
|
|
|
</template>
|
|
|
|
|
|
</el-table-column>
|
|
|
|
|
|
<el-table-column label="操作" align="center" width="60">
|
|
|
|
|
|
<template slot-scope="s">
|
|
|
|
|
|
<el-button v-if="s.row.taskStatus !== 2 && props.row.status === 0"
|
|
|
|
|
|
size="mini" type="text" style="color:#f56c6c"
|
|
|
|
|
|
@click="handleBatchDelete(s.row)">删除</el-button>
|
|
|
|
|
|
</template>
|
|
|
|
|
|
</el-table-column>
|
|
|
|
|
|
</el-table>
|
|
|
|
|
|
</div>
|
2026-04-13 17:04:38 +08:00
|
|
|
|
</template>
|
|
|
|
|
|
</el-table-column>
|
2026-05-29 19:52:32 +08:00
|
|
|
|
<el-table-column type="selection" width="44" align="center" />
|
|
|
|
|
|
<el-table-column label="操作时间" prop="signTime" width="100">
|
|
|
|
|
|
<template slot-scope="scope">{{ parseTime(scope.row.signTime, "{y}-{m}-{d}") }}</template>
|
2026-04-13 17:04:38 +08:00
|
|
|
|
</el-table-column>
|
2026-05-29 19:52:32 +08:00
|
|
|
|
<el-table-column label="操作人" prop="signUser" width="90" />
|
|
|
|
|
|
<el-table-column label="关联需求" min-width="220">
|
2026-04-13 17:04:38 +08:00
|
|
|
|
<template slot-scope="scope">
|
2026-05-29 19:52:32 +08:00
|
|
|
|
<el-select v-model="scope.row.requirementId" placeholder="选择需求" filterable clearable size="mini"
|
|
|
|
|
|
style="width: 100%" @change="updateMasterRemark(scope.row)">
|
|
|
|
|
|
<el-option v-for="item in requirementList" :key="item.requirementId" :label="item.title"
|
|
|
|
|
|
:value="item.requirementId" />
|
|
|
|
|
|
</el-select>
|
2026-04-13 17:04:38 +08:00
|
|
|
|
</template>
|
|
|
|
|
|
</el-table-column>
|
2026-05-29 19:52:32 +08:00
|
|
|
|
<el-table-column label="状态" prop="status" width="90" align="center">
|
2026-04-13 17:04:38 +08:00
|
|
|
|
<template slot-scope="scope">
|
2026-05-29 19:52:32 +08:00
|
|
|
|
<el-tag :type="scope.row.status === 1 ? 'success' : 'warning'" size="mini">
|
|
|
|
|
|
{{ scope.row.status === 1 ? "已完成" : "未完成" }}
|
|
|
|
|
|
</el-tag>
|
2026-04-13 17:04:38 +08:00
|
|
|
|
</template>
|
|
|
|
|
|
</el-table-column>
|
2026-05-29 19:52:32 +08:00
|
|
|
|
<el-table-column label="备注" prop="remark" min-width="200">
|
2026-04-13 17:04:38 +08:00
|
|
|
|
<template slot-scope="scope">
|
2026-05-29 19:52:32 +08:00
|
|
|
|
<el-input v-model="scope.row.remark" size="mini" placeholder="点击编辑"
|
|
|
|
|
|
@blur="updateMasterRemark(scope.row)" />
|
2026-04-13 17:04:38 +08:00
|
|
|
|
</template>
|
|
|
|
|
|
</el-table-column>
|
2026-05-29 19:52:32 +08:00
|
|
|
|
<el-table-column label="操作" align="center" width="220" class-name="small-padding fixed-width">
|
2026-04-13 17:04:38 +08:00
|
|
|
|
<template slot-scope="scope">
|
2026-05-29 19:52:32 +08:00
|
|
|
|
<el-button size="mini" type="text" v-if="scope.row.status === 0"
|
|
|
|
|
|
@click="expandRow(scope.row)">执行入库</el-button>
|
|
|
|
|
|
<el-button size="mini" type="text" v-if="scope.row.status === 0"
|
|
|
|
|
|
@click="handComplete(scope.row)">完成</el-button>
|
|
|
|
|
|
<el-button size="mini" type="text" @click="handleExport(scope.row)">导出</el-button>
|
|
|
|
|
|
<el-button size="mini" type="text" style="color:#f56c6c" @click="handleDelete(scope.row)">删除</el-button>
|
2026-04-13 17:04:38 +08:00
|
|
|
|
</template>
|
|
|
|
|
|
</el-table-column>
|
|
|
|
|
|
</el-table>
|
|
|
|
|
|
|
|
|
|
|
|
<pagination v-show="total > 0" :total="total" :page.sync="queryParams.pageNum" :limit.sync="queryParams.pageSize"
|
|
|
|
|
|
@pagination="getList" />
|
|
|
|
|
|
|
|
|
|
|
|
</div>
|
|
|
|
|
|
</template>
|
|
|
|
|
|
|
|
|
|
|
|
<script>
|
|
|
|
|
|
import { listRequirements } from "@/api/oa/requirement";
|
2026-05-29 19:52:32 +08:00
|
|
|
|
import AddPurchaseDialog from "./components/AddPurchaseDialog.vue";
|
2026-04-13 17:04:38 +08:00
|
|
|
|
import {
|
|
|
|
|
|
addOaWarehouseMaster,
|
|
|
|
|
|
delOaWarehouseMaster, listOaWarehouseMaster,
|
|
|
|
|
|
updateOaWarehouseMaster,
|
|
|
|
|
|
} from "@/api/oa/warehouse/warehouseMaster";
|
|
|
|
|
|
import {
|
|
|
|
|
|
delOaWarehouseTask,
|
|
|
|
|
|
getOaWarehouseTaskByMasterId,
|
|
|
|
|
|
updateOaWarehouseTask,
|
|
|
|
|
|
updateOaWarehouseTaskBatch,
|
|
|
|
|
|
updateOaWarehouseTaskStatus,
|
|
|
|
|
|
updateTaskRemark
|
|
|
|
|
|
} from "@/api/oa/warehouse/warehouseTask";
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
export default {
|
|
|
|
|
|
name: "OaOutWarehouse",
|
2026-05-29 19:52:32 +08:00
|
|
|
|
components: { AddPurchaseDialog },
|
2026-04-13 17:04:38 +08:00
|
|
|
|
data () {
|
|
|
|
|
|
return {
|
2026-05-29 19:52:32 +08:00
|
|
|
|
// 顶部状态筛选
|
|
|
|
|
|
statusFilter: 'all',
|
|
|
|
|
|
stat: { undone: 0, done: 0, urgent: 0 },
|
|
|
|
|
|
// 物料明细缓存(按 masterId)
|
|
|
|
|
|
itemsMap: {},
|
|
|
|
|
|
itemsLoading: {},
|
|
|
|
|
|
// 当前展开的行(单展开)
|
|
|
|
|
|
expandedKeys: [],
|
|
|
|
|
|
// 新建采购单 dialog
|
|
|
|
|
|
addDialogVisible: false,
|
2026-04-13 17:04:38 +08:00
|
|
|
|
completeDrawer: false,
|
|
|
|
|
|
mode: 'single',
|
|
|
|
|
|
batchStatus: null, // 批量入库时选择的状态
|
|
|
|
|
|
searchTime: [], // 搜索时间范围
|
|
|
|
|
|
// 细节数据
|
|
|
|
|
|
detailData: {},
|
|
|
|
|
|
// 抽屉
|
|
|
|
|
|
drawer: false,
|
|
|
|
|
|
// 选中项目名称
|
|
|
|
|
|
selectedProject: "",
|
|
|
|
|
|
// 查看详情弹窗
|
|
|
|
|
|
outDetail: {},
|
|
|
|
|
|
// 弹窗标志
|
|
|
|
|
|
detail: false,
|
|
|
|
|
|
// 绑定项目详情
|
|
|
|
|
|
projectDetail: {},
|
|
|
|
|
|
// 物料信息详情
|
|
|
|
|
|
warehouseDetail: {},
|
|
|
|
|
|
// 入库列表
|
|
|
|
|
|
TaskList: [],
|
|
|
|
|
|
// 按钮loading
|
|
|
|
|
|
buttonLoading: false,
|
|
|
|
|
|
// 遮罩层
|
|
|
|
|
|
loading: true,
|
|
|
|
|
|
// 选中数组
|
|
|
|
|
|
ids: [],
|
|
|
|
|
|
// 非单个禁用
|
|
|
|
|
|
single: true,
|
|
|
|
|
|
selectedRows: [],
|
|
|
|
|
|
// 非多个禁用
|
|
|
|
|
|
multiple: true,
|
|
|
|
|
|
// 显示搜索条件
|
|
|
|
|
|
showSearch: true,
|
|
|
|
|
|
// 总条数
|
|
|
|
|
|
total: 0,
|
|
|
|
|
|
// 弹出层标题
|
|
|
|
|
|
title: "",
|
|
|
|
|
|
// 选择对象
|
|
|
|
|
|
searchItem: {},
|
|
|
|
|
|
// 是否显示弹出层
|
|
|
|
|
|
open: false,
|
|
|
|
|
|
warehouseTaskList: [],
|
|
|
|
|
|
// 查询参数
|
|
|
|
|
|
queryParams: {
|
|
|
|
|
|
pageNum: 1,
|
|
|
|
|
|
pageSize: 50,
|
|
|
|
|
|
type: 2,
|
|
|
|
|
|
},
|
|
|
|
|
|
// 导出参数
|
|
|
|
|
|
exportParams: {
|
|
|
|
|
|
pageNum: 1,
|
|
|
|
|
|
pageSize: 10,
|
|
|
|
|
|
},
|
|
|
|
|
|
statusOptions: [
|
|
|
|
|
|
{ value: 0, label: '未采购' },
|
|
|
|
|
|
{ value: 1, label: '在途' },
|
|
|
|
|
|
{ value: 2, label: '完成' },
|
|
|
|
|
|
{ value: 3, label: '作废' }
|
|
|
|
|
|
],
|
|
|
|
|
|
// 表单参数
|
|
|
|
|
|
form: {},
|
|
|
|
|
|
currentMasterId: null,
|
|
|
|
|
|
requirementList: [],
|
|
|
|
|
|
};
|
|
|
|
|
|
},
|
|
|
|
|
|
created () {
|
|
|
|
|
|
this.getList();
|
|
|
|
|
|
this.getRequirementList();
|
|
|
|
|
|
},
|
|
|
|
|
|
methods: {
|
|
|
|
|
|
// 获取需求列表
|
|
|
|
|
|
getRequirementList () {
|
|
|
|
|
|
listRequirements({
|
|
|
|
|
|
pageNum: 1,
|
|
|
|
|
|
pageSize: 1000,
|
|
|
|
|
|
}).then((res) => {
|
|
|
|
|
|
this.requirementList = res.rows;
|
|
|
|
|
|
});
|
|
|
|
|
|
},
|
|
|
|
|
|
// 返回 endTime 与今天(不含时分秒)的差值(单位:天)
|
|
|
|
|
|
dayDiff (endTime) {
|
|
|
|
|
|
const end = new Date(endTime)
|
|
|
|
|
|
const now = new Date()
|
|
|
|
|
|
end.setHours(0, 0, 0, 0)
|
|
|
|
|
|
now.setHours(0, 0, 0, 0)
|
|
|
|
|
|
// 正数 = future days; 0 = today; 负数 = past days
|
|
|
|
|
|
return Math.floor((end - now) / (1000 * 60 * 60 * 24))
|
|
|
|
|
|
},
|
|
|
|
|
|
// 根据 price 动态过滤:如果行 price 为空,就干掉 value===2
|
|
|
|
|
|
filteredStatusOptions (row) {
|
|
|
|
|
|
if (row.price == null || row.price === '') {
|
|
|
|
|
|
return this.statusOptions.filter(opt => opt.value !== 2);
|
|
|
|
|
|
}
|
|
|
|
|
|
return this.statusOptions;
|
|
|
|
|
|
},
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/** 单个入库接口 */
|
|
|
|
|
|
handleUpdateTask (row) {
|
|
|
|
|
|
this.loading = true;
|
|
|
|
|
|
// 这里如果用户选了“完成”但 price 还是空,你也可以额外做下兜底校验
|
|
|
|
|
|
if (row.taskStatus === 2 && (row.price == null || row.price === '')) {
|
|
|
|
|
|
this.$message.error('请先填写价格,才能标记为完成');
|
|
|
|
|
|
row.taskStatus = 0; // 或者恢复到之前的状态
|
|
|
|
|
|
return;
|
|
|
|
|
|
}
|
|
|
|
|
|
updateOaWarehouseTaskStatus(row).then(response => {
|
|
|
|
|
|
getOaWarehouseTaskByMasterId(row.masterId).then((res) => {
|
|
|
|
|
|
this.currentMasterId = row.masterId;
|
|
|
|
|
|
this.warehouseTaskList = res.data;
|
|
|
|
|
|
this.loading = false;
|
|
|
|
|
|
this.$modal.msgSuccess("操作成功")
|
|
|
|
|
|
this.getList();
|
|
|
|
|
|
});
|
|
|
|
|
|
})
|
|
|
|
|
|
},
|
|
|
|
|
|
/** 状态值 → 文字 */
|
|
|
|
|
|
statusLabel (val) {
|
|
|
|
|
|
const item = this.statusOptions.find(s => s.value === val)
|
|
|
|
|
|
return item ? item.label : ''
|
|
|
|
|
|
},
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
handleRemoveTask (row) {
|
|
|
|
|
|
this.$confirm('确定删除该物料吗?', '提示', {
|
|
|
|
|
|
confirmButtonText: '确定',
|
|
|
|
|
|
cancelButtonText: '取消',
|
|
|
|
|
|
type: 'warning'
|
|
|
|
|
|
}).then(() => {
|
|
|
|
|
|
this.loading = true;
|
|
|
|
|
|
delOaWarehouseTask(row.taskId).then((res) => {
|
|
|
|
|
|
getOaWarehouseTaskByMasterId(this.currentMasterId).then((res) => {
|
|
|
|
|
|
this.warehouseTaskList = res.data;
|
|
|
|
|
|
this.$message.success('删除成功')
|
|
|
|
|
|
})
|
|
|
|
|
|
})
|
|
|
|
|
|
.finally(() => {
|
|
|
|
|
|
this.loading = false;
|
|
|
|
|
|
})
|
|
|
|
|
|
})
|
|
|
|
|
|
},
|
|
|
|
|
|
|
|
|
|
|
|
/** 批量删除 */
|
|
|
|
|
|
handleBatchDelete (row) {
|
|
|
|
|
|
let rows = this.$refs.warehouseTable.selection
|
|
|
|
|
|
|
|
|
|
|
|
if (!rows.length) {
|
|
|
|
|
|
rows = [row]
|
|
|
|
|
|
}
|
|
|
|
|
|
if (!rows.length) return this.$message.warning('请先勾选物料')
|
|
|
|
|
|
|
|
|
|
|
|
const taskIds = rows.map(row => row.taskId)
|
|
|
|
|
|
this.$confirm(`确认删除 ${rows.length} 条记录?`, '提示',
|
|
|
|
|
|
{
|
|
|
|
|
|
confirmButtonText: '确定',
|
|
|
|
|
|
cancelButtonText: '取消',
|
|
|
|
|
|
type: 'warning'
|
|
|
|
|
|
}
|
|
|
|
|
|
).then(() => {
|
|
|
|
|
|
delOaWarehouseTask(taskIds).then((res) => {
|
|
|
|
|
|
this.getList();
|
|
|
|
|
|
this.drawer = false;
|
|
|
|
|
|
this.$message.success('删除成功')
|
|
|
|
|
|
})
|
|
|
|
|
|
|
|
|
|
|
|
})
|
|
|
|
|
|
},
|
|
|
|
|
|
|
|
|
|
|
|
/** 单行删除 */
|
|
|
|
|
|
handleDeleteTask (index) {
|
|
|
|
|
|
this.warehouseTaskList.splice(index, 1)
|
|
|
|
|
|
this.$message.success('删除成功')
|
|
|
|
|
|
},
|
|
|
|
|
|
submitComplete () {
|
|
|
|
|
|
const rows = this.$refs.warehouseTable.selection || []
|
|
|
|
|
|
if (!rows.length) {
|
|
|
|
|
|
return this.$message.warning('请先勾选物料')
|
|
|
|
|
|
}
|
|
|
|
|
|
if (this.batchStatus === null) {
|
|
|
|
|
|
return this.$message.warning('请选择批量状态')
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 前端直接设值(实际项目可调用接口)
|
|
|
|
|
|
rows.forEach(r => { r.taskStatus = this.batchStatus })
|
|
|
|
|
|
|
|
|
|
|
|
// 批量入库采购单
|
|
|
|
|
|
updateOaWarehouseTaskBatch(rows).then(res => {
|
|
|
|
|
|
this.getList();
|
|
|
|
|
|
this.drawer = false;
|
|
|
|
|
|
this.$message.success(`已批量入库 ${rows.length} 条`)
|
|
|
|
|
|
|
|
|
|
|
|
})
|
|
|
|
|
|
|
|
|
|
|
|
},
|
|
|
|
|
|
/** 执行入库操作 */
|
|
|
|
|
|
handleIn (row) {
|
|
|
|
|
|
// 更新采购单情况
|
|
|
|
|
|
this.completeDrawer = true;
|
|
|
|
|
|
this.searchItem = row;
|
|
|
|
|
|
this.form = row;
|
|
|
|
|
|
this.loading = true;
|
|
|
|
|
|
this.currentMasterId = row.masterId;
|
|
|
|
|
|
getOaWarehouseTaskByMasterId(row.masterId).then((res) => {
|
|
|
|
|
|
this.currentMasterId = row.masterId;
|
|
|
|
|
|
this.warehouseTaskList = res.data;
|
|
|
|
|
|
this.loading = false;
|
|
|
|
|
|
});
|
|
|
|
|
|
},
|
|
|
|
|
|
/** 执行完成操作, 这里只是把状态改为1 */
|
|
|
|
|
|
handComplete (row) {
|
|
|
|
|
|
this.form = row;
|
|
|
|
|
|
this.form.status = 1;
|
|
|
|
|
|
updateOaWarehouseMaster(this.form).then((res) => {
|
|
|
|
|
|
this.$modal.msgSuccess("操作成功");
|
|
|
|
|
|
this.getList();
|
|
|
|
|
|
});
|
|
|
|
|
|
},
|
|
|
|
|
|
|
|
|
|
|
|
getDateStr (date) {
|
|
|
|
|
|
if (!date) {
|
|
|
|
|
|
return ''
|
|
|
|
|
|
}
|
|
|
|
|
|
return this.parseTime(date, '{y}-{m}-{d} {h}:{i}:{s}')
|
|
|
|
|
|
},
|
|
|
|
|
|
/** 查询仓库入库列表 */
|
|
|
|
|
|
getList () {
|
|
|
|
|
|
this.loading = true;
|
|
|
|
|
|
// 处理日期范围查询参数
|
|
|
|
|
|
if (this.searchTime && this.searchTime.length === 2) {
|
|
|
|
|
|
this.queryParams.startTime = this.getDateStr(this.searchTime[0]);
|
|
|
|
|
|
this.queryParams.endTime = this.getDateStr(this.searchTime[1]);
|
|
|
|
|
|
} else {
|
|
|
|
|
|
this.queryParams.startTime = '';
|
|
|
|
|
|
this.queryParams.endTime = '';
|
|
|
|
|
|
}
|
|
|
|
|
|
listOaWarehouseMaster(this.queryParams).then((res) => {
|
2026-05-29 19:52:32 +08:00
|
|
|
|
this.TaskList = res.rows || [];
|
|
|
|
|
|
this.total = res.total || 0;
|
2026-04-13 17:04:38 +08:00
|
|
|
|
this.loading = false;
|
2026-05-29 19:52:32 +08:00
|
|
|
|
// 重置已展开行的缓存
|
|
|
|
|
|
this.itemsMap = {};
|
2026-04-13 17:04:38 +08:00
|
|
|
|
});
|
2026-05-29 19:52:32 +08:00
|
|
|
|
this.refreshStat();
|
|
|
|
|
|
},
|
|
|
|
|
|
// 加急判定(备注里含「急」)
|
|
|
|
|
|
isUrgent (remark) {
|
|
|
|
|
|
return !!remark && remark.indexOf('急') !== -1
|
|
|
|
|
|
},
|
|
|
|
|
|
// 加急且未完成 → 行红底
|
|
|
|
|
|
rowClassName ({ row }) {
|
|
|
|
|
|
if (row.status !== 1 && this.isUrgent(row.remark)) return 'row-urgent'
|
|
|
|
|
|
return ''
|
|
|
|
|
|
},
|
|
|
|
|
|
// 拉总览数量(不分页快速 head 计数)
|
|
|
|
|
|
refreshStat () {
|
|
|
|
|
|
const base = { ...this.queryParams, pageNum: 1, pageSize: 1, status: undefined, remark: undefined };
|
|
|
|
|
|
Promise.all([
|
|
|
|
|
|
listOaWarehouseMaster({ ...base, status: 0 }),
|
|
|
|
|
|
listOaWarehouseMaster({ ...base, status: 1 }),
|
|
|
|
|
|
listOaWarehouseMaster({ ...base, remark: '急' })
|
|
|
|
|
|
]).then(([u, d, urg]) => {
|
|
|
|
|
|
this.stat.undone = u.total || 0
|
|
|
|
|
|
this.stat.done = d.total || 0
|
|
|
|
|
|
this.stat.urgent = urg.total || 0
|
|
|
|
|
|
})
|
|
|
|
|
|
},
|
|
|
|
|
|
// tab 切换
|
|
|
|
|
|
onStatusTabChange () {
|
|
|
|
|
|
// 重置过滤
|
|
|
|
|
|
this.queryParams.status = undefined
|
|
|
|
|
|
this.queryParams.remark = undefined
|
|
|
|
|
|
if (this.statusFilter === 'undone') {
|
|
|
|
|
|
this.queryParams.status = 0
|
|
|
|
|
|
} else if (this.statusFilter === 'done') {
|
|
|
|
|
|
this.queryParams.status = 1
|
|
|
|
|
|
} else if (this.statusFilter === 'urgent') {
|
|
|
|
|
|
this.queryParams.remark = '急'
|
|
|
|
|
|
}
|
|
|
|
|
|
this.queryParams.pageNum = 1
|
|
|
|
|
|
this.getList()
|
|
|
|
|
|
},
|
|
|
|
|
|
// 行展开:懒加载物料明细 + 同步 warehouseTaskList(兼容老方法)
|
|
|
|
|
|
onRowExpand (row, expanded) {
|
|
|
|
|
|
// 单展开:只保留当前
|
|
|
|
|
|
if (expanded && expanded.length) {
|
|
|
|
|
|
this.expandedKeys = [row.masterId]
|
|
|
|
|
|
} else {
|
|
|
|
|
|
this.expandedKeys = this.expandedKeys.filter(k => k !== row.masterId)
|
|
|
|
|
|
}
|
|
|
|
|
|
if (!expanded || !expanded.length) return
|
|
|
|
|
|
const id = row.masterId
|
|
|
|
|
|
this.currentMasterId = id
|
|
|
|
|
|
if (this.itemsMap[id]) {
|
|
|
|
|
|
this.warehouseTaskList = this.itemsMap[id]
|
|
|
|
|
|
return
|
|
|
|
|
|
}
|
|
|
|
|
|
this.$set(this.itemsLoading, id, true)
|
|
|
|
|
|
getOaWarehouseTaskByMasterId(id).then(res => {
|
|
|
|
|
|
const list = res.data || res.rows || []
|
|
|
|
|
|
this.$set(this.itemsMap, id, list)
|
|
|
|
|
|
this.warehouseTaskList = list
|
|
|
|
|
|
}).finally(() => {
|
|
|
|
|
|
this.$set(this.itemsLoading, id, false)
|
|
|
|
|
|
})
|
|
|
|
|
|
},
|
|
|
|
|
|
// 程序化展开(用于"执行入库"按钮)
|
|
|
|
|
|
expandRow (row) {
|
|
|
|
|
|
if (this.expandedKeys.includes(row.masterId)) {
|
|
|
|
|
|
this.expandedKeys = this.expandedKeys.filter(k => k !== row.masterId)
|
|
|
|
|
|
return
|
|
|
|
|
|
}
|
|
|
|
|
|
this.expandedKeys = [row.masterId]
|
|
|
|
|
|
// 触发数据加载
|
|
|
|
|
|
this.onRowExpand(row, [row.masterId])
|
2026-04-13 17:04:38 +08:00
|
|
|
|
},
|
|
|
|
|
|
// 取消按钮
|
|
|
|
|
|
cancel () {
|
|
|
|
|
|
this.open = false;
|
|
|
|
|
|
this.reset();
|
|
|
|
|
|
},
|
|
|
|
|
|
// 表单重置
|
|
|
|
|
|
reset () {
|
|
|
|
|
|
this.form = {
|
|
|
|
|
|
projectId: undefined,
|
|
|
|
|
|
warehouseList: [],
|
|
|
|
|
|
remark: ''
|
|
|
|
|
|
};
|
|
|
|
|
|
this.resetForm("form");
|
|
|
|
|
|
},
|
|
|
|
|
|
/** 搜索按钮操作 */
|
|
|
|
|
|
handleQuery () {
|
|
|
|
|
|
this.queryParams.pageNum = 1;
|
|
|
|
|
|
this.getList();
|
|
|
|
|
|
},
|
|
|
|
|
|
/** 重置按钮操作 */
|
|
|
|
|
|
resetQuery () {
|
|
|
|
|
|
this.resetForm("queryForm");
|
|
|
|
|
|
this.handleQuery();
|
|
|
|
|
|
},
|
|
|
|
|
|
// 多选框选中数据
|
|
|
|
|
|
handleSelectionChange (selection) {
|
|
|
|
|
|
this.ids = selection.map((item) => item.masterId);
|
|
|
|
|
|
this.single = selection.length !== 1;
|
|
|
|
|
|
this.multiple = !selection.length;
|
|
|
|
|
|
},
|
|
|
|
|
|
/** 新增按钮操作 */
|
|
|
|
|
|
handleAdd () {
|
|
|
|
|
|
this.reset();
|
|
|
|
|
|
this.open = true;
|
|
|
|
|
|
if (this.drawer) {
|
|
|
|
|
|
// 如果抽屉是打开的说明是从项目处进入的新增,从而加入projectId
|
|
|
|
|
|
this.projectFlag = true;
|
|
|
|
|
|
this.form.projectId = this.selectedProject.projectId;
|
|
|
|
|
|
this.form.masterId = this.searchItem.masterId;
|
|
|
|
|
|
this.form.projectName = this.searchItem.projectName;
|
|
|
|
|
|
this.form.masterNum = this.searchItem.masterNum;
|
|
|
|
|
|
}
|
|
|
|
|
|
this.title = "添加仓库入库";
|
|
|
|
|
|
this.form.remark = '';
|
|
|
|
|
|
},
|
|
|
|
|
|
/** 修改按钮操作 */
|
|
|
|
|
|
handleUpdate (row) {
|
|
|
|
|
|
this.loading = true;
|
|
|
|
|
|
this.reset();
|
|
|
|
|
|
const id = row.masterId || this.ids;
|
|
|
|
|
|
},
|
|
|
|
|
|
/** 提交按钮 */
|
|
|
|
|
|
submitForm () {
|
|
|
|
|
|
this.$refs["form"].validate((valid) => {
|
|
|
|
|
|
if (valid) {
|
|
|
|
|
|
this.buttonLoading = true;
|
|
|
|
|
|
if (this.form.masterId != null) {
|
|
|
|
|
|
updateOaWarehouseMaster(this.form)
|
|
|
|
|
|
.then((response) => {
|
|
|
|
|
|
this.$modal.msgSuccess("修改成功");
|
|
|
|
|
|
this.open = false;
|
|
|
|
|
|
this.drawer = false;
|
|
|
|
|
|
this.getList();
|
|
|
|
|
|
})
|
|
|
|
|
|
.finally(() => {
|
|
|
|
|
|
this.buttonLoading = false;
|
|
|
|
|
|
});
|
|
|
|
|
|
} else {
|
|
|
|
|
|
this.form.type = 1;
|
|
|
|
|
|
addOaWarehouseMaster(this.form)
|
|
|
|
|
|
.then((response) => {
|
|
|
|
|
|
this.$modal.msgSuccess("新增成功");
|
|
|
|
|
|
this.open = false;
|
|
|
|
|
|
// this.getList();
|
|
|
|
|
|
})
|
|
|
|
|
|
.finally(() => {
|
|
|
|
|
|
this.buttonLoading = false;
|
|
|
|
|
|
});
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
});
|
|
|
|
|
|
},
|
|
|
|
|
|
/** 删除按钮操作 */
|
|
|
|
|
|
handleDelete (row) {
|
|
|
|
|
|
const ids = row.masterId || this.ids;
|
|
|
|
|
|
this.$modal
|
|
|
|
|
|
.confirm('是否确认删除仓库入库编号为"' + ids + '"的数据项?')
|
|
|
|
|
|
.then(() => {
|
|
|
|
|
|
this.loading = true;
|
|
|
|
|
|
return delOaWarehouseMaster(ids);
|
|
|
|
|
|
})
|
|
|
|
|
|
.then(() => {
|
|
|
|
|
|
this.getList();
|
|
|
|
|
|
this.$modal.msgSuccess("删除成功");
|
|
|
|
|
|
this.open = false;
|
|
|
|
|
|
this.drawer = false;
|
|
|
|
|
|
})
|
|
|
|
|
|
.catch(() => {
|
|
|
|
|
|
})
|
|
|
|
|
|
.finally(() => {
|
|
|
|
|
|
this.loading = false;
|
|
|
|
|
|
});
|
|
|
|
|
|
},
|
|
|
|
|
|
/** 导出按钮操作 */
|
|
|
|
|
|
handleExport (row) {
|
|
|
|
|
|
this.exportParams.masterId = row.masterId;
|
|
|
|
|
|
this.download(
|
|
|
|
|
|
"oa/oaWarehouseTask/export",
|
|
|
|
|
|
{
|
|
|
|
|
|
...this.exportParams,
|
|
|
|
|
|
},
|
|
|
|
|
|
`采购单_${new Date().getTime()}.xlsx`
|
|
|
|
|
|
);
|
|
|
|
|
|
},
|
|
|
|
|
|
|
|
|
|
|
|
// 查看入库单独条目详情
|
|
|
|
|
|
showDetail (row) {
|
|
|
|
|
|
this.drawer = true;
|
|
|
|
|
|
this.searchItem = row;
|
|
|
|
|
|
this.loading = true;
|
|
|
|
|
|
getOaWarehouseTaskByMasterId(row.masterId).then((res) => {
|
|
|
|
|
|
this.currentMasterId = row.masterId;
|
|
|
|
|
|
this.warehouseTaskList = res.data;
|
|
|
|
|
|
this.loading = false;
|
|
|
|
|
|
});
|
|
|
|
|
|
},
|
|
|
|
|
|
// 修改采购单详情的备注
|
|
|
|
|
|
updateRemark (row) {
|
|
|
|
|
|
// 只提交remark字段,避免无关字段被覆盖
|
|
|
|
|
|
updateOaWarehouseTask({
|
|
|
|
|
|
taskId: row.taskId,
|
|
|
|
|
|
remark: row.remark
|
|
|
|
|
|
}).then(() => {
|
|
|
|
|
|
this.$message.success('备注已保存');
|
|
|
|
|
|
});
|
|
|
|
|
|
},
|
|
|
|
|
|
// 修改采购单据的备注
|
|
|
|
|
|
updateMasterRemark (row) {
|
|
|
|
|
|
updateTaskRemark({
|
|
|
|
|
|
masterId: row.masterId,
|
|
|
|
|
|
remark: row.remark,
|
|
|
|
|
|
masterNum: row.masterNum,
|
|
|
|
|
|
requirementId: row.requirementId ? row.requirementId : 0,
|
|
|
|
|
|
}).then(() => {
|
|
|
|
|
|
this.$message.success('已保存');
|
|
|
|
|
|
});
|
|
|
|
|
|
},
|
|
|
|
|
|
},
|
|
|
|
|
|
};
|
|
|
|
|
|
</script>
|
2026-05-29 19:52:32 +08:00
|
|
|
|
|
|
|
|
|
|
<style lang="scss" scoped>
|
|
|
|
|
|
.add-purchase-btn.el-button {
|
|
|
|
|
|
position: absolute;
|
|
|
|
|
|
top: 12px;
|
|
|
|
|
|
right: 110px; /* 让出 right-toolbar 的位置 */
|
|
|
|
|
|
z-index: 3;
|
|
|
|
|
|
height: 24px;
|
|
|
|
|
|
line-height: 22px;
|
|
|
|
|
|
padding: 0 8px !important;
|
|
|
|
|
|
font-size: 11px !important;
|
|
|
|
|
|
border-radius: 4px;
|
|
|
|
|
|
i { font-size: 11px; margin-right: 2px; }
|
|
|
|
|
|
}
|
|
|
|
|
|
</style>
|