lijingjia 4 months ago
commit cdf009afa5

@ -118,13 +118,7 @@ export function ImportSlotFromFile(parameter) {
})
}
export function CreateBooking0rder(parameter) {
return request<DataResult>({
url: '/opApi/BookingSlotService/CreateBookingOrder',
method: 'post',
data: parameter
})
}
export function ValidateCreateBookingOrder(parameter) {
return request<DataResult>({

@ -231,6 +231,7 @@ export const searchFormSchema: FormSchema[] = [
api: GetCtnSelectList,
labelField: 'ctnName',
mode:"multiple",
immediate: false,
valueField: 'ediCode',
resultField: 'data'
}
@ -246,6 +247,7 @@ export const searchFormSchema: FormSchema[] = [
api: BookingLabelList,
labelField: 'name',
mode:"multiple",
immediate: false,
valueField: 'id',
resultField: 'data',
filterOption: (input: string, option: any) => {

@ -1,5 +1,5 @@
<template>
<BasicModal width="1200px" v-bind="$attrs" :use-wrapper="true" title="马士基订舱" @register="registerModal">
<BasicModal width="1300px" v-bind="$attrs" :use-wrapper="true" title="马士基订舱" @register="registerModal">
<a-spin :spinning="formLoading">
<div class="main">
<a-form :rules="rules" ref="mskform" :model="form" :label-col="labelCol" :wrapper-col="wrapperCol">

@ -4,9 +4,9 @@ import { DataResult, PageRequest } from '/@/api/model/baseModel'
// 获取舱位生成时的箱型箱量
export function getAvailableCtnsBySlot(parameter) {
return request<DataResult>({
url: '/opApi/BookingSlotService/GetAvailableSlots',
method: 'post',
data: parameter
url: '/opApi/BookingSlotService/GetAvailableCtnsBySlot',
method: 'get',
params: parameter
})
}
// 获取客户详情的联系人等信息
@ -16,4 +16,12 @@ export function GetClientInfoWithContact(parameter) {
method: 'post',
data: parameter
})
}
export function CreateBookingOrder(parameter) {
return request<DataResult>({
url: '/opApi/BookingSlotService/CreateBookingOrder',
method: 'post',
data: parameter
})
}

@ -1,28 +1,47 @@
<template>
<BasicModal width="800px" v-bind="$attrs" :use-wrapper="true" title="生成方式选择" @register="registerModal" @ok="handleSave">
<BasicModal width="800px" v-bind="$attrs" :use-wrapper="true" title="生成方式选择" @register="registerModal"
@ok="handleSave">
<BasicForm @register="registerForm">
<template #slotNo="{ model, field }">
<span>{{ model[field] }}</span>
</template>
<template #customerContactList="{ model, field }">
<span v-for="item in model.customerContactList" :key="item.id" style="margin-right: 10px;" >
<span v-for="item in model.customerContactList" :key="item.id" style="margin-right: 10px;">
{{ item.shortName }}{{ item.email }}
</span>
</template>
</BasicForm>
<div class="ctn-box">
<div>选择箱型</div>
<div class="list">
<div class="item" v-for="item in CtnList" :key="item.gid">
<a-input-number style="width: 100%;" :max="item.maxnum" v-model:value="item.ctnNum" :min="0">
<template #prefix>
{{ item.ctnAll }}:
</template>
</a-input-number>
</div>
</div>
<div style="line-height: 20px">
<span style="color:rgb(114, 184, 9);">已选箱型{{ boxTotal }}</span>
</div>
<div style="line-height: 20px">
剩余箱型{{ boxRemaining }}
</div>
</div>
<template #footer>
<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>
@click="handleSave()">保存</a-button>
</template>
</BasicModal>
</template>
<script lang="ts" setup>
import { ref, defineExpose } from 'vue'
import { ref, watch } from 'vue'
import { BasicModal, useModalInner } from '/@/components/Modal'
import { BasicForm, useForm } from '/@/components/Form/index'
import { getAvailableCtnsBySlot } from './api'
import { getAvailableCtnsBySlot, CreateBookingOrder } from './api'
import { formSchema } from './columns'
import { useMessage } from '/@/hooks/web/useMessage'
const { createMessage } = useMessage()
@ -31,27 +50,58 @@ const [registerForm, { resetFields, setFieldsValue, getFieldsValue }] = useForm(
schemas: formSchema,
showActionButtonGroup: false,
})
const [registerModal, { setModalProps,closeModal }] = useModalInner((data) => {
console.log(data)
if(data.type==='init'){
const [registerModal, { setModalProps, closeModal }] = useModalInner((data) => {
if (data.type === 'init') {
setFieldsValue(data.row)
init(data.row)
}
}
})
const type = ref('')
const CtnList = ref([])
const ctnListCopy = ref([])
const slotEdit = ref({})
const CtnList = ref([]) as any
const ctnListCopy = ref([]) as any
const slotEdit = ref({}) as any
const loading = ref(false)
const boxTotal = ref('')
const boxRemaining = ref('')
watch(CtnList, (nval, Old) => {
if (nval && nval.length > 0) {
let str = ''
let str1 = ''
nval.forEach(item => {
if (item.ctnNum > 0) {
str += item.ctnAll + '*' + ' ' + item.ctnNum + ' '
}
})
ctnListCopy.value.forEach(ite => {
nval.forEach(item => {
if (item.ctnAll === ite.ctnAll) {
if (item.ctnNum < ite.ctnNum) {
const num = ite.ctnNum - item.ctnNum
str1 += item.ctnAll + '*' + ' ' + num + ' '
}
}
})
})
boxTotal.value = str
boxRemaining.value = str1
} else {
boxTotal.value = ''
boxRemaining.value = ''
}
}, { deep: true })
function init(row) {
type.value = 'cabin'
setModalProps({ loading: true })
getAvailableCtnsBySlot({ slotId: row.id }).then(res => {
if (res.successed) {
if (res.succeeded) {
slotEdit.value = row
if (res.data.length > 0) {
res.data.forEach(item => {
item.maxnum = item.ctnnum
item.maxnum = item.ctnNum
})
CtnList.value = res.data
ctnListCopy.value = JSON.parse(JSON.stringify(res.data))
@ -66,6 +116,91 @@ function init(row) {
})
}
function handleSave() {
if (type.value === 'cabin') {
handleSaveCabin()
}
}
function handleSaveCabin() {
const projectList = []
// this.bookingServiceItem.forEach(item => {
// if (item.isYield) {
// projectList.push(item.serviceProjectCode)
// }
// })
if (CtnList.value.length > 0) {
const arr = [] as any
CtnList.value.forEach(item => {
if (item.ctnNum > 0) {
arr.push(1)
}
})
if (arr.length === 0) {
createMessage.error('至少选择1个箱子')
return false
}
} else {
createMessage.error('至少选择1个箱子')
return false
}
const ApiData = {
slotId: slotEdit.value.id,
projectList,
...getFieldsValue()
}
setModalProps({ loading: true })
CreateBookingOrder(ApiData).then(res => {
if (res.successed) {
closeModal()
createMessage.success(res.message)
} else {
createMessage.error(res.message)
}
setModalProps({ loading: false })
})
}
</script>
<style lang="less" scoped>
.list {
display: flex;
flex-wrap: wrap;
/deep/ .ant-input-number-input {
background-color: rgb(255, 255, 255);
;
}
/deep/ .ant-input-number-affix-wrapper {
background-color: rgb(255, 255, 255);
;
}
/deep/ .ant-input-number-input {
text-align: center;
}
.item {
margin-right: 20px;
margin-bottom: 10px;
width: 15%;
.item-left {
background: #f59a23;
color: white;
text-align: center;
height: 24px;
line-height: 24px;
display: inline-block;
padding: 0 5px;
font-size: 12px;
}
}
}
</script>
.ctn-box {
background-color: #F5F9FC;
border-radius: 2px;
padding: 10px 20px 15px;
margin-top: 15px;
}
</style>

@ -0,0 +1,45 @@
<template>
<div>
<div class="pdf-header">
<a-tabs style="width:150px" v-model:activeKey="fileCategory" @change="ChangeFileRadio">
<a-tab-pane key="BC" tab="BC文件"></a-tab-pane>
<a-tab-pane key="BC_NOTICE" tab="BC更改文件" ></a-tab-pane>
</a-tabs>
<span style="margin:0 20px;font-size: 16px;font-weight: bold;color: black">{{ pdfName }}</span>
<a-button type="link" @click="handleDownPdf">
<i class="iconfont icon-xiazai1" ></i>
下载pdf文件</a-button>
</div>
<iframe name="custom-iframe-name" width="100%" height="690" frameborder="0" scrolling="auto"
src="http://47.104.85.216:12310/WDFCGBF29932286F.pdf"></iframe>
</div>
</template>
<script lang="ts" setup>
import { ref, defineExpose } from 'vue'
const emit = defineEmits(['handleSuccess', 'handleSuccessCopy'])
const fileCategory = ref('BC')
const pdfName = ref('1131231312231asdasdad.pdf')
const pdfUrl = ref('')
function ChangeFileRadio() {
}
function handleDownPdf() {
}
function init() {
console.log(123)
// pdfUrl.value = '../DB_aabhcbhjagaf0x023A_MODIFY.pdf'
}
defineExpose({ init })
</script>
<style lang="less" scoped>
.pdf-header {
display: flex;
align-items: center;
background: rgba(245, 249, 252, 1);
padding-left: 40px;
}
/deep/ .ant-tabs-nav{
margin-bottom: 0px !important;
}
</style>

@ -1,6 +1,441 @@
<template>
123
<a-spin :spinning="spinning">
<a-row style="padding: 15px;" :gutter="16">
<a-col :span="pdfUrl ? 11 : 24">
<a-form :label-col="labelCol" :wrapper-col="wrapperCol" :model="form">
<div class="box">
<div class="LeftHead">
<p class="title">
Booking Confirmation{{ form.carrierId }}
<i @click="reload" class="icon-refresh-1-copy iconfont"></i>
</p>
<p>订舱时间{{ form.bookingConfirmDate }}</p>
</div>
<a-row>
<a-col :span="8">
<a-form-item label="">
<div>提单号</div>
<span class="text"> {{ form.mblNo }}</span>
<a-icon @click="copyText(form.mblNo)" style="cursor: pointer;" type="copy" />
</a-form-item>
</a-col>
<a-col :span="8">
<a-form-item label="">
<div>船名/航次</div>
<span class="text"> {{ form.vessel }}/{{ form.voyNo }}</span>
</a-form-item>
</a-col>
<a-col :span="8">
<a-form-item label="">
<div>收货地</div>
<span class="text"> {{ form.placeReceipt }}</span>
</a-form-item>
</a-col>
<a-col :span="8">
<a-form-item label="">
<div>ETD</div>
<span class="text"> {{ form.etd ? form.etd.substring(0, 11) : '-' }}</span>
</a-form-item>
</a-col>
<a-col :span="8">
<a-form-item label="">
<div>交货地</div>
<span class="text"> {{ form.placeDelivery }}</span>
</a-form-item>
</a-col>
<a-col :span="8">
<a-form-item label="">
<div>ETA</div>
<span class="text"> {{ form.eta ? form.eta.substring(0, 11) : '-' }}</span>
</a-form-item>
</a-col>
<a-col :span="8">
<a-form-item label="">
<div>订舱人</div>
<span class="text"> {{ form.bookingParty }}</span>
</a-form-item>
</a-col>
<a-col :span="8">
<a-form-item label="">
<div>合约号</div>
<span class="text"> {{ form.contractNo }}</span>
</a-form-item>
</a-col>
<a-col :span="8">
<a-form-item label="">
<div>样单截止时间</div>
<span class="text"> {{ form.siCutDate }}</span>
</a-form-item>
</a-col>
<a-col :span="8">
<a-form-item label="">
<div>箱使天数</div>
<span class="text"> {{ form.detensionFreeDays }}</span>
</a-form-item>
</a-col>
<a-col :span="8">
<a-form-item label="">
<div>舱单截止时间</div>
<span class="text"> {{ form.manifestCutDate }}</span>
</a-form-item>
</a-col>
<a-col :span="8">
<a-form-item label="">
<div>截港时间</div>
<span class="text"> {{ form.cyCutoffTime }}</span>
</a-form-item>
</a-col>
<a-col :span="8">
<a-form-item label="">
<div>MDGF截止时间</div>
<span class="text"> {{ form.mdgfCutDate }}</span>
</a-form-item>
</a-col>
<a-col :span="8">
<a-form-item label="">
<div>VGM截止时间</div>
<span class="text"> {{ form.vgmCutoffTime }}</span>
</a-form-item>
</a-col>
<a-col :span="8">
<a-form-item label="">
<div>箱型箱量</div>
<span class="text"> {{ form.ctnStat }}</span>
</a-form-item>
</a-col>
</a-row>
</div>
<div class="box">
<a-row>
<a-col :span="24">
<p class="title">一程</p>
</a-col>
<a-col :span="8">
<a-form-item label="">
<div>船名/航次</div>
<span class="text">{{ form.vessel }}/{{ form.voyNo }}</span>
</a-form-item>
</a-col>
<a-col :span="8">
<a-form-item label="">
<div>ETD</div>
<span class="text">{{ form.etd ? form.etd.substring(0, 11) : '-' }}</span>
</a-form-item>
</a-col>
<a-col :span="8">
<a-form-item label="">
<div>装货港</div>
<span class="text">{{ form.portload }}</span>
</a-form-item>
</a-col>
<a-col :span="8">
<a-form-item label="">
<div>ETA</div>
<span class="text"> {{ form.eta ? form.eta.substring(0, 11) : '-' }}</span>
</a-form-item>
</a-col>
<a-col :span="8">
<a-form-item label="">
<div>卸货港</div>
<span class="text">{{ form.portDischarge }}</span>
</a-form-item>
</a-col>
<div v-if="form.carriageType == 'TRANSFER_SHIP'">
<a-col :span="24">
<p class="title">二程</p>
</a-col>
<a-col :span="8">
<a-form-item label="">
<div>船名/航次</div>
<span class="text">{{ form.secondVessel }}/{{ form.secondVoyno }}</span>
</a-form-item>
</a-col>
<a-col :span="8">
<a-form-item label="ETD">
<div>ETD</div>
<span class="text"> {{ form.secondETD ? form.secondETD.substring(0, 11) : '-'
}}</span>
</a-form-item>
</a-col>
<a-col :span="8">
<a-form-item label="">
<div>装货港</div>
<span class="text"> {{ form.transferPort1 }}</span>
</a-form-item>
</a-col>
<a-col :span="8">
<a-form-item label="">
<div>ETA</div>
<span class="text"> {{ form.secondETA ? form.secondETA.substring(0, 11) : '-'
}}</span>
</a-form-item>
</a-col>
<a-col :span="8">
<a-form-item label="">
<div>卸货港</div>
<span class="text"> {{ form.portDischarge }}</span>
</a-form-item>
</a-col>
</div>
</a-row>
</div>
<div class="box">
<a-row>
<a-col :span="24">
<p class="title">关联详情</p>
</a-col>
</a-row>
<a-row>
<a-col :span="8">
<a-form-item label="">
<div>已生成舱位</div>
<span class="text">
{{ form.bookingSlotId ? '是' : '否' }}
<span class="CsSee" v-if="form.bookingSlotId" @click="FnSee1">()</span>
</span>
</a-form-item>
</a-col>
<a-col :span="8">
<a-form-item label="">
<div>已生成订舱</div>
<span class="text">
{{ form.bookingOrderId ? '是' : '否' }}
<span class="CsSee" v-if="form.bookingOrderId" @click="FnSee">()</span>
</span>
</a-form-item>
</a-col>
<a-col :span="8">
<a-form-item label="">
<div>任务状态</div>
<span class="text"> {{ form.taskStatus == 'Complete' ? '已完成' : '-' }}</span>
</a-form-item>
</a-col>
</a-row>
</div>
<div class="box">
<a-col :span="24">
<p class="title">关键信息</p>
</a-col>
<div class="unitBox">
<p v-for="(item, index) in form.keywords" :key="index" class="unit" :style="{
background: item.background,
color: Rcolor(item.background),
}">
<i :class="item.icon" class="iconfont"></i>{{ item.name }}
</p>
</div>
</div>
</a-form>
</a-col>
<a-col>
<pdf ref="pdfData"></pdf>
<a-row type="flex" :gutter="16">
<a-col>
<a-button type="primary" @click="OpenUser">
转移任务
</a-button>
</a-col>
<a-col>
<a-button type="primary" @click="FnCompleteTask">
完成任务
</a-button>
</a-col>
<a-col>
<a-button type="primary" @click="OpenModal">
</a-button>
</a-col>
<a-col>
<a-button type="danger" @click="FnCancelTask">
取消任务
</a-button>
</a-col>
<a-col>
<a-button type="primary" @click="handleSendMail">
发送邮件
</a-button>
</a-col>
</a-row>
</a-col>
</a-row>
</a-spin>
</template>
<script lang="ts" setup >
<script lang="ts" setup>
import { ref, onMounted } from 'vue'
import { useRouter } from 'vue-router'
import pdf from '../components/pdf.vue'
const router = useRouter();
const form = ref({
"pkId": "08dcab8e-3757-49bb-8082-1bb3de042459",
"taskId": "08dcab8e-374d-4a44-8093-6dc531177f01",
"busiType": "BookingConfirmation",
"bookingParty": "QINGDAO CHENGSI FREIGHT FORWARDER CO",
"mblNo": "242636125",
"vessel": "GSL MELITA",
"voyNo": "431S",
"placeReceipt": "Qingdao,Shandong,China",
"portload": "QINGDAO QIANWAN CONTAINER CO LTD",
"vgmCutoffTime": "2024-08-01 17:00:00",
"eta": "2024-09-03 00:00:00",
"etd": "2024-08-03 00:00:00",
"portDischarge": "Brisbane Patrick Terminal",
"placeDelivery": "Brisbane,Queensland,Australia",
"contractNo": "299026908",
"fstCustomerSerUserName": "Eight chengsi",
"cyCutoffTime": "2024-08-01 22:00:00",
"ctnList": [
{
"ctnALL": "40HC",
"ctnnum": 1
}
],
"fileList": [
{
"filePath": "BookingAttach\\bcfiles\\08dcab8e-374d-4a44-8093-6dc531177f01\\20240724111048159\\DB_aabhcbhjagaf0x023A.pdf",
"fileType": ".pdf",
"fileName": "DB_aabhcbhjagaf0x023A.pdf",
"fileCategory": "BC",
"fileCategoryName": "Booking Confirmation"
},
{
"filePath": "BookingAttach\\bcnoticefiles\\08dcab8e-374d-4a44-8093-6dc531177f01\\20240724111048174\\DB_aabhcbhjagaf0x023A_MODIFY.pdf",
"fileType": ".pdf",
"fileName": "DB_aabhcbhjagaf0x023A_MODIFY.pdf",
"fileCategory": "BC_NOTICE",
"fileCategoryName": "Booking Confirmation Notice"
}
],
"bookingSlotId": 571905822330949,
"carrierId": "MSK",
"carriageType": "DIRECT_SHIP",
"carriageTypeName": "直达",
"bookingSlotType": "CONTRACT_ORDER",
"bookingSlotTypeName": "合约订舱",
"ctnStat": "40HC*1",
"weekAt": "31",
"detensionFreeDays": 0,
"siCutDate": "2024-07-31 18:00:00",
"bookingConfirmDate": "2024-07-24 11:10:00",
"keywords": [
{
"name": "承运方式:直达",
"background": "#FFFF80",
"icon": "icon-yunshu1"
},
{
"name": "订舱方式:合约订舱",
"background": "#81D3F8",
"icon": "icon-touzijilu"
}
],
"taskStatus": "Create"
}) as any
const pdfUrl = ref('123')
const wrapperCol = { span: 22 }
const labelCol = { span: 0 }
const spinning = ref(false)
const formItemLayout = {
labelCol1: { span: 6 },
wrapperCol1: { span: 18 },
labelCol2: { span: 8 },
wrapperCol2: { span: 16 },
labelCol3: { span: 4 },
wrapperCol3: { span: 20 },
labelCol4: { span: 8 },
wrapperCol4: { span: 16 },
labelCol5: { span: 14 },
wrapperCol5: { span: 10 },
labelCol6: { span: 8 },
wrapperCol6: { span: 16 }
}
function reload() {
}
const pdfData = ref()
onMounted(() => {
pdfData.value.init()
})
function Rcolor(hexColor) {
const hex = hexColor.replace('#', '').toLowerCase()
const red = parseInt(hex.substring(0, 2), 16) - 90
const green = parseInt(hex.substring(2, 4), 16) - 90
const blue = parseInt(hex.substring(4, 6), 16) - 50
return `rgb(${red}, ${green}, ${blue})`
}
function FnSee() {
router.push({ path: '/BookingDetail?id=' + this.form.bookingOrderId })
}
function FnSee1() {
router.push({ path: '/CabinManagementDetails?type=Edit&id=' + this.form.bookingSlotId })
}
function copyText(text) {
const inputDom = document.createElement('textarea')
document.body.appendChild(inputDom)
inputDom.value = text
inputDom.select()
inputDom.focus()
document.execCommand('copy')
document.body.removeChild(inputDom)
this.$message.success('复制成功')
}
</script>
<style lang="less" scoped>
.LeftHead {
display: flex;
justify-content: space-between;
.title {
font-size: 15px;
font-weight: 700;
color: black;
}
}
.text {
font-weight: 700;
color: black;
}
/deep/ .ant-form-item-control-input-content {
div {
color: rgba(122, 135, 152, 1);
}
}
.box {
border: 1px solid rgba(232, 235, 237, 1);
padding: 15px 20px;
margin-bottom: 16px;
.title {
font-size: 15px;
font-weight: 700;
color: black;
}
}
.CsSee {
color: rgb(104, 104, 228);
font-weight: 500;
cursor: pointer;
}
.unitBox {
display: flex;
</script>
.unit {
margin-right: 15px;
padding: 0 5px;
}
}
</style>
Loading…
Cancel
Save