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

571 lines
15 KiB
Vue
Raw Normal View History

<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>