| @@ -0,0 +1,39 @@ | |||
| import request from "@/utils/request.js"; | |||
| /** | |||
| * @description 服务端api签名指南 | |||
| * @params | |||
| * @returns | |||
| */ | |||
| export function getAvailableApiGuideApi() { | |||
| return request({ | |||
| url: `/api/apiGuide/getAvailableApiGuide`, | |||
| method: 'get' | |||
| }) | |||
| } | |||
| /** | |||
| * @description 开放接口列表 | |||
| * @params | |||
| * @returns | |||
| */ | |||
| export function apiMenuApi() { | |||
| return request({ | |||
| url: `/api/apiMenu/list`, | |||
| method: 'get' | |||
| }) | |||
| } | |||
| /** | |||
| * @description 获取接口详情 | |||
| * @params | |||
| * @returns | |||
| */ | |||
| export function getContentApi(id) { | |||
| return request({ | |||
| url: `/api/apiMenu/get?id=${id}`, | |||
| method: 'get' | |||
| }) | |||
| } | |||
| @@ -62,7 +62,7 @@ | |||
| <span>{{ $t("cooperate.title") }}</span> | |||
| </template> | |||
| <el-menu-item-group> | |||
| <el-menu-item index="1-1">{{ $t("cooperate.api.title") }}</el-menu-item> | |||
| <el-menu-item index="1-1" @click="router.push('/api')">{{ $t("cooperate.api.title") }}</el-menu-item> | |||
| <el-menu-item index="1-2" @click="router.push('/privatization')">{{ $t("cooperate.privatization.title") }} </el-menu-item> | |||
| </el-menu-item-group> | |||
| </el-sub-menu> | |||
| @@ -109,23 +109,6 @@ export const constantRoutes: RouteRecordRaw[] = [ | |||
| }, | |||
| ], | |||
| }, { | |||
| path: "/", | |||
| component: Layout, | |||
| redirect: "/myAPI", | |||
| children: [ | |||
| { | |||
| path: "myAPI", | |||
| component: () => import("@/views/myAPI/index.vue"), | |||
| name: "myAPI", | |||
| meta: { | |||
| title: "myAPI", | |||
| icon: "homepage", | |||
| affix: true, | |||
| name: "API.title", | |||
| }, | |||
| }, | |||
| ], | |||
| },{ | |||
| path: "/", | |||
| component: Layout, | |||
| redirect: "/myRecharge", | |||
| @@ -210,6 +193,17 @@ export const constantRoutes: RouteRecordRaw[] = [ | |||
| name: "separation.title", | |||
| }, | |||
| }, | |||
| { | |||
| path: "/api", | |||
| component: () => import("@/views/api/index.vue"), | |||
| name: "api", | |||
| meta: { | |||
| title: "api", | |||
| icon: "homepage", | |||
| affix: true, | |||
| name: "separation.title", | |||
| }, | |||
| }, | |||
| ], | |||
| }, | |||
| @@ -0,0 +1,141 @@ | |||
| <!DOCTYPE html> | |||
| <html lang="en"> | |||
| <head> | |||
| <meta charset="UTF-8"> | |||
| <meta name="viewport" content="width=device-width, initial-scale=1.0"> | |||
| <title>Document</title> | |||
| <style> | |||
| * { | |||
| padding: 0; | |||
| margin: 0; | |||
| } | |||
| .page { | |||
| padding: 50px | |||
| } | |||
| h1 { | |||
| font-size: 20px; | |||
| font-weight: 600; | |||
| margin-bottom: 0.8em; | |||
| } | |||
| p { | |||
| margin-bottom: 0.5em; | |||
| font-size: 14px; | |||
| line-height: 1.6; | |||
| } | |||
| .table { | |||
| margin-top: 50px; | |||
| } | |||
| .table .table-wrp { | |||
| margin: 1em 0 3em; | |||
| overflow-x: auto; | |||
| max-width: 100%; | |||
| } | |||
| .table table { | |||
| display: table; | |||
| width: 100%; | |||
| border-collapse: collapse; | |||
| border-spacing: 0; | |||
| overflow: auto; | |||
| font-size: 14px; | |||
| } | |||
| .table table th { | |||
| font-weight: 600; | |||
| text-align: left; | |||
| border-bottom: 1px solid #888; | |||
| padding: 10px 20px; | |||
| white-space: nowrap; | |||
| color: #888; | |||
| } | |||
| .table table td { | |||
| color: #353535; | |||
| text-align: left; | |||
| border-bottom: 1px solid #e5e5e5; | |||
| padding: 20px 20px; | |||
| height: 62px; | |||
| box-sizing: border-box; | |||
| word-break: normal; | |||
| } | |||
| .style .code{ | |||
| background-color: #f9f9fa; | |||
| margin: 1em 0; | |||
| border-radius: 4px | |||
| } | |||
| </style> | |||
| </head> | |||
| <body> | |||
| <div class="page"> | |||
| <!-- 文字 --> | |||
| <div class="text"> | |||
| <h1>概述</h1> | |||
| <p>在小程序管理后台开启api加密后,开发者需要对原APl的请求内容 加密 与签名,同时AP的回包内容需要开发者验签 与 解密 。支持的api可参考接口调用。</p> | |||
| <p>目前支持以下几种算法,可在MP管理页配置。</p> | |||
| </div> | |||
| <!-- 表格 --> | |||
| <div class="table"> | |||
| <h1>API请求处理</h1> | |||
| <div class="table-wrp"> | |||
| <table> | |||
| <thead> | |||
| <tr> | |||
| <th>参数</th> | |||
| <th>类型</th> | |||
| <th>默认值</th> | |||
| <th>必填</th> | |||
| <th>备注</th> | |||
| </tr> | |||
| </thead> | |||
| <tbody> | |||
| <tr> | |||
| <td>iv</td> | |||
| <td>string</td> | |||
| <td></td> | |||
| <td>是</td> | |||
| <td>初始向量,为16字节base64字符串(解码后为12字节随机字符串)</td> | |||
| </tr> | |||
| <tr> | |||
| <td>data</td> | |||
| <td>string</td> | |||
| <td></td> | |||
| <td>是</td> | |||
| <td>加密后的密文,使用base64编码</td> | |||
| </tr> | |||
| <tr> | |||
| <td>authtag</td> | |||
| <td>string</td> | |||
| <td></td> | |||
| <td>是</td> | |||
| <td>GCM模式输出的认证信息,使用base64编码</td> | |||
| </tr> | |||
| </tbody> | |||
| </table> | |||
| </div> | |||
| </div> | |||
| <!-- 样式 --> | |||
| <div class="style"> | |||
| <h1>样式</h1> | |||
| <div class="code"> | |||
| <pre class="language-json"> | |||
| <code> | |||
| <span>{</span> | |||
| <span>"Sn"</span><span>:</span> <span>"fa05fe1e5bcc79b81ad5ad4b58acf787"</span><span>,</span> | |||
| <span>"Key"</span><span>:</span> <span>"otUpngOjU+nVQaWJIC3D/yMLV17RKaP6t4Ot9tbnzLY="</span> | |||
| <span>}</span> | |||
| </code> | |||
| </pre> | |||
| </div> | |||
| </div> | |||
| </div> | |||
| </body> | |||
| </html> | |||
| @@ -0,0 +1,125 @@ | |||
| <template> | |||
| <div class="page"> | |||
| <div class=""> | |||
| <el-menu | |||
| default-active="1-1" | |||
| class="sidebar" | |||
| @open="handleOpen" | |||
| @close="handleClose" | |||
| > | |||
| <el-sub-menu index="1"> | |||
| <template #title> | |||
| <span>开发前必读</span> | |||
| </template> | |||
| <el-menu-item index="1-1" @click="guide">服务端API签名指南</el-menu-item> | |||
| </el-sub-menu> | |||
| <el-sub-menu index="2"> | |||
| <template #title> | |||
| <span>开发接口</span> | |||
| </template> | |||
| <el-menu-item v-for="item in apiMenuList" :key="item.id" :index="item.id" @click="getContent(item.id)">{{ item.name }}</el-menu-item> | |||
| </el-sub-menu> | |||
| </el-menu> | |||
| </div> | |||
| <div class="content"> | |||
| <div v-html="content"></div> | |||
| </div> | |||
| </div> | |||
| </template> | |||
| <script setup> | |||
| import { getAvailableApiGuideApi, apiMenuApi, getContentApi } from '@/apis/api.js' | |||
| const handleOpen = (key, keyPath) => { | |||
| console.log(key, keyPath) | |||
| if (key === '2') { | |||
| getMenu() | |||
| } | |||
| } | |||
| const handleClose = (key, keyPath) => { | |||
| console.log(key, keyPath) | |||
| } | |||
| const content = ref(''); | |||
| // 签名指南 | |||
| const guide = () => { | |||
| getAvailableApiGuideApi().then(res => { | |||
| if(res.code === 200) { | |||
| content.value = res.data.content | |||
| } | |||
| }) | |||
| } | |||
| // 开发接口 | |||
| const apiMenuList = ref([]) | |||
| const getMenu = () => { | |||
| apiMenuApi().then(res => { | |||
| if (res.code === 200) { | |||
| apiMenuList.value = res.data | |||
| } | |||
| }) | |||
| } | |||
| // 详情 | |||
| const getContent = (id) => { | |||
| getContentApi(id).then(res => { | |||
| if (res.code === 200) { | |||
| content.value = res.data.content || '' | |||
| } | |||
| }) | |||
| } | |||
| onMounted(() => { | |||
| guide() | |||
| }); | |||
| </script> | |||
| <style> | |||
| .sidebar.el-menu--vertical .el-sub-menu__title:hover { | |||
| background-color: #fff !important; | |||
| } | |||
| .sidebar.el-menu--vertical .el-menu-item:hover { | |||
| background-color: #fff !important; | |||
| } | |||
| </style> | |||
| <style lang="scss" scoped> | |||
| .page { | |||
| display: flex; | |||
| width: 100%; | |||
| overflow: hidden; | |||
| overflow-y: scroll; | |||
| background-color: #f5f5f5; | |||
| border-radius: 25px 0 0 0; | |||
| min-height: calc(100vh - 80px); | |||
| // text-align: center; | |||
| .title { | |||
| font-size: 50px; | |||
| } | |||
| .sidebar { | |||
| position: absolute; | |||
| width: 340px; | |||
| top: 0; | |||
| bottom: 0; | |||
| overflow: auto; | |||
| padding: 40px 30px; | |||
| box-sizing: border-box; | |||
| z-index: 1; | |||
| } | |||
| .content{ | |||
| position: absolute; | |||
| left: 340px; | |||
| right: 0; | |||
| top: 0; | |||
| bottom:0; | |||
| background: #fff; | |||
| padding: 40px 30px; | |||
| overflow: auto; | |||
| } | |||
| } | |||
| :deep(.el-submenu .el-menu:hover) { | |||
| background: transparent; | |||
| color: #d75b5f; | |||
| } | |||
| </style> | |||
| @@ -1,67 +0,0 @@ | |||
| <template> | |||
| <div class="page"> | |||
| <!-- <div class="title">{{ $t("API.comingSoon") }}</div> --> | |||
| <!-- 左侧名称 --> | |||
| <div class="left"> | |||
| <div class="scrollBox"> | |||
| <p>啊实打实大</p> | |||
| </div> | |||
| </div> | |||
| <!-- 右侧介绍 --> | |||
| <div class="right"> | |||
| <div class="scrollBox"></div> | |||
| </div> | |||
| </div> | |||
| </template> | |||
| <script setup> | |||
| // import { ref } from 'vue' | |||
| </script> | |||
| <style lang="scss" scoped> | |||
| .page { | |||
| display: flex; | |||
| width: 100%; | |||
| overflow: hidden; | |||
| overflow-y: scroll; | |||
| background-color: #f5f5f5; | |||
| border-radius: 25px 0 0 0; | |||
| min-height: calc(100vh - 80px); | |||
| // text-align: center; | |||
| .title { | |||
| font-size: 50px; | |||
| } | |||
| } | |||
| .left { | |||
| height: calc(100vh - 80px); | |||
| width: 30%; | |||
| padding: 30px 15px 30px 30px; | |||
| font-size: 20px; | |||
| background-color: #f5f5f5; | |||
| .scrollBox { | |||
| padding: 20px; | |||
| height: calc(100vh - 80px - 60px); | |||
| width: 100%; | |||
| overflow-y: scroll; | |||
| background-color: #fff; | |||
| border-radius: 20px; | |||
| box-shadow: rgba(0, 0, 0, 0.5) 0px 0px 15px; | |||
| } | |||
| } | |||
| .right { | |||
| height: calc(100vh - 80px); | |||
| width: 80%; | |||
| padding: 30px 30px 30px 15px; | |||
| background-color: #f5f5f5; | |||
| .scrollBox { | |||
| padding: 20px; | |||
| height: calc(100vh - 80px - 60px); | |||
| width: 100%; | |||
| overflow-y: scroll; | |||
| background-color: #fff; | |||
| border-radius: 20px; | |||
| box-shadow: rgba(0, 0, 0, 0.5) 0px 0px 15px; | |||
| } | |||
| } | |||
| </style> | |||