Files
geg-gas-web/src/views/erp/purchase/components/OrderModal.vue

571 lines
15 KiB
Vue
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<template>
<BasicModal
v-bind="$attrs"
@register="registerModal"
:title="getTitle"
@ok="handleSubmit"
:width="1000"
>
<div class="sub-title">基础信息</div>
<BasicForm @register="registerForm">
<template #code="{ model }">
<a-input
v-model:value="model.purchaseNumber"
placeholder="请输入采购单号"
:readonly="model.isSysNumBoolean"
/>
</template>
<template #isSysNum="{ model }">
<a-checkbox
v-model:checked="model.isSysNumBoolean"
@change="handleSysChange"
style="margin-left: 10px"
>
用系统编号
</a-checkbox>
</template>
<template #isRelation="{ model }">
<a-checkbox
v-model:checked="model.isRelationApplyBoolean"
@change="handleRelationChange"
style="margin-left: 10px"
>
不关联
</a-checkbox>
</template>
<template #user="{ model }">
<SelectUser
v-model:value="model.purchasePersonId"
:multiple="false"
suffix="ant-design:setting-outlined"
placeholder="请选择采购人员"
@change="handleUserChange"
/>
</template>
</BasicForm>
<BasicTable @register="registerTable">
<template #toolbar>
<a-button type="primary" @click="openModal(true, { type: 'checkbox' })"> 添加 </a-button>
<a-button type="primary" danger @click="handleDelete"> 移除</a-button>
</template>
<template #bodyCell="{ column, record }">
<template v-if="column.key === 'price'">
<a-input-number
v-model:value="record.price"
:min="0"
@change="handleNumberChange(record)"
/>
</template>
<template v-if="column.key === 'count'">
<a-input-number
v-model:value="record.count"
:min="0"
@change="handleNumberChange(record)"
/>
</template>
<template v-if="column.key === 'discount'">
<a-input-number
v-model:value="record.discount"
addon-after="%"
:min="0"
@change="handleNumberChange(record)"
/>
</template>
<template v-if="column.key === 'taxRate'">
<a-input-number
v-model:value="record.taxRate"
addon-after="%"
:min="0"
@change="handleNumberChange(record)"
/>
</template>
<template v-if="column.key === 'taxBreak'">
<a-input v-model:value="record.taxBreak" disabled />
</template>
<template v-if="column.key === 'afterTaxAmount'">
<a-input v-model:value="record.afterTaxAmount" disabled />
</template>
<template v-if="column.key === 'deliveryDate'">
<XjrDatePicker v-model:value="record.deliveryDate" format="YYYY-MM-DD" />
</template>
<template v-if="column.key === 'remark'">
<a-input v-model:value="record.remark" />
</template>
</template>
</BasicTable>
<div class="table-bottom">
<span>合计</span>
<div>
<span>
总量
<span class="price">{{ total.countSum }}</span>
</span>
<span>
总金额
<span class="price">{{ total.amountSum }}</span>
</span>
</div>
</div>
<div class="sub-title">附件</div>
<Upload
v-model:value="folderId"
listType="dragger"
:tip="fileTip"
:style="{ width: '200px' }"
/>
<SelectModal @register="registerSelectModal" @success="handleSuccess" />
</BasicModal>
</template>
<script lang="ts" setup>
import { ref, computed, unref } from 'vue';
import { BasicModal, useModalInner, useModal } from '/@/components/Modal';
import { BasicForm, useForm } from '/@/components/Form/index';
import { BasicTable, useTable, BasicColumn, FormSchema } from '/@/components/Table';
import Upload from '/@/components/Form/src/components/Upload.vue';
import SelectModal from '../../bom/components/SelectModal.vue';
import SelectUser from '/@/components/Form/src/components/SelectUser.vue';
import { XjrDatePicker } from '/@/components/DatePicker';
import { getSaleCode } from '/@/api/erp/sale/order';
import { getPurchaseInfo, updatePurchase, addPurchase } from '/@/api/erp/purchase/order';
import { getCaseErpApply } from '/@/api/erp/purchase/apply';
import { getCaseErpApplyList } from '/@/api/erp/purchase/apply';
import { getSupplierList } from '/@/api/erp/supplier/list';
import { getUser } from '/@/api/system/user';
import { useMessage } from '/@/hooks/web/useMessage';
import { useI18n } from '/@/hooks/web/useI18n';
const { t } = useI18n();
const handleApplyChange = async (id) => {
const res = await getCaseErpApply(id);
let userInfo;
if (res.applyUserIds) {
userInfo = await getUser(res.applyUserIds);
}
setFieldsValue({
relatedProject: res.relatedProject,
purchasePersonId: res.applyUserIds,
purchaseDeptId: res.applyDepId,
purchasePhone: userInfo?.mobile || '',
filePath: res.filePath,
});
unref(total).countSum = res.countSum || 0;
unref(total).amountSum = res.amountSum || 0;
setTableData(res.caseErpApplyDetailList || []);
};
const FormSchema: FormSchema[] = [
{
field: 'purchaseNumber',
label: '采购单号',
component: 'Input',
slot: 'code',
required: true,
colProps: { span: 9 },
},
{
field: 'isSysNumBoolean',
label: '',
component: 'Input',
slot: 'isSysNum',
colProps: { span: 3 },
},
{
field: 'applyId',
label: '关联申请单',
component: 'ApiSelect',
colProps: { span: 9 },
componentProps: {
placeholder: '请选择关联申请单',
api: getCaseErpApplyList,
labelField: 'theme',
valueField: 'id',
getPopupContainer: () => document.body,
onChange: handleApplyChange,
},
},
{
field: 'isRelationApplyBoolean',
label: '',
component: 'Input',
slot: 'isRelation',
colProps: { span: 3 },
},
{
field: 'theme',
label: '订单主题',
component: 'Input',
required: true,
colProps: { span: 24 },
componentProps: {
placeholder: '请输入订单主题',
},
},
{
field: 'purchaseDate',
label: '采购日期',
component: 'DatePicker',
required: true,
colProps: { span: 12 },
componentProps: {
format: 'YYYY-MM-DD',
placeholder: '请选择采购日期',
getPopupContainer: () => document.body,
},
},
{
field: 'supplierId',
label: '供应商名称',
component: 'ApiSelect',
colProps: { span: 12 },
componentProps: {
placeholder: '请选择供应商名称',
api: getSupplierList,
labelField: 'name',
valueField: 'id',
getPopupContainer: () => document.body,
onChange: (_, option) => {
if (option) {
setFieldsValue({
supplierPerson: option.person || '',
supplierWay: option.phone || '',
});
}
},
},
},
{
field: 'supplierPerson',
label: '联系人',
component: 'Input',
colProps: { span: 12 },
componentProps: {
disabled: true,
},
},
{
field: 'supplierWay',
label: '联系方式',
component: 'Input',
colProps: { span: 12 },
componentProps: {
disabled: true,
},
},
{
field: 'purchaseDeptId',
label: '采购部门',
component: 'Dept',
colProps: { span: 12 },
},
{
field: 'purchasePersonId',
label: '采购人员',
component: 'Input',
slot: 'user',
colProps: { span: 12 },
},
{
field: 'purchasePhone',
label: '联系电话',
component: 'Input',
colProps: { span: 12 },
componentProps: {
disabled: true,
},
},
{
field: 'relatedProject',
label: '关联项目',
component: 'DicSelect',
colProps: { span: 12 },
componentProps: {
placeholder: '请选择关联项目',
itemId: '1680768933996957698',
isShowAdd: false,
getPopupContainer: () => document.body,
},
},
{
field: 'payType',
label: '结算方式',
component: 'DicSelect',
colProps: { span: 12 },
componentProps: {
placeholder: '请选择结算方式',
itemId: '1680821338692333570',
isShowAdd: false,
getPopupContainer: () => document.body,
},
},
{
field: 'payAddress',
label: '交付地址',
component: 'Input',
colProps: { span: 24 },
componentProps: {
placeholder: '请输入交货地址',
},
},
{
field: 'remark',
label: '备注',
component: 'InputTextArea',
colProps: { span: 24 },
componentProps: {
placeholder: '请输入备注',
},
},
];
const columns: BasicColumn[] = [
{
title: '物料编码',
dataIndex: 'code',
},
{
title: '物料名称',
dataIndex: 'name',
},
{
title: '规格型号',
dataIndex: 'model',
},
{
title: '单位',
dataIndex: 'unitName',
},
{
title: '单价',
dataIndex: 'price',
},
{
title: '数量',
dataIndex: 'count',
},
{
title: '折扣',
dataIndex: 'discount',
},
{
title: '税率',
dataIndex: 'taxRate',
},
{
title: '税费',
dataIndex: 'taxBreak',
},
{
title: '税后金额',
dataIndex: 'afterTaxAmount',
},
{
title: '交付日期',
dataIndex: 'deliveryDate',
},
];
const { notification } = useMessage();
const isUpdate = ref(true);
const rowId = ref('');
const folderId = ref('');
const fileTip = '支持扩展名:.doc .docx .pdf .jpg ...';
const total = ref({
countSum: 0 as any,
amountSum: 0 as any,
});
const emit = defineEmits(['success']);
const [registerForm, { setFieldsValue, resetFields, validate, updateSchema }] = useForm({
labelWidth: 100,
schemas: FormSchema,
showActionButtonGroup: false,
actionColOptions: {
span: 23,
},
});
const customRow = (record) => {
return {
onClick: () => {
let selectedRowKeys = [...getSelectRowKeys()];
if (selectedRowKeys.indexOf(record.key) >= 0) {
let index = selectedRowKeys.indexOf(record.key);
selectedRowKeys.splice(index, 1);
} else {
selectedRowKeys.push(record.key);
}
setSelectedRowKeys(selectedRowKeys);
},
};
};
const [registerTable, { setSelectedRowKeys, getSelectRowKeys, setTableData, getDataSource }] =
useTable({
title: '采购物料',
columns,
striped: false,
pagination: false,
rowSelection: {
type: 'checkbox',
},
customRow,
});
const [registerSelectModal, { openModal }] = useModal();
const [registerModal, { setModalProps, closeModal }] = useModalInner(async (data) => {
resetFields();
setModalProps({ confirmLoading: false, destroyOnClose: true });
isUpdate.value = !!data?.isUpdate;
if (unref(isUpdate)) {
rowId.value = data.id;
const record = await getPurchaseInfo(data.id);
folderId.value = record.filePath || '';
setFieldsValue({
...record,
});
setTableData(record.caseErpPurchaseDetails || []);
unref(total).countSum = record.countSum || 0;
unref(total).amountSum = record.amountSum || 0;
} else {
folderId.value = '';
const code = await getSaleCode();
setFieldsValue({ purchaseNumber: code, isSysNumBoolean: true });
}
});
const getTitle = computed(() => (!unref(isUpdate) ? '新增订单' : '编辑订单'));
const handleSysChange = async (e) => {
let code = '';
if (e.target.checked) {
code = await getSaleCode();
}
setFieldsValue({ purchaseNumber: code });
};
const handleRelationChange = async (e) => {
updateSchema({
field: 'applyId',
componentProps: { disabled: e.target.checked },
});
if (e.target.checked) {
setFieldsValue({
applyId: '',
relatedProject: '',
purchasePersonId: '',
purchaseDeptId: '',
purchasePhone: '',
filePath: '',
});
unref(total).countSum = 0;
unref(total).amountSum = 0;
setTableData([]);
}
};
const handleUserChange = (_, options) => {
setFieldsValue({ purchasePhone: options[0]?.mobile });
};
const handleNumberChange = (record) => {
const price = record.price || 0;
const count = record.count || 0;
const discount = record.discount || 0;
const taxRate = record.taxRate || 0;
if (discount) {
record.taxBreak = price * count * (1 - discount / 100) * (taxRate / 100);
} else {
record.taxBreak = price * count * (taxRate / 100);
}
record.afterTaxAmount = price * count * (1 - discount / 100) + record.taxBreak;
record.taxBreak = record.taxBreak.toFixed(2);
record.afterTaxAmount = record.afterTaxAmount.toFixed(2);
handleTotalChange();
};
const handleSuccess = async (data) => {
data.map((x) => {
x.taxRate = 3;
x.count = 0;
});
setTableData([...getDataSource(), ...data]);
};
const handleDelete = () => {
const datasource = getDataSource().filter((x) => !getSelectRowKeys().includes(x.key));
setTableData(datasource);
handleTotalChange();
};
const handleSubmit = async () => {
try {
const values = await validate();
values.filePath = folderId.value;
values.addCaseErpPurchaseDetailDtoList = getDataSource() || [];
Object.assign(values, unref(total));
setModalProps({ confirmLoading: true });
if (!unref(isUpdate)) {
await addPurchase(values);
notification.success({
message: '新增订单',
description: t('成功'),
});
} else {
values.id = rowId.value;
await updatePurchase(values);
notification.success({
message: '编辑订单',
description: t('成功'),
});
}
closeModal();
emit('success');
} catch (error) {
setModalProps({ confirmLoading: false });
}
};
const handleTotalChange = () => {
unref(total).countSum = 0;
unref(total).amountSum = 0;
getDataSource().map((item) => {
const price = item.price || 0;
const count = item.count || 0;
unref(total).countSum += count;
unref(total).amountSum += count * price;
});
unref(total).amountSum = unref(total).amountSum.toFixed(2);
};
</script>
<style lang="less" scoped>
.sub-title {
font-weight: bold;
margin: 15px 0 20px 30px;
color: #606266;
}
.table-bottom {
display: flex;
justify-content: space-between;
border-bottom: 1px solid #ddd;
padding: 5px;
& > div > span {
margin-left: 40px;
}
}
.price {
color: #f00;
}
</style>