|
|
|
@ -75,7 +75,8 @@
|
|
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
<div v-if="tableLoaded">
|
|
|
|
|
<BasicTable @register="register" @row-dbClick="EditRow" @edit-row-end="EditRowEnd" />
|
|
|
|
|
<hot-table ref="hotTb" :data="list" :settings="settings"></hot-table>
|
|
|
|
|
<!-- <BasicTable @register="register" @row-dbClick="EditRow" @edit-row-end="EditRowEnd" /> -->
|
|
|
|
|
<!-- rowKeyFieldName="rowKey" -->
|
|
|
|
|
<!-- <vxe-table
|
|
|
|
|
:columns="columns"
|
|
|
|
@ -187,6 +188,8 @@
|
|
|
|
|
import { useMessage } from '/@/hooks/web/useMessage'
|
|
|
|
|
const { notification } = useMessage()
|
|
|
|
|
import { useRoute } from 'vue-router'
|
|
|
|
|
import { HotTable } from '@handsontable/vue3'
|
|
|
|
|
import { getDictDropDown } from '/@/api/common'
|
|
|
|
|
const route = useRoute()
|
|
|
|
|
const props = defineProps({
|
|
|
|
|
details: { type: Object, default: {} },
|
|
|
|
@ -260,6 +263,387 @@
|
|
|
|
|
autoCreateKey: false,
|
|
|
|
|
showIndexColumn: true,
|
|
|
|
|
})
|
|
|
|
|
// 箱型字段
|
|
|
|
|
const ctnDict = ref([])
|
|
|
|
|
// 费用名称字典
|
|
|
|
|
const feeDict = ref([])
|
|
|
|
|
// 费用标准字典
|
|
|
|
|
const unitDict = ref([])
|
|
|
|
|
// 币别字典
|
|
|
|
|
const currencyDict = ref([])
|
|
|
|
|
// 表格插件
|
|
|
|
|
const hotTb = ref<any>()
|
|
|
|
|
const list = ref<any>([])
|
|
|
|
|
// 定义表格所有列
|
|
|
|
|
const columns = [
|
|
|
|
|
{
|
|
|
|
|
data: 'selected',
|
|
|
|
|
type: 'checkbox',
|
|
|
|
|
title: ' ',
|
|
|
|
|
width: 32,
|
|
|
|
|
className: 'htCenter',
|
|
|
|
|
readOnly: false,
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
title: '箱型代码',
|
|
|
|
|
width: 120,
|
|
|
|
|
data: 'ctnCode',
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
title: '箱型',
|
|
|
|
|
width: 120,
|
|
|
|
|
data: 'ctn',
|
|
|
|
|
type: 'dropdown',
|
|
|
|
|
// 下拉框数据,可以同步或者异步返回(异步需要process返回)
|
|
|
|
|
source: async (query, process) => {
|
|
|
|
|
const res = ctnDict.value.length
|
|
|
|
|
? ctnDict.value
|
|
|
|
|
: (await getDictDropDown({ code: 'ctn_code' }))?.data
|
|
|
|
|
if (!ctnDict.value.length) ctnDict.value = res
|
|
|
|
|
const dict = res.map((res) => {
|
|
|
|
|
return res.name
|
|
|
|
|
})
|
|
|
|
|
process(dict)
|
|
|
|
|
},
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
title: '箱量',
|
|
|
|
|
width: 80,
|
|
|
|
|
data: 'ctnNum',
|
|
|
|
|
type: 'numeric',
|
|
|
|
|
format: '0',
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
title: '箱号',
|
|
|
|
|
width: 80,
|
|
|
|
|
data: 'cntrNo',
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
title: '封号',
|
|
|
|
|
width: 80,
|
|
|
|
|
data: 'sealNo',
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
title: '件数',
|
|
|
|
|
width: 80,
|
|
|
|
|
data: 'pkgs',
|
|
|
|
|
type: 'numeric',
|
|
|
|
|
format: '0',
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
title: '包装',
|
|
|
|
|
width: 80,
|
|
|
|
|
data: 'kindPkgs',
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
title: '毛重',
|
|
|
|
|
width: 80,
|
|
|
|
|
data: 'kgs',
|
|
|
|
|
type: 'numeric',
|
|
|
|
|
format: '0',
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
title: '尺寸',
|
|
|
|
|
width: 80,
|
|
|
|
|
data: 'size',
|
|
|
|
|
type: 'numeric',
|
|
|
|
|
format: '0',
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
title: '皮重',
|
|
|
|
|
width: 80,
|
|
|
|
|
data: 'tareWeight',
|
|
|
|
|
type: 'numeric',
|
|
|
|
|
format: '0',
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
title: '称重方式',
|
|
|
|
|
width: 80,
|
|
|
|
|
data: 'weightType',
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
title: '称重重量',
|
|
|
|
|
width: 80,
|
|
|
|
|
data: 'weightKGS',
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
title: '称重日期',
|
|
|
|
|
width: 100,
|
|
|
|
|
data: 'weightDate',
|
|
|
|
|
type: 'date',
|
|
|
|
|
dateFormat: 'YYYY-MM-DD',
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
title: 'TEU',
|
|
|
|
|
width: 80,
|
|
|
|
|
data: 'weightKGS',
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
title: '表现形式',
|
|
|
|
|
width: 80,
|
|
|
|
|
data: 'ctnAll',
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
title: '毛重',
|
|
|
|
|
width: 80,
|
|
|
|
|
data: 'kgs',
|
|
|
|
|
type: 'numeric',
|
|
|
|
|
format: '0',
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
title: '尺码',
|
|
|
|
|
width: 80,
|
|
|
|
|
data: 'cbm',
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
title: '品名',
|
|
|
|
|
width: 80,
|
|
|
|
|
data: 'goodsName',
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
title: '箱状态',
|
|
|
|
|
width: 80,
|
|
|
|
|
data: 'ctnStatus',
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
title: 'VGM联系人',
|
|
|
|
|
width: 80,
|
|
|
|
|
data: 'weightATTN',
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
title: 'VGM联系人电话',
|
|
|
|
|
width: 80,
|
|
|
|
|
data: 'weightTel',
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
title: 'VGM联系人签名',
|
|
|
|
|
width: 80,
|
|
|
|
|
data: 'weightSign',
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
title: '主票业务编号',
|
|
|
|
|
width: 80,
|
|
|
|
|
data: 'masterNo',
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
title: '承运车队',
|
|
|
|
|
width: 80,
|
|
|
|
|
data: 'trucker',
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
title: '车号',
|
|
|
|
|
width: 80,
|
|
|
|
|
data: 'truckNo',
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
title: '运费',
|
|
|
|
|
width: 80,
|
|
|
|
|
data: 'truckFee',
|
|
|
|
|
type: 'numeric',
|
|
|
|
|
format: '0',
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
title: '免堆存天数',
|
|
|
|
|
width: 80,
|
|
|
|
|
data: 'freeStorageDay',
|
|
|
|
|
type: 'numeric',
|
|
|
|
|
format: '0',
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
title: '堆存天数',
|
|
|
|
|
width: 80,
|
|
|
|
|
data: 'storageDay',
|
|
|
|
|
type: 'numeric',
|
|
|
|
|
format: '0',
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
title: '堆存费/天',
|
|
|
|
|
width: 80,
|
|
|
|
|
data: 'storagePrice',
|
|
|
|
|
type: 'numeric',
|
|
|
|
|
format: '0',
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
title: '堆存费',
|
|
|
|
|
width: 80,
|
|
|
|
|
data: 'storageFee',
|
|
|
|
|
type: 'numeric',
|
|
|
|
|
format: '0',
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
title: '免箱使天数',
|
|
|
|
|
width: 80,
|
|
|
|
|
data: 'freeCtnDay',
|
|
|
|
|
type: 'numeric',
|
|
|
|
|
format: '0',
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
title: '箱使天数',
|
|
|
|
|
width: 80,
|
|
|
|
|
data: 'ctnDay',
|
|
|
|
|
type: 'numeric',
|
|
|
|
|
format: '0',
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
title: '箱使费/天',
|
|
|
|
|
width: 80,
|
|
|
|
|
data: 'ctnPrice',
|
|
|
|
|
type: 'numeric',
|
|
|
|
|
format: '0',
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
title: '箱使费',
|
|
|
|
|
width: 80,
|
|
|
|
|
data: 'ctnFee',
|
|
|
|
|
type: 'numeric',
|
|
|
|
|
format: '0',
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
title: '是否暂出',
|
|
|
|
|
width: 80,
|
|
|
|
|
data: 'isTemp',
|
|
|
|
|
type: 'dropdown',
|
|
|
|
|
source: ['是', '否'],
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
title: 'VGM地址',
|
|
|
|
|
width: 80,
|
|
|
|
|
data: 'vgmAddr',
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
title: 'VGM邮箱',
|
|
|
|
|
width: 80,
|
|
|
|
|
data: 'vgmEmail',
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
title: '提箱时间',
|
|
|
|
|
width: 100,
|
|
|
|
|
data: 'pickUpTime',
|
|
|
|
|
type: 'date',
|
|
|
|
|
dateFormat: 'YYYY-MM-DD',
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
title: '实际到港时间',
|
|
|
|
|
width: 100,
|
|
|
|
|
data: 'actualArrivalPortTime',
|
|
|
|
|
type: 'date',
|
|
|
|
|
dateFormat: 'YYYY-MM-DD',
|
|
|
|
|
},
|
|
|
|
|
]
|
|
|
|
|
// 表格配置项
|
|
|
|
|
const settings = {
|
|
|
|
|
height: '400',
|
|
|
|
|
width: '100%',
|
|
|
|
|
autoWrapRow: true,
|
|
|
|
|
autoWrapCol: true,
|
|
|
|
|
// 每行的高度
|
|
|
|
|
rowHeights: 32,
|
|
|
|
|
// 需要隐藏的列
|
|
|
|
|
// hiddenColumns: {
|
|
|
|
|
// columns: [1],
|
|
|
|
|
// indicators: true,
|
|
|
|
|
// },
|
|
|
|
|
// 如果通过复制或者填写校验出现错误,清空输入框
|
|
|
|
|
afterValidate: function (isValid, value, row, prop, source) {
|
|
|
|
|
if (!isValid) {
|
|
|
|
|
hotTb.value.hotInstance.setDataAtRowProp(row, prop, '')
|
|
|
|
|
}
|
|
|
|
|
},
|
|
|
|
|
columns: columns,
|
|
|
|
|
// 此行直接复制,必须(非商用)
|
|
|
|
|
licenseKey: 'non-commercial-and-evaluation',
|
|
|
|
|
// 定义所有单元格发生变化的回调处理
|
|
|
|
|
afterChange(changes, source) {
|
|
|
|
|
// 这里定义了编辑,自动填充和拷贝数据的处理逻辑
|
|
|
|
|
if (source === 'edit' || source === 'Autofill.fill' || source === 'CopyPaste.paste') {
|
|
|
|
|
let dict = {}
|
|
|
|
|
changes.forEach((res) => {
|
|
|
|
|
console.log(res)
|
|
|
|
|
|
|
|
|
|
// 修改费用名称
|
|
|
|
|
if (res[1] === 'feeName') {
|
|
|
|
|
// 获取当前选中的字典对象数据
|
|
|
|
|
const item = feeDict.value.filter((item) => {
|
|
|
|
|
return item.name === changes[0][3]
|
|
|
|
|
})
|
|
|
|
|
if (item) dict = item[0]
|
|
|
|
|
list.value[res[0]]['feeEnName'] = dict['enName']
|
|
|
|
|
list.value[res[0]]['feeCode'] = dict['code']
|
|
|
|
|
}
|
|
|
|
|
})
|
|
|
|
|
|
|
|
|
|
// 修改费用英文名称
|
|
|
|
|
if (changes[0][1] === 'feeEnName') {
|
|
|
|
|
}
|
|
|
|
|
// 修改客户类别
|
|
|
|
|
if (changes[0][1] === 'customerTypeName') {
|
|
|
|
|
getDictOption('djy_cust_prop').then((res) => {
|
|
|
|
|
const item = res.filter((item) => {
|
|
|
|
|
return item.name === changes[0][3]
|
|
|
|
|
})
|
|
|
|
|
if (item) dict = item[0]
|
|
|
|
|
list.value[changes[0][0]]['customerType'] = dict?.value
|
|
|
|
|
})
|
|
|
|
|
}
|
|
|
|
|
// 修改单位
|
|
|
|
|
if (changes[0][1] === 'unitName') {
|
|
|
|
|
const item = unitDict.value.filter((item) => {
|
|
|
|
|
return item.name === changes[0][3]
|
|
|
|
|
})
|
|
|
|
|
if (item) dict = item[0]
|
|
|
|
|
list.value[changes[0][0]]['unit'] = dict?.value
|
|
|
|
|
}
|
|
|
|
|
// 修改币别
|
|
|
|
|
if (changes[0][1] === 'currencyName') {
|
|
|
|
|
const item = currencyDict.value.filter((item) => {
|
|
|
|
|
return item.name === changes[0][3]
|
|
|
|
|
})
|
|
|
|
|
if (item) dict = item[0]
|
|
|
|
|
list.value[changes[0][0]]['currency'] = dict?.codeName
|
|
|
|
|
}
|
|
|
|
|
// 当前操作的行
|
|
|
|
|
const index = changes[0][0]
|
|
|
|
|
// 修改不含税单价计算
|
|
|
|
|
if (changes[0][1] === 'noTaxPrice') {
|
|
|
|
|
// 单价
|
|
|
|
|
list.value[index].unitPrice =
|
|
|
|
|
(changes[0][3] || 0) * ((list.value[index].taxRate || 0) / 100 + 1)
|
|
|
|
|
// 金额
|
|
|
|
|
list.value[index].amount =
|
|
|
|
|
(list.value[index].unitPrice || 0) * (list.value[index].quantity || 0)
|
|
|
|
|
// 不含税金额
|
|
|
|
|
list.value[index].noTaxAmount = (changes[0][3] || 0) * (list.value[index].quantity || 0)
|
|
|
|
|
}
|
|
|
|
|
// 修改单价计算
|
|
|
|
|
if (changes[0][1] === 'unitPrice') {
|
|
|
|
|
// 不含税单价
|
|
|
|
|
list.value[index].noTaxPrice =
|
|
|
|
|
(changes[0][3] || 0) / ((list.value[index].taxRate || 0) / 100 + 1)
|
|
|
|
|
// 金额
|
|
|
|
|
list.value[index].amount = (changes[0][3] || 0) * (list.value[index].quantity || 0)
|
|
|
|
|
// 不含税金额
|
|
|
|
|
list.value[index].noTaxAmount =
|
|
|
|
|
(list.value[index].noTaxPrice || 0) * (list.value[index].quantity || 0)
|
|
|
|
|
}
|
|
|
|
|
// 修改数量
|
|
|
|
|
if (changes[0][1] === 'quantity') {
|
|
|
|
|
// 金额
|
|
|
|
|
list.value[index].amount = (changes[0][3] || 0) * (list.value[index].unitPrice || 0)
|
|
|
|
|
// 不含税金额
|
|
|
|
|
list.value[index].noTaxAmount = (changes[0][3] || 0) * (list.value[index].noTaxPrice || 0)
|
|
|
|
|
}
|
|
|
|
|
// 修改税率
|
|
|
|
|
if (changes[0][1] === 'taxRate') {
|
|
|
|
|
// 不含税单价
|
|
|
|
|
list.value[index].noTaxPrice =
|
|
|
|
|
(list.value[index].unitPrice || 0) / ((changes[0][3] || 0) / 100 + 1)
|
|
|
|
|
// 不含税金额
|
|
|
|
|
list.value[index].noTaxAmount =
|
|
|
|
|
(list.value[index].noTaxPrice || 0) * (list.value[index].quantity || 0)
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
},
|
|
|
|
|
}
|
|
|
|
|
// 添加行
|
|
|
|
|
function addboxLine() {
|
|
|
|
|
const data = {
|
|
|
|
|