箱管 批量变动导入、批量变动导入_模板管理 单程租入 单程租出

szh-new
张同海 2 months ago
parent 980d6f7011
commit 1ecf5534e4

@ -362,10 +362,8 @@
fileId: dsFile.value.dsFileList.SelectId,
}
ApiDealExcel(ApiData).then((res) => {
list.value.splice(0)
res.data.forEach((item) => {
list.value.push(item)
})
refresh()
notification.success({ message: res.message, duration: 3 })
})
} else {
notification.warning({ message: '请先在电子文档中勾选一个文件。', duration: 3 })

@ -373,10 +373,8 @@
fileId: dsFile.value.dsFileList.SelectId,
}
ApiDealExcel(ApiData).then((res) => {
list.value.splice(0)
res.data.forEach((item) => {
list.value.push(item)
})
refresh()
notification.success({ message: res.message, duration: 3 })
})
} else {
notification.warning({ message: '请先在电子文档中勾选一个文件。', duration: 3 })

@ -375,10 +375,8 @@
fileId: dsFile.value.dsFileList.SelectId,
}
ApiDealExcel(ApiData).then((res) => {
list.value.splice(0)
res.data.forEach((item) => {
list.value.push(item)
})
refresh()
notification.success({ message: res.message, duration: 3 })
})
} else {
notification.warning({ message: '请先在电子文档中勾选一个文件。', duration: 3 })

@ -362,10 +362,8 @@
fileId: dsFile.value.dsFileList.SelectId,
}
ApiDealExcel(ApiData).then((res) => {
list.value.splice(0)
res.data.forEach((item) => {
list.value.push(item)
})
refresh()
notification.success({ message: res.message, duration: 3 })
})
} else {
notification.warning({ message: '请先在电子文档中勾选一个文件。', duration: 3 })

@ -0,0 +1,853 @@
<template>
<BasicModal
v-bind="$attrs"
:use-wrapper="true"
title="单程业务维护"
width="55%"
@register="registerModal"
@ok="handleSave"
>
<BasicForm @register="registerForm" />
<a-tabs v-model:activeKey="activeKey">
<a-tab-pane key="1" tab="业务明细">
<div class="HotTable">
<div>
<a-button type="link" @click="TableAdd" class="pl0">
<span class="iconfont icon-new_document"></span>
新增
</a-button>
<a-popconfirm
title="确定要删除所选数据?"
ok-text="确定"
cancel-text="取消"
@confirm="FnClickDel"
>
<a-button type="link" class="pl0">
<span class="iconfont icon-shanchu21"></span>
删除
</a-button>
</a-popconfirm>
<a-button type="link" @click="handleSave(false)" class="pl0">
<span class="iconfont icon-baocun" v-repeat></span>
保存
</a-button>
</div>
<div style="position: relative">
<input
class="ds-tb-check ds-goods-tb-check"
type="checkbox"
v-model="allCheck"
:indeterminate="someCheck"
v-if="list.length !== 0"
/>
<hot-table ref="hotTb" :data="list" :settings="settings">
<img
v-show="!list.length"
class="hot-tb-no-data"
src="../../../assets/images/nodata.png"
alt=""
/>
</hot-table>
</div>
</div>
</a-tab-pane>
<a-tab-pane key="2" tab="电子文档" :disabled="!rowId">
<DsFile
ref="dsFile"
fileType="infoclient"
:id="rowId"
:SetSelect="{
show: true,
}"
/>
</a-tab-pane>
<a-tab-pane key="3" tab="费用" :disabled="!rowId">
<div class="fee-card-box mt15">
<FeeTable
tbType="receive"
:height="height"
type="1"
:broData="broPayData"
:id="rowId"
@broInsert="broReceive"
></FeeTable>
</div>
<!-- 应付表格 -->
<div class="fee-card-box mt15">
<FeeTable
tbType="pay"
:height="height"
type="1"
:broData="broReceiveData"
:id="rowId"
@broInsert="broPay"
></FeeTable>
</div>
</a-tab-pane>
</a-tabs>
<!--右下角按钮-->
<template #footer>
<a-button
pre-icon="ant-design:check-circle-outlined"
type="primary"
:loading="loading"
@click="Confirm()"
>
确认执行
</a-button>
<a-button
pre-icon="ant-design:close-circle-outlined"
type="primary"
:loading="loading"
@click="Cancel()"
>
取消执行
</a-button>
<a-button
pre-icon="ant-design:file-excel-outlined"
type="primary"
:loading="loading"
@click="DealExcel()"
>
识别excel
</a-button>
<a-button
pre-icon="ant-design:close-outlined"
type="warning"
:loading="loading"
ghost
style="margin-right: 0.8rem"
@click="closeModal"
>取消</a-button
>
<a-button
type="success"
:loading="loading"
pre-icon="ant-design:check-outlined"
style="margin-right: 0.8rem"
@click="handleSave(false)"
>仅保存</a-button
>
<a-button
pre-icon="ant-design:check-circle-outlined"
type="primary"
:loading="loading"
style="margin-right: 0.8rem"
@click="handleSave(true)"
>保存并关闭</a-button
>
<!-- <a-button
pre-icon="ant-design:check-circle-outlined"
type="primary"
:loading="loading"
:disabled="!rowId"
@click="MakeFee()"
>
生成费用
</a-button> -->
</template>
</BasicModal>
</template>
<script lang="ts" setup>
import { ref, computed, unref, watchEffect, watch } from 'vue'
import { BasicModal, useModalInner } from '/@/components/Modal'
import { BasicForm, useForm } from '/@/components/Form/index'
import { HotTable } from '@handsontable/vue3'
import { registerAllModules } from 'handsontable/registry'
registerAllModules()
import 'handsontable/dist/handsontable.full.css'
import { formSchema, formSearchBoxSchema } from './columns'
import {
GetCtnSelectList,
GetClientPortSelectList,
} from '/@/views/operation/seaexport/api/BookingLedger'
import {
ApiEdit,
ApiInfo,
// ApiListDetail,
ApiDelDetail,
// // ApiMakeFee,
// ApiDetailView,
// ApiAddCtn,
ApiConfirm,
ApiCancel,
} from './api'
import { ApiDealExcel } from '/@/views/ContainerManagement/RentIn/api'
import { GetClientListByCode } from '/@/api/common'
import { useMessage } from '/@/hooks/web/useMessage'
const { notification } = useMessage()
import { useOptionsStore } from '/@/store/modules/options'
const optionsStore = useOptionsStore()
import DsFile from '/@/components/File/index.vue'
//
import FeeTable from '/@/components/CostEntry/feeTable.vue'
import moment from 'moment'
import { getDictOption } from '/@/utils/dictUtil'
// Emits
const emit = defineEmits(['success', 'register'])
const isUpdate = ref(true)
const loading = ref(false)
const rowId = ref('')
const height = ref(300)
const [registerForm, { resetFields, setFieldsValue, validate }] = useForm({
labelWidth: 100,
schemas: formSchema,
showActionButtonGroup: false,
})
const [registerModal, { setModalProps, closeModal }] = useModalInner(async (data) => {
resetFields()
setModalProps({ confirmLoading: false, loading: true })
isUpdate.value = !!data?.isUpdate
activeKey.value = '1'
list.value.splice(0)
if (unref(isUpdate)) {
// setModalProps({ confirmLoading: true });
rowId.value = data.record.id
const res: any = await ApiInfo({ id: unref(rowId) })
if (res.succeeded) {
allCheck.value = false
someCheck.value = false
setFieldsValue({
...res.data,
})
if (res.data.bodyList) {
res.data.bodyList.forEach((item) => {
list.value.push(item)
})
}
}
} else {
rowId.value = ''
}
setModalProps({ loading: false })
})
// function MakeFee() {
// ApiMakeFee({ id: rowId.value }).then((res) => {
// notification.success({ message: res.message, duration: 3 })
// })
// }
async function Confirm() {
await handleSave(false)
let type: boolean = true
let ApiData: any = {
id: rowId.value,
ids: [],
}
list.value.forEach((e: any, i) => {
if (e.selected) {
if (e.id) {
ApiData.ids.push(e.id)
} else {
type = false
}
}
})
if (type) {
ApiConfirm(ApiData).then((res) => {
notification.success({ message: res.message, duration: 3 })
emit('success')
})
} else {
notification.success({ message: '请先保存明细表', duration: 3 })
}
}
async function Cancel() {
await handleSave(false)
let type: boolean = true
let ApiData: any = {
id: rowId.value,
ids: [],
}
list.value.forEach((e: any, i) => {
if (e.selected) {
if (e.id) {
ApiData.ids.push(e.id)
} else {
type = false
}
}
})
if (type) {
ApiCancel(ApiData).then((res) => {
notification.success({ message: res.message, duration: 3 })
emit('success')
})
} else {
notification.success({ message: '请先保存明细表', duration: 3 })
}
}
const dsFile = ref()
function DealExcel() {
if (rowId.value) {
if (dsFile.value.dsFileList.SelectId) {
let ApiData: any = {
id: unref(rowId),
formName: 'CM_RentOneWay',
tableName: '',
fileId: dsFile.value.dsFileList.SelectId,
}
ApiDealExcel(ApiData).then((res) => {
refresh()
notification.success({ message: res.message, duration: 3 })
})
} else {
notification.warning({ message: '请先在电子文档中勾选一个文件。', duration: 3 })
}
} else {
notification.warning({ message: '请先保存', duration: 3 })
}
}
async function handleSave(exit) {
try {
const values = await validate()
setModalProps({ confirmLoading: true, loading: true })
// TODO custom api
values.bodyList = list.value
let Arr = ['pickupDate', 'dropoffDate', 'feeStartDate', 'bsdate']
values.bodyList.forEach((item) => {
Arr.forEach((item2) => {
if (!item[item2]) {
item[item2] = null
}
})
})
if (values.bsdate) {
console.log(values.bsdate)
values.bsdate = moment(values.bsdate).format('YYYY-MM-DD 00:00:00')
console.log(values.bsdate)
}
if (values.accdate) {
values.accdate = moment(values.bsdate).format('YYYY-MM')
}
// loading.value = true;
const res: API.DataResult = await ApiEdit(values)
if (res.succeeded) {
notification.success({ message: res.message, duration: 3 })
emit('success')
//
if (!exit) {
if (unref(isUpdate)) {
await refresh()
} else {
rowId.value = res.data
isUpdate.value = true
await refresh()
}
}
} else {
notification.error({ message: res.message, duration: 3 })
}
exit && closeModal()
} finally {
// loading.value = false;
setModalProps({ confirmLoading: false, loading: false })
}
}
async function refresh() {
const res: API.DataResult = await ApiInfo({ id: unref(rowId) })
if (res.succeeded) {
list.value.splice(0)
await setFieldsValue({
...res.data,
})
if (res.data.bodyList) {
res.data.bodyList.forEach((item) => {
list.value.push(item)
})
}
}
}
const activeKey = ref('1')
//--------------------------------------- tab1 ---------------------------------------
const list = ref<any>([])
//
const allCheck = ref(false)
//
const someCheck = ref(false)
const hotTb = ref()
//
const ctnDict = ref([])
//
const ContainerOwnerDict = ref([])
//
const PortDict = ref([])
const rentDirectDict = ref([])
const rentTypeDict = ref([])
// //
// const currencyDict = ref([])
watchEffect(() => {
//
if (allCheck.value) {
list.value.forEach((item: any) => {
item.selected = true
})
} else {
//
list.value.forEach((item: any) => {
item.selected = false
})
}
})
watch(
list.value,
(val) => {
let a = 0
let b = 0
val.forEach((item: any) => {
if (item.selected) {
a += 1
} else {
b += 1
}
})
if (a == 0) {
allCheck.value = false
}
if (b == 0) {
allCheck.value = true
}
if (a != 0 && b != 0) {
someCheck.value = true
} else {
someCheck.value = false
}
},
{
deep: true,
},
)
const columns = [
{
data: 'selected',
type: 'checkbox',
title: ' ',
width: 32,
className: 'htCenter',
readOnly: false,
},
// -----------------
{
title: '主键Id',
width: 200,
data: 'id',
},
{
title: '租箱业务id',
width: 200,
data: 'pid',
},
{
title: '箱型代码',
width: 120,
data: 'ctnCode',
},
{
title: '原箱主',
width: 120,
data: 'oldContainerOwnerId',
},
{
title: '提箱港口ID',
width: 120,
data: 'pickupPortid',
},
{
title: '提箱港口五字码',
width: 120,
data: 'pickupPortCode',
},
{
title: '还箱港口ID',
width: 120,
data: 'dropoffPortid',
},
{
title: '还箱港口五字码',
width: 120,
data: 'dropoffPortCode',
},
{
title: '租箱客户ID',
width: 120,
data: 'rentCustomerId',
},
{
title: '租箱业务ID',
width: 120,
data: 'rentDirectId',
},
// -----------------
// {
// title: '',
// width: 200,
// data: 'billno',
// readOnly: true,
// },
{
title: '箱号',
width: 120,
data: 'cntrno',
},
{
title: '箱型',
width: 120,
data: 'ctnall',
type: 'dropdown',
// (process)
source: async (query, process) => {
const res = ctnDict.value.length ? ctnDict.value : (await GetCtnSelectList())?.data
if (!ctnDict.value.length) ctnDict.value = res
const dict = res.map((res) => {
return res.ctnName
})
process(dict)
},
},
{
title: '租箱客户',
width: 120,
data: 'rentCustomerName',
type: 'dropdown',
// (process)
source: async (query, process) => {
const res = ContainerOwnerDict.value.length
? ContainerOwnerDict.value
: (await GetClientListByCode({ code: 'leasing' }))?.data
if (!ContainerOwnerDict.value.length) ContainerOwnerDict.value = res
const dict = res.map((res) => {
return res.pinYinCode
})
process(dict)
},
},
{
title: '租箱业务',
width: 120,
data: 'rentDirect',
type: 'dropdown',
source: async (query, process) => {
const res = rentDirectDict.value.length
? rentDirectDict.value
: await getDictOption('CM_RentDirect')
if (!rentDirectDict.value.length) rentDirectDict.value = res
const dict = res.map((res) => {
return res.label
})
process(dict)
},
},
{
title: '租箱类型',
width: 120,
data: 'rentType',
type: 'dropdown',
source: async (query, process) => {
const res = rentTypeDict.value.length
? rentTypeDict.value
: await getDictOption('CM_RentType')
if (!rentTypeDict.value.length) rentTypeDict.value = res
const dict = res.map((res) => {
return res.label
})
process(dict)
},
},
{
title: '放箱单号',
width: 120,
data: 'ctnReleaseNo',
},
{
title: '租箱日期',
width: 120,
data: 'bsdate',
type: 'date',
dateFormat: 'YYYY-MM-DD',
},
{
title: '开始计费日期',
width: 120,
data: 'feeStartDate',
type: 'date',
dateFormat: 'YYYY-MM-DD',
},
{
title: '币别',
width: 120,
data: 'currency',
type: 'dropdown',
// (process)
source: async (query, process) => {
const results = await optionsStore.getOptionsByCodeAsync('GetFeeCurrencySelectList')
const dict = results.map((item: any) => {
return item.codeName
})
process(dict)
},
},
{
title: '日租金',
width: 120,
data: 'dailyRate',
type: 'numeric',
format: '0',
},
{
title: '提箱费',
width: 120,
data: 'pickupFee',
type: 'numeric',
format: '0',
},
{
title: '还箱费',
width: 120,
data: 'dropoffFee',
type: 'numeric',
format: '0',
},
// {
// title: '',
// width: 120,
// data: 'dropoffFee',
// type: 'numeric',
// format: '0',
// },
{
title: '还箱日期',
width: 120,
data: 'dropoffDate',
type: 'date',
dateFormat: 'YYYY-MM-DD',
},
{
title: '起租地点',
width: 120,
data: 'rentalPort',
type: 'dropdown',
// (process)
source: async (query, process) => {
const res = (await GetClientPortSelectList({ queryKey: query }))?.data
PortDict.value = res
const dict = res.map((res) => {
return res.portName
})
process(dict)
},
},
{
title: '提箱港口',
width: 120,
data: 'pickupPort',
type: 'dropdown',
// (process)
source: async (query, process) => {
const res = (await GetClientPortSelectList({ queryKey: query }))?.data
PortDict.value = res
const dict = res.map((res) => {
return res.portName
})
process(dict)
},
},
{
title: '还箱港口',
width: 120,
data: 'dropoffPort',
type: 'dropdown',
// (process)
source: async (query, process) => {
const res = (await GetClientPortSelectList({ queryKey: query }))?.data
PortDict.value = res
const dict = res.map((res) => {
return res.portName
})
process(dict)
},
},
{
title: '业务编号/提单号',
width: 120,
data: 'mblno',
},
{
title: '船名航次',
width: 120,
data: 'vesselVoyno',
},
// {
// title: '',
// width: 120,
// data: 'billState',
// },
// {
// title: '',
// width: 120,
// data: 'pickupDate',
// type: 'date',
// dateFormat: 'YYYY-MM-DD',
// },
]
const settings = {
height: '260',
autoWrapRow: true,
autoWrapCol: true,
//
rowHeights: 26,
fixedColumnsLeft: 1,
//
hiddenColumns: {
columns: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10],
indicators: true,
},
//
enterMoves: 'row',
columnSorting: true,
//
afterValidate: function (isValid, value, row, prop, source) {
if (!isValid) {
hotTb.value.hotInstance.setDataAtRowProp(row, prop, '')
}
},
columns: columns,
// ()
licenseKey: 'non-commercial-and-evaluation',
//
async afterChange(changes, source) {
if (source === 'edit' || source === 'Autofill.fill' || source === 'CopyPaste.paste') {
let dict: any = {}
if (changes[0][1] === 'ctnall') {
const res = ctnDict.value.length ? ctnDict.value : (await GetCtnSelectList())?.data
if (!ctnDict.value.length) ctnDict.value = res
const item = res.filter((item) => {
return item.ctnName === changes[0][3]
})
if (item) dict = item[0]
list.value[changes[0][0]]['ctnall'] = dict?.ctnName
list.value[changes[0][0]]['ctnCode'] = dict?.ediCode
}
if (changes[0][1] === 'rentCustomerName') {
const res = ContainerOwnerDict.value.length
? ContainerOwnerDict.value
: (await GetClientListByCode({ code: 'leasing' }))?.data
if (!ContainerOwnerDict.value.length) ContainerOwnerDict.value = res
const item = res.filter((item) => {
return item.pinYinCode === changes[0][3]
})
if (item) dict = item[0]
list.value[changes[0][0]]['rentCustomerName'] = dict?.pinYinCode
list.value[changes[0][0]]['rentCustomerId'] = dict?.id
}
if (changes[0][1] === 'rentDirect') {
const res = rentDirectDict.value.length
? rentDirectDict.value
: await getDictOption('CM_RentDirect')
if (!rentDirectDict.value.length) rentDirectDict.value = res
const item = res.filter((item) => {
return item.label === changes[0][3]
})
if (item) dict = item[0]
list.value[changes[0][0]]['rentDirect'] = dict?.label
list.value[changes[0][0]]['rentDirectId'] = dict?.value
}
if (changes[0][1] === 'rentType') {
const res = rentTypeDict.value.length
? rentTypeDict.value
: await getDictOption('CM_RentType')
if (!rentTypeDict.value.length) rentTypeDict.value = res
const item = res.filter((item) => {
return item.label === changes[0][3]
})
if (item) dict = item[0]
list.value[changes[0][0]]['rentType'] = dict?.label
list.value[changes[0][0]]['rentTypeId'] = dict?.value
}
if (changes[0][1] === 'pickupPort' || changes[0][1] === 'dropoffPort') {
const res = PortDict.value.length
? PortDict.value
: (await GetClientPortSelectList())?.data
if (!PortDict.value.length) PortDict.value = res
const item = res.filter((item) => {
return item.portName === changes[0][3]
})
if (item) dict = item[0]
if (changes[0][1] === 'pickupPort') {
list.value[changes[0][0]]['pickupPort'] = dict?.portName
list.value[changes[0][0]]['pickupPortid'] = dict?.id
list.value[changes[0][0]]['pickupPortCode'] = dict?.ediCode
}
if (changes[0][1] === 'dropoffPort') {
list.value[changes[0][0]]['dropoffPort'] = dict?.portName
list.value[changes[0][0]]['dropoffPortid'] = dict?.id
list.value[changes[0][0]]['dropoffPortCode'] = dict?.ediCode
}
}
}
},
}
function TableAdd() {
list.value.push({ selected: false })
}
function FnClickDel() {
let ApiData: any = { ids: [] }
list.value.forEach((e: any, i) => {
if (e.selected) {
if (e.id) {
ApiData.ids.push(e.id)
} else {
list.value.splice(i, 1)
}
}
})
if (ApiData.ids.length) {
ApiDelDetail(ApiData).then((res) => {
if (res.succeeded) {
refresh()
notification.success({ message: res.message, duration: 3 })
}
})
}
}
//--------------------------------------- tab3 ---------------------------------------
//
const broReceiveData = ref([])
//
const broPayData = ref([])
//
const broReceive = (v) => {
broReceiveData.value = v
}
//
const broPay = (v) => {
broPayData.value = v
}
</script>
<style lang="less" scoped>
.ds-goods-tb-check {
position: absolute;
left: 15px;
}
.SearchBox {
display: flex;
.Form {
flex: 1;
margin-right: 10px;
}
.mt-4 {
margin-left: 10px;
}
}
</style>

