提交 9f41382d 作者: 潘亚楠

button测试200完成

上级 07fa1bbf
# web_log_test # 用户操作日志对接文档
## 说明
目前整个mis平台的日志系统,没有将前后端的日志串联起来,基于全链路追踪日志的设计,需要设计出一款适用于整个平台的日志系统。
## 日志形成及流向
+ 用户的交互操作(如按钮点击),会由组件库(或插件)生成统一的唯一key(时间戳+账号信息);
+ 组件库(或插件)将该key + 用户交互信息发送到日志服务, 写入数据库;
+ 因该次操作所产生的业务请求,也会携带key, 发送到业务服务;
+ 标准库中的拦截器将key + 业务服务的正常/异常响应,通过MQ发送到日志服务,日志服务消费之后,通过key形成用户操作到服务响应的闭环
> 测试用户交互操作的日志收集 ## 前端对接
## Build Setup
### 安装依赖
``` bash ``` bash
# install dependencies 1. 设置npm源
npm install npm config set registry http://39.106.145.141:9000/repository/node-public/
2. 安装
# serve with hot reload at localhost:8080 npm install wb_notebook-test1 -S
npm run dev ```
### 指令使用 项目入口文件 main.js
# build for production with minification ``` bash
npm run build // 操作收集指令
import collect from 'web_notebook-test1';
Vue.use(collect);
```
### axios替换
将axios替换为web_notebook-test1模块的Request, 该Request为[web标准库](https://git.allhome.com.cn/NetWorksDatas/Public/standard/blob/master/%E5%8D%83%E5%AE%B6Web%E6%A0%87%E5%87%86%E5%BA%93%E4%BD%BF%E7%94%A8%E8%AF%B4%E6%98%8E%E6%96%87%E6%A1%A3.md)中封装的
#### 由easy-mock-cli生成的的api, 修改instance.js;
``` bash
import config from '../config';
import { Request } from 'web_notebook-test1';
const baseURL = {
mock: 'http://mock.allhome.com.cn/mock/5db2630933901100102f2e2f/javaLog',
development : 'http://192.168.10.12:8991',
lan: `http://192.168.10.200:8009/projectName`,
pred: `https://dtgateway.allhome.com.cn/projectName`,
production: `https://gateway.allhome.com.cn/projectName`
}['development'];
# build for production and view the bundle analyzer report const request = new Request({
npm run build --report baseURL,
timeout: 60000,
}, 'development', 'yourWebAppName');
# run unit tests const devToken = 'tokenString';
npm run unit const token = window.token? window.token: (window.token = devToken);
# run e2e tests // 设置拦截器
npm run e2e request.interceptors({
request: config => {
config.headers.token = token;
return config
},
response: res => {
let {message, result, statusCode} = res.data
// 退出登录状态码
let logoutCodes = new Set([435001, 435011, 436050])
if (statusCode === 1000) {
// 更新全局token
let {pragma} = res.headers
if (pragma) window.token = pragma
// 返回数据
return result
} else if (logoutCodes.has(statusCode)) {
setTimeout(() => window.logout(), 1000)
return Promise.reject({message})
} else {
return Promise.reject({message,statusCode})
}
},
error: error => Promise.reject(error.response.data),
})
export default request.axios;
# run all tests
npm test
``` ```
#### 未使用easy-mock-cli的项目可直接直接参考[web标准库](https://git.allhome.com.cn/NetWorksDatas/Public/standard/blob/master/%E5%8D%83%E5%AE%B6Web%E6%A0%87%E5%87%86%E5%BA%93%E4%BD%BF%E7%94%A8%E8%AF%B4%E6%98%8E%E6%96%87%E6%A1%A3.md)替换
For a detailed explanation on how things work, check out the [guide](http://vuejs-templates.github.io/webpack/) and [docs for vue-loader](http://vuejs.github.io/vue-loader). \ No newline at end of file
...@@ -78,7 +78,11 @@ module.exports = { ...@@ -78,7 +78,11 @@ module.exports = {
limit: 10000, limit: 10000,
name: utils.assetsPath('fonts/[name].[hash:7].[ext]') name: utils.assetsPath('fonts/[name].[hash:7].[ext]')
} }
} },
{
test: /.md$/,
loader: 'text-loader'
},
] ]
}, },
node: { node: {
......
...@@ -15,6 +15,10 @@ ...@@ -15,6 +15,10 @@
}, },
"dependencies": { "dependencies": {
"axios": "^0.18.0", "axios": "^0.18.0",
"mavon-editor": "^2.7.7",
"moment": "^2.24.0",
"text-loader": "0.0.1",
"vue-markdown": "^2.2.4",
"vue-router": "^3.0.1", "vue-router": "^3.0.1",
"vuex": "^3.1.0", "vuex": "^3.1.0",
"web_notebook-test1": "^1.2.4" "web_notebook-test1": "^1.2.4"
......
...@@ -11,7 +11,20 @@ ...@@ -11,7 +11,20 @@
<el-main> <el-main>
<el-row> <el-row>
<el-col :span="24"> <el-col :span="24">
<router-view></router-view> <router-view @get-log="getLog">
<el-card class="box-card">
<div>
<div class='title'>交互日志</div>
<div v-for="(o) in interactionLog" :key="o._id" class="text item" style="word-break: break-all">
{{ JSON.stringify(o) }}
</div>
<div class='title'>服务日志</div>
<div v-for="(o, index) in serverLog" :key="o._id" class="text item" style="word-break: break-all">
<i style="padding-right: 20px;">{{ index + 1 }}</i>{{ JSON.stringify(o) }}
</div>
</div>
</el-card>
</router-view>
</el-col> </el-col>
</el-row> </el-row>
</el-main> </el-main>
...@@ -21,8 +34,54 @@ ...@@ -21,8 +34,54 @@
</template> </template>
<script> <script>
import bus from "@/assets/js/bus";
import axios from "axios";
import moment from 'moment';
export default { export default {
name: "App" name: "App",
data() {
return {
token: "",
interactionTimestamp: 0,
interactionLog: [],
serverLog: [],
};
},
created() {
bus.$on("request", ({ token, interactionTimestamp }) => {
this.token = token;
this.interactionTimestamp = interactionTimestamp;
});
},
methods: {
async getLog() {
const { token, interactionTimestamp } = this;
const request = axios.create({
baseURL: "http://192.168.10.200:8020/upaLogs",
headers: {
token,
interaction_timestamp: interactionTimestamp
}
});
// 给MQ传递预留2000ms
setTimeout(async _ => {
const { data } = await request.get("/dev/logLine"),
{ result } = data,
{ interactionLog, serverLog } = result;
this.interactionLog = this.formatTime(interactionLog);
this.serverLog = this.formatTime(serverLog);
}, 500);
},
formatTime(datas) {
return datas.map(obj => {
const { interaction_date } = obj;
obj.interaction_date = moment(interaction_date).format('YYYY-MM-DD: HH:mm:ss');
return obj;
})
}
}
}; };
</script> </script>
......
import Vue from 'vue';
export default new Vue();
\ No newline at end of file
/**
* @date 2019.10.25
* @author 潘亚楠
* @information 拦截器配置
*/
import createDebug from 'debug'
import bus from './bus';
// token // token
const devToken = 'L2bhC0FyEWXo9zkt6mQ15lMzsSgS3dR/V+w5iWSiMmG0H0t1pL9lr4o+nSKXhjOm9qT+UrXqbLUpiWmITwS1q6TPmZvSumEkoEzpYFr0ylbxHafk+uE8yvK9OWiYl9WEH/JdnMw2LVnVYur7LOe/r57MMxw4e/NxGKPo07pqgn8='; const devToken = 'L2bhC0FyEWXo9zkt6mQ15lMzsSgS3dR/V+w5iWSiMmG0H0t1pL9lr4o+nSKXhjOm9qT+UrXqbLUpiWmITwS1q6TPmZvSumEkoEzpYFr0ylbxHafk+uE8yvK9OWiYl9WEH/JdnMw2LVnVYur7LOe/r57MMxw4e/NxGKPo07pqgn8=';
const token = window.token? window.token: (window.token = devToken); const token = window.token? window.token: (window.token = devToken);
const debug = createDebug('test-拦截器');
export default { export default {
request: config => { request: config => {
config.headers.token = token; config.headers.token = token;
debug(config.headers);
const { interaction_timestamp: interactionTimestamp } = config.headers;
bus.$emit('request', { token, interactionTimestamp });
return config return config
}, },
response: res => { response: res => {
......
...@@ -22,13 +22,13 @@ function test_user_post(data) { ...@@ -22,13 +22,13 @@ function test_user_post(data) {
} }
/** 获取用户 */ /** 获取用户 */
function test_user_get(data) { function test_user_userId_get(data) {
return instance['get']( '/test/user', data) return instance['get'](convertRESTAPI('/test/user/{userId}', data), data)
} }
/** 删除一个用户 */ /** 删除一个用户 */
function test_user_delete(data) { function test_user_userId_delete(data) {
return instance['delete']( '/test/user', data) return instance['delete'](convertRESTAPI('/test/user/{userId}', data), data)
} }
/** 服务异常接口测试 */ /** 服务异常接口测试 */
...@@ -41,7 +41,7 @@ export { ...@@ -41,7 +41,7 @@ export {
test_user_page_head_get, test_user_page_head_get,
test_user_put, test_user_put,
test_user_post, test_user_post,
test_user_get, test_user_userId_get,
test_user_delete, test_user_userId_delete,
test_error_put test_error_put
}; };
...@@ -14,10 +14,14 @@ import collect from 'web_notebook-test1'; ...@@ -14,10 +14,14 @@ import collect from 'web_notebook-test1';
import debug from 'debug'; import debug from 'debug';
// 引入样式 // 引入样式
import './style/index.scss'; import './style/index.scss';
// 引入markdown编辑器
import mavonEditor from 'mavon-editor'
import 'mavon-editor/dist/css/index.css'
Vue.use(collect); Vue.use(collect);
Vue.use(element); Vue.use(element);
Vue.use(scan); Vue.use(scan);
Vue.use(mavonEditor)
Vue.config.productionTip = false; Vue.config.productionTip = false;
console.log(process.env.NODE_ENV ) console.log(process.env.NODE_ENV )
if (process.env.NODE_ENV === 'development') { if (process.env.NODE_ENV === 'development') {
......
import Vue from 'vue'; import Vue from 'vue';
import Router from 'vue-router'; import Router from 'vue-router';
// import HelloWorld from '@/components/HelloWorld' // import HelloWorld from '@/components/HelloWorld'
import Index from '@/view/index'; import Index from '@/view/Index';
import ButtonClick from '@/view/ButtonClick' import ButtonClick from '@/view/ButtonClick'
Vue.use(Router); Vue.use(Router);
......
...@@ -2,6 +2,7 @@ ...@@ -2,6 +2,7 @@
<div> <div>
<el-button @click="successfulClick">正常响应</el-button> <el-button @click="successfulClick">正常响应</el-button>
<el-button @click="errorClick">异常响应</el-button> <el-button @click="errorClick">异常响应</el-button>
<slot></slot>
</div> </div>
</template> </template>
...@@ -25,15 +26,25 @@ export default { ...@@ -25,15 +26,25 @@ export default {
* @information 服务器正常响应的点击事件 * @information 服务器正常响应的点击事件
*/ */
async successfulClick() { async successfulClick() {
const model = { const nodeModel = {
"userName": "string", "userName": "string",
"password": "string" "password": "string"
} }
let node = await nodeApi.rightServerPost({ const javaModel = {
userName: '张译',
phone: '10086'
}
try {
await nodeApi.rightServerPost({
param: [1, 2], param: [1, 2],
data: model data: nodeModel
}); });
let java = await javaApi.test_error_put(); await javaApi.test_user_post(javaModel);
} catch (error) {
}
this.$emit('get-log')
}, },
/** /**
* @date 2019.10.24 * @date 2019.10.24
...@@ -41,9 +52,19 @@ export default { ...@@ -41,9 +52,19 @@ export default {
* @information 服务器异常响应的点击事件 * @information 服务器异常响应的点击事件
*/ */
async errorClick() { async errorClick() {
await nodeApi.errorServerGet({ try {
await Promise.all([
nodeApi.errorServerGet({
query: {test: 111} query: {test: 111}
}) }),
javaApi.test_error_put()
])
// await
// await ;
} catch (error) {
}
this.$emit('get-log')
} }
} }
} }
......
<template> <template>
<div id="index"> <div id="index">
<el-card class="box-card">
<div>
<div class='title'>Button点击</div>
<div v-for="o in 4" :key="o" class="text item">
{{'说明TODO ' + o }}
</div>
</div>
<template slot="footer">
<div>
发布人:张某某
</div>
<div> <div>
<el-button type="info" plain @click="$router.push('buttonClick')">按钮测试页</el-button> <el-button type="info" plain @click="$router.push('buttonClick')">按钮测试页</el-button>
</div> </div>
</template> <vue-markdown>{{ README }}</vue-markdown>
</el-card>
</div> </div>
</template> </template>
...@@ -25,7 +13,21 @@ ...@@ -25,7 +13,21 @@
* @author author * @author author
* @date 2019-05-17 * @date 2019-05-17
*/ */
import VueMarkdown from 'vue-markdown';
import README from '../../README.md';
export default { export default {
name: 'Index',
components: {
VueMarkdown,
},
data() {
return {
mdValue: '',
edit: false,
README
}
},
mounted() { mounted() {
console.log("测试:", this); console.log("测试:", this);
} }
......
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论