🆕 查看和修改盘点结果

This commit is contained in:
my_ong 2024-12-09 15:56:21 +08:00
parent 6fd544fc02
commit 1a7d70bd29
8 changed files with 628 additions and 50 deletions

View File

@ -3712,6 +3712,94 @@
}
]
},
{
"description": "获取盘点结果数据",
"name": "getComparisonRes",
"method": "get",
"path": "/comparison-result/{applyId}",
"response": {
"typeArgs": [],
"typeName": "ComparisonResDTO",
"isDefsType": true,
"templateIndex": -1,
"compileTemplateKeyword": "#/definitions/",
"enum": [],
"typeProperties": []
},
"parameters": [
{
"description": "申请单ID",
"required": true,
"in": "path",
"name": "applyId",
"dataType": {
"typeArgs": [],
"typeName": "string",
"isDefsType": false,
"templateIndex": -1,
"compileTemplateKeyword": "#/definitions/",
"enum": [],
"typeProperties": []
}
}
]
},
{
"description": "处理盘点异常数据",
"name": "updateReviewResult",
"method": "put",
"path": "/handle-exceptional-data/{applyId}",
"response": {
"typeArgs": [],
"typeName": "",
"isDefsType": false,
"templateIndex": -1,
"compileTemplateKeyword": "#/definitions/",
"enum": [],
"typeProperties": []
},
"parameters": [
{
"description": "申请单ID",
"required": true,
"in": "path",
"name": "applyId",
"dataType": {
"typeArgs": [],
"typeName": "string",
"isDefsType": false,
"templateIndex": -1,
"compileTemplateKeyword": "#/definitions/",
"enum": [],
"typeProperties": []
}
},
{
"required": true,
"in": "body",
"name": "requestBody",
"dataType": {
"typeArgs": [
{
"typeArgs": [],
"typeName": "StocktakingScanExceptionalData",
"isDefsType": true,
"templateIndex": -1,
"compileTemplateKeyword": "#/definitions/",
"enum": [],
"typeProperties": []
}
],
"typeName": "Array",
"isDefsType": false,
"templateIndex": -1,
"compileTemplateKeyword": "#/definitions/",
"enum": [],
"typeProperties": []
}
}
]
},
{
"description": "提交盘点扫码数据",
"name": "saveScanData",
@ -4780,6 +4868,60 @@
}
]
},
{
"name": "ComparisonResDTO",
"templateArgs": [],
"properties": [
{
"dataType": {
"typeArgs": [
{
"typeArgs": [],
"typeName": "StockDetailInfo",
"isDefsType": true,
"templateIndex": -1,
"compileTemplateKeyword": "#/definitions/",
"enum": [],
"typeProperties": []
}
],
"typeName": "Array",
"isDefsType": false,
"templateIndex": -1,
"compileTemplateKeyword": "#/definitions/",
"enum": [],
"typeProperties": []
},
"name": "details",
"description": "库存明细",
"required": false
},
{
"dataType": {
"typeArgs": [
{
"typeArgs": [],
"typeName": "StocktakingScanExceptionalData",
"isDefsType": true,
"templateIndex": -1,
"compileTemplateKeyword": "#/definitions/",
"enum": [],
"typeProperties": []
}
],
"typeName": "Array",
"isDefsType": false,
"templateIndex": -1,
"compileTemplateKeyword": "#/definitions/",
"enum": [],
"typeProperties": []
},
"name": "exceptionalData",
"description": "差异数据",
"required": false
}
]
},
{
"description": "全局错误",
"name": "GlobalError",
@ -5312,6 +5454,97 @@
}
]
},
{
"description": "库存明细",
"name": "StockDetailInfo",
"templateArgs": [],
"properties": [
{
"dataType": {
"typeArgs": [],
"typeName": "string",
"isDefsType": false,
"templateIndex": -1,
"compileTemplateKeyword": "#/definitions/",
"enum": [],
"typeProperties": []
},
"name": "materialCode",
"description": "物料编码",
"required": false
},
{
"dataType": {
"typeArgs": [],
"typeName": "number",
"isDefsType": false,
"templateIndex": -1,
"compileTemplateKeyword": "#/definitions/",
"enum": [],
"typeProperties": []
},
"name": "materialId",
"description": "物料名称",
"required": false
},
{
"dataType": {
"typeArgs": [],
"typeName": "string",
"isDefsType": false,
"templateIndex": -1,
"compileTemplateKeyword": "#/definitions/",
"enum": [],
"typeProperties": []
},
"name": "materialName",
"description": "物料名称",
"required": false
},
{
"dataType": {
"typeArgs": [],
"typeName": "number",
"isDefsType": false,
"templateIndex": -1,
"compileTemplateKeyword": "#/definitions/",
"enum": [],
"typeProperties": []
},
"name": "stockReal",
"description": "实际库存(明细数据中统计来的)",
"required": false
},
{
"dataType": {
"typeArgs": [],
"typeName": "number",
"isDefsType": false,
"templateIndex": -1,
"compileTemplateKeyword": "#/definitions/",
"enum": [],
"typeProperties": []
},
"name": "stockTotal",
"description": "在存总数(物料表)",
"required": false
},
{
"dataType": {
"typeArgs": [],
"typeName": "number",
"isDefsType": false,
"templateIndex": -1,
"compileTemplateKeyword": "#/definitions/",
"enum": [],
"typeProperties": []
},
"name": "stockTotalScan",
"description": "扫码数量",
"required": false
}
]
},
{
"description": "扫码盘点明细表(记录历次盘点扫码的数据)",
"name": "StocktakingScanDetail",
@ -5399,6 +5632,157 @@
"required": false
}
]
},
{
"description": "扫码盘点异常数据表",
"name": "StocktakingScanExceptionalData",
"templateArgs": [],
"properties": [
{
"dataType": {
"typeArgs": [],
"typeName": "number",
"isDefsType": false,
"templateIndex": -1,
"compileTemplateKeyword": "#/definitions/",
"enum": [],
"typeProperties": []
},
"name": "applyId",
"description": "申请单id",
"required": false
},
{
"dataType": {
"typeArgs": [],
"typeName": "string",
"isDefsType": false,
"templateIndex": -1,
"compileTemplateKeyword": "#/definitions/",
"enum": [],
"typeProperties": []
},
"name": "barcode",
"description": "条码",
"required": false
},
{
"dataType": {
"typeArgs": [],
"typeName": "string",
"isDefsType": false,
"templateIndex": -1,
"compileTemplateKeyword": "#/definitions/",
"enum": [],
"typeProperties": []
},
"name": "createdTime",
"required": false
},
{
"dataType": {
"typeArgs": [],
"typeName": "",
"isDefsType": false,
"templateIndex": -1,
"compileTemplateKeyword": "#/definitions/",
"enum": [
"'INBOUND'",
"'OUTBOUND'",
"'DISCARD'"
],
"typeProperties": []
},
"name": "exceptionHandle",
"description": "异常处理",
"required": false
},
{
"dataType": {
"typeArgs": [],
"typeName": "",
"isDefsType": false,
"templateIndex": -1,
"compileTemplateKeyword": "#/definitions/",
"enum": [
"'SOCK_IN_BUT_SCAN_NOT_EXIST'",
"'SOCK_OUT_BUT_SCAN_EXIST'",
"'SOCK_NOT_EXIST_BUT_SCAN_EXIST'"
],
"typeProperties": []
},
"name": "exceptionReason",
"description": "异常类型",
"required": false
},
{
"dataType": {
"typeArgs": [],
"typeName": "number",
"isDefsType": false,
"templateIndex": -1,
"compileTemplateKeyword": "#/definitions/",
"enum": [],
"typeProperties": []
},
"name": "id",
"required": false
},
{
"dataType": {
"typeArgs": [],
"typeName": "number",
"isDefsType": false,
"templateIndex": -1,
"compileTemplateKeyword": "#/definitions/",
"enum": [],
"typeProperties": []
},
"name": "materialId",
"description": "物料ID",
"required": false
},
{
"dataType": {
"typeArgs": [],
"typeName": "string",
"isDefsType": false,
"templateIndex": -1,
"compileTemplateKeyword": "#/definitions/",
"enum": [],
"typeProperties": []
},
"name": "materialName",
"required": false
},
{
"dataType": {
"typeArgs": [],
"typeName": "string",
"isDefsType": false,
"templateIndex": -1,
"compileTemplateKeyword": "#/definitions/",
"enum": [],
"typeProperties": []
},
"name": "remark",
"description": "备注",
"required": false
},
{
"dataType": {
"typeArgs": [],
"typeName": "string",
"isDefsType": false,
"templateIndex": -1,
"compileTemplateKeyword": "#/definitions/",
"enum": [],
"typeProperties": []
},
"name": "updatedTime",
"required": false
}
]
}
]
}