@ -0,0 +1,110 @@
// @ts-ignore
import { request } from '/@/utils/request'
import { DataResult, PageRequest } from '/@/api/model/baseModel'
enum Api {
list = '/containerManagementApi/CM_RentOneWay_In/GetCM_RentOneWay_InList',
edit = '/containerManagementApi/CM_RentOneWay_In/EditCM_RentOneWay_In',
info = '/containerManagementApi/CM_RentOneWay_In/GetCM_RentOneWay_In',
del = '/containerManagementApi/CM_RentOneWay_In/DeleteCM_RentOneWay_In',
// listDetail = '/containerManagementApi/CM_RentOneWay_Detail/GetCM_RentOneWay_DetailList',
// editDetail = '/containerManagementApi/CM_RentOneWay_Detail/EditCM_RentOneWay_Detail',
delDetail = '/containerManagementApi/CM_RentOneWay_Detail/DeleteCM_RentOneWay_Detail',
Confirm = '/containerManagementApi/CM_RentOneWay_In/CM_RentOneWay_In_Confirm',
Cancel = '/containerManagementApi/CM_RentOneWay_In/CM_RentOneWay_In_Cancel',
// DetailView = '/containerManagementApi/CM_RentOut/CM_RentOut_NeedRent_View',
// AddCtn = '/containerManagementApi/CM_RentOneWay/CM_RentOneWay_AddCtn',
}
// 列表 (Auth)
export function ApiList(data: PageRequest) {
return request<DataResult>({
url: Api.list,
method: 'post',
data,
})
}
// 编辑 (Auth)
export function ApiEdit(data: PageRequest) {
return request<DataResult>({
url: Api.edit,
method: 'post',
data,
})
}
// 详情 (Auth)
export function ApiInfo(query) {
return request<DataResult>({
url: Api.info,
method: 'get',
params: query,
})
}
// 删除 (Auth)
export function ApiDel(data: PageRequest) {
return request<DataResult>({
url: Api.del,
method: 'post',
data,
})
}
// // 列表详情 (Auth)
// export function ApiListDetail(data: PageRequest) {
// return request<DataResult>({
// url: Api.listDetail,
// method: 'post',
// data,
// })
// }
// // 编辑详情 (Auth)
// export function ApiEditDetail(data: PageRequest) {
// return request<DataResult>({
// url: Api.editDetail,
// method: 'post',
// data,
// })
// }
// 删除详情 (Auth)
export function ApiDelDetail(data: PageRequest) {
return request<DataResult>({
url: Api.delDetail,
method: 'post',
data,
})
}
// _确认 (Auth)
export function ApiConfirm(data: PageRequest) {
return request<DataResult>({
url: Api.Confirm,
method: 'post',
data,
})
}
// _取消 (Auth)
export function ApiCancel(data: PageRequest) {
return request<DataResult>({
url: Api.Cancel,
method: 'post',
data,
})
}
// // 租箱租入明细视图 (Auth)
// export function ApiDetailView(data: PageRequest) {
// return request<DataResult>({
// url: Api.DetailView,
// method: 'post',
// data,
// })
// }
// // 租箱租入退租_添加 (Auth)
// export function ApiAddCtn(data: PageRequest) {
// return request<DataResult>({
// url: Api.AddCtn,
// method: 'post',
// data,
// })
// }

