增加入库单

main
HUOJIN\92525 2025-03-26 17:57:40 +08:00
parent cac5d3d2f0
commit f717e63946
7 changed files with 609 additions and 22 deletions

View File

@ -0,0 +1,48 @@
/**
* api
*
* @Author:
* @Date: 2025-03-26 15:10:02
* @Copyright
*/
import { postRequest, getRequest } from '/@/lib/axios';
export const asnApi = {
/**
* @author
*/
queryPage : (param:object) => {
return postRequest('/asn/queryPage', param);
},
/**
* @author
*/
add: (param:object) => {
return postRequest('/asn/add', param);
},
/**
* @author
*/
update: (param:object) => {
return postRequest('/asn/update', param);
},
/**
* @author
*/
delete: (asnId:number) => {
return getRequest('/asn/delete',{asnId});
},
/**
* @author
*/
batchDelete: (idList:number[]) => {
return postRequest('/asn/batchDelete', idList);
},
};

View File

@ -0,0 +1,24 @@
/*
*
*
*/
import {SmartEnum} from '/@/types/smart-enum';
export const ASN_ORDER_TYPE_ENUM: SmartEnum<string> = {
PURCHASE: {
value: 'PURCHASE',
desc: '采购入库',
},
RETURN: {
value: 'RETURN',
desc: '退货入库',
},
OTHER: {
value: 'OTHER',
desc: '其他入库',
},
};
export default {
ASN_ORDER_TYPE_ENUM,
};

View File

@ -10,9 +10,9 @@
import menu from './system/menu-const';
import goods from './business/erp/goods-const';
import category from './business/erp/category-const';
import { LOGIN_DEVICE_ENUM } from './system/login-device-const';
import { FLAG_NUMBER_ENUM, GENDER_ENUM, USER_TYPE_ENUM } from './common-const';
import { LAYOUT_ENUM } from './layout-const';
import {LOGIN_DEVICE_ENUM} from './system/login-device-const';
import {FLAG_NUMBER_ENUM, GENDER_ENUM, USER_TYPE_ENUM} from './common-const';
import {LAYOUT_ENUM} from './layout-const';
import file from './support/file-const';
import notice from './business/oa/notice-const';
import loginLog from './support/login-log-const';
@ -21,24 +21,26 @@ import message from './business/message/message-const';
import codeGeneratorConst from './support/code-generator-const';
import changeLogConst from './support/change-log-const';
import jobConst from './support/job-const';
import USAGE_STATUS_ENUM from './business/base/usagestatus-const'
import USAGE_STATUS_ENUM from './business/base/usagestatus-const'
import ASN_ORDER_TYPE_ENUM from '/@/api/business/receive/asn/asn-const'
export default {
FLAG_NUMBER_ENUM,
LOGIN_DEVICE_ENUM,
GENDER_ENUM,
USER_TYPE_ENUM,
LAYOUT_ENUM,
...loginLog,
...menu,
...goods,
...category,
...file,
...notice,
...enterprise,
...message,
...codeGeneratorConst,
...changeLogConst,
...jobConst,
...USAGE_STATUS_ENUM
FLAG_NUMBER_ENUM,
LOGIN_DEVICE_ENUM,
GENDER_ENUM,
USER_TYPE_ENUM,
LAYOUT_ENUM,
...loginLog,
...menu,
...goods,
...category,
...file,
...notice,
...enterprise,
...message,
...codeGeneratorConst,
...changeLogConst,
...jobConst,
...USAGE_STATUS_ENUM,
...ASN_ORDER_TYPE_ENUM
};

View File