View File

@ -187,6 +187,17 @@ declare namespace material {
updatedTime?: string;
}
/**
* ComparisonResDTO
*/
export interface ComparisonResDTO {
/** 库存明细 */
details?: Array<material.StockDetailInfo>;
/** 差异数据 */
exceptionalData?: Array<material.StocktakingScanExceptionalData>;
}
/**
*
*/
@ -248,6 +259,29 @@ declare namespace material {
updatedTime?: string;
}
/**
*
*/
export interface StockDetailInfo {
/** 物料编码 */
materialCode?: string;
/** 物料名称 */
materialId?: number;
/** 物料名称 */
materialName?: string;
/** 实际库存(明细数据中统计来的) */
stockReal?: number;
/** 在存总数(物料表) */
stockTotal?: number;
/** 扫码数量 */
stockTotalScan?: number;
}
/**
* ()
*/
@ -270,4 +304,42 @@ declare namespace material {
/** updatedTime */
updatedTime?: string;
}
/**
*
*/
export interface StocktakingScanExceptionalData {
/** 申请单id */
applyId?: number;
/** 条码 */
barcode?: string;
/** createdTime */
createdTime?: string;
/** 异常处理 */
exceptionHandle?: 'INBOUND' | 'OUTBOUND' | 'DISCARD';
/** 异常类型 */
exceptionReason?:
| 'SOCK_IN_BUT_SCAN_NOT_EXIST'
| 'SOCK_OUT_BUT_SCAN_EXIST'
| 'SOCK_NOT_EXIST_BUT_SCAN_EXIST';
/** id */
id?: number;
/** 物料ID */
materialId?: number;
/** materialName */
materialName?: string;
/** 备注 */
remark?: string;
/** updatedTime */
updatedTime?: string;
}
}