@ -0,0 +1,517 @@
import { ref } from 'vue'
import moment from 'moment'
import { BasicColumn, FormSchema } from '/@/components/Table'
import { Tag } from 'ant-design-vue'
import { GetCtnSelectList, GetClientListByCode } from '/@/api/common'
import { GetDeptList } from '/@/views/operation/seaexport/api/BookingLedger'
import { useOptionsStore } from '/@/store/modules/options'
const optionsStore = useOptionsStore()
// 字典
import { getDictOption } from '/@/utils/dictUtil'
// 业务类型字典
const businessTypeDict = ref([])
getDictOption('CM_BusinessType').then((res) => {
businessTypeDict.value = res
})
// 租箱类型字典
const rentTypeIdDict = ref([])
getDictOption('CM_RentType').then((res) => {
rentTypeIdDict.value = res
})
export const columns: BasicColumn[] = [
{
title: '单程业务号',
dataIndex: 'billno',
sorter: true,
width: 150,
},
{
title: '业务类型',
dataIndex: 'businessType',
sorter: true,
width: 150,
customRender: ({ text }) => {
let RData = '-'
businessTypeDict.value.forEach((item: any) => {
if (text == item.value) {
RData = item.label
}
})
return RData
},
},
{
title: '租箱业务',
dataIndex: 'rentDirect',
sorter: true,
width: 150,
},
{
title: '租箱类型',
dataIndex: 'rentTypeId',
sorter: true,
width: 150,
customRender: ({ text }) => {
let RData = '-'
rentTypeIdDict.value.forEach((item: any) => {
if (text == item.value) {
RData = item.label
}
})
return RData
},
},
{
title: '业务状态',
dataIndex: 'billState',
sorter: true,
width: 200,
},
{
title: '租箱客户',
dataIndex: 'rentCustomerName',
sorter: true,
width: 200,
},
{
title: '业务日期',
dataIndex: 'bsdate',
sorter: true,
width: 200,
},
{
title: '会计期间',
dataIndex: 'accdate',
sorter: true,
width: 200,
},
{
title: '业务锁定',
dataIndex: 'isBusinessLocking',
sorter: true,
width: 200,
customRender: ({ text }) => {
if (text) {
return <Tag color="success"></Tag>
} else {
return <Tag color="error"></Tag>
}
return text
},
},
{
title: '费用锁定',
dataIndex: 'isFeeLocking',
sorter: true,
width: 200,
customRender: ({ text }) => {
if (text) {
return <Tag color="success"></Tag>
} else {
return <Tag color="error"></Tag>
}
return text
},
},
// {
// title: '费用状态??',
// dataIndex: 'accdate',
// sorter: true,
// width: 200,
// },
{
title: '备注',
dataIndex: 'remark',
sorter: true,
width: 200,
},
]
export const searchFormSchema: FormSchema[] = [
{
field: 'billno',
label: '租箱业务号',
component: 'Input',
colProps: { span: 4 },
},
{
field: 'rentCustomerName',
label: '租箱客户',
component: 'ApiSelect',
required: false,
dynamicDisabled: false,
colProps: { span: 4 },
componentProps: ({ formModel }) => {
return {
allowClear: true,
showSearch: true,
api: GetClientListByCode,
params: { code: 'leasing' },
labelField: 'pinYinCode',
showName: 'shortName',
valueField: 'shortName',
resultField: 'data',
immediate: false,
filterOption: (input: string, option: any) => {
return option.label.toLowerCase().indexOf(input.toLowerCase()) >= 0
},
}
},
},
// {
// field: 'rentDirectId',
// label: '租箱业务',
// component: 'ApiSelect',
// colProps: { span: 4 },
// componentProps: ({}) => {
// return {
// api: () => {
// return new Promise((resolve) => {
// getDictOption('CM_RentDirect').then((res) => {
// let data: any = []
// res.forEach((item) => {
// item.value = parseInt(item.value)
// if (!item.label.indexOf('租入')) {
// data.push(item)
// }
// })
// resolve(data)
// })
// })
// },
// labelField: 'label',
// valueField: 'value',
// resultField: 'data',
// filterOption: (input: string, option: any) => {
// return option.label.toLowerCase().indexOf(input.toLowerCase()) >= 0
// },
// }
// },
// },
{
field: 'bsdate',
label: '业务日期',
component: 'DatePicker',
colProps: { span: 4 },
defaultValue: '',
componentProps: {
allowClear: true,
valueFormat: 'YYYY-MM-DD 00:00:00',
style: 'width:100%',
},
},
{
field: 'accdate',
label: '会计期间',
component: 'MonthPicker',
colProps: { span: 4 },
defaultValue: '',
componentProps: {
showTime: true,
allowClear: true,
valueFormat: 'YYYY-MM',
format: 'YYYY-MM',
},
},
// {
// field: 'etd',
// label: 'ETD',
// component: 'DatePicker',
// colProps: { span: 4 },
// defaultValue: '',
// componentProps: {
// showTime: true,
// style: 'width:100%',
// },
// },
// {
// field: 'eta',
// label: 'ETA',
// component: 'DatePicker',
// colProps: { span: 4 },
// defaultValue: '',
// componentProps: {
// showTime: true,
// style: 'width:100%',
// },
// },
]
export const formSchema: FormSchema[] = [
{
label: '',
field: 'id',
component: 'Input',
defaultValue: '',
show: false,
},
{
field: 'businessType',
label: '业务类型',
component: 'ApiSelect',
colProps: { span: 6 },
defaultValue: 103,
dynamicDisabled: ({}) => {
return true
},
componentProps: ({}) => {
return {
api: () => {
return new Promise((resolve) => {
getDictOption('CM_BusinessType').then((res) => {
res.forEach((item) => {
item.value = parseInt(item.value)
})
resolve(res)
})
})
},
labelField: 'label',
valueField: 'value',
resultField: 'data',
filterOption: (input: string, option: any) => {
return option.label.toLowerCase().indexOf(input.toLowerCase()) >= 0
},
}
},
},
// {
// field: 'rentDirectId',
// label: '租箱业务',
// component: 'ApiSelect',
// colProps: { span: 6 },
// defaultValue: 2,
// dynamicDisabled: ({ values }) => {
// return !!values.id
// },
// componentProps: ({ formModel, formActionType }) => {
// return {
// api: () => {
// return new Promise((resolve) => {
// getDictOption('CM_RentDirect').then((res) => {
// let data: any = []
// res.forEach((item) => {
// item.value = parseInt(item.value)
// if (!item.label.indexOf('租出')) {
// data.push(item)
// }
// })
// resolve(data)
// })
// })
// },
// labelField: 'label',
// valueField: 'value',
// resultField: 'data',
// filterOption: (input: string, option: any) => {
// return option.label.toLowerCase().indexOf(input.toLowerCase()) >= 0
// },
// onChange: (e, obj) => {
// formActionType ? formActionType.submit() : null
// if (e && obj) {
// formModel.rentDirect = obj.label
// } else {
// formModel.rentDirect = ''
// }
// },
// }
// },
// },
// {
// field: 'rentTypeId',
// label: '租箱类型',
// component: 'ApiSelect',
// colProps: { span: 6 },
// defaultValue: 1,
// dynamicDisabled: ({ values }) => {
// return !!values.id
// },
// componentProps: ({}) => {
// return {
// api: () => {
// return new Promise((resolve) => {
// getDictOption('CM_RentType').then((res) => {
// res.forEach((item) => {
// item.value = parseInt(item.value)
// })
// resolve(res)
// })
// })
// },
// labelField: 'label',
// valueField: 'value',
// resultField: 'data',
// filterOption: (input: string, option: any) => {
// return option.label.toLowerCase().indexOf(input.toLowerCase()) >= 0
// },
// }
// },
// },
// {
// field: 'billState',
// label: '业务状态',
// component: 'Input',
// colProps: { span: 6 },
// dynamicDisabled: ({}) => {
// return true
// },
// },
{
field: 'rentCustomerId',
label: '租箱客户',
component: 'Input',
colProps: { span: 6 },
show: false,
},
{
field: 'rentCustomerName',
label: '租箱客户',
component: 'ApiSelect',
required: false,
dynamicDisabled: false,
colProps: { span: 6 },
componentProps: ({ formModel }) => {
return {
allowClear: true,
showSearch: true,
api: GetClientListByCode,
params: { code: 'leasing' },
labelField: 'pinYinCode',
showName: 'shortName',
valueField: 'shortName',
resultField: 'data',
immediate: false,
filterOption: (input: string, option: any) => {
return option.label.toLowerCase().indexOf(input.toLowerCase()) >= 0
},
onChange: (e, obj) => {
if (e && obj) {
formModel.rentCustomerId = obj.id
}
if (!e && !obj) {
formModel.rentCustomerId = ''
}
},
}
},
},
{
field: 'bsdate',
label: '业务日期',
component: 'DatePicker',
colProps: { span: 6 },
defaultValue: moment(),
componentProps: {
allowClear: true,
valueFormat: 'YYYY-MM-DD 00:00:00',
style: 'width:100%',
},
},
{
field: 'accdate',
label: '会计期间',
component: 'MonthPicker',
colProps: { span: 6 },
defaultValue: moment(),
componentProps: {
showTime: true,
allowClear: true,
valueFormat: 'YYYY-MM',
format: 'YYYY-MM',
},
},
{
field: 'isBusinessLocking',
label: '业务锁定',
component: 'Switch',
defaultValue: false,
colProps: { span: 6 },
componentProps: {
checkedChildren: '是',
unCheckedChildren: '否',
},
dynamicDisabled: ({}) => {
return true
},
},
{
field: 'isFeeLocking',
label: '费用锁定',
component: 'Switch',
defaultValue: false,
colProps: { span: 6 },
componentProps: {
checkedChildren: '是',
unCheckedChildren: '否',
},
dynamicDisabled: ({}) => {
return true
},
},
{
field: 'remark',
label: '备注',
component: 'Input',
colProps: { span: 24 },
},
]
export const formSearchBoxSchema: FormSchema[] = [
{
field: 'rentCustomerName',
label: '租箱客户',
component: 'ApiSelect',
required: false,
dynamicDisabled: false,
colProps: { span: 6 },
componentProps: ({ formModel }) => {
return {
allowClear: true,
showSearch: true,
api: GetClientListByCode,
params: { code: 'leasing' },
labelField: 'pinYinCode',
showName: 'shortName',
valueField: 'shortName',
resultField: 'data',
immediate: false,
filterOption: (input: string, option: any) => {
return option.label.toLowerCase().indexOf(input.toLowerCase()) >= 0
},
}
},
},
{
field: 'ctnall',
label: '箱型',
component: 'ApiSelect',
required: false,
dynamicDisabled: false,
colProps: { span: 6 },
componentProps: () => {
return {
allowClear: true,
showSearch: true,
api: GetCtnSelectList,
params: { code: 'leasing' },
labelField: 'ctnName',
showName: 'ctnName',
valueField: 'ctnName',
resultField: 'data',
immediate: false,
filterOption: (input: string, option: any) => {
return option.label.toLowerCase().indexOf(input.toLowerCase()) >= 0
},
}
},
},
{
field: 'cntrno',
label: '箱号',
component: 'Input',
colProps: { span: 10 },
},
]

