<template> <div> <div class="filters mb-10" v-if="showFilter"> <template v-if="!type"> {{$t('运输方式')}} <dict-selector :type='DICT_TYPE.ECW_TRANSPORT_TYPE' v-model="transportType" :placeholder="$t('请选择运输方式')" :filter="transportFilter" style="width:150px" /> </template> {{$t('始发地')}}: <el-select :placeholder="$t('请选择始发地')" v-model="exportCity" clearable> <el-option v-for="item in exportCityList" :key="item.id" :label="item.titleZh" :value="item.id" /> </el-select> {{$t('目的国')}}: <el-select :placeholder="$t('请选择目的国')" v-model="destCountryIds" multiple clearable> <el-option v-for="item in countryList" :key="item.id" :label="$l(item, 'title')" :value="item.id" /> </el-select> {{$t('目的城市')}}: <!-- <el-select :placeholder="$t('请选择目的地')" v-model="importCity" clearable> <el-option v-for="item in importCityList" :key="item.id" :label="item.titleZh" :value="item.id" /> </el-select> --> <el-select :placeholder="$t('请选择目的城市')" v-model="destCityIds" multiple clearable> <el-option v-for="item in AddressCity" :key="item.shi" :label="item.shiName" :value="item.shi" /> </el-select> {{$t('目的仓')}}: <el-select :placeholder="$t('请选择目的仓')" v-model="destWarehouseIds" multiple clearable> <el-option v-for="item in AddressTown" :key="item.id" :label="item.titleZh" :value="item.id" /> </el-select> <template v-if="type != 'sea'"> {{$t('出货渠道')}}: <el-select :placeholder="$t('请选择出货渠道')" v-model="channelId" clearable> <el-option v-for="item in channelList" :key="item.channelId" :label="item.nameZh" :value="item.channelId" /> </el-select> </template> </div> <div class="mb-10 flex-row" v-if="showFilter"> <el-radio-group v-model="checkAll"> <el-radio :label="true">{{$t('全选')}}</el-radio> <el-radio :label="false">{{$t('全不选')}}</el-radio> </el-radio-group> <el-link class="ml-20" type="danger">{{$t('已选择{n}条路线', {n: selectedRoutes.length})}}</el-link> </div> <el-row class="" :gutter="10"> <template v-for="(item, index) in filteredRouterList"> <el-col :span="12" :key="item.value"> <el-card class="mb-10"> <div slot="header"> {{$l(item, 'label')}} <el-link type="primary" @click.native="toggleHide(item.value)" style="float:right">{{item._hide ? $t('展开') : $t('折叠')}}</el-link> </div> <!--table需要给一个key,否则全选的时候不会自动更新渲染--> <el-table v-if="!hideMap[item.value]" :data="item.routerList" :span-method="SpanMethod" border :key="item.value"> <el-table-column :label="$t('始发仓')" prop="startTitleZh"> <template slot-scope="{row}"> {{$l(row, 'startTitle')}} </template> </el-table-column> <el-table-column :label="$t('目的仓')" prop="destTitleZh" > <template slot-scope="{row}"> {{$l(row, 'destTitle')}} </template> </el-table-column> <el-table-column :label="$t('渠道')" prop="startTitleZh" v-if="[3,4].indexOf(+item.value) > -1"> <template slot-scope="{row}"> {{$l(row.channel, 'name')}} </template> </el-table-column> <el-table-column v-if="showAttr" :label="$t('商品特性')" prop="startTitleZh"> <template slot-scope="{row}"> <!--{{ getAttrNames(row.attrId) }}--> <template v-if="row.channel && row.channel.attrNameList"> {{row.channel.attrNameList.join(',')}} </template> </template> </el-table-column> <el-table-column :label="$t('操作')" prop=""> <template slot="header"> <el-checkbox @change="toggleGroupChecker(index, $event)" v-model="groupChecker[item.value]"></el-checkbox> </template> <template slot-scope="{row}"> <!--给一个Key让他在全选后更新渲染--> <el-checkbox :key="getSelectedIndex(row)" :checked="getSelectedIndex(row) > -1" @change="toggleChecker(row, $event)"></el-checkbox> </template> </el-table-column> </el-table> </el-card> </el-col> </template> </el-row> </div> </template> <script> import {getChannelList} from '@/api/ecw/channel' import {getListTree, getTradeCityList} from '@/api/ecw/region' import {getRegionList} from "@/api/ecw/order"; import {openedRouterList} from '@/api/ecw/warehouse' import {getProductAttrList} from "@/api/ecw/productAttr"; import Template from "@/views/cms/template"; export default { components: {Template}, props:{ value: { type: Array }, option: Object, // 类型,sea海运,air空运 type: String, showFilter:{ type: Boolean, default: true } }, data(){ return { transportTypeDicts: this.getDictDatas(this.DICT_TYPE.ECW_TRANSPORT_TYPE), channelList:[], tradeCityList:[], openedRouterList:[], // 开放路线 transportType: null, // 运输方式 importCity: null, // 目的地(进口城市) exportCity: null, // 始发地(出口城市) channelId: null, selectedRoutes: [], // 勾选的路线渠道 hideMap: {}, // 折叠状态 checkAll: null, groupChecker: {}, // 分组全选状态 attrList:[], // 商品特性 inited: false, countryList: [], //目的国 AddressCity: [], //目的地 AddressTown: [], //目的仓 destCountryIds: null, destCityIds: null, destWarehouseIds: null, } }, computed:{ importCityList(){ return this.tradeCityList.filter(item => item.type == 1 || item.type == 3) }, exportCityList(){ //字典:贸易类型字典region_trade_type,0非进出口,1进口,2出口,3进出口 return this.tradeCityList.filter(item => item.type == 2 || item.type == 3) }, exportCityIds(){ let ids = [] this.exportCityList.forEach(item => { ids.push(item.id) }) return ids }, importCityIds(){ let ids = [] this.importCityList.forEach(item => { ids.push(item.id) }) return ids }, // 根据选择的渠道筛选 availChannelList(){ return this.channelList.filter(item => !this.channelId || this.channelId == item.channelId) }, filteredRouterList(){ let transportTypeList = [] this.transportTypeDicts .filter(this.transportFilter) .filter(transport => !this.channelId || transport.cssClass == 'channel') .forEach(item => { if(this.transportType === null || this.transportType == '' || this.transportType == item.value){ let routerList = [] this.openedRouterList.forEach(router => { if(router.transportType == item.value){ let availChannels = [] // 空运相关的,没有可用的渠道则不显示线路 if(item.cssClass === 'channel'){ availChannels = this.availChannelList.filter(channel => channel.countryId == router.destCountryId) if(!availChannels.length) return } routerList.push(Object.assign({ _merge: item.cssClass == 'channel' ? availChannels.length || 1 : 1, channel: item.cssClass == 'channel' ? availChannels[0] || { channelId: 0} : {channelId: 0}, }, router) ) // 字典的cssClass =channel则表示渠道相关(空运,海空联运) if(item.cssClass == 'channel'){ availChannels.slice(1).forEach(channel => { routerList.push(Object.assign({channel, _merge: 0}, router)) }) } } }) let child = { label: item.label, labelEn: item.labelEn, value: item.value, _hide: false, // 是否折叠 routerList: routerList } transportTypeList.push(child) } }) console.log(transportTypeList) return transportTypeList }, // 是否显示商品特性(渠道) showAttr(){ return this.type == 'air' }, // 显示产品特性 getAttrName(){ return (id) => { let item = this.attrList.find(item => item.id === +id) if(!item) return '' return this.$l(item, 'attrName') } }, // 显示多个商品特性 getAttrNames(){ return (ids) => { if(!ids) return '' return ids.split(',').filter( item => !!item).map(id => this.getAttrName(id)).join(',') } } }, watch:{ exportCity(){ this.getOpenedRouterList() }, /*importCity(){ this.getChannelList() this.getOpenedRouterList() },*/ selectedRoutes(val){ this.$emit('input', val) // 如果选择发生变化 let total = 0 this.filteredRouterList.forEach(item => { total += item.routerList.length }) if(total != val.length && val.length){ this.checkAll = null } }, value(val){ this.selectedRoutes = val || [] }, checkAll(val){ if(val === true || val === false){ console.log('选中全部') this.filteredRouterList.forEach(item => { item.routerList.forEach(router => { if(this.getSelectedIndex(router) > -1 != val )this.toggleChecker(router, val) }) }) } }, option(option){ if(option){ this.changeOption() } }, // 显示的路线发生变化之后,清空已勾选的路线 filteredRouterList(){ if(this.inited){ this.selectedRoutes = [] Object.keys(this.groupChecker).forEach(key => { this.groupChecker[key] = false }) } }, destCountryId: { //监听当前地区值的变化,于与上方地区值进行了双向绑定 deep: true, //深度监听 handler() { //每当值省份值改变时其下地区值进行清空 this.AddressCity = []; this.AddressTown = []; this.destWarehouseIds = ""; this.destCityIds = ""; this.findByprovinceCode(); if (this.destCountryIds == "") { //1 是所有区域,2 国家,3是市, this.getAddressCity() this.getAddressTown() } else if ( this.destCountryIds != "" && this.destCityIds == "" && this.destWarehouseIds == "" ) { this.getAddressTown() } this.getOpenedRouterList() }, }, destCityId: { deep: true, //深度监听 目的仓 handler() { this.AddressTown = []; this.destWarehouseIds = ""; this.findBycityCode(); if ( this.destCityIds != "" && this.destCountryIds != "" && this.destWarehouseIds == "" ) { //获取当前城市值id,获取该城市下区域 } else if ( this.destCountryIds == "" && this.destCityIds == "" && this.destWarehouseIds == "" ) { this.getAddressTown() } else if ( this.destCountryIds != "" && this.destCityIds == "" && this.destWarehouseIds == "" ) { this.findByprovinceCode() this.getAddressTown() } else if ( this.destCountryIds == "" && this.destCityIds != "" && this.destWarehouseIds == "" ) { //获取当前城市值id,获取该城市下区域 } this.getOpenedRouterList() this.getChannelList() }, }, destWarehouseId: { deep: true, //深度监听 handler() { if ( this.destCountryIds != "" && this.destCityIds != "" && this.destWarehouseIds == "" ) { //获取当前城市值id,获取该城市下区域 this.findBycityCode() } else if ( this.destCountryIds != "" && this.destCityIds == "" && this.destWarehouseIds == "" ) { this.getAddressTown() } else if ( this.destCountryIds == "" && this.destCityIds != "" && this.destWarehouseIds == "" ) { this.findBycityCode() } this.getOpenedRouterList() }, }, }, async created(){ this.tradeCityList = (await getTradeCityList()).data // 路线需要过滤失效的进出口城市,所以在程序加载后再加载路线 await this.getOpenedRouterList() if(this.option){ this.changeOption() } await this.$nextTick() this.getCountryList() this.getAddressCity() this.getAddressTown() this.getChannelList() if(this.value && this.value.length){ this.selectedRoutes = this.value } // 如果显示特性,则需要查询特数据备用 if(this.showAttr){ this.getAttrList() } await this.$nextTick() this.inited = true }, methods:{ getChannelList(){ if (this.type == 'sea') return let query = { // cityId: this.importCity cityId: this.destCityIds } getChannelList(query).then(res => { this.channelList = res.data }) }, getAttrList(){ getProductAttrList().then(res => { this.attrList = res.data }) }, changeOption(){ if(!this.option) return this.destCountryIds = +this.option.destCountryId || null this.destCityIds = +this.option.destCityId || null this.destWarehouseIds = +this.option.destWarehouseId || null // this.importCity = +this.option.importCity || null this.exportCity = +this.option.exportCity || null this.transportType = this.option.transportId || null this.channelId = +this.option.channelId || null }, // 全选、全不选 某个运输方式所有线路 toggleGroupChecker(index, selected){ let routerList = this.filteredRouterList[index].routerList console.log(routerList.length, selected) routerList.forEach(router => { this.toggleChecker(router, selected) }) }, async getOpenedRouterList(){ let params = {} if(this.exportCity){ params.startCityId = this.exportCity } if(this.destCountryIds){ params.destCountryIds = this.destCountryId } if(this.destCityIds){ params.destCityIds = this.destCityIds } if(this.destWarehouseIds){ params.destWarehouseIds = this.destWarehouseIds } const res = await openedRouterList(params) this.openedRouterList = res.data.filter(item => { return this.exportCityIds.indexOf(item.startCityId) > -1 && this.importCityIds.indexOf(item.destCityId) > -1 }) }, // 切换路线选择 toggleChecker(router, selected){ // this.getSelectedIndex(router) /* this.selectedRoutes.forEach((item, i)=>{ if(item.lineId == router.id && item.shippingChannelId == item.channel.id){ index = i break } }) */ if(selected){ // 先判断是否已勾选 if(this.getSelectedIndex(router) > -1) return this.selectedRoutes.push({ lineId: router.id, shippingChannelId: router.channel.channelId, transportId: router.transportType }) }else{ let index = this.getSelectedIndex(router) if(index > -1){ this.selectedRoutes.splice(index, 1) } } }, getSelectedIndex(router){ return this.selectedRoutes.findIndex(item => { return item.lineId == router.id && item.shippingChannelId == router.channel.channelId }) }, SpanMethod({ row, column, rowIndex, columnIndex }){ if (columnIndex < 2 ) { return { rowspan: row._merge, colspan: 1 } } return { rowspan: 1, colspan: 1 } }, // 折叠,展开 toggleHide(value){ this.$set(this.hideMap, value, !this.hideMap[value]) }, // 运输方式筛选 transportFilter(item){ // 未指定类型则全部可用 if(!this.type) return true return (this.type == 'sea' ? ['1','2'] : ['3', '4']).indexOf(item.value) > -1 }, /* 国家 */ getCountryList() { getListTree({ treeType: 1 }).then((response) => { this.countryList = response.data; }) }, getAddressCity() { getRegionList(4, 4).then(({ data }) => { this.AddressCity = data; }) }, getAddressTown() { getRegionList(5, 5).then(({ data }) => { this.AddressTown = data; }) }, findByprovinceCode() { if (this.destCountryIds != null && this.destCountryIds != '') { //获取当前省份值id,获取该省份下城市 destCountryId provinceCode getRegionList(2, this.destCountryIds).then(({ data }) => { this.AddressCity = data; }) } }, findBycityCode() { if (this.destCityIds != null && this.destCityIds != '') { //获取当前城市值id,获取该城市下区域 getRegionList(3, this.destCityIds).then(({ data }) => { this.AddressTown = data; }) } }, } } </script> <style scoped> .mb-10{ margin-bottom: 10px } </style>