@ -19,6 +19,8 @@ let businessERPInitTableId = 40000;
let businessBASEInitTableId = 50000;
let businessRECEIVEInitTableId = 60000;
export const TABLE_ID_CONST = {
/**
*
@ -41,6 +43,9 @@ export const TABLE_ID_CONST = {
STOCK:businessBASEInitTableId+4,//容器
ADDRESS:businessBASEInitTableId+5,//地址
CUSTOMER:businessBASEInitTableId+6,//客户
},
RECEIVE:{
ASN:businessRECEIVEInitTableId+1,//入库单
}
},

View File

@ -26,7 +26,7 @@
<a-input style="width: 100%" v-model:value="form.telephone" placeholder="电话" />
</a-form-item>
<a-form-item label="地址" name="address">
<textarea v-model="form.address" style="width: 100%; height: 100px; outline: none"></textarea>
<a-textarea v-model="form.address" style="width: 100%; height: 100px; outline: none" />
</a-form-item>
</a-form>

View File

@ -0,0 +1,201 @@
<!--
* 入库单 详情
*
-->
<template>
<div class="detail-header">
<a-page-header :title="'添加入库单'" :avatar="{ src: logo }">
<template #extra>
<a-button @click="onSubmit" type="primary">
<template #icon>
<EditOutlined/>
</template>
保存
</a-button>
<a-button @click="onSubmit" type="primary" danger>
<template #icon>
<ArrowLeftOutlined />
</template>
返回
</a-button>
</template>
<div>
<a-form ref="formRef" :model="form" :rules="rules">
<a-row :gutter="24">
<a-col :span="8">
<a-form-item label="客户" name="customerId">
<CustomerSelect style="width: 100%" v-model:value="form.customerId" :disabled-flag="true" @change="changeCustomerSelect"/>
</a-form-item>
</a-col>
<a-col :span="8">
<a-form-item label="客户订单号" name="customerNumber">
<a-input style="width: 100%" v-model:value="form.customerNumber" placeholder="客户订单号"/>
</a-form-item>
</a-col>
<a-col :span="8">
<a-form-item label="单据类型" name="orderType">
<SmartEnumSelect style="width: 100%" enum-name="ASN_ORDER_TYPE_ENUM" v-model:value="form.orderType"/>
</a-form-item>
</a-col>
</a-row>
<a-row :gutter="24">
<a-col :span="8">
<a-form-item label="单位" name="addressId">
<AddressSelect style="width: 100%" v-model:value="form.addressId" :disabled-flag="true" @change="changeAddressSelect"/>
</a-form-item>
</a-col>
<a-col :span="4">
<a-form-item label="联系人" name="person">
<a-input style="width: 100%" v-model:value="form.person" placeholder="联系人"/>
</a-form-item>
</a-col>
<a-col :span="4">
<a-form-item label="电话" name="telephone">
<a-input style="width: 100%" v-model:value="form.telephone" placeholder="电话"/>
</a-form-item>
</a-col>
<a-col :span="8">
<a-form-item label="订单日期" name="orderDate">
<a-date-picker style="width: 100%" format="YYYY-MM-DD" v-model:value="form.orderDate" />
</a-form-item>
</a-col>
</a-row>
<a-row >
<a-col :span="24">
<a-form-item label="地址" name="address">
<a-textarea v-model:value="form.address" style="width: 100%; height: 100px; outline: none;" auto-size />
</a-form-item>
</a-col>
</a-row>
</a-form>
</div>
</a-page-header>
</div>
<a-card class="smart-margin-top10" size="small">
<a-tabs>
<a-tab-pane key="employee" tab="员工信息">
<EmployeeList :enterpriseId="enterpriseId" />
</a-tab-pane>
<a-tab-pane key="bank" tab="银行信息">
<BankList :enterpriseId="enterpriseId" />
</a-tab-pane>
<a-tab-pane key="invoice" tab="发票信息">
<InvoiceList :enterpriseId="enterpriseId" />
</a-tab-pane>
<a-tab-pane key="dataTracer" tab="变更记录">
<DataTracer :dataId="enterpriseId" :type="DATA_TRACER_TYPE_ENUM.OA_ENTERPRISE.value" />
</a-tab-pane>
</a-tabs>
</a-card>
</template>
<script setup lang="ts">
import _ from 'lodash';
import {computed, onMounted, reactive, ref} from 'vue';
import { useRoute } from 'vue-router';
import { enterpriseApi } from '/@/api/business/oa/enterprise-api';
import { SmartLoading } from '/@/components/framework/smart-loading';
import DataTracer from '/@/components/support/data-tracer/index.vue';
import { DATA_TRACER_TYPE_ENUM } from '/@/constants/support/data-tracer-const';
import { smartSentry } from '/@/lib/smart-sentry';
import CustomerSelect from "/@/views/business/base/customer/customer-select.vue";
import SmartEnumSelect from "/@/components/framework/smart-enum-select/index.vue";
import AddressSelect from "/@/views/business/base/address/address-select.vue";
import dayjs from 'dayjs';
import {message} from "ant-design-vue";
//
const formRef = ref();
const formDefault = {
customerId: undefined, //
customerNumber: undefined, //
orderType: undefined,//
orderDate: dayjs(),//
addressId: undefined,//
person: undefined,//
telephone: undefined,//
address: undefined,//
};
let form = reactive({...formDefault});
//
const rules = {
customerId: [{ required: true, message: '客户 必填' }],
customerNumber: [{ required: true, message: '客户订单号 必填' }],
orderType: [{ required: true, message: '单据类型 必填' }],
orderDate: [{ required: true, message: '订单日期 必填' }],
addressId: [{ required: true, message: '收货单位 必填' }],
};
//
function changeAddressSelect(selectValue: any) {
if (selectValue) {
form.addressId = selectValue.addressId;
form.address = selectValue.address;
form.person = selectValue.person;
form.telephone = selectValue.telephone;
}
}
const route = useRoute();
let enterpriseId = ref();
onMounted(() => {
if (route.query.enterpriseId) {
enterpriseId.value = Number(route.query.enterpriseId);
getDetail();
}
});
//
//
async function onSubmit() {
try {
await formRef.value.validateFields();
} catch (err) {
message.error('参数验证错误,请仔细填写表单数据!');
}
}
//
let detail = ref({});
async function getDetail() {
try {
let result = await enterpriseApi.detail(enterpriseId.value);
detail.value = result.data;
} catch (error) {
smartSentry.captureError(error);
} finally {
SmartLoading.hide();
}
}
const logo = computed(() => {
if (!detail.value) {
return '';
}
if (!_.isEmpty(detail.value.enterpriseLogo)) {
return detail.value.enterpriseLogo[0].fileUrl;
}
return '';
});
</script>
<style lang="less" scoped>
.detail-header {
background-color: #fff;
padding: 10px;
}
</style>

View File

@ -0,0 +1,307 @@
<!--
* 入库单
*
* @Author: 霍锦
* @Date: 2025-03-26 15:10:02
* @Copyright 友仓
-->
<template>
<!---------- 查询表单form begin ----------->
<a-form class="smart-query-form">
<a-row class="smart-query-form-row">
<a-form-item label="客户订单号" class="smart-query-form-item">
<a-input style="width: 200px" v-model:value="queryForm.customerNumber" placeholder="客户订单号"/>
</a-form-item>
<a-form-item class="smart-query-form-item">
<a-button type="primary" @click="onSearch" class="smart-margin-left10">
<template #icon>
<SearchOutlined/>
</template>
查询
</a-button>
<a-button @click="resetQuery" class="smart-margin-left10">
<template #icon>
<ReloadOutlined/>
</template>
重置
</a-button>
</a-form-item>
</a-row>
</a-form>
<!---------- 查询表单form end ----------->
<a-card size="small" :bordered="false" :hoverable="true">
<!---------- 表格操作行 begin ----------->
<a-row class="smart-table-btn-block">
<div class="smart-table-operate-block">
<a-button @click="showForm" type="primary" v-privilege="'asn:add'">
<template #icon>
<PlusOutlined/>
</template>
新建
</a-button>
<a-button @click="confirmBatchDelete" type="primary" danger v-privilege="'asn:batchDelete'"
:disabled="selectedRowKeyList.length == 0">
<template #icon>
<DeleteOutlined/>
</template>
批量删除
</a-button>
</div>
<div class="smart-table-setting-block">
<TableOperator v-model="columns" :tableId="TABLE_ID_CONST.BUSINESS.RECEIVE.ASN" :refresh="queryData"/>
</div>
</a-row>
<!---------- 表格操作行 end ----------->
<!---------- 表格 begin ----------->
<a-table
size="small"
:dataSource="tableData"
:columns="columns"
rowKey="asnId"
bordered
:loading="tableLoading"
:pagination="false"
:row-selection="{ selectedRowKeys: selectedRowKeyList, onChange: onSelectChange }"
>
<template #bodyCell="{ text, record, column }">
<template v-if="column.dataIndex === 'action'">
<div class="smart-table-operate">
<a-button @click="showForm(record)" type="link" v-privilege="'asn:update'">
<template #icon>
<EditOutlined/>
</template>
编辑
</a-button>
<a-button @click="onDelete(record)" danger type="link" v-privilege="'asn:delete'">
<template #icon>
<DeleteOutlined/>
</template>
删除
</a-button>
</div>
</template>
</template>
</a-table>
<!---------- 表格 end ----------->
<div class="smart-query-table-page">
<a-pagination
showSizeChanger
showQuickJumper
show-less-items
:pageSizeOptions="PAGE_SIZE_OPTIONS"
:defaultPageSize="queryForm.pageSize"
v-model:current="queryForm.pageNum"
v-model:pageSize="queryForm.pageSize"
:total="total"
@change="queryData"
@showSizeChange="queryData"
:show-total="(total:number) => `共${total}条`"
/>
</div>
</a-card>
</template>
<script setup lang="ts">
import {reactive, ref, onMounted} from 'vue';
import {message, Modal} from 'ant-design-vue';
import {SmartLoading} from '/@/components/framework/smart-loading';
import {PAGE_SIZE_OPTIONS} from '/@/constants/common-const';
import {smartSentry} from '/@/lib/smart-sentry';
import TableOperator from '/@/components/support/table-operator/index.vue';
import {asnApi} from '/@/api/business/receive/asn/asn-api';
import {TABLE_ID_CONST} from "/@/constants/support/table-id-const";
import {useRouter} from "vue-router";
// ---------------------------- ----------------------------
const columns = ref([
{
title: '入库单id',
dataIndex: 'asnId',
ellipsis: true,
},
{
title: '入库单号',
dataIndex: 'asnNumber',
ellipsis: true,
},
{
title: '客户订单号',
dataIndex: 'customerNumber',
ellipsis: true,
},
{
title: '单据类型',
dataIndex: 'orderType',
ellipsis: true,
},
{
title: '状态',
dataIndex: 'status',
ellipsis: true,
},
{
title: '收货地址',
dataIndex: 'addressId',
ellipsis: true,
},
{
title: '订单数量',
dataIndex: 'orderQuantity',
ellipsis: true,
},
{
title: '收货数量',
dataIndex: 'receivedQuantity',
ellipsis: true,
},
{
title: '订单日期',
dataIndex: 'orderDate',
ellipsis: true,
},
{
title: '创建时间',
dataIndex: 'createTime',
ellipsis: true,
},
{
title: '操作',
dataIndex: 'action',
fixed: 'right',
width: 90,
},
]);
// ---------------------------- ----------------------------
const queryFormState = {
customerNumber: undefined, //
pageNum: 1,
pageSize: 10,
};
// form
const queryForm = reactive({...queryFormState});
// loading
const tableLoading = ref(false);
//
const tableData = ref([]);
//
const total = ref(0);
//
function resetQuery() {
let pageSize = queryForm.pageSize;
Object.assign(queryForm, queryFormState);
queryForm.pageSize = pageSize;
queryData();
}
//
function onSearch() {
queryForm.pageNum = 1;
queryData();
}
//
async function queryData() {
tableLoading.value = true;
try {
let queryResult = await asnApi.queryPage(queryForm);
tableData.value = queryResult.data.list;
total.value = queryResult.data.total;
} catch (e) {
smartSentry.captureError(e);
} finally {
tableLoading.value = false;
}
}
onMounted(queryData);
// ---------------------------- / ----------------------------
let router = useRouter();
function showForm() {
router.push({
path: '/receive/asn/asn-form',
query: { enterpriseId: 1 }
});
}
// ---------------------------- ----------------------------
//
function onDelete(data:object) {
Modal.confirm({
title: '提示',
content: '确定要删除选吗?',
okText: '删除',
okType: 'danger',
onOk() {
requestDelete(data);
},
cancelText: '取消',
onCancel() {
},
});
}
//
async function requestDelete(data:any) {
SmartLoading.show();
try {
await asnApi.delete(data.asnId);
message.success('删除成功');
await queryData();
} catch (e) {
smartSentry.captureError(e);
} finally {
SmartLoading.hide();
}
}
// ---------------------------- ----------------------------
//
const selectedRowKeyList = ref([]);
function onSelectChange(selectedRowKeys: any) {
selectedRowKeyList.value = selectedRowKeys;
}
//
function confirmBatchDelete() {
Modal.confirm({
title: '提示',
content: '确定要批量删除这些数据吗?',
okText: '删除',
okType: 'danger',
onOk() {
requestBatchDelete();
},
cancelText: '取消',
onCancel() {
},
});
}
//
async function requestBatchDelete() {
try {
SmartLoading.show();
await asnApi.batchDelete(selectedRowKeyList.value);
message.success('删除成功');
await queryData();
} catch (e) {
smartSentry.captureError(e);
} finally {
SmartLoading.hide();
}
}
</script>