@ -0,0 +1,169 @@
<template>
<div>
<BasicTable class="ds-table" @register="registerTable" @row-dbClick="handleAudit">
<template #tableTitle>
<a-button type="link" @click="handleCreate">
<span class="iconfont icon-tianjia"></span>
新建
</a-button>
<a-popconfirm
title="确定删除当前选中数据?"
ok-text="是"
cancel-text="否"
@confirm="handleDel"
>
<a-button type="link">
<span class="iconfont icon-shanchu21"></span>
删除
</a-button>
</a-popconfirm>
<a-button type="link" @click="Confirm">
<span class="iconfont icon-yiwancheng2"></span>
确认执行
</a-button>
<a-button type="link" @click="Cancel">
<span class="iconfont icon-weiwancheng"></span>
取消确认
</a-button>
</template>
<template #bodyCell="{ column, record }">
<template v-if="column.key === 'action'">
<TableAction
:actions="[
{
icon: 'clarity:note-edit-line',
tooltip: '编辑',
onClick: handleAudit.bind(null, record),
},
]"
/>
</template>
</template>
</BasicTable>
<TenantAuditStepModal @register="registerModal" @success="handleSuccess" />
</div>
</template>
<script lang="ts" setup>
import { ref } from 'vue'
import { BasicTable, useTable, TableAction } from '/@/components/Table'
import { ApiList, ApiDel, ApiConfirm, ApiCancel } from './api'
import { useModal } from '/@/components/Modal'
import TenantAuditStepModal from './TenantAuditStepModal.vue'
import { columns, searchFormSchema } from './columns'
import { useMessage } from '/@/hooks/web/useMessage'
const { notification } = useMessage()
//
import { formatParams } from '/@/hooks/web/common'
const [registerModal, { openModal }] = useModal()
const [registerTable, { reload, getSelectRows }] = useTable({
title: '',
api: async (p) => {
const res: API.DataResult = await ApiList(p)
return new Promise((resolve) => {
resolve({ data: [...res.data], total: res.count })
})
},
beforeFetch: (p) => {
return formatParams(p, ['rentCustomerName', 'bsdate', 'accdate'])
},
columns,
formConfig: {
labelWidth: 120,
schemas: searchFormSchema,
},
isTreeTable: false,
pagination: true,
striped: true,
useSearchForm: true,
showTableSetting: true,
bordered: true,
showIndexColumn: true,
indexColumnProps: {
width: 60,
},
canResize: true,
resizeHeightOffset: 35,
immediate: true,
actionColumn: {
width: 80,
title: '操作',
dataIndex: 'action',
fixed: 'right',
},
})
function handleCreate() {
openModal(true, {
isParent: false,
isUpdate: false,
})
}
function Confirm() {
const select = getSelectRows()
let ApiData: any = {
id: '',
ids: [],
}
if (select.length === 0) {
notification.warning({ message: '请至少选择一条数据', duration: 3 })
return false
} else {
ApiData.ids = select.map((item) => {
return item.id
})
}
ApiConfirm(ApiData).then((res) => {
reload()
notification.success({ message: res.message, duration: 3 })
})
}
function Cancel() {
const select = getSelectRows()
let ApiData: any = {
id: '',
ids: [],
}
if (select.length === 0) {
notification.warning({ message: '请至少选择一条数据', duration: 3 })
return false
} else {
ApiData.ids = select.map((item) => {
return item.id
})
}
ApiCancel(ApiData).then((res) => {
reload()
notification.success({ message: res.message, duration: 3 })
})
}
function handleDel() {
const select = getSelectRows()
let ApiData: any = {
ids: [],
}
if (select.length === 0) {
notification.warning({ message: '请至少选择一条数据', duration: 3 })
return false
} else {
ApiData.ids = select.map((item) => {
return item.id
})
}
ApiDel(ApiData).then((res) => {
console.log(res)
notification.success({ message: res.message, duration: 3 })
reload()
})
}
function handleSuccess() {
reload()
}
function handleAudit(record) {
openModal(true, {
record,
isUpdate: true,
})
}
</script>