View File

@ -1,33 +0,0 @@
/**
* @desc
*/
import { defaultSuccess, defaultError, http } from '@/plugins/axios';
import type { AxiosResponse } from 'axios';
import type { IPage } from '@/api/api';
export interface Params {
/** 类型 */
type: number;
/** 页码 */
page?: number;
/** 页面大小 */
size?: number;
/** 搜索关键词 */
key?: string;
}
export default async function (
params: Params,
success: (data: IPage<material.ApplyForm>) => void = defaultSuccess,
fail: (error: { code: string; error?: string }) => void = defaultError,
): Promise<void> {
return http({
method: 'get',
url: `/apply`,
params,
})
.then((data: AxiosResponse<IPage<material.ApplyForm>, unknown>) => {
success(data.data);
})
.catch((error: { code: string; error?: string }) => fail(error));
}

View File

@ -0,0 +1,21 @@
/**
* @desc
*/
import { defaultSuccess, defaultError, http } from '@/plugins/axios';
import type { AxiosResponse } from 'axios';
export default async function (
/** 申请单ID */
applyId: string,
success: (data: material.ComparisonResDTO) => void = defaultSuccess,
fail: (error: { code: string; error?: string }) => void = defaultError,
): Promise<void> {
return http({
method: 'get',
url: `/comparison-result/${applyId}`,
})
.then((data: AxiosResponse<material.ComparisonResDTO, unknown>) => {
success(data.data);
})
.catch((error: { code: string; error?: string }) => fail(error));
}

View File

