Files
shzg_projectManage/src/views/wisdom/outbound/index.vue

1575 lines
43 KiB
Vue
Raw Normal View History

2026-01-20 16:56:01 +08:00
<template>
<div class="app-container">
<el-splitter>
<el-splitter-panel size="40%">
<el-form
:model="queryParams"
ref="queryRef"
v-show="showSearch"
label-width="80"
>
<el-row>
2026-01-20 16:56:01 +08:00
<el-col :span="12">
<el-form-item label="出库时间" prop="ckTime">
<el-date-picker
v-model="ckTime"
type="datetimerange"
start-placeholder="开始时间"
end-placeholder="结束时间"
format="YYYY/MM/DD HH:mm:ss"
value-format="YYYY-MM-DD HH:mm:ss"
/>
2026-01-20 16:56:01 +08:00
</el-form-item>
</el-col>
<el-col :span="10">
<el-form-item label="单据号" prop="billNoCk">
<el-input
v-model="queryParams.billNoCk"
placeholder="请输入单据号"
clearable
@keyup.enter="handleQuery"
/>
</el-form-item>
</el-col>
</el-row>
<el-row :gutter="10" class="mb8">
<el-col :span="12">
<el-form-item label="出库类型" prop="operationType">
<el-select
v-model="queryParams.operationType"
placeholder="请选择出库类型"
clearable
>
<el-option
v-for="dict in storeTypeList"
:key="dict.id"
:label="dict.typeName"
:value="dict.typeCode"
/>
</el-select>
</el-form-item>
2026-01-20 16:56:01 +08:00
</el-col>
<el-col :span="12">
<el-form-item>
<el-button type="primary" icon="Search" @click="handleQuery"
>搜索</el-button
>
2026-01-20 16:56:01 +08:00
<el-button icon="Refresh" @click="resetQuery">重置</el-button>
</el-form-item>
</el-col>
</el-row>
<el-row :gutter="10" class="mb8">
<el-col :span="1.5">
<el-button
type="primary"
plain
icon="Plus"
@click="handleAdd"
2026-01-22 17:37:55 +08:00
v-hasPermi="['wisdom:bill:add']"
>新增出库</el-button
>
</el-col>
<el-col :span="1.5">
<el-button
type="warning"
plain
icon="Download"
@click="handleExport"
2026-01-22 17:37:55 +08:00
v-hasPermi="['wisdom:bill:export']"
>导出</el-button
>
</el-col>
</el-row>
2026-01-20 16:56:01 +08:00
</el-form>
<el-table
v-loading="loading"
:data="billList"
:row-class-name="tableBillRowClassName"
@row-dblclick="billClick"
>
<el-table-column
label="单据号"
align="center"
prop="billNo"
width="180"
/>
<el-table-column label="库存状态" align="center">
<template #default="scope">
<span>{{ getExecStatusName(scope.row.execStatus) }}</span>
</template>
</el-table-column>
<el-table-column label="操作类型" align="center">
<template #default="scope">
<dict-tag :options="dictTagData()" :value="scope.row.bizType" />
</template>
</el-table-column>
<el-table-column label="是否派送" align="center" prop="isDelivery">
<template #default="scope">
<span v-if="scope.row.isDelivery == '0' || !scope.row.isDelivery"
></span
>
<span v-else-if="scope.row.isDelivery === '1'"></span>
<span v-else-if="scope.row.isDelivery === '2'">配送中</span>
<span v-else-if="scope.row.isDelivery === '3'">配送完成</span>
</template>
</el-table-column>
<el-table-column
label="出库类型"
align="center"
prop="operationTypeName"
width="160"
/>
<el-table-column label="出库时间" align="center" width="180">
<template #default="scope">
<span>{{
parseTime(scope.row.operationTime, "{y}-{m}-{d} {h}:{i}:{s}")
}}</span>
</template>
</el-table-column>
<el-table-column label="理货员" align="center" prop="operatorName" />
<el-table-column
label="施工队"
align="center"
prop="teamName"
width="200"
/>
<el-table-column
label="操作"
align="center"
width="220"
fixed="right"
>
<template #default="scope">
<el-button
link
type="primary"
@click="picDetailFun(scope.row.billNoCk)"
>图片</el-button
>
<el-button
link
type="primary"
@click="billClick(scope.row, 'bill')"
>出库单</el-button
>
<el-button link type="primary" @click="editData(scope.row)"
>修改</el-button
>
<el-button link type="primary" @click="delData(scope.row)">删除</el-button>
</template>
</el-table-column>
2026-01-20 16:56:01 +08:00
</el-table>
2026-01-20 16:56:01 +08:00
<pagination
v-show="total > 0"
2026-01-20 16:56:01 +08:00
:total="total"
v-model:page="queryParams.pageNum"
v-model:limit="queryParams.pageSize"
@pagination="getList"
/>
</el-splitter-panel>
<el-splitter-panel :min="200">
<el-row :gutter="10" v-show="outboundList.length > 0" class="mb8">
<el-col :span="1.5">
2026-01-20 16:56:01 +08:00
<el-button
type="success"
plain
icon="Printer"
@click="handlePrint"
v-print="printViewInfo"
v-hasPermi="['wisdom:bill:print']"
>打印单据</el-button
>
</el-col>
<el-col :span="1.5">
<el-button type="primary" plain icon="Plus" @click="handleDispatch"
>生成调度任务</el-button
>
</el-col>
<el-col :span="1.5">
<el-button
type="primary"
plain
icon="Plus"
@click="handleOneClickWarehousing"
>一键出库</el-button
>
2026-01-20 16:56:01 +08:00
</el-col>
<el-col :span="1.5">
2026-01-20 16:56:01 +08:00
<el-button
type="primary"
plain
icon="Plus"
@click="handleOneClickStockDelete"
>一键撤销</el-button
>
</el-col>
<el-col :span="1.5">
<el-button
type="primary"
plain
icon="Delete"
@click="handleOneClickStockDel"
>一键删除</el-button
>
2026-01-20 16:56:01 +08:00
</el-col>
</el-row>
<el-table
v-loading="detailLoading"
show-overflow-tooltip
border
:data="outboundList"
@selection-change="selectionChange"
>
<el-table-column type="selection" width="55" align="center" />
<el-table-column
label="序号"
align="center"
type="index"
width="70"
/>
<el-table-column label="库存状态" align="center">
<template #default="scope">
<span>{{ getExecStatusName(scope.row.execStatus) }}</span>
</template>
</el-table-column>
<el-table-column
label="订单编号"
align="center"
prop="sapNo"
width="150"
/>
<el-table-column
label="项目号"
align="center"
prop="xmNo"
width="150"
/>
<el-table-column
label="项目描述"
align="center"
prop="xmMs"
width="250"
/>
<el-table-column
label="物料号"
align="center"
prop="wlNo"
width="100"
/>
<el-table-column
label="物料描述"
align="center"
prop="wlMs"
width="250"
/>
<el-table-column
label="供应商名称"
align="center"
prop="gysMc"
width="200"
/>
<el-table-column
label="合同单价"
align="center"
prop="htDj"
width="120"
/>
<el-table-column label="计量单位" align="center" prop="dw" />
<el-table-column
label="实际出库数量"
align="center"
prop="realQty"
width="120"
/>
<el-table-column
label="所属仓库"
align="center"
prop="cangkuName"
width="150"
>
<template #default="scope">
<span>{{
scope.row.parentWarehouseName + "/" + scope.row.warehouseName
}}</span>
</template>
</el-table-column>
<el-table-column
label="备注"
align="center"
prop="remark"
width="200"
/>
<el-table-column
label="库位码"
align="center"
prop="pcode"
width="120"
/>
<el-table-column label="托盘码" align="center" prop="trayCode" />
<el-table-column
label="身份码"
align="center"
prop="entityId"
width="200"
/>
<el-table-column label="物资类型" align="center" prop="wlTypeName" />
<el-table-column
label="现场图片"
align="center"
v-if="isExamine == 1"
>
<template #default="scope">
<el-image
:src="scope.row.scenePhotoUrl"
style="width: 50px; height: 50px"
:zoom-rate="1.2"
:max-scale="7"
:min-scale="0.2"
:preview-src-list="srcList"
show-progress
:initial-index="4"
:preview-teleported="true"
@click="preview(scope.row.scenePhotoUrl)"
/>
</template>
</el-table-column>
<el-table-column
label="一次封样号"
align="center"
prop="fycde1"
width="150"
/>
<el-table-column
label="二次封样号"
align="center"
prop="fycde2"
width="150"
/>
<el-table-column
label="操作"
align="center"
class-name="small-padding fixed-width"
width="150"
>
<template #default="scope">
<el-button
link
type="primary"
icon="Edit"
@click="handleUpdate(scope.row)"
v-hasPermi="['wisdom:bill:edit']"
>修改</el-button
>
<el-button
link
type="primary"
icon="Delete"
@click="handleStockDelete(scope.row)"
v-show="scope.row.execStatus == 1"
v-hasPermi="['wisdom:bill:delete']"
>撤销</el-button
>
</template>
</el-table-column>
</el-table>
2026-01-20 16:56:01 +08:00
</el-splitter-panel>
</el-splitter>
<!-- 添加或修改库存单据主对话框 -->
<el-dialog
:title="title"
v-model="open"
width="75%"
:close-on-click-modal="false"
:z-index="4"
:draggable="true"
>
<el-form ref="stockRef" :model="storeData" :rules="rules">
2026-01-20 16:56:01 +08:00
<el-row :gutter="20">
<el-col :span="6">
<el-form-item label="项目号">
<el-input
v-model="outQueryParams.xmNo"
placeholder="请输入项目号"
/>
2026-01-20 16:56:01 +08:00
</el-form-item>
</el-col>
<el-col :span="6">
<el-form-item label="订单号">
<el-input
v-model="outQueryParams.sapNo"
placeholder="请输入订单号"
/>
2026-01-20 16:56:01 +08:00
</el-form-item>
</el-col>
<el-col :span="6">
<el-form-item label="物料号">
<el-input
v-model="outQueryParams.wlNo"
placeholder="请输入物料号"
/>
2026-01-20 16:56:01 +08:00
</el-form-item>
</el-col>
<el-col :span="6">
<el-form-item label="物料描述">
<el-input
v-model="outQueryParams.wlMs"
placeholder="请输入物料描述"
/>
2026-01-20 16:56:01 +08:00
</el-form-item>
</el-col>
</el-row>
<el-row :gutter="20">
<el-col :span="6">
<el-form-item label="项目描述">
2026-01-20 16:56:01 +08:00
<el-input v-model="outQueryParams.xmMs" placeholder="项目描述" />
</el-form-item>
</el-col>
<el-col :span="6">
<el-form-item label="库位">
2026-01-20 16:56:01 +08:00
<el-input v-model="outQueryParams.pcode" placeholder="库位" />
</el-form-item>
</el-col>
<el-col :span="6">
<el-form-item label="物资类型">
<el-select
v-model="outQueryParams.wlType"
placeholder="请选择物资类型"
clearable
>
<el-option
v-for="dict in wzlxList"
:key="dict.id"
:label="dict.typeName"
:value="dict.typeCode"
/>
2026-01-20 16:56:01 +08:00
</el-select>
</el-form-item>
</el-col>
<el-col :span="6">
<el-form-item label="所属仓库">
<el-cascader
style="width: 100%"
:options="warehouseList"
v-model="outQueryParams.cangku"
:props="{
children: 'children',
label: 'warehouseName',
value: 'warehouseCode',
}"
/>
2026-01-20 16:56:01 +08:00
</el-form-item>
</el-col>
</el-row>
<el-row :gutter="20">
<el-col :span="6">
<el-form-item label="供应商">
2026-01-20 16:56:01 +08:00
<el-input v-model="outQueryParams.gysMc" placeholder="供应商" />
</el-form-item>
</el-col>
<el-col :span="6">
<el-form-item label="备注">
2026-01-20 16:56:01 +08:00
<el-input v-model="outQueryParams.remark" placeholder="备注" />
</el-form-item>
</el-col>
<el-col :span="4">
<el-button type="primary" @click="searchPlan">查询</el-button>
2026-01-20 16:56:01 +08:00
</el-col>
</el-row>
<el-row :gutter="20">
<el-col :span="6">
<el-form-item label="出库类型" prop="operationType">
<el-select
v-model="storeData.operationType"
placeholder="请选择出库类型"
clearable
>
<el-option
v-for="dict in storeTypeList"
:key="dict.id"
:label="dict.typeName"
:value="dict.typeCode"
/>
2026-01-20 16:56:01 +08:00
</el-select>
</el-form-item>
</el-col>
<el-col :span="6">
<el-form-item label="施工队" prop="teamCode">
<el-select
v-model="storeData.teamCode"
placeholder="请选择施工队"
clearable
filterable
>
<el-option
v-for="dict in wzTypeList"
:key="dict.id"
:label="dict.teamName"
:value="dict.teamCode"
/>
2026-01-20 16:56:01 +08:00
</el-select>
</el-form-item>
</el-col>
<el-col :span="6">
<el-form-item label="理货员" prop="operator">
<el-select
v-model="storeData.operator"
placeholder="请选择理货员"
clearable
>
<el-option
v-for="dict in personList"
:key="dict.userId"
:label="dict.userName"
:value="dict.userId"
/>
2026-01-20 16:56:01 +08:00
</el-select>
</el-form-item>
</el-col>
<el-col :span="6">
<el-form-item label="是否配送" prop="isDelivery">
<el-select
v-model="storeData.isDelivery"
placeholder="请选择是否配送"
clearable
>
<el-option :key="1" label="是" value="1" />
<el-option :key="0" label="否" value="0" />
2026-01-20 16:56:01 +08:00
</el-select>
</el-form-item>
</el-col>
<el-col :span="6">
<el-form-item label="库存状态" prop="execStatus">
<el-select
v-model="storeData.execStatus"
placeholder="请选择"
clearable
>
<el-option
v-for="dict in execStatusList"
:key="dict.value"
:label="dict.label"
:value="dict.value"
/>
</el-select>
2026-01-20 16:56:01 +08:00
</el-form-item>
</el-col>
2026-01-20 16:56:01 +08:00
</el-row>
<!-- <el-row :gutter="20">
2026-01-20 16:56:01 +08:00
<el-col :span="6">
<el-form-item label="项目号" >
<el-input v-model="storeData.xmNoCk" placeholder="请输入项目号" />
</el-form-item>
</el-col>
<el-col :span="18">
<el-form-item label="项目描述" >
<el-input v-model="storeData.xmMsCk" placeholder="请输入项目描述" />
</el-form-item>
</el-col>
</el-row> -->
2026-01-20 16:56:01 +08:00
</el-form>
<el-table
:data="planList"
height="400"
border
show-overflow-tooltip
style="width: 100%"
@selection-change="handleSelectionChange"
>
2026-01-20 16:56:01 +08:00
<el-table-column type="selection" width="55" align="center" />
<el-table-column label="序号" type="index" align="center" width="70" />
<el-table-column
label="物料号"
align="center"
prop="wlNo"
width="100"
/>
<el-table-column
label="订单号"
align="center"
prop="sapNo"
width="100"
/>
<el-table-column
label="物料描述"
align="center"
prop="wlMs"
width="200"
/>
<el-table-column
label="出库数量"
align="center"
prop="realQty"
width="100"
>
2026-01-20 16:56:01 +08:00
<template #default="scope">
<el-input
v-model="scope.row.realQty"
placeholder="请输入出库数量"
/>
2026-01-20 16:56:01 +08:00
</template>
</el-table-column>
<el-table-column label="单价" align="center" prop="htDj" />
<el-table-column label="单位" align="center" prop="dw" />
<el-table-column
label="库位"
align="center"
prop="pcode"
width="150"
></el-table-column>
<el-table-column
label="项目定义号"
align="center"
prop="xmNo"
width="150"
/>
<el-table-column
label="项目名称"
align="center"
prop="xmMs"
width="250"
/>
<el-table-column
label="供应商"
align="center"
prop="gysMc"
width="200"
/>
<el-table-column
label="容器码"
align="center"
prop="trayCode"
></el-table-column>
<el-table-column
label="身份码"
align="center"
prop="entityId"
width="200"
></el-table-column>
<el-table-column label="备注" align="center" width="200">
2026-01-20 16:56:01 +08:00
<template #default="scope">
<el-input
v-model="scope.row.remark"
placeholder="请输入备注"
></el-input>
2026-01-20 16:56:01 +08:00
</template>
</el-table-column>
<el-table-column
label="一次封样号"
align="center"
prop="fycde1"
width="150"
/>
<el-table-column
label="二次封样号"
align="center"
prop="fycde2"
width="150"
/>
<el-table-column
label="上传"
align="center"
width="150"
v-if="isExamine == 1"
>
<template #default="scope">
<el-upload
class="upload-demo"
:action="actionUrl"
:multiple="false"
:headers="headers"
:on-preview="handlePreview"
:on-remove="
function (response) {
return handleRemove(response, scope.row.id);
}
"
:on-success="
function (response) {
return handleAvatarSuccess(response, scope.row.id);
}
"
>
<el-button
type="primary"
size="small"
v-show="!scope.row.photoUrl"
>选择图片</el-button
2026-01-20 16:56:01 +08:00
>
</el-upload>
</template>
2026-01-20 16:56:01 +08:00
</el-table-column>
</el-table>
<!-- 审批模块 暂时注释-->
<div class="examine" v-show="isExamine == 1">
<el-row :gutter="20">
<el-col :span="8">
<el-form-item label="审批人">
<el-select
v-model="storeData.approverId"
clearable
filterable
placeholder="请选择审批人"
>
<el-option
v-for="dict in personList"
:key="dict.userId"
:label="dict.userName"
:value="dict.userId"
/>
</el-select>
</el-form-item>
</el-col>
</el-row>
</div>
2026-01-20 16:56:01 +08:00
<template #footer>
<div class="dialog-footer">
<el-button type="primary" @click="submitForm"> </el-button>
2026-01-20 16:56:01 +08:00
<el-button @click="cancel"> </el-button>
</div>
</template>
</el-dialog>
<!-- 修改主单据等字段 -->
<el-dialog title="修改" v-model="openBill" append-to-body width="40%">
<el-form
:model="billData"
:rules="rules"
ref="editRef"
label-width="100px"
>
<el-form-item label="出库类型" prop="operationType">
<el-select
v-model="billData.operationType"
placeholder="请选择出库类型"
clearable
>
<el-option
v-for="dict in storeTypeList"
:key="dict.id"
:label="dict.typeName"
:value="dict.typeCode"
/>
2026-01-20 16:56:01 +08:00
</el-select>
</el-form-item>
<el-form-item label="施工队" prop="teamCode">
<el-select
v-model="billData.teamCode"
placeholder="请选择施工队"
clearable
>
<el-option
v-for="dict in wzTypeList"
:key="dict.id"
:label="dict.teamName"
:value="dict.teamCode"
/>
2026-01-20 16:56:01 +08:00
</el-select>
</el-form-item>
<el-form-item label="理货员" prop="operator">
<el-select
v-model="billData.operator"
placeholder="请选择理货员"
clearable
>
<el-option
v-for="dict in personList"
:key="dict.userId"
:label="dict.userName"
:value="dict.userId"
/>
</el-select>
</el-form-item>
<!-- <el-form-item label="库存状态" prop="execStatus">
<el-select
v-model="billData.execStatus"
placeholder="请选择"
clearable
>
<el-option
v-for="dict in execStatusList"
:key="dict.value"
:label="dict.label"
:value="dict.value"
/>
2026-01-20 16:56:01 +08:00
</el-select>
</el-form-item> -->
2026-01-20 16:56:01 +08:00
<el-form-item label="是否配送" prop="isDelivery">
<el-select
v-model="billData.isDelivery"
placeholder="请选择是否配送"
clearable
>
<el-option :key="1" label="是" value="1" />
<el-option :key="0" label="否" value="0" />
2026-01-20 16:56:01 +08:00
</el-select>
</el-form-item>
</el-form>
<template #footer>
<div class="dialog-footer">
<el-button type="primary" @click="editForm"> </el-button>
2026-01-20 16:56:01 +08:00
</div>
</template>
</el-dialog>
<!-- 出库单 -->
<el-dialog
title="出库单"
v-model="dialogBill"
append-to-body
width="80%"
:close-on-click-modal="false"
>
<bill :billAllObj="billAllObj" billStatus="ck" />
<template #footer>
<div class="dialog-footer">
<el-button @click="dialogBill = false"> </el-button>
</div>
</template>
</el-dialog>
<!-- 打印 -->
<div id="printMe" class="printMeBox" v-show="showContent">
<printBill :billAllObj="outboundList" billStatus="ck" />
</div>
2026-01-20 16:56:01 +08:00
<!-- 图片预览 -->
<el-dialog v-model="dialogVisible">
<img w-full :src="dialogImageUrl" alt="Preview Image" />
</el-dialog>
<el-dialog title="图片详情" v-model="dialogPicDetailVisible">
<el-image
style="width: 100px; height: 100px; margin-right: 20px"
:src="url"
v-for="url in picList"
:key="url"
:preview-src-list="picList"
/>
2026-01-20 16:56:01 +08:00
</el-dialog>
<el-dialog
title="调度任务"
v-model="dispatchOpen"
width="30%"
:close-on-click-modal="false"
>
<el-form>
<el-row>
<el-col>
<el-form-item label="调度模式">
2026-01-20 16:56:01 +08:00
<el-radio-group v-model="resource">
<el-radio value="1">仅立库</el-radio>
<el-radio value="2">立库+AGV</el-radio>
</el-radio-group>
</el-form-item>
</el-col>
</el-row>
</el-form>
<template #footer>
<div class="dialog-footer">
<el-button type="primary" @click="submitDispatch"> </el-button>
2026-01-20 16:56:01 +08:00
</div>
</template>
</el-dialog>
<!-- 修改主单据入库时间等字段 -->
<el-dialog title="修改" v-model="outInfoDialog" append-to-body width="40%">
<el-form
:model="outInfoData"
:rules="outInfoRules"
ref="outInfoRef"
label-width="100px"
>
2026-01-20 16:56:01 +08:00
<el-form-item label="出库数量" prop="realQty">
<el-input
v-model="outInfoData.realQty"
placeholder="请输入出库数量"
/>
2026-01-20 16:56:01 +08:00
</el-form-item>
<el-form-item label="备注" prop="remark">
<el-input v-model="outInfoData.remark" placeholder="请输入备注" />
2026-01-20 16:56:01 +08:00
</el-form-item>
</el-form>
<template #footer>
<div class="dialog-footer">
<el-button type="primary" @click="outInfoForm"> </el-button>
2026-01-20 16:56:01 +08:00
</div>
</template>
</el-dialog>
</div>
</template>
<script setup name="Outbound">
import {
listBill,
listStock as listOutStock,
delBill,
updateBill,
updateRecord,
} from "@/api/wisdom/bill";
import { listStock } from "@/api/wisdom/stock";
import {
addOutbound,
recordFinish,
backoutRecord,
recordRemove,
picDetail,
generateDispatch,
} from "@/api/wisdom/outbound"; //列表
import { listOuttype } from "@/api/information/outtype"; //出库类型
import { listConstruction } from "@/api/information/construction"; //施工队
2026-01-20 16:56:01 +08:00
// import {warehouseDict} from "@/api/information/warehouseinfo"; //所属仓库
import { warehouseAll } from "@/api/information/warehouseinfo"; //所属仓库
import { materialtypeDict } from "@/api/information/materialtype"; //物资类型
import { personListDict } from "@/api/system/user"; //理货员
2026-01-20 16:56:01 +08:00
// import {getKwList} from "@/api/information/pcdedetail"; //库位下拉数据
// import { getAudit, ckDelStock, updateStock} from "@/api/wisdom/stock";
2026-01-20 16:56:01 +08:00
import { getToken } from "@/utils/auth";
import bill from "@/components/storageBill/bill.vue";
import printBill from "@/components/printBill/bill.vue";
2026-01-20 16:56:01 +08:00
import { ref } from "vue";
const headers = ref({
Authorization: "Bearer " + getToken(),
2026-01-20 16:56:01 +08:00
});
const { proxy } = getCurrentInstance();
const open = ref(false);
2026-01-20 16:56:01 +08:00
const dispatchOpen = ref(false);
const showSearch = ref(true);
const ids = ref([]);
const single = ref(true);
const multiple = ref(true);
2026-01-20 16:56:01 +08:00
const title = ref("");
const planLoading = ref(true);
const orderNum = ref(""); //搜索条件:订单号
2026-01-20 16:56:01 +08:00
const showContent = ref(false); // 控制打印内容是否显示
const dateStr = ref(""); //打印单据生成的日期
const printList = ref([]); //要打印的数据列表
const isExamine = ref(0); //是否需要开启审核 1开启0不开启
const actionUrl =
import.meta.env.VITE_APP_BASE_API + "/wisdom/signature/upload";
const dialogImageUrl = ref("");
const dialogVisible = ref(false);
const srcList = ref([]);
const ckTime = ref([]);
const dialogPicDetailVisible = ref(false);
const picList = ref([]);
const resource = ref(""); //调度模式 1仅立库2立库+AGV
2026-01-20 16:56:01 +08:00
const data = reactive({
form: {},
storeData: {}, //出库数据
2026-01-20 16:56:01 +08:00
rules: {
operationType: [
{ required: true, message: "出库类型不能为空", trigger: "change" },
],
teamCode: [
{ required: true, message: "施工队不能为空", trigger: "change" },
],
execStatus: [
{ required: true, message: "是否预入库不能为空", trigger: "change" },
],
operator: [
{ required: true, message: "理货员不能为空", trigger: "change" },
],
isDelivery: [
{ required: true, message: "是否需要配送", trigger: "change" },
],
2026-01-20 16:56:01 +08:00
},
printViewInfo: {
id: "printMe", //打印区域的唯一的id属性
popTitle: "入库信息打印", // 页眉文字 不设置时显示undifined页眉页脚可以在打印页面的更多设置的选项中取消勾选
beforeOpenCallback() {
2026-01-20 16:56:01 +08:00
showContent.value = false;
}, // 开始打印之前的callback
openCallback() {}, // 调用打印时的callback
closeCallback() {}, // 关闭打印的callback(无法区分确认or取消)
clickMounted() {},
2026-01-20 16:56:01 +08:00
standard: "",
extarCss: "",
},
2026-01-20 16:56:01 +08:00
});
const { storeData, rules, form, printViewInfo } = toRefs(data);
2026-01-20 16:56:01 +08:00
//物资类型下拉数据
const wzlxList = ref([]); //物资类型下拉数据
function wzTypeFun() {
materialtypeDict().then((response) => {
wzlxList.value = response.data;
2026-01-20 16:56:01 +08:00
});
}
wzTypeFun();
//所属仓库下拉数据
const warehouseList = ref([]);
function cangkuFun() {
warehouseAll().then((response) => {
warehouseList.value = response.data;
2026-01-20 16:56:01 +08:00
});
}
cangkuFun();
2026-01-20 16:56:01 +08:00
//出库类型下拉数据
const storeTypeList = ref([]);
function ckTypeFun() {
listOuttype({ pageNum: 1, pageSize: 500 }).then((response) => {
storeTypeList.value = response.rows;
});
2026-01-20 16:56:01 +08:00
}
ckTypeFun();
//施工队下拉数据
const wzTypeList = ref([]);
function listConstructionFun() {
listConstruction({ pageNum: 1, pageSize: 500 }).then((response) => {
wzTypeList.value = response.rows;
});
2026-01-20 16:56:01 +08:00
}
listConstructionFun();
//理货员下拉数据
const personList = ref([]);
function personListDictFun() {
personListDict().then((response) => {
personList.value = response.data;
});
2026-01-20 16:56:01 +08:00
}
personListDictFun();
// 是否预入库
const execStatusList = ref([
{ value: "0", label: "预出库" },
{ value: "1", label: "已出库" },
]);
const getExecStatusName = (value) => {
return execStatusList.value.find((item) => item.value === value)?.label;
};
// 左侧显示库存状态
const bizTypeList = ref([
{ value: 0, label: "已入库", elTagType: "success", elTagClass: null },
{ value: 1, label: "已出库", elTagType: "warning", elTagClass: null },
{ value: 2, label: "借料出库", elTagType: "danger", elTagClass: null },
{ value: 3, label: "还料入库", elTagType: "primary", elTagClass: null },
]);
const dictTagData = () => {
return bizTypeList.value.map((item) => ({
...item,
value: String(item.value),
}));
};
// 显示预出库的状态
const tableBillRowClassName = ({ row, rowIndex }) => {
if (row.execStatus == 0) {
return "success-row";
2026-01-20 16:56:01 +08:00
}
return "";
};
2026-01-20 16:56:01 +08:00
/** 查询单据主数据 */
const loading = ref(true);
const queryParams = ref({
pageNum: 1,
pageSize: 10,
statDate: null,
endDate: null,
operationType: "",
});
const total = ref(0);
const billList = ref([]);
2026-01-20 16:56:01 +08:00
function getList() {
loading.value = true;
queryParams.value.bizTypeList = [1, 2];
listBill(queryParams.value).then((response) => {
2026-01-20 16:56:01 +08:00
billList.value = response.rows;
total.value = response.total;
loading.value = false;
});
}
getList();
// 模糊条件
const outQueryParams = ref({
xmNo: "",
wlNo: "",
sapNo: "",
wlMs: "",
xmMs: "",
pcode: "",
wlType: "",
cangku: "",
gysMc: "",
pageNum: 1,
pageSize: 50,
remark: "",
});
//查询库存中数据 搜索
const planList = ref([]);
function searchPlan() {
if (outQueryParams.value.cangku.length > 0) {
outQueryParams.value.cangku = outQueryParams.value.cangku[1];
}
listStock(outQueryParams.value).then((response) => {
if (response.rows.length == 0) {
proxy.$modal.msgWarning("库存无数据");
planList.value = [];
} else {
planList.value = response.rows;
}
});
}
//出库 多选框选中数据
const checkOutList = ref([]);
function handleSelectionChange(selection) {
checkOutList.value = selection;
}
/** 新增按钮操作 */
function handleAdd() {
reset();
open.value = true;
title.value = "添加出库单据";
}
/** 提交按钮 */
function submitForm() {
proxy.$refs["stockRef"].validate((valid) => {
if (valid) {
if (checkOutList.value.length == 0) {
proxy.$modal.msgError("请勾选数据");
return;
}
let submitData = {
rkBill: {
teamCode: storeData.value.teamCode, //施工队
operationType: storeData.value.operationType, //出库类型
operator: storeData.value.operator, //理货员
// xmNoCk:storeData.value.xmNoCk?storeData.value.xmNoCk:"", //原本要出的项目号
// xmMsCk:storeData.value.xmMsCk?storeData.value.xmMsCk:"", //原本要出的项目描述
execStatus: storeData.value.execStatus, //是否预出库
isDelivery: storeData.value.isDelivery,
bizType: 1,
},
rkInfoList: checkOutList.value,
};
addOutbound(submitData).then((response) => {
proxy.$modal.msgSuccess("操作成功");
open.value = false;
getList();
});
}
});
}
/** 导出按钮操作 */
function handleExport() {
proxy.download(
"wisdom/stock/export",
{
...queryParams.value,
},
`stock_${new Date().getTime()}.xlsx`
);
2026-01-20 16:56:01 +08:00
}
// 取消按钮
function cancel() {
open.value = false;
reset();
}
// 表单重置
function reset() {
planList.value = [];
storeData.value = {};
orderNum.value = "";
2026-01-20 16:56:01 +08:00
proxy.resetForm("stockRef");
}
/** 搜索按钮操作 */
function handleQuery() {
if (ckTime.value && ckTime.value.length > 0) {
queryParams.value.statDate = ckTime.value[0];
queryParams.value.endDate = ckTime.value[1];
} else {
queryParams.value.statDate = "";
queryParams.value.endDate = "";
2026-01-20 16:56:01 +08:00
}
queryParams.value.pageNum = 1;
getList();
}
/** 重置按钮操作 */
function resetQuery() {
proxy.resetForm("queryRef");
ckTime.value = [];
2026-01-20 16:56:01 +08:00
handleQuery();
}
// 左侧修改
const openBill = ref(false);
const billData = ref({
operationType: "",
teamCode: "",
execStatus: "",
operator: "",
isDelivery: "",
});
const editData = (row) => {
billData.value = JSON.parse(JSON.stringify(row));
console.log(billData.value);
openBill.value = true;
};
const editRef = ref(null);
//修改主单据 确定按钮
function editForm() {
editRef.value.validate((valid) => {
if (valid) {
updateBill(billData.value).then((response) => {
proxy.$modal.msgSuccess("操作成功");
openBill.value = false;
getList();
});
}
});
2026-01-20 16:56:01 +08:00
}
// 删除单据
const delData = (row) => {
delBill([row.id]).then((response) => {
proxy.$modal.msgSuccess("删除成功");
getList();
});
2026-01-20 16:56:01 +08:00
}
// 双击主单据查询明细
const billDoubleClickObj = ref({});
const detailLoading = ref(false);
function billClick(row, type) {
if (type !== "bill") {
detailLoading.value = true;
}
billDoubleClickObj.value = row;
getDetailList(type);
}
// 查询右侧明细
const dialogBill = ref(false);
const billAllObj = ref([]); // 单据数据
const outboundList = ref([]);
const getDetailList = (type) => {
listOutStock(billDoubleClickObj.value.billNo).then((response) => {
2026-01-22 18:30:32 +08:00
if (response.data.length == 0) {
proxy.$modal.msgError("该条入库单暂无明细");
return;
}
if (type == "bill") {
billAllObj.value = response.data;
dialogBill.value = true;
return;
}
outboundList.value = response.data;
detailLoading.value = false;
});
};
2026-01-20 16:56:01 +08:00
//打印单据
function handlePrint() {
2026-01-20 16:56:01 +08:00
const date = new Date();
const year = date.getFullYear();
const month = date.getMonth() + 1; // 月份从0开始需要加1
const day = date.getDate();
const hour = date.getHours();
const minute = date.getMinutes();
const second = date.getSeconds();
dateStr.value =
year + "-" + month + "-" + day + " " + hour + ":" + minute + ":" + second;
showContent.value = true;
2026-01-20 16:56:01 +08:00
}
// 右侧多选
const checkStockList = ref([]);
function selectionChange(selection) {
checkStockList.value = selection;
2026-01-20 16:56:01 +08:00
}
// 一键出库
function handleOneClickWarehousing() {
if (checkStockList.value.length == 0) {
proxy.$modal.msgError("请勾选数据");
return;
2026-01-20 16:56:01 +08:00
}
const ids = [];
for (let i = 0; i < checkStockList.value.length; i++) {
if (checkStockList.value[i].execStatus == 0) {
ids.push(checkStockList.value[i].id);
2026-01-20 16:56:01 +08:00
}
}
if (ids.length == 0) {
proxy.$modal.msgSuccess("勾选数据出库完成");
return;
}
recordFinish({ ids: ids }).then((response) => {
if (response.code == 200) {
proxy.$modal.msgSuccess("操作成功");
getDetailList();
} else {
proxy.$modal.msgError("操作失败");
2026-01-20 16:56:01 +08:00
}
});
2026-01-20 16:56:01 +08:00
}
// 一键撤销
const handleOneClickStockDelete = (row) => {
if (checkStockList.value.length == 0) {
proxy.$modal.msgError("请勾选数据");
return;
}
const ids = [];
for (let i = 0; i < checkStockList.value.length; i++) {
if (checkStockList.value[i].execStatus == 1) {
ids.push(checkStockList.value[i].id);
}
}
if (ids.length == 0) {
proxy.$modal.msgSuccess("勾选数据撤销完成");
return;
}
backoutRecord({ ids: ids }).then((response) => {
if (response.code == 200) {
proxy.$modal.msgSuccess("操作成功");
getDetailList();
} else {
proxy.$modal.msgError("操作失败");
2026-01-20 16:56:01 +08:00
}
});
};
2026-01-20 16:56:01 +08:00
// 一键删除
const handleOneClickStockDel = () => {
if (checkStockList.value.length == 0) {
proxy.$modal.msgError("请勾选数据");
return;
}
if (checkStockList.value.some((item) => item.execStatus == 1)) {
proxy.$modal.msgError("已出库数据不能删除");
return;
}
const ids = checkStockList.value.map((item) => item.id);
recordRemove(ids).then((response) => {
if (response.code == 200) {
proxy.$modal.msgSuccess("操作成功");
getDetailList();
} else {
proxy.$modal.msgError("操作失败");
2026-01-20 16:56:01 +08:00
}
});
};
2026-01-20 16:56:01 +08:00
// 右侧修改
const outInfoDialog = ref(false);
2026-01-20 16:56:01 +08:00
const outInfoData = ref({
realQty: "",
remark: "",
});
2026-01-20 16:56:01 +08:00
const outInfoRules = ref({
realQty: [{ required: true, message: "请输入出库数量", trigger: "blur" }],
});
const outInfoRef = ref(null);
2026-01-20 16:56:01 +08:00
function handleUpdate(row) {
console.log(row);
outInfoData.value = JSON.parse(JSON.stringify(row));
outInfoDialog.value = true;
2026-01-20 16:56:01 +08:00
}
const outInfoForm = () => {
outInfoRef.value.validate((valid) => {
2026-01-20 16:56:01 +08:00
if (valid) {
updateRecord(outInfoData.value).then((response) => {
2026-01-20 16:56:01 +08:00
proxy.$modal.msgSuccess("操作成功");
outInfoDialog.value = false;
getDetailList();
2026-01-20 16:56:01 +08:00
});
}
});
};
2026-01-20 16:56:01 +08:00
// 撤销出库
2026-01-20 16:56:01 +08:00
const handleStockDelete = (row) => {
proxy.$modal
.confirm("确定撤销吗?")
.then(function () {
return backoutRecord({ ids: [row.id] });
})
.then(() => {
getDetailList();
proxy.$modal.msgSuccess("操作成功");
})
.catch(() => {});
};
function picDetailFun(billNoCk) {
picDetail({ billNo: billNoCk, photoType: 1 }).then((response) => {
if (response.data.length > 0) {
dialogPicDetailVisible.value = true;
picList.value = response.data;
} else {
proxy.$modal.msgWarning("暂无图片");
2026-01-20 16:56:01 +08:00
}
});
2026-01-20 16:56:01 +08:00
}
function preview(url) {
srcList.value = [url];
}
//预览图片
function handlePreview(uploadFile) {
// console.log(222222)
// console.log(res)
dialogImageUrl.value = uploadFile.response.url;
dialogVisible.value = true;
2026-01-20 16:56:01 +08:00
}
//删除图片
function handleRemove(res, id) {
for (let i = 0; i < planList.value.length; i++) {
if (planList.value[i].id == id) {
planList.value[i].photoUrl = "";
}
}
}
// 图片上传成功回调
function handleAvatarSuccess(res, id) {
for (let i = 0; i < planList.value.length; i++) {
if (planList.value[i].id == id) {
planList.value[i].photoUrl = res.url;
}
}
}
//点击 生成调度任务 按钮
function handleDispatch() {
if (checkStockList.value.length == 0) {
proxy.$modal.msgError("请勾选数据");
return;
}
dispatchOpen.value = true;
}
// 提交调度任务
function submitDispatch() {
if (!resource.value) {
proxy.$modal.msgWarning("请选择调度模式");
return;
}
//调用生成调度任务接口
const data = checkStockList.value.map((item) => ({
sourceName: item.pcode,
targetName: "V01-230101",
taskTypeName: "下架",
taskType: 1,
mid: item.wlNo,
num: 1,
dispatchMode: resource.value,
}));
generateDispatch(data).then((response) => {
// console.log(11111)
// console.log(response)
if (response.code == 200) {
proxy.$modal.msgSuccess("生成调度任务成功");
dispatchOpen.value = false;
} else {
proxy.$modal.msgError(response.msg);
}
});
}
</script>
<style scoped>
.printMeBox {
div {
2026-01-20 16:56:01 +08:00
line-height: 30px;
}
}
.titleBox {
2026-01-20 16:56:01 +08:00
text-align: center;
margin-bottom: 20px;
}
.topBox {
2026-01-20 16:56:01 +08:00
display: flex;
flex-wrap: wrap;
}
.topEveryBox {
2026-01-20 16:56:01 +08:00
width: 50%;
}
.tableBox {
2026-01-20 16:56:01 +08:00
margin-top: 10px;
}
.oneLineBox {
2026-01-20 16:56:01 +08:00
display: flex;
}
.everyBox {
2026-01-20 16:56:01 +08:00
width: 25%;
}
.bottomBox {
2026-01-20 16:56:01 +08:00
margin-top: 10px;
}
</style>