@ -393,10 +393,8 @@
fileId: dsFile.value.dsFileList.SelectId,
}
ApiDealExcel(ApiData).then((res) => {
list.value.splice(0)
res.data.forEach((item) => {
list.value.push(item)
})
refresh()
notification.success({ message: res.message, duration: 3 })
})
} else {
notification.warning({ message: '请先在电子文档中勾选一个文件。', duration: 3 })

@ -373,10 +373,8 @@
fileId: dsFile.value.dsFileList.SelectId,
}
ApiDealExcel(ApiData).then((res) => {
list.value.splice(0)
res.data.forEach((item) => {
list.value.push(item)
})
refresh()
notification.success({ message: res.message, duration: 3 })
})
} else {
notification.warning({ message: '请先在电子文档中勾选一个文件。', duration: 3 })

@ -93,7 +93,7 @@
const { notification } = useMessage()
// Emits
const emit = defineEmits(['success', 'register'])
const select = ref([])
const isUpdate = ref(true)
const loading = ref(false)
const rowId = ref()
const { createMessage } = useMessage()
@ -106,14 +106,23 @@
const [registerModal, { setModalProps, closeModal }] = useModalInner(async (data) => {
resetFields()
setModalProps({ confirmLoading: false, loading: true })
select.value = data.select
if (select.value.length) {
console.log(select.value)
let cntrno = ''
select.value.forEach((item: any) => {
cntrno = cntrno ? `${cntrno},${item.cntrno}` : item.cntrno
})
setFieldsValue({ cntrno })
isUpdate.value = !!data?.isUpdate
list.value.splice(0)
if (unref(isUpdate)) {
rowId.value = data.record.id
const res: any = await ApiInfo({ id: unref(rowId) })
if (res.succeeded) {
setFieldsValue({
...res.data,
})
allCheck.value = false
someCheck.value = false
res.data.bodyList.forEach((item) => {
list.value.push({ ...item, selected: false })
})
}
} else {
setFieldsValue({ permissionIdentity: unref(2) })
}
setModalProps({ loading: false })
})
@ -123,15 +132,19 @@
const values = await validate()
setModalProps({ confirmLoading: true, loading: true })
values.bodyList = list.value
const res: API.DataResult = await ApiEdit(values)
const res: any = await ApiEdit(values)
if (res.succeeded) {
createMessage.success(res.message)
emit('success')
//
if (!exit) {
rowId.value = res.data
select.value = []
await refresh()
if (unref(isUpdate)) {
await refresh()
} else {
rowId.value = res.data
isUpdate.value = true
await refresh()
}
}
} else {
createMessage.error(res.message)
@ -144,11 +157,17 @@
}
}
async function refresh() {
const res: API.DataResult = await ApiInfo({ id: unref(rowId) })
list.value.splice(0)
const res: any = await ApiInfo({ id: unref(rowId) })
if (res.succeeded) {
await setFieldsValue({
setFieldsValue({
...res.data,
})
allCheck.value = false
someCheck.value = false
res.data.bodyList.forEach((item) => {
list.value.push({ ...item, selected: false })
})
}
}
// ------------------------
@ -292,7 +311,7 @@
},
}
function TableAdd() {
list.value.push({ selected: false })
list.value.push({ pid: rowId.value ? rowId.value : '', selected: false })
}
function FnClickDel() {
let ApiData: any = { ids: [] }

@ -1,6 +1,6 @@
<template>
<div>
<BasicTable class="ds-table" @register="registerTable">
<BasicTable class="ds-table" @register="registerTable" @row-dbClick="handleAudit">
<template #tableTitle>
<a-button type="link" @click="handleCreate">
<span class="iconfont icon-tianjia"></span>
@ -18,6 +18,19 @@
</a-button>
</a-popconfirm>
</template>
<template #bodyCell="{ column, record }">
<template v-if="column.key === 'action'">
<TableAction
:actions="[
{
icon: 'clarity:note-edit-line',
tooltip: '编辑',
onClick: handleAudit.bind(null, record),
},
]"
/>
</template>
</template>
</BasicTable>
<TenantAuditStepModal @register="registerModal" @success="handleSuccess" />
</div>
@ -36,7 +49,7 @@
const [registerTable, { reload, getForm, getSelectRows }] = useTable({
title: '批量变动导入_模板管理',
api: async (p) => {
const res: API.DataResult = await ApiList(p)
const res: any = await ApiList(p)
return new Promise((resolve) => {
resolve({ data: [...res.data], total: res.count })
})
@ -62,6 +75,12 @@
canResize: true,
resizeHeightOffset: 35,
immediate: true,
actionColumn: {
width: 80,
title: '操作',
dataIndex: 'action',
fixed: 'right',
},
})
function handleCreate() {
const select = getSelectRows()
@ -90,6 +109,12 @@
reload()
})
}
function handleAudit(record) {
openModal(true, {
record,
isUpdate: true,
})
}
function handleSuccess() {
reload()
}

