New file |
| | |
| | | package com.zy.asrs.common.openapi.entity.param; |
| | | |
| | | import com.zy.asrs.common.domain.dto.DetlDto; |
| | | import lombok.Data; |
| | | |
| | | import java.util.List; |
| | | |
| | | @Data |
| | | public class GenerateOrderPakInParam { |
| | | |
| | | private String orderNo; |
| | | |
| | | private Integer orderType; |
| | | |
| | | private List<DetlDto> orderDetails; |
| | | |
| | | private String sign; |
| | | |
| | | } |
New file |
| | |
| | | package com.zy.asrs.openapi.controller; |
| | | |
| | | import com.alibaba.fastjson.JSON; |
| | | import com.alibaba.fastjson.JSONObject; |
| | | import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; |
| | | import com.zy.asrs.common.openapi.entity.HostKey; |
| | | import com.zy.asrs.common.openapi.entity.param.GenerateOrderPakInParam; |
| | | import com.zy.asrs.common.openapi.service.HostKeyService; |
| | | import com.zy.asrs.common.web.BaseController; |
| | | import com.zy.asrs.framework.common.BaseRes; |
| | | import com.zy.asrs.framework.common.Cools; |
| | | import com.zy.asrs.framework.common.R; |
| | | import com.zy.asrs.framework.exception.CoolException; |
| | | import lombok.extern.slf4j.Slf4j; |
| | | import org.apache.commons.codec.digest.DigestUtils; |
| | | import org.springframework.beans.factory.annotation.Autowired; |
| | | import org.springframework.web.bind.annotation.*; |
| | | |
| | | import java.util.Map; |
| | | |
| | | @Slf4j |
| | | @RestController |
| | | @RequestMapping("/api") |
| | | public class ApiController extends BaseController { |
| | | |
| | | @Autowired |
| | | private HostKeyService hostKeyService; |
| | | |
| | | @PostMapping("/generateOrderPakIn") |
| | | public synchronized R pakinOrderCreate(@RequestHeader(required = false) String appkey, |
| | | @RequestBody GenerateOrderPakInParam param) { |
| | | auth(appkey, param); |
| | | if (Cools.isEmpty(param)) { |
| | | return R.parse(BaseRes.PARAM); |
| | | } |
| | | if (Cools.isEmpty(param.getOrderNo())) { |
| | | return R.error("单据编号[orderNo]不能为空"); |
| | | } |
| | | if (Cools.isEmpty(param.getOrderType())) { |
| | | return R.error("单据类型[orderType]不能为空"); |
| | | } |
| | | if (Cools.isEmpty(param.getOrderDetails())) { |
| | | return R.error("单据明细[orderDetails]不能为空"); |
| | | } |
| | | // openService.pakinOrderCreate(param); |
| | | return R.ok(); |
| | | } |
| | | |
| | | private void auth(String appkey, Object obj) { |
| | | if (Cools.isEmpty(appkey)) { |
| | | throw new CoolException("认证失败,请确认appKey无误!"); |
| | | } |
| | | |
| | | HostKey hostKey = hostKeyService.getOne(new LambdaQueryWrapper<HostKey>().eq(HostKey::getAppKey, appkey)); |
| | | if (hostKey == null) { |
| | | throw new CoolException("认证失败,请确认appKey无误!"); |
| | | } |
| | | |
| | | if (hostKey.getSignStatus() == 1) { |
| | | //需要进行签名校验 |
| | | //创建自然排序map |
| | | JSONObject param = new JSONObject(true); |
| | | JSONObject jsonObject = JSON.parseObject(JSON.toJSONString(obj)); |
| | | for (Map.Entry<String, Object> entry : jsonObject.entrySet()) { |
| | | if (!entry.getKey().equals("sign")) {//剔除sign |
| | | param.put(entry.getKey(), entry.getValue()); |
| | | } |
| | | } |
| | | param.put("signKey", hostKey.getSignKey()); |
| | | String md5Hex = DigestUtils.md5Hex(param.toJSONString()); |
| | | if (!jsonObject.get("sign").toString().equals(md5Hex)) { |
| | | throw new CoolException("签名校验失败"); |
| | | } |
| | | } |
| | | } |
| | | |
| | | } |
New file |
| | |
| | | #content { |
| | | width: 80%; |
| | | margin-left: 10%; |
| | | } |
| | | |
| | | #content table { |
| | | background: #fff; |
| | | border: solid 1px #ddd; |
| | | margin-bottom: 1.25rem; |
| | | table-layout: auto |
| | | } |
| | | |
| | | #content table caption { |
| | | background: transparent; |
| | | color: #222; |
| | | font-size: 1rem; |
| | | font-weight: bold |
| | | } |
| | | |
| | | #content table thead { |
| | | background: #F5F5F5 |
| | | } |
| | | |
| | | #content table thead tr th,#content table thead tr td { |
| | | color: #222; |
| | | font-size: 0.875rem; |
| | | font-weight: bold; |
| | | padding: 0.5rem 0.625rem 0.625rem |
| | | } |
| | | |
| | | #content table tfoot { |
| | | background: #F5F5F5 |
| | | } |
| | | |
| | | #content table tfoot tr th,#content table tfoot tr td { |
| | | color: #222; |
| | | font-size: 0.875rem; |
| | | font-weight: bold; |
| | | padding: 0.5rem 0.625rem 0.625rem |
| | | } |
| | | |
| | | #content table tr th,#content table tr td { |
| | | color: #222; |
| | | font-size: 0.875rem; |
| | | padding: 0.5625rem 0.625rem; |
| | | text-align: left |
| | | } |
| | | |
| | | #content table tr.even,#content table tr.alt,#content table tr:nth-of-type(even) { |
| | | background: #F9F9F9 |
| | | } |
| | | |
| | | #content table thead tr th,#content table tfoot tr th,#content table tfoot tr td,#content table tbody tr th,#content table tbody tr td,#content table tr td { |
| | | display: table-cell; |
| | | line-height: 1.125rem |
| | | } |
| | | |
| | | #content pre { |
| | | white-space: pre-wrap; /* css-3 */ |
| | | white-space: -moz-pre-wrap; /* Mozilla, since 1999 */ |
| | | white-space: -o-pre-wrap; /* Opera 7 */ |
| | | word-wrap: break-word; /* Internet Explorer 5.5+ */ |
| | | background-color: #f8f8f8; |
| | | border: 1px solid #dfdfdf; |
| | | margin-top: 1.5em; |
| | | margin-bottom: 1.5em; |
| | | padding: 0.125rem 0.3125rem 0.0625rem; |
| | | } |
| | | |
| | | #content pre code { |
| | | background-color: transparent; |
| | | border: 0; |
| | | padding: 0; |
| | | } |
| | | |
| | | .el-dropdown-link { |
| | | cursor: pointer; |
| | | color: #409EFF; |
| | | } |
| | | .el-icon-arrow-down { |
| | | font-size: 12px; |
| | | } |
| | | |
| | | .slider { |
| | | position: fixed; |
| | | top: 20px; |
| | | right: 20px; |
| | | width: 130px; |
| | | border-left: 3px solid #f0f0f0; |
| | | padding-left: 15px; |
| | | } |
| | | |
| | | .slider > .el-divider { |
| | | margin: 5px 0; |
| | | } |
New file |
| | |
| | | <!DOCTYPE html> |
| | | <html lang="en"> |
| | | <head> |
| | | <meta charset="UTF-8"> |
| | | <title>API开放平台 - API管理</title> |
| | | <link rel="stylesheet" href="../static/css/element.css"> |
| | | <link rel="stylesheet" href="../static/css/common.css"> |
| | | <script type="text/javascript" src="../static/js/jquery/jquery-3.3.1.min.js"></script> |
| | | <script type="text/javascript" src="../static/js/vue.min.js"></script> |
| | | <script type="text/javascript" src="../static/js/showdown.min.js"></script> |
| | | <script type="text/javascript" src="../static/js/common.js"></script> |
| | | <script type="text/javascript" src="../static/js/element.js"></script> |
| | | </head> |
| | | <body> |
| | | <div id="app" style="display: flex;justify-content: center;flex-wrap: wrap;"> |
| | | <div style="width: 80%;"> |
| | | <el-card class="box-card"> |
| | | <el-form :inline="true" :model="tableSearchParam" class="demo-form-inline"> |
| | | <el-form-item label=""> |
| | | <el-input v-model="tableSearchParam.task_no" placeholder="任务号"></el-input> |
| | | </el-form-item> |
| | | <el-form-item> |
| | | <el-button type="primary" @click="getTableData">查询</el-button> |
| | | <el-button type="primary" @click="resetParam">重置</el-button> |
| | | </el-form-item> |
| | | </el-form> |
| | | <el-table ref="singleTable" :data="tableData" style="width: 100%;"> |
| | | <el-table-column property="id" label="#ID"> |
| | | </el-table-column> |
| | | <el-table-column property="wrkNo" label="工作号"> |
| | | </el-table-column> |
| | | <el-table-column property="taskNo" label="任务号"> |
| | | </el-table-column> |
| | | <el-table-column property="commandStatus$" label="指令状态"> |
| | | </el-table-column> |
| | | <el-table-column show-overflow-tooltip property="durationTime" label="持续时长"> |
| | | </el-table-column> |
| | | <el-table-column property="commandType" label="指令类型"> |
| | | </el-table-column> |
| | | <el-table-column property="device" label="设备"> |
| | | </el-table-column> |
| | | <el-table-column property="deviceLog" label="设备执行信息"> |
| | | </el-table-column> |
| | | <el-table-column property="commandDesc" label="命令描述"> |
| | | </el-table-column> |
| | | <el-table-column show-overflow-tooltip property="startTime$" label="开始时间"> |
| | | </el-table-column> |
| | | <el-table-column show-overflow-tooltip property="executeTime$" label="执行时间"> |
| | | </el-table-column> |
| | | <el-table-column show-overflow-tooltip property="completeTime$" label="完成时间"> |
| | | </el-table-column> |
| | | <el-table-column show-overflow-tooltip property="command" label="命令报文" width="250"> |
| | | </el-table-column> |
| | | </el-table> |
| | | |
| | | <div style="margin-top: 10px;"> |
| | | <el-pagination @size-change="handleSizeChange" @current-change="handleCurrentChange" |
| | | :current-page="currentPage" :page-sizes="pageSizes" :page-size="pageSize" |
| | | layout="total, sizes, prev, pager, next, jumper" :total="pageTotal"> |
| | | </el-pagination> |
| | | </div> |
| | | </el-card> |
| | | </div> |
| | | |
| | | <div style="position: fixed;top: 20px;right: 20px;width: 150px;border-left: 3px solid #f0f0f0;padding-left: 15px;"> |
| | | <div><el-button type="text" @click="switchPage('index.html')">规范说明</el-button></div> |
| | | <div><el-button type="text" @click="switchPage('reportCompleted.html')">任务完成上报</el-button></div> |
| | | <div><el-button type="text" @click="switchPage('reportCompleted.html')">任务取消上报</el-button></div> |
| | | <div><el-button type="text" @click="switchPage('reportCompleted.html')">库存上报</el-button></div> |
| | | <div><el-button type="text" @click="switchPage('reportApiManage.html')">上报API管理</el-button></div> |
| | | </div> |
| | | </div> |
| | | |
| | | <script> |
| | | var app = new Vue({ |
| | | el: '#app', |
| | | data: { |
| | | tableData: [], |
| | | currentPage: 1, |
| | | pageSizes: [16, 30, 50, 100, 150, 200], |
| | | pageSize: 16, |
| | | pageTotal: 0, |
| | | tableSearchParam: { |
| | | task_no: null, |
| | | }, |
| | | }, |
| | | created() { |
| | | this.init() |
| | | }, |
| | | methods: { |
| | | init() { |
| | | this.getTableData() |
| | | }, |
| | | getTableData() { |
| | | let that = this; |
| | | let data = this.tableSearchParam |
| | | data.curr = this.currentPage |
| | | data.limit = this.pageSize |
| | | $.ajax({ |
| | | url: baseUrl + "/commandInfoLog/list/auth", |
| | | headers: { |
| | | 'token': localStorage.getItem('token') |
| | | }, |
| | | data: data, |
| | | dataType: 'json', |
| | | contentType: 'application/json;charset=UTF-8', |
| | | method: 'GET', |
| | | success: function(res) { |
| | | if (res.code == 200) { |
| | | that.tableData = res.data.records |
| | | that.pageTotal = res.data.total |
| | | } else { |
| | | that.$message({ |
| | | message: res.msg, |
| | | type: 'error' |
| | | }); |
| | | } |
| | | } |
| | | }); |
| | | }, |
| | | handleSizeChange(val) { |
| | | console.log(`每页 ${val} 条`); |
| | | this.pageSize = val |
| | | this.getTableData() |
| | | }, |
| | | handleCurrentChange(val) { |
| | | console.log(`当前页: ${val}`); |
| | | this.currentPage = val |
| | | this.getTableData() |
| | | }, |
| | | resetParam() { |
| | | this.tableSearchParam = { |
| | | task_no: null, |
| | | status: null, |
| | | wrk_no: null |
| | | } |
| | | this.getTableData() |
| | | }, |
| | | switchPage(url) { |
| | | location.href = url |
| | | } |
| | | } |
| | | }) |
| | | </script> |
| | | </body> |
| | | </html> |
New file |
| | |
| | | <!DOCTYPE html> |
| | | <html lang="en"> |
| | | <head> |
| | | <meta charset="UTF-8"> |
| | | <title>API开放平台 - 生成入库</title> |
| | | <link rel="stylesheet" href="../static/css/element.css"> |
| | | <link rel="stylesheet" href="../static/css/common.css"> |
| | | <script type="text/javascript" src="../static/js/jquery/jquery-3.3.1.min.js"></script> |
| | | <script type="text/javascript" src="../static/js/vue.min.js"></script> |
| | | <script type="text/javascript" src="../static/js/showdown.min.js"></script> |
| | | <script type="text/javascript" src="../static/js/common.js"></script> |
| | | <script type="text/javascript" src="../static/js/element.js"></script> |
| | | </head> |
| | | <body> |
| | | <div id="app"> |
| | | <div id="content"></div> |
| | | <div class="slider"> |
| | | <div><el-button type="text" @click="switchPage('index.html')">规范说明</el-button></div> |
| | | <el-divider></el-divider> |
| | | <div><el-button type="text" @click="switchPage('reportCompleted.html')">任务完成上报</el-button></div> |
| | | <div><el-button type="text" @click="switchPage('reportCompleted.html')">任务取消上报</el-button></div> |
| | | <div><el-button type="text" @click="switchPage('reportCompleted.html')">库存上报</el-button></div> |
| | | <div><el-button type="text" @click="switchPage('reportApiManage.html')">上报API管理</el-button></div> |
| | | <el-divider></el-divider> |
| | | <div><el-button type="text" @click="switchPage('generatePakIn.html')">生成入库订单</el-button></div> |
| | | <el-divider></el-divider> |
| | | <div><el-button type="text" @click="keyList()">密钥管理</el-button></div> |
| | | </div> |
| | | |
| | | <el-dialog title="密钥管理" :visible.sync="keyTableVisible"> |
| | | <el-table :data="keyTableData" v-loading="loading"> |
| | | <el-table-column property="hostId$" label="仓库"></el-table-column> |
| | | <el-table-column property="signKey" label="签名密钥" width="150"></el-table-column> |
| | | <el-table-column property="appKey" label="接口请求密钥" width="250"></el-table-column> |
| | | <el-table-column property="createTime$" label="时间" width="200"></el-table-column> |
| | | <el-table-column label="操作" width="400"> |
| | | <template slot-scope="scope"> |
| | | <el-button size="mini" @click="generateSignKey(scope.row.hostId)">签名密钥</el-button> |
| | | <el-button size="mini" @click="generateAppKey(scope.row.hostId)">接口密钥</el-button> |
| | | <el-switch |
| | | v-model="scope.row.signStatus" |
| | | @change="switchChange(scope.row.hostId,scope.row.signStatus)" |
| | | active-text="开启签名" |
| | | inactive-text="关闭签名"> |
| | | </el-switch> |
| | | </template> |
| | | </el-table-column> |
| | | </el-table> |
| | | </el-dialog> |
| | | </div> |
| | | |
| | | <script> |
| | | showdown.setOption('tables', true); |
| | | var converter = new showdown.Converter() |
| | | |
| | | var app = new Vue({ |
| | | el: '#app', |
| | | data: { |
| | | keyTableVisible: false, |
| | | keyTableData: [], |
| | | loading: true, |
| | | }, |
| | | created() { |
| | | this.init() |
| | | }, |
| | | methods: { |
| | | init() { |
| | | this.introduceClick() |
| | | }, |
| | | introduceClick() { |
| | | $.ajax({ |
| | | url: "md/generatePakIn.md", |
| | | headers: {'token': localStorage.getItem('token')}, |
| | | method: 'GET', |
| | | success: function (res) { |
| | | // $("#content").html(marked.parse(res)) |
| | | // console.log(converter.makeHtml(res)) |
| | | $("#content").html(converter.makeHtml(res)) |
| | | } |
| | | }); |
| | | }, |
| | | keyList() { |
| | | let that = this |
| | | this.keyTableVisible = true |
| | | $.ajax({ |
| | | url: baseUrl + "/hostKey/list/auth", |
| | | headers: {'token': localStorage.getItem('token')}, |
| | | data: {}, |
| | | dataType:'json', |
| | | contentType:'application/json;charset=UTF-8', |
| | | method: 'POST', |
| | | success: function (res) { |
| | | let tmp = [] |
| | | res.data.forEach((item, index) => { |
| | | item.signStatus = item.signStatus == 1 ? true : false; |
| | | tmp.push(item) |
| | | }); |
| | | that.keyTableData = tmp |
| | | that.loading = false |
| | | } |
| | | }); |
| | | }, |
| | | generateSignKey(hostId) { |
| | | let that = this |
| | | this.$confirm('此操作将覆盖原签名密钥, 是否继续?', '提示', { |
| | | confirmButtonText: '确定', |
| | | cancelButtonText: '取消', |
| | | type: 'warning' |
| | | }).then(() => { |
| | | $.ajax({ |
| | | url: baseUrl + "/hostKey/generateSignKey/auth", |
| | | headers: {'token': localStorage.getItem('token')}, |
| | | data: { |
| | | hostId: hostId |
| | | }, |
| | | dataType: 'json', |
| | | contentType: 'application/json;charset=UTF-8', |
| | | method: 'GET', |
| | | success: function (res) { |
| | | if (res.code === 200) { |
| | | that.$message({ |
| | | type: 'success', |
| | | message: '生成成功' |
| | | }); |
| | | |
| | | that.keyTableData.forEach((item, index) => { |
| | | if (item.hostId == hostId) { |
| | | item.signKey = res.data.signKey |
| | | } |
| | | }); |
| | | } else { |
| | | that.$message({ |
| | | type: 'error', |
| | | message: res.msg |
| | | }); |
| | | } |
| | | } |
| | | }); |
| | | }).catch(() => { |
| | | //取消 |
| | | }); |
| | | }, |
| | | generateAppKey(hostId) { |
| | | let that = this |
| | | this.$confirm('此操作将覆盖原接口密钥, 是否继续?', '提示', { |
| | | confirmButtonText: '确定', |
| | | cancelButtonText: '取消', |
| | | type: 'warning' |
| | | }).then(() => { |
| | | $.ajax({ |
| | | url: baseUrl + "/hostKey/generateAppKey/auth", |
| | | headers: {'token': localStorage.getItem('token')}, |
| | | data: { |
| | | hostId: hostId |
| | | }, |
| | | dataType: 'json', |
| | | contentType: 'application/json;charset=UTF-8', |
| | | method: 'GET', |
| | | success: function (res) { |
| | | if (res.code === 200) { |
| | | that.$message({ |
| | | type: 'success', |
| | | message: '生成成功' |
| | | }); |
| | | |
| | | that.keyTableData.forEach((item, index) => { |
| | | if (item.hostId == hostId) { |
| | | item.appKey = res.data.appKey |
| | | } |
| | | }); |
| | | } else { |
| | | that.$message({ |
| | | type: 'error', |
| | | message: res.msg |
| | | }); |
| | | } |
| | | } |
| | | }); |
| | | }).catch(() => { |
| | | //取消 |
| | | }); |
| | | }, |
| | | switchChange(hostId, signStatus) { |
| | | let that = this |
| | | //签名校验开关 |
| | | $.ajax({ |
| | | url: baseUrl + "/hostKey/switchSign/auth", |
| | | headers: {'token': localStorage.getItem('token')}, |
| | | data: { |
| | | hostId: hostId, |
| | | signStatus: signStatus ? 1 : 0, |
| | | }, |
| | | dataType: 'json', |
| | | contentType: 'application/json;charset=UTF-8', |
| | | method: 'GET', |
| | | success: function (res) { |
| | | if (res.code === 200) { |
| | | that.$message({ |
| | | type: 'success', |
| | | message: '切换成功' |
| | | }); |
| | | } else { |
| | | that.$message({ |
| | | type: 'error', |
| | | message: res.msg |
| | | }); |
| | | } |
| | | } |
| | | }); |
| | | }, |
| | | switchPage(url) { |
| | | location.href = url |
| | | }, |
| | | } |
| | | }) |
| | | </script> |
| | | </body> |
| | | </html> |
| | |
| | | <meta charset="UTF-8"> |
| | | <title>API开放平台</title> |
| | | <link rel="stylesheet" href="../static/css/element.css"> |
| | | <link rel="stylesheet" href="../static/css/common.css"> |
| | | <script type="text/javascript" src="../static/js/jquery/jquery-3.3.1.min.js"></script> |
| | | <script type="text/javascript" src="../static/js/vue.min.js"></script> |
| | | <script type="text/javascript" src="../static/js/showdown.min.js"></script> |
| | | <script type="text/javascript" src="../static/js/common.js"></script> |
| | | <script type="text/javascript" src="../static/js/element.js"></script> |
| | | <style> |
| | | #content { |
| | | width: 80%; |
| | | margin-left: 10%; |
| | | } |
| | | |
| | | #content table { |
| | | background: #fff; |
| | | border: solid 1px #ddd; |
| | | margin-bottom: 1.25rem; |
| | | table-layout: auto |
| | | } |
| | | |
| | | #content table caption { |
| | | background: transparent; |
| | | color: #222; |
| | | font-size: 1rem; |
| | | font-weight: bold |
| | | } |
| | | |
| | | #content table thead { |
| | | background: #F5F5F5 |
| | | } |
| | | |
| | | #content table thead tr th,#content table thead tr td { |
| | | color: #222; |
| | | font-size: 0.875rem; |
| | | font-weight: bold; |
| | | padding: 0.5rem 0.625rem 0.625rem |
| | | } |
| | | |
| | | #content table tfoot { |
| | | background: #F5F5F5 |
| | | } |
| | | |
| | | #content table tfoot tr th,#content table tfoot tr td { |
| | | color: #222; |
| | | font-size: 0.875rem; |
| | | font-weight: bold; |
| | | padding: 0.5rem 0.625rem 0.625rem |
| | | } |
| | | |
| | | #content table tr th,#content table tr td { |
| | | color: #222; |
| | | font-size: 0.875rem; |
| | | padding: 0.5625rem 0.625rem; |
| | | text-align: left |
| | | } |
| | | |
| | | #content table tr.even,#content table tr.alt,#content table tr:nth-of-type(even) { |
| | | background: #F9F9F9 |
| | | } |
| | | |
| | | #content table thead tr th,#content table tfoot tr th,#content table tfoot tr td,#content table tbody tr th,#content table tbody tr td,#content table tr td { |
| | | display: table-cell; |
| | | line-height: 1.125rem |
| | | } |
| | | |
| | | #content pre { |
| | | white-space: pre-wrap; /* css-3 */ |
| | | white-space: -moz-pre-wrap; /* Mozilla, since 1999 */ |
| | | white-space: -o-pre-wrap; /* Opera 7 */ |
| | | word-wrap: break-word; /* Internet Explorer 5.5+ */ |
| | | background-color: #f8f8f8; |
| | | border: 1px solid #dfdfdf; |
| | | margin-top: 1.5em; |
| | | margin-bottom: 1.5em; |
| | | padding: 0.125rem 0.3125rem 0.0625rem; |
| | | } |
| | | |
| | | #content pre code { |
| | | background-color: transparent; |
| | | border: 0; |
| | | padding: 0; |
| | | } |
| | | |
| | | .el-dropdown-link { |
| | | cursor: pointer; |
| | | color: #409EFF; |
| | | } |
| | | .el-icon-arrow-down { |
| | | font-size: 12px; |
| | | } |
| | | </style> |
| | | </head> |
| | | <body> |
| | | <div id="app"> |
| | | <div id="content"></div> |
| | | <div style="position: fixed;top: 20px;right: 20px;width: 100px;"> |
| | | <el-menu default-active="1"> |
| | | <el-menu-item index="1"> |
| | | <span slot="title" @click="introduceClick()">规范说明</span> |
| | | </el-menu-item> |
| | | <el-menu-item index="2"> |
| | | <span slot="title" @click="keyList()">密钥管理</span> |
| | | </el-menu-item> |
| | | </el-menu> |
| | | <div class="slider"> |
| | | <div><el-button type="text" @click="switchPage('index.html')">规范说明</el-button></div> |
| | | <el-divider></el-divider> |
| | | <div><el-button type="text" @click="switchPage('reportCompleted.html')">任务完成上报</el-button></div> |
| | | <div><el-button type="text" @click="switchPage('reportCompleted.html')">任务取消上报</el-button></div> |
| | | <div><el-button type="text" @click="switchPage('reportCompleted.html')">库存上报</el-button></div> |
| | | <div><el-button type="text" @click="switchPage('reportApiManage.html')">上报API管理</el-button></div> |
| | | <el-divider></el-divider> |
| | | <div><el-button type="text" @click="switchPage('generatePakIn.html')">生成入库订单</el-button></div> |
| | | <el-divider></el-divider> |
| | | <div><el-button type="text" @click="keyList()">密钥管理</el-button></div> |
| | | </div> |
| | | |
| | | <el-dialog title="密钥管理" :visible.sync="keyTableVisible"> |
| | |
| | | data: { |
| | | keyTableVisible: false, |
| | | keyTableData: [], |
| | | loading: true |
| | | loading: true, |
| | | }, |
| | | created() { |
| | | this.init() |
| | |
| | | } |
| | | } |
| | | }); |
| | | } |
| | | }, |
| | | switchPage(url) { |
| | | location.href = url |
| | | }, |
| | | } |
| | | }) |
| | | </script> |
New file |
| | |
| | | ## 生成入库订单 |
| | | |
| | | - **接口说明:** 生成入库订单 |
| | | - **接口地址:** /api/generatePakIn |
| | | |
| | | #### 请求参数 |
| | | |
| | | 参数名称 |类型 |出现要求 |描述 |
| | | :---- |:--- |:------ |:--- |
| | | Header | |必填 |请求报文头 |
| | |  appkey |string |必填 |密钥管理中生成appkey |
| | | Body | |必填 | |
| | |  orderNo |string |必填 |订单号 |
| | |  orderType |int |必填 |订单类型(通过订单类型查询接口获取) |
| | |  orderDetails |object |必填 |物料详情 |
| | |   orderNo |string |必填 |订单号 |
| | |   matnr |string |必填 |物料号 |
| | |   anfme |double |必填 |数量 |
| | |  sign |string |可选 |签名 |
| | | |
| | | |
| | | 请求示例: |
| | | |
| | | ``` |
| | | { |
| | | "Header":{ |
| | | "appkey":"6cfb9f11935b4d0e1740f41598970c97", |
| | | }, |
| | | "Body":{ |
| | | "orderNo": 2024010311062541, |
| | | "orderType": 1, |
| | | "orderDetails": [ |
| | | { |
| | | "orderNo": 2024010311062541, |
| | | "matnr": "test001", |
| | | "anfme": 10 |
| | | } |
| | | ], |
| | | "sign": "8a7036cfe218e12f50f9107e9eb4a437" |
| | | } |
| | | } |
| | | |
| | | ``` |
| | | |
| | | |
| | | #### 返回结果 |
| | | |
| | | 参数名称 |类型 |出现要求 |描述 |
| | | :---- |:--- |:------ |:--- |
| | | code |int |必填 |响应码,代码定义请见“附录A 响应吗说明” |
| | | msg |string |必填 | |
| | | data |object |可选 | |
| | | |
| | | 示例: |
| | | |
| | | ``` |
| | | { |
| | | "msg": "操作成功", |
| | | "code": 200 |
| | | } |
| | | ``` |
| | | |
| | | ## 附录A 响应码说明 |
| | | |
| | | 响应码 |说明 |
| | | :---- |:--- |
| | | 200 |处理成功 |
| | | 500 |系统内部错误 |
| | |
| | | # API平台接口文档 v1.0 |
| | | |
| | | # AA公司BC平台接口文档 v3.2.0 |
| | | ## 规范说明 |
| | | |
| | | ## 1 规范说明 |
| | | ### 通信协议 |
| | | HTTP协议 |
| | | |
| | | ### 1.1 通信协议 |
| | | ### 请求方法 |
| | | 接口支持POST方法发起请求。 |
| | | |
| | | HTTPS协议[HTTPS协议](generateSign.html) |
| | | |
| | | ### 1.2 请求方法 |
| | | 所有接口只支持POST方法发起请求。 |
| | | |
| | | ### 1.3 字符编码 |
| | | HTTP通讯及报文BASE64编码均采用UTF-8字符集编码格式。 |
| | | |
| | | ### 1.4 格式说明 |
| | | 元素出现要求说明: |
| | | |
| | | 符号 |说明 |
| | | :----: |:--- |
| | | R |报文中该元素必须出现(Required) |
| | | O |报文中该元素可选出现(Optional) |
| | | C |报文中该元素在一定条件下出现(Conditional) |
| | | |
| | | ### 1.5 报文规范说明 |
| | | |
| | | 1. 报文规范仅针对交易请求数据进行描述; |
| | | |
| | | 2. 报文规范中请求报文的内容为Https请求报文中RequestData值的明文内容; |
| | | |
| | | 3. 报文规范分为请求报文和响应报文。请求报文描述由发起方,响应报文由报文接收方响应。 |
| | | |
| | | ### 1.6 请求报文结构 |
| | | 接口只接收两个参数 **RequestData** 和 **SignData** ,其中RequestData的值为请求内容,SignData的值为签名内容。 |
| | | |
| | | #### 1.6.1 参数说明 |
| | | **RequestData(请求内容):** 其明文为每次请求的具体参数,采用 JSON 格式,依次经过 DES 加密(以UTF-8编码、BASE64编码输出结果)和 URLEncode 后,作为 RequestData 的值。 |
| | | |
| | | **SignData(签名内容):** 请求参数(明文)的MD5加密字符串,用于校验RequestData是否合法。 |
| | | |
| | | #### 1.6.2 请求内容(RequestData)明文结构说明 |
| | | ### 请求内容结构说明 |
| | | |
| | | 采用JSON格式,其中包含Header(公有参数)、Body(私有参数)节点: |
| | | |
| | |
| | | |
| | | 公共参数(Header)是用于标识产品及接口鉴权的参数,每次请求均需要携带这些参数: |
| | | |
| | | 参数名称 |类型 |出现要求 |描述 |
| | | 参数名称 |类型 |参数要求 |描述 |
| | | :---- |:--- |:------ |:--- |
| | | Token |string |R |用户登录后token,没有登录则为空字符串 |
| | | Version |string |R |接口版本号 |
| | | SystemId |int |R |机构号,请求的系统Id |
| | | Timestamp |long |R |当前UNIX时间戳 |
| | | appkey |string | 必填 |密钥管理中生成appkey |
| | | |
| | | |
| | | #### 1.6.3 校验流程: |
| | | 服务端接收到请求后首先对RequestData进行DES解密出JSON字符串,然后对JSON字符串进行MD5加密,加密后的值与请求中的SignData值进行对比,如对比通过,视为合法请求,否则视为非法请求。 |
| | | ### 签名校验流程: |
| | | 服务端接收到请求后首先对Body剔除sign参数,并添加signKey值,再对Bode的key值进行自然排序。然后对JSON字符串进行MD5加密,加密后的值与Body中的sign值进行对比,如对比通过,视为合法请求,否则视为非法请求。 |
| | | |
| | | **DES加密/解密函数示例:** |
| | | |
| | | C#版: |
| | | |
| | | ``` |
| | | /// <summary> |
| | | /// 进行DES加密。 |
| | | /// </summary> |
| | | /// <param name="decryptString">要加密的字符串。</param> |
| | | /// <param name="secretKey">密钥,且必须为8位。</param> |
| | | /// <returns>以Base64格式返回的加密字符串。</returns> |
| | | public static string DesEncrypt(string decryptString, string secretKey) |
| | | { |
| | | using (DESCryptoServiceProvider des = new DESCryptoServiceProvider()) |
| | | { |
| | | byte[] inputByteArray = Encoding.UTF8.GetBytes(decryptString); |
| | | des.Key = Encoding.ASCII.GetBytes(secretKey); |
| | | des.IV = Encoding.ASCII.GetBytes(secretKey); |
| | | MemoryStream ms = new MemoryStream(); |
| | | using (CryptoStream cs = new CryptoStream(ms, des.CreateEncryptor(), CryptoStreamMode.Write)) |
| | | { |
| | | cs.Write(inputByteArray, 0, inputByteArray.Length); |
| | | cs.FlushFinalBlock(); |
| | | cs.Close(); |
| | | } |
| | | string str = Convert.ToBase64String(ms.ToArray()); |
| | | ms.Close(); |
| | | return str; |
| | | } |
| | | } |
| | | |
| | | /// <summary> |
| | | /// 进行DES解密。 |
| | | /// </summary> |
| | | /// <param name="encryptedString">要解密的以Base64</param> |
| | | /// <param name="secretKey">密钥,且必须为8位。</param> |
| | | /// <returns>已解密的字符串。</returns> |
| | | public static string DesDecrypt(string encryptedString, string secretKey) |
| | | { |
| | | byte[] inputByteArray = Convert.FromBase64String(encryptedString); |
| | | using (DESCryptoServiceProvider des = new DESCryptoServiceProvider()) |
| | | { |
| | | des.Key = Encoding.ASCII.GetBytes(secretKey); |
| | | des.IV = Encoding.ASCII.GetBytes(secretKey); |
| | | MemoryStream ms = new MemoryStream(); |
| | | using (CryptoStream cs = new CryptoStream(ms, des.CreateDecryptor(), CryptoStreamMode.Write)) |
| | | { |
| | | cs.Write(inputByteArray, 0, inputByteArray.Length); |
| | | cs.FlushFinalBlock(); |
| | | cs.Close(); |
| | | } |
| | | string str = Encoding.UTF8.GetString(ms.ToArray()); |
| | | ms.Close(); |
| | | return str; |
| | | } |
| | | } |
| | | ``` |
| | | |
| | | JAVA版: |
| | | |
| | | ``` |
| | | /* DES解密 */ |
| | | public static String decrypt(String message, String key) throws Exception { |
| | | |
| | | byte[] bytesrc = Base64.decode(message); |
| | | //convertHexString(message); |
| | | Cipher cipher = Cipher.getInstance("DES/CBC/PKCS5Padding"); |
| | | DESKeySpec desKeySpec = new DESKeySpec(key.getBytes("UTF-8")); |
| | | SecretKeyFactory keyFactory = SecretKeyFactory.getInstance("DES"); |
| | | SecretKey secretKey = keyFactory.generateSecret(desKeySpec); |
| | | IvParameterSpec iv = new IvParameterSpec(key.getBytes("UTF-8")); |
| | | cipher.init(Cipher.DECRYPT_MODE, secretKey, iv); |
| | | byte[] retByte = cipher.doFinal(bytesrc); |
| | | return new String(retByte); |
| | | } |
| | | |
| | | |
| | | /* DES加密 */ |
| | | public static byte[] encrypt(String message, String key) throws Exception { |
| | | Cipher cipher = Cipher.getInstance("DES/CBC/PKCS5Padding"); |
| | | DESKeySpec desKeySpec = new DESKeySpec(key.getBytes("UTF-8")); |
| | | SecretKeyFactory keyFactory = SecretKeyFactory.getInstance("DES"); |
| | | SecretKey secretKey = keyFactory.generateSecret(desKeySpec); |
| | | IvParameterSpec iv = new IvParameterSpec(key.getBytes("UTF-8")); |
| | | cipher.init(Cipher.ENCRYPT_MODE, secretKey, iv); |
| | | return cipher.doFinal(message.getBytes("UTF-8")); |
| | | } |
| | | ``` |
| | | |
| | | #### 1.6.4 DES密钥 |
| | | |
| | | 测试环境:az2ih1uY |
| | | |
| | | 生产环境:另外提供。 |
| | | |
| | | #### 1.6.5 请求报文示例 |
| | | ### 请求报文示例 |
| | | 请求内容明文: |
| | | |
| | | ``` |
| | | { |
| | | "Header":{ |
| | | "Token":"2366CF921FAD44CCBB07FF9CD02FC90E", |
| | | "Version":"3.2.0", |
| | | "SystemId":100, |
| | | "Timestamp":1502870664 |
| | | }, |
| | | "Body":{ |
| | | "Mobile":"18520322032", |
| | | "Password":"acb000000" |
| | | } |
| | | } |
| | | |
| | | ``` |
| | | |
| | | 请求报文示例: |
| | | |
| | | ``` |
| | | url?RequestData=UFAYIRF21XzGoaAaEU54qoDBYaFkT2KbRpWxKZuqqltApdIneF7AjlEArPLsg3%2Fo1Pu7FHFmsKZn%0A9KJb%2BGuwx0P%2F3jzv2TgwUpVtgwEdfd0vIRfqEF4jCouldaxxVBjbHvd%2F08pUoYJDNZJLvNrJ%2BsK4%0A79de92T0Cyu4hKNMUPtVI7Tp0IC%2BBw%3D%3D&SignData=0865c7d625f90d3bb5457f5d9ac3725d |
| | | ``` |
| | | |
| | | ### 1.7 响应报文结构 |
| | | #### 1.7.1 结构说明 |
| | | 所有接口响应均采用JSON格式,如无特殊说明,每次请求的返回值中,都包含下列字段: |
| | | |
| | | 参数名称 |类型 |出现要求 |描述 |
| | | :---- |:--- |:------ |:--- |
| | | Code |int |R |响应码,代码定义请见“附录A 响应吗说明” |
| | | Msg |string |R |响应描述 |
| | | Data |object |R |每个接口特有的参数,详见每个接口定义 |
| | | |
| | | |
| | | #### 1.7.2 响应报文示例 |
| | | |
| | | ``` |
| | | { |
| | | "Code":200, |
| | | "Msg":"调用成功", |
| | | "Data":{ |
| | | "Channel":"A10086", |
| | | "Type":7004 |
| | | } |
| | | "orderNo": 2024010311062541, |
| | | "orderType": 1, |
| | | "orderDetails": [ |
| | | { |
| | | "orderNo": 2024010311062541, |
| | | "matnr": "test001", |
| | | "anfme": 10 |
| | | } |
| | | ], |
| | | "sign": "8a7036cfe218e12f50f9107e9eb4a437" |
| | | } |
| | | ``` |
| | | |
| | | |
| | | ## 2. 接口定义 |
| | | |
| | | ### 2.1 密码登录 |
| | | - **接口说明:** 密码登录 |
| | | - **接口地址:** /account/signin |
| | | |
| | | #### 2.1.1 请求参数 |
| | | |
| | | 参数名称 |类型 |出现要求 |描述 |
| | | :---- |:--- |:------ |:--- |
| | | Header | |R |请求报文头 |
| | |  Token |string |R |用户登录后token,没有登录则为空字符串 |
| | |  Version |string |R |接口版本号 |
| | |  SystemId |int |R |机构号,请求的系统Id |
| | |  Timestamp |long |R |当前UNIX时间戳 |
| | | Body | |R | |
| | |  Mobile |string |R |手机号 |
| | |  Password |string |R |密码 |
| | | |
| | | |
| | | 请求示例: |
| | | ### 等待签名报文示例 |
| | | 等待签名报文(已剔除sign值、已添加signKey值并对key进行自然排序): |
| | | |
| | | ``` |
| | | { |
| | | "Header":{ |
| | | "Token":"", |
| | | "Version":"3.2.0", |
| | | "SystemId":100, |
| | | "Timestamp":1502870664 |
| | | }, |
| | | "Body":{ |
| | | "Mobile":"18520322032", |
| | | "Password":"acb000000" |
| | | } |
| | | } |
| | | |
| | | {"orderDetails":[{"orderNo":"2024010311062541","matnr":"test001","anfme":10.0}],"orderType":1,"orderNo":"2024010311062541","signKey":"29823ebbfbc2f04a5fbb407ea926832f"} |
| | | ``` |
| | | |
| | | |
| | | #### 2.1.2 返回结果 |
| | | |
| | | 参数名称 |类型 |出现要求 |描述 |
| | | :---- |:--- |:------ |:--- |
| | | Code |int |R |响应码,代码定义请见“附录A 响应吗说明” |
| | | Msg |string |R | |
| | | Data |object |R | |
| | |  UserId |string |R |用户Id |
| | | |
| | | 示例: |
| | | |
| | | ``` |
| | | { |
| | | "Code":200, |
| | | "Msg":"登录成功", |
| | | "Data":{ |
| | | "UserId":"7D916C7283434955A235C17DD9B71C64" |
| | | } |
| | | } |
| | | ``` |
| | | |
| | | |
| | | |
| | | ### 2.2 获取登录用户信息 |
| | | - **接口说明:** 获取登录用户信息 |
| | | - **接口地址:** /account/profile |
| | | |
| | | #### 2.2.1 请求参数 |
| | | |
| | | 参数名称 |类型 |出现要求 |描述 |
| | | :---- |:--- |:------ |:--- |
| | | Header | |R |请求报文头 |
| | |  Token |string |R |用户登录后token,没有登录则为空字符串 |
| | |  Version |string |R |接口版本号 |
| | |  SystemId |int |R |机构号,请求的系统Id |
| | |  Timestamp |long |R |当前UNIX时间戳 |
| | | Body | |R | |
| | | |
| | | |
| | | |
| | | 请求示例: |
| | | |
| | | ``` |
| | | |
| | | { |
| | | "Header":{ |
| | | "Token":"CA64A439E7C344B0BA7F5C825E17C7AB", |
| | | "Version":"3.2.0", |
| | | "SystemId":100, |
| | | "Timestamp":1502870664 |
| | | }, |
| | | "Body":null |
| | | } |
| | | |
| | | ``` |
| | | |
| | | |
| | | #### 2.2.2 返回结果 |
| | | |
| | | 参数名称 |类型 |出现要求 |描述 |
| | | :---- |:--- |:------ |:--- |
| | | Code |int |R |响应码,代码定义请见“附录A 响应吗说明” |
| | | Msg |string |R | |
| | | Data |object |R | |
| | |  UserId |string |R |用户Id |
| | |  RealName |string |R |姓名 |
| | |  ImageUrl |string |R |头像 |
| | |  Score |int |R |积分 |
| | |  Nickname |string |R |昵称 |
| | |  Sex |int |R |性别:0-未知、1-男、2-女 |
| | |  Title |string |R |头衔 |
| | | |
| | | |
| | | 示例: |
| | | |
| | | ``` |
| | | { |
| | | "Code":200, |
| | | "Msg":"处理成功", |
| | | "Data":{ |
| | | "UserId":"7D916C7283434955A235C17DD9B71C64", |
| | | "RealName":"张三", |
| | | "ImageUrl":"https://img.xx.net/afdicew8751.png", |
| | | "Score":4732, |
| | | "Nickname":"张冠李戴", |
| | | "Sex":1, |
| | | "Title":"侠客Lv4" |
| | | } |
| | | } |
| | | ``` |
| | | |
| | | |
| | | ## 3 附录A 响应码说明 |
| | | |
| | | 响应码 |说明 |
| | | :---- |:--- |
| | | 200 |处理成功 |
| | | 301 |解析报文错误 |
| | | 302 |无效调用凭证 |
| | | 303 |参数不正确 |
| | | 500 |系统内部错误 |
| | | 999 |处理失败 |
| | | |
| | | |
| | | ## 4 附录B 币种 |
| | | |
| | | 币种 |说明 |
| | | :---- |:--- |
| | | RMB |人民币 |
| | | HKD |港币 |
| | | JPY |日元 |
| | | TWD |新台币 |
| | | USD |美元 |
| | | VND |越南盾 |
| | | THB |泰铢 |
| | | 将上面的报文进行md5加密得出值为:```8a7036cfe218e12f50f9107e9eb4a437``` |
New file |
| | |
| | | <!DOCTYPE html> |
| | | <html lang="en"> |
| | | <head> |
| | | <meta charset="UTF-8"> |
| | | <title>API开放平台 - 上报接口管理</title> |
| | | <link rel="stylesheet" href="../static/css/element.css"> |
| | | <link rel="stylesheet" href="../static/css/common.css"> |
| | | <script type="text/javascript" src="../static/js/jquery/jquery-3.3.1.min.js"></script> |
| | | <script type="text/javascript" src="../static/js/vue.min.js"></script> |
| | | <script type="text/javascript" src="../static/js/showdown.min.js"></script> |
| | | <script type="text/javascript" src="../static/js/common.js"></script> |
| | | <script type="text/javascript" src="../static/js/element.js"></script> |
| | | </head> |
| | | <body> |
| | | <div id="app" style="display: flex;justify-content: center;flex-wrap: wrap;"> |
| | | <div style="width: 80%;"> |
| | | <el-card class="box-card"> |
| | | <el-form :inline="true" :model="tableSearchParam" class="demo-form-inline"> |
| | | <el-form-item label=""> |
| | | <el-input v-model="tableSearchParam.task_no" placeholder="任务号"></el-input> |
| | | </el-form-item> |
| | | <el-form-item> |
| | | <el-button type="primary" @click="getTableData">查询</el-button> |
| | | <el-button type="primary" @click="resetParam">重置</el-button> |
| | | </el-form-item> |
| | | </el-form> |
| | | <el-table ref="singleTable" :data="tableData" style="width: 100%;"> |
| | | <el-table-column property="id" label="#ID"> |
| | | </el-table-column> |
| | | <el-table-column property="wrkNo" label="工作号"> |
| | | </el-table-column> |
| | | <el-table-column property="taskNo" label="任务号"> |
| | | </el-table-column> |
| | | <el-table-column property="commandStatus$" label="指令状态"> |
| | | </el-table-column> |
| | | <el-table-column show-overflow-tooltip property="durationTime" label="持续时长"> |
| | | </el-table-column> |
| | | <el-table-column property="commandType" label="指令类型"> |
| | | </el-table-column> |
| | | <el-table-column property="device" label="设备"> |
| | | </el-table-column> |
| | | <el-table-column property="deviceLog" label="设备执行信息"> |
| | | </el-table-column> |
| | | <el-table-column property="commandDesc" label="命令描述"> |
| | | </el-table-column> |
| | | <el-table-column show-overflow-tooltip property="startTime$" label="开始时间"> |
| | | </el-table-column> |
| | | <el-table-column show-overflow-tooltip property="executeTime$" label="执行时间"> |
| | | </el-table-column> |
| | | <el-table-column show-overflow-tooltip property="completeTime$" label="完成时间"> |
| | | </el-table-column> |
| | | <el-table-column show-overflow-tooltip property="command" label="命令报文" width="250"> |
| | | </el-table-column> |
| | | </el-table> |
| | | |
| | | <div style="margin-top: 10px;"> |
| | | <el-pagination @size-change="handleSizeChange" @current-change="handleCurrentChange" |
| | | :current-page="currentPage" :page-sizes="pageSizes" :page-size="pageSize" |
| | | layout="total, sizes, prev, pager, next, jumper" :total="pageTotal"> |
| | | </el-pagination> |
| | | </div> |
| | | </el-card> |
| | | </div> |
| | | |
| | | <div style="position: fixed;top: 20px;right: 20px;width: 150px;border-left: 3px solid #f0f0f0;padding-left: 15px;"> |
| | | <div><el-button type="text" @click="switchPage('index.html')">规范说明</el-button></div> |
| | | <div><el-button type="text" @click="switchPage('reportCompleted.html')">任务完成上报</el-button></div> |
| | | <div><el-button type="text" @click="switchPage('reportCompleted.html')">任务取消上报</el-button></div> |
| | | <div><el-button type="text" @click="switchPage('reportCompleted.html')">库存上报</el-button></div> |
| | | <div><el-button type="text" @click="switchPage('reportApiManage.html')">上报API管理</el-button></div> |
| | | </div> |
| | | </div> |
| | | |
| | | <script> |
| | | var app = new Vue({ |
| | | el: '#app', |
| | | data: { |
| | | tableData: [], |
| | | currentPage: 1, |
| | | pageSizes: [16, 30, 50, 100, 150, 200], |
| | | pageSize: 16, |
| | | pageTotal: 0, |
| | | tableSearchParam: { |
| | | task_no: null, |
| | | }, |
| | | }, |
| | | created() { |
| | | this.init() |
| | | }, |
| | | methods: { |
| | | init() { |
| | | this.getTableData() |
| | | }, |
| | | getTableData() { |
| | | let that = this; |
| | | let data = this.tableSearchParam |
| | | data.curr = this.currentPage |
| | | data.limit = this.pageSize |
| | | $.ajax({ |
| | | url: baseUrl + "/commandInfoLog/list/auth", |
| | | headers: { |
| | | 'token': localStorage.getItem('token') |
| | | }, |
| | | data: data, |
| | | dataType: 'json', |
| | | contentType: 'application/json;charset=UTF-8', |
| | | method: 'GET', |
| | | success: function(res) { |
| | | if (res.code == 200) { |
| | | that.tableData = res.data.records |
| | | that.pageTotal = res.data.total |
| | | } else { |
| | | that.$message({ |
| | | message: res.msg, |
| | | type: 'error' |
| | | }); |
| | | } |
| | | } |
| | | }); |
| | | }, |
| | | handleSizeChange(val) { |
| | | console.log(`每页 ${val} 条`); |
| | | this.pageSize = val |
| | | this.getTableData() |
| | | }, |
| | | handleCurrentChange(val) { |
| | | console.log(`当前页: ${val}`); |
| | | this.currentPage = val |
| | | this.getTableData() |
| | | }, |
| | | resetParam() { |
| | | this.tableSearchParam = { |
| | | task_no: null, |
| | | status: null, |
| | | wrk_no: null |
| | | } |
| | | this.getTableData() |
| | | }, |
| | | switchPage(url) { |
| | | location.href = url |
| | | } |
| | | } |
| | | }) |
| | | </script> |
| | | </body> |
| | | </html> |
New file |
| | |
| | | <!DOCTYPE html> |
| | | <html lang="en"> |
| | | <head> |
| | | <meta charset="UTF-8"> |
| | | <title>API开放平台</title> |
| | | <link rel="stylesheet" href="../static/css/element.css"> |
| | | <link rel="stylesheet" href="../static/css/common.css"> |
| | | <script type="text/javascript" src="../static/js/jquery/jquery-3.3.1.min.js"></script> |
| | | <script type="text/javascript" src="../static/js/vue.min.js"></script> |
| | | <script type="text/javascript" src="../static/js/showdown.min.js"></script> |
| | | <script type="text/javascript" src="../static/js/common.js"></script> |
| | | <script type="text/javascript" src="../static/js/element.js"></script> |
| | | </head> |
| | | <body> |
| | | <div id="app"> |
| | | <div id="content"></div> |
| | | <div style="position: fixed;top: 20px;right: 20px;width: 100px;"> |
| | | <div style="position: fixed;top: 20px;right: 20px;width: 150px;border-left: 3px solid #f0f0f0;padding-left: 15px;"> |
| | | <div><el-button type="text" @click="switchPage('index.html')">规范说明</el-button></div> |
| | | <div><el-button type="text" @click="switchPage('reportCompleted.html')">任务完成上报</el-button></div> |
| | | <div><el-button type="text" @click="switchPage('reportCompleted.html')">任务取消上报</el-button></div> |
| | | <div><el-button type="text" @click="switchPage('reportCompleted.html')">库存上报</el-button></div> |
| | | <div><el-button type="text" @click="reportApiManage()">上报接口管理</el-button></div> |
| | | |
| | | |
| | | <div><el-button type="text" @click="keyList()">密钥管理</el-button></div> |
| | | </div> |
| | | </div> |
| | | |
| | | <el-dialog title="密钥管理" :visible.sync="keyTableVisible"> |
| | | <el-table :data="keyTableData" v-loading="loading"> |
| | | <el-table-column property="hostId$" label="仓库"></el-table-column> |
| | | <el-table-column property="signKey" label="签名密钥" width="150"></el-table-column> |
| | | <el-table-column property="appKey" label="接口请求密钥" width="250"></el-table-column> |
| | | <el-table-column property="createTime$" label="时间" width="200"></el-table-column> |
| | | <el-table-column label="操作" width="400"> |
| | | <template slot-scope="scope"> |
| | | <el-button size="mini" @click="generateSignKey(scope.row.hostId)">签名密钥</el-button> |
| | | <el-button size="mini" @click="generateAppKey(scope.row.hostId)">接口密钥</el-button> |
| | | <el-switch |
| | | v-model="scope.row.signStatus" |
| | | @change="switchChange(scope.row.hostId,scope.row.signStatus)" |
| | | active-text="开启签名" |
| | | inactive-text="关闭签名"> |
| | | </el-switch> |
| | | </template> |
| | | </el-table-column> |
| | | </el-table> |
| | | </el-dialog> |
| | | </div> |
| | | |
| | | <script> |
| | | showdown.setOption('tables', true); |
| | | var converter = new showdown.Converter() |
| | | |
| | | var app = new Vue({ |
| | | el: '#app', |
| | | data: { |
| | | keyTableVisible: false, |
| | | keyTableData: [], |
| | | loading: true |
| | | }, |
| | | created() { |
| | | this.init() |
| | | }, |
| | | methods: { |
| | | init() { |
| | | this.introduceClick() |
| | | }, |
| | | introduceClick() { |
| | | $.ajax({ |
| | | url: "md/introduce.md", |
| | | headers: {'token': localStorage.getItem('token')}, |
| | | method: 'GET', |
| | | success: function (res) { |
| | | // $("#content").html(marked.parse(res)) |
| | | // console.log(converter.makeHtml(res)) |
| | | $("#content").html(converter.makeHtml(res)) |
| | | } |
| | | }); |
| | | }, |
| | | keyList() { |
| | | let that = this |
| | | this.keyTableVisible = true |
| | | $.ajax({ |
| | | url: baseUrl + "/hostKey/list/auth", |
| | | headers: {'token': localStorage.getItem('token')}, |
| | | data: {}, |
| | | dataType:'json', |
| | | contentType:'application/json;charset=UTF-8', |
| | | method: 'POST', |
| | | success: function (res) { |
| | | let tmp = [] |
| | | res.data.forEach((item, index) => { |
| | | item.signStatus = item.signStatus == 1 ? true : false; |
| | | tmp.push(item) |
| | | }); |
| | | that.keyTableData = tmp |
| | | that.loading = false |
| | | } |
| | | }); |
| | | }, |
| | | generateSignKey(hostId) { |
| | | let that = this |
| | | this.$confirm('此操作将覆盖原签名密钥, 是否继续?', '提示', { |
| | | confirmButtonText: '确定', |
| | | cancelButtonText: '取消', |
| | | type: 'warning' |
| | | }).then(() => { |
| | | $.ajax({ |
| | | url: baseUrl + "/hostKey/generateSignKey/auth", |
| | | headers: {'token': localStorage.getItem('token')}, |
| | | data: { |
| | | hostId: hostId |
| | | }, |
| | | dataType: 'json', |
| | | contentType: 'application/json;charset=UTF-8', |
| | | method: 'GET', |
| | | success: function (res) { |
| | | if (res.code === 200) { |
| | | that.$message({ |
| | | type: 'success', |
| | | message: '生成成功' |
| | | }); |
| | | |
| | | that.keyTableData.forEach((item, index) => { |
| | | if (item.hostId == hostId) { |
| | | item.signKey = res.data.signKey |
| | | } |
| | | }); |
| | | } else { |
| | | that.$message({ |
| | | type: 'error', |
| | | message: res.msg |
| | | }); |
| | | } |
| | | } |
| | | }); |
| | | }).catch(() => { |
| | | //取消 |
| | | }); |
| | | }, |
| | | generateAppKey(hostId) { |
| | | let that = this |
| | | this.$confirm('此操作将覆盖原接口密钥, 是否继续?', '提示', { |
| | | confirmButtonText: '确定', |
| | | cancelButtonText: '取消', |
| | | type: 'warning' |
| | | }).then(() => { |
| | | $.ajax({ |
| | | url: baseUrl + "/hostKey/generateAppKey/auth", |
| | | headers: {'token': localStorage.getItem('token')}, |
| | | data: { |
| | | hostId: hostId |
| | | }, |
| | | dataType: 'json', |
| | | contentType: 'application/json;charset=UTF-8', |
| | | method: 'GET', |
| | | success: function (res) { |
| | | if (res.code === 200) { |
| | | that.$message({ |
| | | type: 'success', |
| | | message: '生成成功' |
| | | }); |
| | | |
| | | that.keyTableData.forEach((item, index) => { |
| | | if (item.hostId == hostId) { |
| | | item.appKey = res.data.appKey |
| | | } |
| | | }); |
| | | } else { |
| | | that.$message({ |
| | | type: 'error', |
| | | message: res.msg |
| | | }); |
| | | } |
| | | } |
| | | }); |
| | | }).catch(() => { |
| | | //取消 |
| | | }); |
| | | }, |
| | | switchChange(hostId, signStatus) { |
| | | let that = this |
| | | //签名校验开关 |
| | | $.ajax({ |
| | | url: baseUrl + "/hostKey/switchSign/auth", |
| | | headers: {'token': localStorage.getItem('token')}, |
| | | data: { |
| | | hostId: hostId, |
| | | signStatus: signStatus ? 1 : 0, |
| | | }, |
| | | dataType: 'json', |
| | | contentType: 'application/json;charset=UTF-8', |
| | | method: 'GET', |
| | | success: function (res) { |
| | | if (res.code === 200) { |
| | | that.$message({ |
| | | type: 'success', |
| | | message: '切换成功' |
| | | }); |
| | | } else { |
| | | that.$message({ |
| | | type: 'error', |
| | | message: res.msg |
| | | }); |
| | | } |
| | | } |
| | | }); |
| | | }, |
| | | switchPage(url) { |
| | | location.href = url |
| | | } |
| | | } |
| | | }) |
| | | </script> |
| | | </body> |
| | | </html> |