作者 朱兆平

add:

1.增加邮件风控界面
  1 +import http from '../http.js';
  2 +let MailInfoBase = 'wlpt-mail-risk-analysis/InternationalMailInfo';
  3 +
  4 +// 新增国际邮件信息
  5 +export const riskManagement = (data,params) => {
  6 + return http.post(`${MailInfoBase}/riskManagementLink`, data,params);
  7 +};
  8 +// 查询搜索
  9 +export const searchListAPI = (data,params) => {
  10 + return http.post(`${MailInfoBase}/list`, data,params);
  11 +};
@@ -209,6 +209,9 @@ import ManagerWaybill from "./views/exportorder/ManagerWaybill.vue"; @@ -209,6 +209,9 @@ import ManagerWaybill from "./views/exportorder/ManagerWaybill.vue";
209 import ZhiDan from './views/zhidan/zhidan.vue' 209 import ZhiDan from './views/zhidan/zhidan.vue'
210 import Rate from './views/zhidan/rate.vue' 210 import Rate from './views/zhidan/rate.vue'
211 211
  212 +// 邮件风控
  213 +import MailRisk from './views/mail_risk/index.vue'
  214 +
212 let routes = [ 215 let routes = [
213 { 216 {
214 path: '/login', 217 path: '/login',
@@ -698,6 +701,15 @@ let routes = [ @@ -698,6 +701,15 @@ let routes = [
698 ] 701 ]
699 }, 702 },
700 { 703 {
  704 + path: '/customs_mail',
  705 + component: HomeNew,
  706 + name: '邮件监管',
  707 + iconCls:'el-icon-wind-power',
  708 + children:[
  709 + {path:'/mail_risk_analysis',component:MailRisk,name:'风控分析'},
  710 + ]
  711 + },
  712 + {
701 path: '/cbecd', 713 path: '/cbecd',
702 component: HomeNew, 714 component: HomeNew,
703 name: '跨境电商申报', 715 name: '跨境电商申报',
  1 +<template>
  2 + <div>
  3 + <!-- 搜索区域 -->
  4 + <!-- 搜索区域 -->
  5 + <el-row :gutter="10" class="toolbar">
  6 + <el-col :span="7">
  7 + <el-input v-model="queryInfo.mailId" prefix-icon="el-icon-search" size="small" placeholder="邮件号 (主键)" clearable>
  8 + <template slot="prepend">邮&nbsp;&nbsp;&nbsp;件&nbsp;&nbsp;&nbsp;号</template>
  9 + </el-input>
  10 + </el-col>
  11 + <el-col :span="7">
  12 + <el-input v-model="queryInfo.mailType" prefix-icon="el-icon-search" size="small" placeholder="邮件类型" clearable>
  13 + <template slot="prepend">邮&nbsp;件&nbsp;类&nbsp;型</template>
  14 + </el-input>
  15 + </el-col>
  16 + <el-col :span="7">
  17 + <el-input v-model="queryInfo.receiverName" prefix-icon="el-icon-search" size="small" placeholder="收件人姓名" clearable>
  18 + <template slot="prepend">收件人姓名</template>
  19 + </el-input>
  20 + </el-col>
  21 +
  22 + <el-col :span="7">
  23 + <el-input v-model="queryInfo.receiverAddress" prefix-icon="el-icon-search" size="small" placeholder="收件人地址" clearable>
  24 + <template slot="prepend">收件人地址</template>
  25 + </el-input>
  26 + </el-col>
  27 + <el-col :span="7">
  28 + <el-input v-model="queryInfo.receiverPhone" prefix-icon="el-icon-search" size="small" placeholder="收件人电话" clearable>
  29 + <template slot="prepend">收件人电话</template>
  30 + </el-input>
  31 + </el-col>
  32 + <el-col :span="7">
  33 + <el-input v-model="queryInfo.receiverIdNumber" prefix-icon="el-icon-search" size="small" placeholder="收件人证件号码" clearable>
  34 + <template slot="prepend">收件人证件</template>
  35 + </el-input>
  36 + </el-col>
  37 +
  38 + <el-col :span="7">
  39 + <el-input v-model="queryInfo.declarer" prefix-icon="el-icon-search" size="small" placeholder="申报人" clearable>
  40 + <template slot="prepend">申&nbsp;&nbsp;&nbsp;报&nbsp;&nbsp;&nbsp;人</template>
  41 + </el-input>
  42 + </el-col>
  43 + <el-col :span="7">
  44 + <el-input v-model="queryInfo.declarerUnit" prefix-icon="el-icon-search" size="small" placeholder="申报单位" clearable>
  45 + <template slot="prepend">申&nbsp;报&nbsp;单&nbsp;位</template>
  46 + </el-input>
  47 + </el-col>
  48 + </el-row>
  49 + <el-row :gutter="10" class="toolbar">
  50 + <el-col :span="7">
  51 + <el-select v-model="queryInfo.returnStatus" placeholder="退件状态" size="small" clearable>
  52 + <el-option label="未退件" value="0"></el-option>
  53 + <el-option label="已退件" value="1"></el-option>
  54 + </el-select>
  55 + </el-col>
  56 + <el-col :span="7">
  57 + <el-select v-model="queryInfo.inspectionStatus" placeholder="检验状态" size="small" clearable>
  58 + <el-option label="未检验" value="0"></el-option>
  59 + <el-option label="已检验" value="1"></el-option>
  60 + </el-select>
  61 + </el-col>
  62 + <el-col :span="10">
  63 + <el-date-picker
  64 + v-model="queryInfo.declarationTimeRange"
  65 + type="datetimerange"
  66 + range-separator="至"
  67 + start-placeholder="开始日期"
  68 + end-placeholder="结束日期"
  69 + size="small"
  70 + value-format="yyyy-MM-dd HH:mm:ss"
  71 + clearable>
  72 + </el-date-picker>
  73 + </el-col>
  74 + </el-row>
  75 + <el-row :gutter="10" class="toolbar">
  76 + <el-col :span="6">
  77 + <el-button type="primary" icon="el-icon-search" size="small" @click="getList()">
  78 + 查询
  79 + </el-button>
  80 + <el-button type="success" icon="el-icon-plus" size="small" @click="applyAdd()">新增</el-button>
  81 + <el-button type="success" icon="el-icon-plus" size="small" @click="analysis()">分析</el-button>
  82 + </el-col>
  83 + </el-row>
  84 +
  85 + <!-- 表格 -->
  86 + <el-table :data="tableData" border style="width: 100%" stripe>
  87 + <el-table-column prop="mailId" label="邮单" width="250"></el-table-column>
  88 + <el-table-column prop="itemName" label="物品名称"></el-table-column>
  89 + <el-table-column prop="mailType" label="邮件类型"></el-table-column>
  90 + <el-table-column prop="totalWeight" label="总重量"></el-table-column>
  91 + <el-table-column prop="itemCount" label="物品数量"></el-table-column>
  92 + <el-table-column prop="currency" label="货币"></el-table-column>
  93 + <el-table-column prop="itemValueCny" label="物品价值(CNY)"></el-table-column>
  94 + <el-table-column prop="taxAmountCny" label="税费(CNY)"></el-table-column>
  95 + <el-table-column prop="postageCny" label="邮费(CNY)"></el-table-column>
  96 + <el-table-column prop="receiverName" label="收件人姓名"></el-table-column>
  97 + <el-table-column prop="receiverAddress" label="收件人地址"></el-table-column>
  98 + <el-table-column prop="receiverPhone" label="收件人电话"></el-table-column>
  99 + <el-table-column prop="receiverIdType" label="收件人证件类型"></el-table-column>
  100 + <el-table-column prop="receiverIdNumber" label="收件人证件号码"></el-table-column>
  101 + <el-table-column prop="senderName" label="寄件人姓名"></el-table-column>
  102 + <el-table-column prop="senderAddress" label="寄件人地址"></el-table-column>
  103 + <el-table-column prop="senderPhone" label="寄件人电话"></el-table-column>
  104 + <el-table-column prop="senderIdType" label="寄件人证件类型"></el-table-column>
  105 + <el-table-column prop="senderIdNumber" label="寄件人证件号码"></el-table-column>
  106 + <el-table-column prop="returnStatus" label="退件状态"></el-table-column>
  107 + <el-table-column prop="inspectionStatus" label="检验状态"></el-table-column>
  108 + <el-table-column prop="specialMailFlag" label="特殊邮件标志"></el-table-column>
  109 + <el-table-column prop="declarationArea" label="申报区域"></el-table-column>
  110 + <el-table-column prop="declarationTime" label="申报时间"></el-table-column>
  111 + <el-table-column prop="declarerUnit" label="申报单位"></el-table-column>
  112 + <el-table-column prop="declarer" label="申报人"></el-table-column>
  113 + <el-table-column prop="remarks" label="备注"></el-table-column>
  114 + <el-table-column prop="createdAt" label="创建时间"></el-table-column>
  115 + <el-table-column prop="updatedAt" label="更新时间"></el-table-column>
  116 + <!-- Operation column -->
  117 + <el-table-column fixed="right" label="操作">
  118 + <template slot-scope="scope">
  119 + <el-button type="primary" size="mini" @click="applyView(scope.row)">查看</el-button>
  120 +<!-- <el-button type="success" size="mini" @click="applyEdit(scope.row)">编辑</el-button>-->
  121 +<!-- <el-button type="danger" size="mini" @click="applyDel(scope.$index, scope.row)">删除</el-button>-->
  122 + </template>
  123 + </el-table-column>
  124 + </el-table>
  125 +
  126 + <!-- Pagination -->
  127 + <el-pagination
  128 + background
  129 + layout="total, sizes, prev, pager, next, jumper"
  130 + :current-page.sync="queryInfo.pageNum"
  131 + :page-size.sync="queryInfo.pageSize"
  132 + :total="total"
  133 + @size-change="handleSizeChange"
  134 + @current-change="handleCurrentChange">
  135 + </el-pagination>
  136 +
  137 + <el-drawer
  138 + title="分析结果"
  139 + :visible.sync="drawerVisible"
  140 + direction="rtl"
  141 + :show-close="false"
  142 + >
  143 + <el-input
  144 + type="textarea"
  145 + :autosize="{ minRows: 12}"
  146 + placeholder="风险分析结果"
  147 + v-model="reskResult">
  148 + </el-input>
  149 + </el-drawer>
  150 +
  151 +
  152 + <!-- Dialog -->
  153 + <el-dialog :title="dialogStateMap[dialogType]" :visible.sync="showDialog" width="80%">
  154 + <el-form ref="formRef" :model="formData" :rules="rules" label-width="120px">
  155 + <!-- Form fields go here, for example: -->
  156 + <el-form-item prop="mailId" label="邮件号 (主键)">
  157 + <el-input v-model="formData.mailId"></el-input>
  158 + </el-form-item>
  159 + <!-- Add more form fields as needed -->
  160 +
  161 + </el-form>
  162 + <span slot="footer">
  163 + <el-button @click="showDialog = false">取消</el-button>
  164 + <el-button type="primary" @click="submitForm(dialogType)">确认</el-button>
  165 + </span>
  166 + </el-dialog>
  167 + </div>
  168 +</template>
  169 +
  170 +<script>
  171 +import {riskManagement, searchList, searchListAPI} from '@/api/mail_risk/api';
  172 +import {loginedUserInfo} from "@/api/user";
  173 +import jsutil from "@/common/js/util";
  174 +
  175 +export default {
  176 + data() {
  177 + return {
  178 + queryInfo: {
  179 + mailId: undefined,
  180 + mailType: undefined,
  181 + receiverName: undefined,
  182 + receiverAddress: undefined,
  183 + receiverPhone: undefined,
  184 + receiverIdNumber: undefined,
  185 + returnStatus: undefined,
  186 + inspectionStatus: undefined,
  187 + declarationTimeRange: [],
  188 + declarer: undefined,
  189 + declarerUnit: undefined,
  190 + pageNum: 1,
  191 + pageSize: 10,
  192 + serialnumber: undefined,
  193 + opter: undefined
  194 + },
  195 + reskResult: "",
  196 + tableData: [],
  197 + total: 0,
  198 + drawerVisible:false,
  199 + dialogType: 'view',
  200 + showDialog: false,
  201 + formData: {},
  202 + rules: {
  203 + // Form validation rules go here, for example:
  204 + mailId: [
  205 + { required: true, message: '请输入邮件号', trigger: 'blur' }
  206 + ],
  207 + // Add more rules as needed
  208 + },
  209 + dialogStateMap: {
  210 + view: '查看',
  211 + edit: '编辑',
  212 + add: '新增'
  213 + }
  214 + };
  215 + },
  216 + methods: {
  217 + // 建立连接
  218 + createSseConnect(clientId){
  219 + if(window.EventSource){
  220 + const eventSource = new EventSource('/api/wlpt-mail-risk-analysis/InternationalMailInfo/anonymous/createSseEmitter?clientId='+clientId,);
  221 + // console.log(eventSource)
  222 +
  223 + eventSource.onmessage = (event) =>{
  224 + // console.log("onmessage:"+clientId+": "+event.data)
  225 + this.reskResult += event.data + '\n';
  226 + };
  227 +
  228 + eventSource.onopen = (event) =>{
  229 + this.$message.success('建立SSE链接,成功!')
  230 + };
  231 +
  232 + eventSource.onerror = (event) =>{
  233 + // console.log("onerror :"+clientId+": "+event)
  234 + this.$message.error('建立SSE链接,失败!')
  235 + };
  236 +
  237 + eventSource.close = (event) =>{
  238 + this.$message.success('关闭SSE链接,成功!')
  239 + };
  240 +
  241 + }else{
  242 + this.$message.error('你的浏览器不支持SSE,建立SSE链接,失败!')
  243 + }
  244 + // console.log(" 测试 打印")
  245 + },
  246 + getList() {
  247 + let _this = this
  248 + //携带client ID,访问接口触发流程
  249 + searchListAPI(_this.queryInfo).then(response => {
  250 + if (response.data.code === '200') {
  251 + _this.tableData = response.data.data.list;
  252 + _this.$message.success('搜索完成!')
  253 + }else {
  254 + _this.$message.error('接口访问失败!')
  255 + }
  256 + })
  257 + },
  258 + applyAdd() {
  259 + this.dialogType = 'add';
  260 + this.showDialog = true;
  261 + this.formData = {};
  262 + },
  263 + analysis(){
  264 + let sse = {
  265 + clientId:this.queryInfo.serialnumber
  266 + }
  267 + this.drawerVisible = true;
  268 + riskManagement(this.queryInfo,sse)
  269 + this.reskResult = ''
  270 + },
  271 + applyEdit(row) {
  272 + this.dialogType = 'edit';
  273 + this.showDialog = true;
  274 + this.formData = Object.assign({}, row);
  275 + },
  276 + applyView(row) {
  277 +
  278 + },
  279 + applyDel(index, row) {
  280 + // Implement delete functionality
  281 + },
  282 + submitForm(type) {
  283 + if (type === 'add') {
  284 + // addInternationalMailInfo(this.formData).then(response => {
  285 + // this.showDialog = false;
  286 + // this.getList(); // Refresh table data after adding.
  287 + // });
  288 + // } else if (type === 'edit') {
  289 + // updateInternationalMailInfo(this.formData).then(response => {
  290 + // this.showDialog = false;
  291 + // this.getList(); // Refresh table data after editing.
  292 + // });
  293 + }
  294 + },
  295 + handleSizeChange(val) {
  296 + // Update queryInfo.pageSize and fetch new data
  297 + },
  298 + handleCurrentChange(val) {
  299 + // Update queryInfo.pageNum and fetch new data
  300 + },
  301 + initUserInfo(){
  302 + let userinfo = loginedUserInfo();
  303 + if (!jsutil.checkNull(userinfo) && !jsutil.checkNull(userinfo.username)){
  304 + this.$message.error("获取用户信息出错")
  305 + }else{
  306 + this.queryInfo.opter = userinfo.username
  307 + }
  308 + },
  309 + serialNumber(){
  310 + let serialDate= new Date();
  311 + let serialCode = this.queryInfo.opter + serialDate.format("yyyyMMddhhmmssS")
  312 + return serialCode
  313 + },
  314 + drawerhandleClose(done) {
  315 + this.$confirm('确认关闭?')
  316 + .then(_ => {
  317 + done();
  318 + })
  319 + .catch(_ => {});
  320 + }
  321 + },
  322 + mounted(){
  323 +
  324 + this.initUserInfo()
  325 + this.queryInfo.serialnumber = this.serialNumber()
  326 + if (this.queryInfo.serialnumber){
  327 + this.createSseConnect(this.queryInfo.serialnumber)
  328 + }
  329 +
  330 +
  331 + }
  332 +};
  333 +</script>