@ -0,0 +1,444 @@
<template>
<BasicModal
v-bind="$attrs"
:use-wrapper="true"
title="批量变动导入"
width="55%"
@register="registerModal"
@ok="handleSave"
>
<BasicForm @register="registerForm" />
<a-tabs v-model:activeKey="activeKey">
<a-tab-pane key="1" tab="预识别明细">
<div class="HotTable">
<div>
<!-- <a-button type="link" @click="TableAdd" class="pl0">
<span class="iconfont icon-new_document"></span>
新增
</a-button> -->
<a-popconfirm
title="确定要删除所选数据?"
ok-text="确定"
cancel-text="取消"
@confirm="FnClickDel"
>
<a-button type="link" class="pl0">
<span class="iconfont icon-shanchu21"></span>
删除
</a-button>
</a-popconfirm>
<!-- <a-button type="link" @click="handleSave(false)" class="pl0">
<span class="iconfont icon-baocun" v-repeat></span>
保存
</a-button> -->
</div>
<div style="position: relative">
<input
class="ds-tb-check ds-goods-tb-check"
type="checkbox"
v-model="allCheck"
:indeterminate="someCheck"
v-if="list.length !== 0"
/>
<hot-table ref="hotTb" :data="list" :settings="settings">
<img
v-show="!list.length"
class="hot-tb-no-data"
src="../../../assets/images/nodata.png"
alt=""
/>
</hot-table>
</div>
</div>
</a-tab-pane>
<a-tab-pane key="2" tab="电子文档" :disabled="!rowId">
<DsFile
ref="dsFile"
fileType="infoclient"
:id="rowId"
:SetSelect="{
show: true,
}"
/>
</a-tab-pane>
</a-tabs>
<!--右下角按钮-->
<template #footer>
<a-button
pre-icon="ant-design:check-circle-outlined"
type="primary"
:loading="loading"
@click="Confirm()"
>
确认执行
</a-button>
<a-button
pre-icon="ant-design:file-excel-outlined"
type="primary"
:loading="loading"
@click="DealExcel()"
>
识别excel
</a-button>
<a-button
pre-icon="ant-design:close-outlined"
type="warning"
:loading="loading"
ghost
style="margin-right: 0.8rem"
@click="closeModal"
>取消</a-button
>
<a-button
type="success"
:loading="loading"
pre-icon="ant-design:check-outlined"
style="margin-right: 0.8rem"
@click="handleSave(false)"
>仅保存</a-button
>
<a-button
pre-icon="ant-design:check-circle-outlined"
type="primary"
:loading="loading"
@click="handleSave(true)"
>保存并关闭</a-button
>
</template>
</BasicModal>
</template>
<script lang="ts" setup>
import { ref, watchEffect, watch, unref } from 'vue'
import { BasicModal, useModalInner } from '/@/components/Modal'
import { BasicForm, useForm } from '/@/components/Form/index'
import { formSchema, InfoColumns } from './columns'
import { ApiEdit, ApiInfo, ApiDelDetail, ApiImport } from './api'
import { ApiDealExcel } from '/@/views/ContainerManagement/RentIn/api'
//
import { getDictOption } from '/@/utils/dictUtil'
import { HotTable } from '@handsontable/vue3'
import { registerAllModules } from 'handsontable/registry'
registerAllModules()
import 'handsontable/dist/handsontable.full.css'
import { useMessage } from '/@/hooks/web/useMessage'
const { notification } = useMessage()
import DsFile from '/@/components/File/index.vue'
// Emits
const emit = defineEmits(['success', 'register'])
const isUpdate = ref(true)
const loading = ref(false)
const rowId = ref()
const activeKey = ref('1')
const { createMessage } = useMessage()
const [registerForm, { resetFields, setFieldsValue, validate }] = useForm({
labelWidth: 100,
schemas: formSchema,
showActionButtonGroup: false,
})
const [registerModal, { setModalProps, closeModal }] = useModalInner(async (data) => {
resetFields()
setModalProps({ confirmLoading: false, loading: true })
isUpdate.value = !!data?.isUpdate
activeKey.value = '1'
list.value.splice(0)
if (unref(isUpdate)) {
rowId.value = data.record.id
const res: any = await ApiInfo({ id: unref(rowId) })
if (res.succeeded) {
setFieldsValue({
...res.data,
})
allCheck.value = false
someCheck.value = false
res.data.bodyList.forEach((item) => {
list.value.push({ ...item, selected: false })
})
}
} else {
setFieldsValue({ permissionIdentity: unref(2) })
}
setModalProps({ loading: false })
})
async function handleSave(exit) {
try {
const values = await validate()
setModalProps({ confirmLoading: true, loading: true })
const res: any = await ApiEdit(values)
if (res.succeeded) {
createMessage.success(res.message)
emit('success')
//
if (!exit) {
if (unref(isUpdate)) {
await refresh()
} else {
rowId.value = res.data
isUpdate.value = true
await refresh()
}
}
} else {
createMessage.error(res.message)
}
exit && closeModal()
} finally {
// loading.value = false;
setModalProps({ confirmLoading: false, loading: false })
}
}
async function refresh() {
list.value.splice(0)
const res: any = await ApiInfo({ id: unref(rowId) })
if (res.succeeded) {
setFieldsValue({
...res.data,
})
allCheck.value = false
someCheck.value = false
res.data.bodyList.forEach((item) => {
list.value.push({ ...item, selected: false })
})
}
}
const dsFile = ref()
function DealExcel() {
if (rowId.value) {
if (dsFile.value.dsFileList.SelectId) {
let ApiData: any = {
id: unref(rowId),
formName: 'CM_State_Change_TemplatImport',
tableName: '',
fileId: dsFile.value.dsFileList.SelectId,
}
ApiDealExcel(ApiData).then((res) => {
if (res.succeeded) {
refresh()
notification.success({ message: res.message, duration: 3 })
}
})
} else {
notification.warning({ message: '请先在电子文档中勾选一个文件。', duration: 3 })
}
} else {
notification.warning({ message: '请先保存', duration: 3 })
}
}
async function Confirm() {
await handleSave(false)
let type: boolean = true
let ApiData: any = {
id: rowId.value,
ids: [],
}
list.value.forEach((e: any, i) => {
if (e.selected) {
if (e.id) {
ApiData.ids.push(e.id)
} else {
type = false
}
}
})
if (type) {
ApiImport(ApiData).then((res) => {
notification.success({ message: res.message, duration: 3 })
emit('success')
})
} else {
notification.success({ message: '请先保存明细表', duration: 3 })
}
}
// ------------------------
const list = ref<any>([])
//
const allCheck = ref(false)
//
const someCheck = ref(false)
const hotTb = ref()
watchEffect(() => {
//
if (allCheck.value) {
list.value.forEach((item: any) => {
item.selected = true
})
} else {
//
list.value.forEach((item: any) => {
item.selected = false
})
}
})
watch(
list.value,
(val) => {
let a = 0
let b = 0
val.forEach((item: any) => {
if (item.selected) {
a += 1
} else {
b += 1
}
})
if (a == 0) {
allCheck.value = false
}
if (b == 0) {
allCheck.value = true
}
if (a != 0 && b != 0) {
someCheck.value = true
} else {
someCheck.value = false
}
},
{
deep: true,
},
)
const columns = [
{
data: 'selected',
type: 'checkbox',
title: ' ',
width: 32,
className: 'htCenter',
readOnly: false,
},
{
title: '主键Id',
width: 200,
data: 'id',
},
{
title: '箱号',
width: 120,
data: 'cntrno',
},
{
title: '变动来源',
width: 200,
data: 'changeSource',
},
{
title: '业务类型',
width: 120,
data: 'ctnBizState',
},
{
title: '箱来源',
width: 120,
data: 'ctnSource',
},
{
title: '状态变动',
width: 120,
data: 'ctnFlowState',
},
{
title: '新旧箱',
width: 120,
data: 'usedState',
},
{
title: '箱型',
width: 120,
data: 'ctnall',
},
{
title: '箱状态',
width: 120,
data: 'ctnState',
},
{
title: '空重箱',
width: 120,
data: 'isHeavy',
},
{
title: '当前港口',
width: 120,
data: 'port',
},
{
title: 'DEPOT/TEIMINAL',
width: 120,
data: 'depot',
},
{
title: 'DATE',
width: 120,
data: 'changeTime',
},
]
const settings = {
height: '260',
readOnly: true,
autoWrapRow: true,
autoWrapCol: true,
//
rowHeights: 26,
fixedColumnsLeft: 1,
//
hiddenColumns: {
columns: [1, 2],
indicators: true,
},
//
enterMoves: 'row',
columnSorting: true,
//
afterValidate: function (isValid, value, row, prop, source) {
if (!isValid) {
hotTb.value.hotInstance.setDataAtRowProp(row, prop, '')
}
},
columns: columns,
// ()
licenseKey: 'non-commercial-and-evaluation',
//
async afterChange(changes, source) {
if (source === 'edit' || source === 'Autofill.fill' || source === 'CopyPaste.paste') {
let dict: any = {}
if (changes[0][1] === 'fieldName') {
const res = await getDictOption('CM_StateChange_Field')
const item = res.filter((item) => {
return item.name === changes[0][3]
})
if (item) dict = item[0]
list.value[changes[0][0]]['fieldName'] = dict?.name
list.value[changes[0][0]]['fieldTitle'] = dict?.value
}
}
},
}
// function TableAdd() {
// list.value.push({ pid: rowId.value ? rowId.value : '', selected: false })
// }
function FnClickDel() {
let ApiData: any = { ids: [] }
list.value.forEach((e: any, i) => {
if (e.selected) {
if (e.id) {
ApiData.ids.push(e.id)
} else {
list.value.splice(i, 1)
}
}
})
if (ApiData.ids.length) {
ApiDelDetail(ApiData).then((res) => {
if (res.succeeded) {
refresh()
notification.success({ message: res.message, duration: 3 })
}
})
}
}
</script>