@ -7,6 +7,8 @@ import saveApply from './saveApply';
import detail from './detail';
import searchAuditPage from './searchAuditPage';
import auditApply from './auditApply';
import getComparisonRes from './getComparisonRes';
import updateReviewResult from './updateReviewResult';
import saveScanData from './saveScanData';
export default {
@ -15,5 +17,7 @@ export default {
detail,
searchAuditPage,
auditApply,
getComparisonRes,
updateReviewResult,
saveScanData,
};

View File

@ -0,0 +1,25 @@
/**
* @desc
*/
import { defaultSuccess, defaultError, http } from '@/plugins/axios';
import type { AxiosResponse } from 'axios';
export default async function (
/** 申请单ID */
applyId: string,
/** 请求体 */
requestBody: Array<material.StocktakingScanExceptionalData>,
success: (data: void) => void = defaultSuccess,
fail: (error: { code: string; error?: string }) => void = defaultError,
): Promise<void> {
return http({
method: 'put',
url: `/handle-exceptional-data/${applyId}`,
data: requestBody,
})
.then((data: AxiosResponse<void, unknown>) => {
success(data.data);
})
.catch((error: { code: string; error?: string }) => fail(error));
}

View File

@ -0,0 +1,78 @@
<template>
<vxe-table border stripe show-overflow ref="resulRef" max-height="500" :column-config="{ resizable: true }"
:data="tableData" :keyboard-config="{ isEsc: true }" size="medium" empty-text="盘点数据和库存数据一致,可以直接提交审核"
:edit-config="{ trigger: 'click', mode: 'cell' }">
<vxe-column type="seq" title="序号" width="60"></vxe-column>
<vxe-column field="id" title="ID" :visible="false" />
<vxe-column field="materialName" title="物料名称" />
<vxe-column field="barcode" title="物料条码" />
<vxe-column field="exceptionReason" title="异常原因">
<template #default="{ row }">
<template v-if="row.exceptionReason === 'SOCK_IN_BUT_SCAN_NOT_EXIST'"> 库房在库状态但是扫码不存在</template>
<template v-if="row.exceptionReason === 'SOCK_OUT_BUT_SCAN_EXIST'"> 库房不是在库状态但是扫码存在</template>
<template v-if="row.exceptionReason === 'SOCK_NOT_EXIST_BUT_SCAN_EXIST'"> 库房不存在该条码但是扫码存在</template>
</template>
</vxe-column>
<vxe-column field="exceptionHandle" title="异常处理(手动选择)" :edit-render="handelEditRender"></vxe-column>
<vxe-column field="remark" title="备注说明" width="25%" :edit-render="{ name: 'textarea' }"></vxe-column>
</vxe-table>
</template>
<script setup lang="ts">
import api from '@/api'
import { toRefs } from 'vue';
import type { VxeColumnPropTypes,VxeTableInstance } from 'vxe-table'
import type { VxeSelectProps } from 'vxe-pc-ui'
//
const props = defineProps(
{
applyId: {
type: Number,
required: false
}
}
)
const resulRef = ref<VxeTableInstance<material.StocktakingScanExceptionalData>>()
const getTableData = () => {
const $table = resulRef.value
if ($table) {
return $table.getTableData().fullData.map(item => ({
id: item.id,
exceptionHandle: item.exceptionHandle,
remark: item.remark
}))
}}
defineExpose({getTableData});
const { applyId } = toRefs(props)
const tableData = ref<Array<material.StocktakingScanExceptionalData>>()
const result = ref()
api.materialApi.apply.getComparisonRes(props.applyId + '', (data) => {
result.value = data
tableData.value = data.exceptionalData
})
//id
watch(applyId, () => {
api.materialApi.apply.getComparisonRes(props.applyId + '', (data) => {
result.value = data
tableData.value = data.exceptionalData
})
})
//
const handelEditRender = ref<VxeColumnPropTypes.EditRender<undefined, VxeSelectProps>>({
name: 'VxeSelect',
options: [
{ label: '入库+1', value: 'INBOUND' },
{ label: '不入库-1', value: 'OUTBOUND' },
{ label: '丢弃-1', value: 'DISCARD' },
]
})
</script>

View File

@ -36,13 +36,14 @@
</template>
<template v-if="column.dataIndex === 'operation'">
<a-button type="link" @click="showModal(record.id)" v-if="record.reviewResult === 'WAIT_SCAN'
|| record.reviewResult === 'REJECT'">
<template #icon >
|| record.reviewResult === 'REJECT'">
<template #icon>
<icon-font type="icon-edit" />
</template>
开始扫码
</a-button>
<a-button type="link" style="margin-left: 10px" v-if="record.reviewResult === 'WAIT_SUBMIT'">
<a-button type="link" style="margin-left: 10px" @click="showResultModal(record.id)"
v-if="record.reviewResult === 'WAIT_SUBMIT' || record.reviewResult === 'WAIT_SCAN'">
<template #icon>
<icon-font type="icon-plus" />
</template>
@ -61,13 +62,18 @@
</div>
</page-container>
<!-- 新增申请抽屉 -->
<!-- 新增申请抽屉 -->
<form-drawer ref="formDrawer" v-model="applyForm" :form-items="items" :config="formConfig"
:disabled-fields=disabledFields @ok="doSave" title="扫码盘点" />
<!-- 盘点作业弹窗 -->
<a-modal v-model:open="open" title="盘点作业" width="100%" wrap-class-name="full-modal" @ok="handleOk" :confirm-loading="confirmLoading">
<!-- 盘点作业弹窗 -->
<a-modal v-model:open="open" title="盘点作业" width="100%" wrap-class-name="full-modal" @ok="handleOk"
:confirm-loading="confirmLoading">
<scan-form ref="scanFormRef" :apply-id="applyIdRef" :total-value="88"></scan-form>
</a-modal>
<!-- 盘点结果弹窗 -->
<a-modal v-model:open="openResult" title="盘点异常数据:" okText= "提交审核" @ok="submitHandle" width="80%" :confirm-loading="confirmLoading">
<result-form ref="handleResultRef" :apply-id="applyIdRef"></result-form>
</a-modal>
</template>
@ -81,11 +87,13 @@ import { notification } from 'ant-design-vue'
import dayjs from 'dayjs';
import { useUserStore } from '@/stores/user'
import scanForm from '../component/scanForm.vue'
import resultForm from '../stocktaking/resultForm.vue'
const searchKey = ref('')
const userStore = useUserStore()
const scanFormRef = ref(); //
const handleResultRef = ref(); //
const confirmLoading = ref(false) // loading
//
const applyForm = ref<Partial<material.AuditApplyInfo>>({
@ -138,7 +146,6 @@ const formConfig = computed(() => {
})
//
const items = computed(() => {
return formItems(materialList.value, required, personList.value)
})
//
@ -148,7 +155,7 @@ const loadData = async (page = 1, size = 10) => {
{
page: page,
size: size,
reviewResults: [ 'WAIT_SUBMIT', 'WAIT_SCAN', 'WAIT_REVIEW', 'PASS'],
reviewResults: ['WAIT_SUBMIT', 'WAIT_SCAN', 'WAIT_REVIEW', 'PASS'],
}, (data) => {
auditPage.value = data
loading.value = false
@ -160,9 +167,8 @@ loadData()
//
const columns = [
{
title: '申请id',
title: '申请ID',
dataIndex: 'id',
visible: false,
},
{
title: '盘点类型',
@ -235,19 +241,40 @@ const showModal = (applyId: number) => {
//
const handleOk = (e: MouseEvent) => {
const handleOk = () => {
confirmLoading.value = true;
if(scanFormRef.value){
if (scanFormRef.value) {
const data = scanFormRef.value.getApplyData();
api.materialApi.apply.saveScanData(applyIdRef.value, data, () => {
open.value = false;
confirmLoading.value = false;
loadData(1)
})
api.materialApi.apply.saveScanData(applyIdRef.value, data, () => {
open.value = false;
confirmLoading.value = false;
loadData(1)
})
}
};
//
const openResult = ref<boolean>(false);
const showResultModal = (applyId: number) => {
window.console.log("点击传参" + applyId);
openResult.value = true;
applyIdRef.value = applyId;
};
//
const submitHandle = () => {
confirmLoading.value = true;
const handleData =handleResultRef.value.getTableData();
api.materialApi.apply.updateReviewResult(applyIdRef.value, handleData, () => {
openResult.value = false;
loadData(1)
});
confirmLoading.value = false;
}