@ -0,0 +1,60 @@
// @ts-ignore
import { request } from '/@/utils/request'
import { DataResult, PageRequest } from '/@/api/model/baseModel'
enum Api {
list = '/containerManagementApi/CM_State_Change_TemplatImport/GetCM_State_Change_TemplatImportList',
edit = '/containerManagementApi/CM_State_Change_TemplatImport/EditCM_State_Change_TemplatImport',
info = '/containerManagementApi/CM_State_Change_TemplatImport/Get_State_Change_TemplatImport',
del = '/containerManagementApi/CM_State_Change_TemplatImport/DeleteCM_State_Change_TemplatImport',
delDetail = '/containerManagementApi/CM_State_Change_TemplatImport/DeleteCM_State_Change_Temp',
import = '/containerManagementApi/CM_State_Change_TemplatImport/CM_State_Change_TemplatImport_Confirm',
}
// 列表 (Auth)
export function ApiList(data: PageRequest) {
return request<DataResult>({
url: Api.list,
method: 'post',
data,
})
}
// 编辑 (Auth)
export function ApiEdit(data: PageRequest) {
return request<DataResult>({
url: Api.edit,
method: 'post',
data,
})
}
// 详情 (Auth)
export function ApiInfo(query) {
return request<DataResult>({
url: Api.info,
method: 'get',
params: query,
})
}
// 批量删除 (Auth)
export function ApiDel(data: PageRequest) {
return request<DataResult>({
url: Api.del,
method: 'post',
data,
})
}
// 删除明细 (Auth)
export function ApiDelDetail(data: PageRequest) {
return request<DataResult>({
url: Api.delDetail,
method: 'post',
data,
})
}
// 确认引入 (Auth)
export function ApiImport(data: PageRequest) {
return request<DataResult>({
url: Api.import,
method: 'post',
data,
})
}

@ -0,0 +1,246 @@
import { BasicColumn, FormSchema } from '/@/components/Table'
import { Tag } from 'ant-design-vue'
import { ApiList } from '../Templat/api'
export const columns: BasicColumn[] = [
{
title: '模板名称',
dataIndex: 'templetName',
sorter: true,
width: 150,
},
{
title: '导入人',
dataIndex: 'createUserName',
sorter: true,
width: 200,
},
{
title: '导入时间',
dataIndex: 'createTime',
sorter: true,
width: 200,
},
{
title: '是否已执行',
dataIndex: 'billState',
sorter: true,
width: 200,
},
{
title: '备注',
dataIndex: 'remark',
sorter: true,
width: 200,
},
]
export const searchFormSchema: FormSchema[] = [
{
field: 'templetName',
label: '模板名称',
component: 'Input',
colProps: { span: 4 },
},
{
field: 'remark',
label: '备注',
component: 'Input',
colProps: { span: 4 },
},
]
export const formSchema: FormSchema[] = [
{
label: '',
field: 'id',
component: 'Input',
defaultValue: '',
show: false,
},
{
label: '模板Id',
field: 'templetId',
component: 'Input',
show: false,
},
{
label: '模板名称',
field: 'templetName',
component: 'ApiSelect',
required: false,
dynamicDisabled: false,
colProps: { span: 6 },
componentProps: ({ formModel }) => {
return {
api: () => {
return new Promise((resolve) => {
ApiList({
queryCondition: '[]',
pageCondition: { pageIndex: 1, pageSize: 100, sortConditions: [] },
}).then((res) => {
resolve(res)
})
})
},
labelField: 'templetName',
valueField: 'templetName',
resultField: 'data',
onChange: (e, obj) => {
console.log(e, obj)
if (e && obj) {
formModel.templetName = obj.label
formModel.templetId = obj.value
}
if (!e && !obj) {
formModel.templetName = null
formModel.templetId = null
}
},
filterOption: (input: string, option: any) => {
return option.label.toLowerCase().indexOf(input.toLowerCase()) >= 0
},
}
},
},
{
label: '导入人',
field: 'createUserName',
component: 'Input',
defaultValue: '',
dynamicDisabled: true,
},
// {
// label: '导入人',
// field: 'createUser',
// component: 'ApiSelect',
// required: false,
// dynamicDisabled: false,
// colProps: { span: 6 },
// componentProps: ({ formModel }) => {
// return {
// allowClear: true,
// showSearch: true,
// api: GetClientListByCode,
// params: { code: 'leasing' },
// labelField: 'pinYinCode',
// showName: 'shortName',
// valueField: 'shortName',
// resultField: 'data',
// immediate: false,
// filterOption: (input: string, option: any) => {
// return option.label.toLowerCase().indexOf(input.toLowerCase()) >= 0
// },
// }
// },
// },
{
label: '导入时间',
field: 'createTime',
component: 'DatePicker',
colProps: { span: 6 },
componentProps: {
showTime: false,
style: 'width:100%',
valueFormat: 'YYYY-MM-DD 00:00:00',
},
},
{
label: '是否已执行',
field: 'billState',
component: 'Input',
defaultValue: '',
colProps: { span: 6 },
dynamicDisabled: true,
},
{
field: 'remark',
label: '备注',
component: 'InputTextArea',
// required: true,
colProps: { span: 12 },
componentProps: {
rows: 3,
},
},
]
export const InfoColumns: BasicColumn[] = [
{
title: '箱号',
dataIndex: 'cntrno',
sorter: true,
width: 150,
},
{
title: '变动来源',
dataIndex: 'changeSource',
sorter: true,
width: 150,
},
{
title: '业务类型',
dataIndex: 'ctnBizState',
sorter: true,
width: 150,
},
{
title: '箱来源',
dataIndex: 'ctnSource',
sorter: true,
width: 150,
},
{
title: '状态变动',
dataIndex: 'ctnFlowState',
sorter: true,
width: 150,
},
{
title: '新旧箱',
dataIndex: 'usedState',
sorter: true,
width: 150,
},
{
title: '箱型',
dataIndex: 'ctnall',
sorter: true,
width: 150,
},
{
title: '箱状态',
dataIndex: 'ctnState',
sorter: true,
width: 150,
},
{
title: '空重箱',
dataIndex: 'isHeavy',
sorter: true,
width: 80,
customRender: ({ text }) => {
if (text) {
return <Tag color="success"></Tag>
} else {
return <Tag color="error"></Tag>
}
return text
},
},
{
title: '当前港口',
dataIndex: 'port',
sorter: true,
width: 150,
},
{
title: 'DEPOT/TEIMINAL',
dataIndex: 'depot',
sorter: true,
width: 150,
},
{
title: 'DATE',
dataIndex: 'changeTime',
sorter: true,
width: 150,
},
]

@ -0,0 +1,121 @@
<template>
<div>
<BasicTable class="ds-table" @register="registerTable" @row-dbClick="handleAudit">
<template #tableTitle>
<a-button type="link" @click="handleCreate">
<span class="iconfont icon-tianjia"></span>
新建
</a-button>
<a-popconfirm
title="确定删除当前选中数据?"
ok-text="是"
cancel-text="否"
@confirm="handleDel"
>
<a-button type="link">
<span class="iconfont icon-shanchu21"></span>
删除
</a-button>
</a-popconfirm>
</template>
<template #bodyCell="{ column, record }">
<template v-if="column.key === 'action'">
<TableAction
:actions="[
{
icon: 'clarity:note-edit-line',
tooltip: '编辑',
onClick: handleAudit.bind(null, record),
},
]"
/>
</template>
</template>
</BasicTable>
<TenantAuditStepModal @register="registerModal" @success="handleSuccess" />
</div>
</template>
<script lang="ts" setup>
import { ref } from 'vue'
import { BasicTable, useTable, TableAction, SorterResult } from '/@/components/Table'
import { ApiList, ApiDel } from './api'
import { useModal } from '/@/components/Modal'
import TenantAuditStepModal from './TenantAuditStepModal.vue'
import { columns, searchFormSchema } from './columns'
import { formatParams } from '/@/hooks/web/common'
import { useMessage } from '/@/hooks/web/useMessage'
const { notification } = useMessage()
const [registerModal, { openModal }] = useModal()
const [registerTable, { reload, getForm, getSelectRows }] = useTable({
title: '批量变动导入',
api: async (p) => {
const res: any = await ApiList(p)
return new Promise((resolve) => {
resolve({ data: [...res.data], total: res.count })
})
},
beforeFetch: (p) => {
return formatParams(p)
},
columns,
formConfig: {
labelWidth: 120,
schemas: searchFormSchema,
},
isTreeTable: false,
pagination: true,
striped: true,
useSearchForm: true,
showTableSetting: true,
bordered: true,
showIndexColumn: true,
indexColumnProps: {
width: 60,
},
canResize: true,
resizeHeightOffset: 35,
immediate: true,
actionColumn: {
width: 80,
title: '操作',
dataIndex: 'action',
fixed: 'right',
},
})
function handleCreate() {
const select = getSelectRows()
openModal(true, {
isParent: false,
isUpdate: false,
select,
})
}
function handleDel() {
const select = getSelectRows()
let ApiData: any = {
ids: [],
}
if (select.length === 0) {
notification.warning({ message: '请至少选择一条数据', duration: 3 })
return false
} else {
ApiData.ids = select.map((item) => {
return item.id
})
}
ApiDel(ApiData).then((res) => {
notification.success({ message: res.message, duration: 3 })
reload()
})
}
function handleAudit(record) {
openModal(true, {
record,
isUpdate: true,
})
}
function handleSuccess() {
reload()
}
</script>

@ -92,7 +92,7 @@
condition.push({
FieldName: 'SequenceId',
FieldValue: unref(pid),
ConditionalType: 1,
ConditionalType: 0,
})
postParam.queryCondition = JSON.stringify(condition)
// console.log(postParam)

Loading…
Cancel
Save