Authored by 陈峰

commit

<template>
<Collapse accordion v-model="openAct" @on-change="actChange">
<Panel :name="act.name" v-for="act in list" :key="act.name">
{{act.name}}({{act.desc}})
<div slot="content" class="act-content" v-if="act.__rendered">
<h2>接口路径</h2>
<div class="path">{{getPath(act)}}</div>
<div v-if="showUrlParams(act)">
<h2>提交参数</h2>
<Table :columns="reqColumns" :data="paramsColumns(act)"></Table>
</div>
<div v-if="act.reqMethod === 'JSON'">
<h2>提交示例</h2>
<json-view :value="paramsJsonColumns(act)" icon-prefix="ivu-icon" @copied="copied"></json-view>
</div>
<div v-if="act.responseInfo.data">
<h2>返回示例</h2>
<json-view :value="act.responseInfo.data" icon-prefix="ivu-icon" @copied="copied"></json-view>
</div>
<div v-if="act.responseInfo.codeDesc.length">
<h2>状态码</h2>
<Table :width="500" :columns="codeColumns" :data="act.responseInfo.codeDesc"></Table>
</div>
</div>
</Panel>
</Collapse>
</template>
<script>
import _ from 'lodash';
import config from 'config';
import JsonView from 'vue-json-viewer';
export default {
name: 'DocActList',
props: {
list: Array
},
data() {
return {
test2: '',
openAct: [],
reqColumns: [{
title: '名称',
key: 'name'
}, {
title: '类型',
key: 'paramType'
}, {
title: '必填',
key: 'required'
}, {
title: '默认值',
key: 'defaultValue'
}, {
title: '描述',
key: 'desc'
}],
resColumns: [{
title: '类型',
key: 'clazz'
}, {
title: '描述',
key: 'desc'
}],
codeColumns: [{
title: '状态码',
key: 'code'
}, {
title: '说明',
key: 'desc'
}],
reqData: [],
resData: []
};
},
methods: {
actChange(open) {
let act = this.list.find(a => a.name === open[0]);
if (act) {
act.__rendered = true;
}
},
getPath(act) {
if (act.reqMethod === 'JSON') {
return config.axiosBaseUrl + act.path;
}
const params = act.paramInfo.map(param => {
return `${param.name}=${param.defaultValue}`;
}).join('&');
if (act.path.indexOf('method') >= 0) {
return `${config.axiosBaseUrl}/?${act.path}&${params}`;
}
return `${config.axiosBaseUrl}/?${params}`;
},
paramsColumns(act) {
return act.paramInfo[0].data ? this.transformParams(act.paramInfo[0].data) : act.paramInfo;
},
paramsJsonColumns(act) {
if (act.paramInfo.length && act.paramInfo[0].data !== 'object') {
let data = {};
act.paramInfo.forEach(param => {
data[param.name] = param.defaultValue;
});
return data;
}
return act.paramInfo[0].data;
},
showUrlParams(act) {
return (act.reqMethod === 'URL' && act.paramInfo.length) ||
(act.reqMethod === 'JSON' && act.paramInfo.length && typeof act.paramInfo[0].data !== 'object');
},
transformParams(data) {
return _.map(data, (v, k) => {
return {
name: k,
paramType: typeof v
};
});
},
copied() {
this.$Message.success('复制成功');
}
},
components: {
JsonView
}
};
</script>
<style lang="scss">
.act-content {
padding: 0 16px;
.path {
font-size: 15px;
}
}
</style>
<template>
<i-menu width="auto" class="doc-menu" :active-name="store.groupName" @on-select="selectGroup">
<i-menu-group title="分组">
<i-menu-item
:name="group.name"
v-for="group in store.groups"
:key="group.name">
{{group.desc}}
<i-spin class="group-spin"
size="small"
v-if="store.groupName === group.name && store.featchApising">
<Icon type="load-c" size="14" class="spin-icon-load"></Icon>
</i-spin>
</i-menu-item>
</i-menu-group>
</i-menu>
</template>
<script>
import {
FETCH_GROUP_REQUEST,
FETCH_API_REQUEST
} from 'store/types';
import {mapState} from 'vuex';
export default {
name: 'DocMenu',
computed: {
...mapState(['store'])
},
created() {
this.$store.dispatch(FETCH_GROUP_REQUEST);
},
methods: {
selectGroup(groupName) {
this.$store.dispatch(FETCH_API_REQUEST, {
groupName,
keyword: '',
searchType: ''
}).then(() => {
window.scrollTo(0, 0);
});
}
}
};
</script>
<style lang="scss">
.doc-menu {
.ivu-menu-item {
word-wrap: break-word;
}
.group-spin {
display: inline-block;
float: right;
}
.spin-icon-load {
animation: ani-spin 1s linear infinite;
}
@keyframes ani-spin {
from { transform: rotate(0deg);}
50% { transform: rotate(180deg);}
to { transform: rotate(360deg);}
}
}
</style>
<template>
<div class="search-box">
<i-form ref="formInline" inline>
<i-form-item>
<Input v-model="keyword" style="width: 300px;">
<Select v-model="searchType" slot="prepend" style="width: 100px">
<Option value="controller">controller</Option>
<Option value="keyword">关键词</Option>
</Select>
</Input>
</i-form-item>
<i-form-item>
<i-button type="primary" @click="searchAll" >搜全部</i-button>
<i-button type="primary" @click="searchGroup" v-show="store.groupName">搜当前分组</i-button>
<i-button type="warning" @click="reset">清空</i-button>
</i-form-item>
</i-form>
</div>
</template>
<script>
import {
FETCH_API_REQUEST
} from 'store/types';
import {mapState} from 'vuex';
export default {
name: 'DocSearch',
computed: {
...mapState(['store'])
},
data() {
return {
searchType: 'controller',
keyword: ''
};
},
methods: {
searchGroup() {
if (!this.keyword) {
this.$Message.warning('请输入关键词');
return;
}
this.$store.dispatch(FETCH_API_REQUEST, {
groupName: this.store.groupName,
keyword: this.keyword,
searchType: this.searchType
}).then(() => {
window.scrollTo(0, 0);
});
},
searchAll() {
if (!this.keyword) {
this.$Message.warning('请输入关键词');
return;
}
this.$store.dispatch(FETCH_API_REQUEST, {
groupName: '',
keyword: this.keyword,
searchType: this.searchType
}).then(() => {
window.scrollTo(0, 0);
});
},
reset() {
if (this.store.apiSearchType) {
this.keyword = '';
this.$store.dispatch(FETCH_API_REQUEST, {
groupName: this.store.groupName,
keyword: '',
searchType: ''
}).then(() => {
window.scrollTo(0, 0);
});
}
}
}
};
</script>
<style lang="scss">
.search-box {
padding: 20px;
border-bottom: solid 1px #dddee1;
.ivu-form-item {
margin-bottom: 0;
}
}
</style>
import DocMenu from './doc-menu';
import DocSearch from './doc-search';
import DocCtrlList from './doc-ctrl-list';
import DocActList from './doc-act-list';
import DocHeader from './doc-header';
import LayoutSearch from './layout-search';
import LayoutHeader from './layout-header';
import LayoutList from './layout-list';
export default {
DocMenu,
DocSearch,
DocCtrlList,
DocActList,
DocHeader
LayoutSearch,
LayoutHeader,
LayoutList
};
... ...
... ... @@ -10,7 +10,7 @@
<script>
export default {
name: 'DocHeader'
name: 'LayoutHeader'
};
</script>
... ...
<template>
<div class="result-list">
<h3>查询结果:</h3>
<i-table :columns="columns" :data="fulltext.fulltexts"></i-table>
<i-page
:current="fulltext.searchParams.page"
:page-size="fulltext.searchParams.rows"
:show-total="true"
:show-sizer="true"
:total="fulltext.count"
@on-change="pageChange"
@on-page-size-change="pageSizeChange"></i-page>
</div>
</template>
<script>
import ListExtend from './list-extend';
import {FETCH_FULLTEXT_REQUEST} from 'store/types';
import {mapState} from 'vuex';
export default {
name: 'LayoutList',
data() {
return {
columns: [{
type: 'expand',
width: 50,
render: (h, params) => {
return h(ListExtend, {
props: {
value: params.row
}
});
}
}, {
title: 'uid',
key: 'uid'
}, {
title: 'os',
key: 'os'
}, {
title: 'pt',
key: 'pt'
}, {
title: 'pn',
key: 'pn'
}, {
title: 'av',
key: 'av'
}]
};
},
computed: {
...mapState(['fulltext'])
},
methods: {
pageChange(page) {
this.$store.dispatch(FETCH_FULLTEXT_REQUEST, {page: page});
},
pageSizeChange(rows) {
this.$store.dispatch(FETCH_FULLTEXT_REQUEST, {rows: rows, page: 1});
}
}
};
</script>
<style lang="scss">
.result-list {
.ivu-page {
margin-top: 20px;
}
h3 {
margin-bottom: 10px;
}
}
</style>
... ...
<template>
<div class="search-box">
<h3>查询条件:</h3>
<i-form :label-width="60">
<i-form-item label="uid:">
<i-input v-model="forms.uid" placeholder="请输入uid"></i-input>
</i-form-item>
<i-form-item label="os:">
<i-input v-model="forms.os" placeholder="请输入(android or iOS)"></i-input>
</i-form-item>
<i-form-item label="pt:">
<i-input v-model="forms.pt" placeholder="请输入pt"></i-input>
</i-form-item>
<i-form-item label="pn:">
<i-input v-model="forms.pn" placeholder="请输入pn"></i-input>
</i-form-item>
<i-form-item label="av:">
<i-input v-model="forms.av" placeholder="请输入av"></i-input>
</i-form-item>
<i-form-item label="times:">
<Date-picker
type="datetimerange"
v-model="dateRange"
placement="bottom-start"
format="yyyy-MM-dd HH:mm:ss"
class="dt-limit"
:options="dtLimitOpt"
placeholder="选择开始结束日期"></Date-picker>
</i-form-item>
<i-form-item>
<i-button type="primary" @click="search">查询</i-button>
<i-button type="warning" @click="reset">清空</i-button>
</i-form-item>
</i-form>
</div>
</template>
<script>
import moment from 'moment';
import {FETCH_FULLTEXT_REQUEST} from 'store/types';
export default {
name: 'LayoutSearch',
data() {
return {
forms: {
uid: '',
os: '',
pt: '',
pn: '',
av: '',
ts_start: '',
ts_end: ''
},
dateRange: [moment().add(-7, 'days').format('YYYY-MM-DD HH:mm:ss'), moment().format('YYYY-MM-DD HH:mm:ss')],
dtLimitOpt: {
shortcuts: [
{
text: '最近一周',
value() {
const end = new Date();
const start = new Date();
start.setTime(start.getTime() - 3600 * 1000 * 24 * 7);
return [start, end];
}
},
{
text: '最近一个月',
value() {
const end = new Date();
const start = new Date();
start.setTime(start.getTime() - 3600 * 1000 * 24 * 30);
return [start, end];
}
},
{
text: '最近三个月',
value() {
const end = new Date();
const start = new Date();
start.setTime(start.getTime() - 3600 * 1000 * 24 * 90);
return [start, end];
}
}
]
}
};
},
methods: {
search() {
this.forms.ts_start = this.dateRange[0] ? moment(this.dateRange[0]).unix() : '';
this.forms.ts_end = this.dateRange[1] ? moment(this.dateRange[1]).unix() : '';
this.$store.dispatch(FETCH_FULLTEXT_REQUEST, Object.assign(this.forms, {
page: 1
}));
},
reset() {
this.forms = {
uid: '',
os: '',
pt: '',
pn: '',
av: '',
ts_start: '',
ts_end: ''
};
this.dateRange = [];
this.$store.dispatch(FETCH_FULLTEXT_REQUEST, Object.assign(this.forms, {
page: 1
}));
}
}
};
</script>
<style lang="scss">
.search-box {
.ivu-form-item {
margin-bottom: 10px;
}
h3 {
margin-bottom: 10px;
}
.dt-limit {
width: 280px;
}
}
</style>
... ...
<template>
<json-viewer :value="value" icon-prefix="ivu-icon" class="list-extend" @copied="copied"></json-viewer>
</template>
<script>
import JsonViewer from 'vue-json-viewer';
export default {
name: 'ListExtend',
props: {
value: [Object, Array]
},
components: {
JsonViewer
},
methods: {
copied() {
this.$Message.success('复制成功');
}
}
};
</script>
<style lang="scss">
.list-extend {
background: #fff;
}
</style>
... ...
const config = {
dev: {
axiosBaseUrl: 'http://172.16.6.201:8080',
axiosBaseUrl: '/api',
axiosResponseType: 'json',
},
production: {
axiosBaseUrl: 'http://172.16.6.201:8080',
axiosBaseUrl: '/api',
axiosResponseType: 'json',
}
};
... ...
<template>
<div class="layout">
<doc-header></doc-header>
<layout-header></layout-header>
<div class="layout-content">
<div class="layout-left">
<doc-menu></doc-menu>
<layout-search></layout-search>
</div>
<div class="layout-right">
<article>
<doc-search></doc-search>
<doc-ctrl-list></doc-ctrl-list>
</article>
<layout-list></layout-list>
</div>
</div>
<BackTop></BackTop>
... ... @@ -39,12 +36,15 @@ export default {
flex: auto;
}
.layout-left {
width: 200px;
padding-top: 5px;
padding-bottom: 5px;
width: 380px;
padding: 20px;
padding-top: 10px;
border-right: solid 1px #dddee1;
}
.layout-right {
flex: auto;
flex: 1;
padding: 20px;
padding-top: 10px;
position: relative;
& article:after {
... ...
import {
FETCH_FULLTEXT_FAILURE,
FETCH_FULLTEXT_REQUEST,
FETCH_FULLTEXT_SUCCESS
} from './types';
import api from 'common/api';
export default {
state: {
fetching: false,
fulltexts: [],
searchParams: {
page: 1,
count: 10
},
count: 0
},
mutations: {
[FETCH_FULLTEXT_REQUEST](state, params) {
state.featchApising = true;
state.searchParams = Object.assign(state.searchParams, params);
},
[FETCH_FULLTEXT_FAILURE](state) {
state.featchApising = false;
},
[FETCH_FULLTEXT_SUCCESS](state, params) {
state.featchApising = false;
state.fulltexts = params.data;
state.count = params.count;
}
},
actions: {
[FETCH_FULLTEXT_REQUEST]({commit, state}, params) {
commit(FETCH_FULLTEXT_REQUEST, params);
return api.get('/list', state.searchParams).then(res => {
if (res.code === 200) {
commit(FETCH_FULLTEXT_SUCCESS, {data: res.data, count: res.count});
} else {
commit(FETCH_FULLTEXT_FAILURE);
}
}, () => {
commit(FETCH_FULLTEXT_FAILURE);
});
}
}
};
... ...
import Vue from 'vue';
import Vuex from 'vuex';
import store from './store';
import fulltext from './fulltext';
Vue.use(Vuex);
... ... @@ -9,7 +9,7 @@ Vue.use(Vuex);
export function createStore() {
return new Vuex.Store({
modules: {
store
fulltext
},
strict: process.env.NODE_ENV !== 'production'
});
... ...
import {
FETCH_API_FAILURE,
FETCH_API_REQUEST,
FETCH_API_SUCCESS,
FETCH_GROUP_FAILURE,
FETCH_GROUP_REQUEST,
FETCH_GROUP_SUCCESS
} from './types';
import api from 'common/api';
export default {
state: {
cacheApis: {},
groups: [],
fetchGroupsing: false,
apis: [],
featchApising: false,
groupName: '',
apiPage: 1,
apiRows: 10,
apiCount: 0,
apiKeyword: '',
apiSearchType: ''
},
mutations: {
[FETCH_GROUP_REQUEST](state) {
state.fetchGroupsing = true;
},
[FETCH_GROUP_FAILURE](state) {
state.fetchGroupsing = false;
},
[FETCH_GROUP_SUCCESS](state, params) {
state.fetchGroupsing = false;
state.groups = params.list;
params.list.forEach(group => {
state.cacheApis[group.name] = {
rows: [],
total: 0
};
});
},
[FETCH_API_REQUEST](state, params) {
if (params.groupName === '') {
state.groupName = '';
} else if (params.groupName) {
state.groupName = params.groupName;
}
if (params.keyword === '') {
state.apiKeyword = '';
} else if (params.keyword) {
state.apiKeyword = params.keyword;
}
if (params.searchType === '') {
state.apiSearchType = '';
} else if (params.searchType) {
state.apiSearchType = params.searchType;
}
state.apiPage = params.page || 1;
state.apiRows = params.rows || state.apiRows;
state.featchApising = true;
},
[FETCH_API_FAILURE](state) {
state.featchApising = false;
},
[FETCH_API_SUCCESS](state, params) {
state.featchApising = false;
state.apiCount = params.data.total;
state.apis = params.data.rows;
if (!state.apiSearchType && state.groupName && !params.cache) {
const groupCache = state.cacheApis[state.groupName];
const start = (state.apiPage - 1) * state.apiRows;
if (groupCache.rows.length >= start) {
groupCache.rows.splice(start, state.apiRows, ...params.data.rows);
groupCache.total = params.data.total;
}
groupCache.__cached = true;
}
}
},
actions: {
[FETCH_GROUP_REQUEST]({commit}) {
commit(FETCH_GROUP_REQUEST);
return api.get('/gateway/api/findGroup').then(res => {
commit(FETCH_GROUP_SUCCESS, {list: res});
}, () => {
commit(FETCH_GROUP_FAILURE);
});
},
[FETCH_API_REQUEST]({commit, state}, params) {
let apiPromise;
commit(FETCH_API_REQUEST, params);
if (state.apiSearchType === 'controller') {
apiPromise = api.get('/gateway/api/findByName', {
groupName: state.groupName || void 0,
key: state.apiKeyword,
page: state.apiPage,
rows: state.apiRows
});
} else if (state.apiSearchType === 'keyword') {
apiPromise = api.get('/gateway/api/find', {
groupName: state.groupName || void 0,
key: state.apiKeyword,
page: state.apiPage,
rows: state.apiRows
});
} else {
const cacheGroup = state.cacheApis[state.groupName];
if (cacheGroup && cacheGroup.__cached) {
const start = (state.apiPage - 1) * state.apiRows;
const end = state.apiPage * state.apiRows > cacheGroup.total ? cacheGroup.total : state.apiPage * state.apiRows;
if (cacheGroup.rows.length >= end) {
commit(FETCH_API_SUCCESS, {
data: {
total: cacheGroup.total,
rows: cacheGroup.rows.slice(start, end)
},
cache: true
});
return Promise.resolve();
}
}
apiPromise = api.get('/gateway/api/findByGroup', {
key: state.groupName,
page: state.apiPage,
rows: state.apiRows
});
}
return apiPromise.then(res => {
if (res.code === 200) {
commit(FETCH_API_SUCCESS, {data: res.data});
} else {
commit(FETCH_API_FAILURE);
}
}, () => {
commit(FETCH_API_FAILURE);
});
}
}
};
export const FETCH_GROUP_REQUEST = 'FETCH_GROUP_REQUEST';
export const FETCH_GROUP_SUCCESS = 'FETCH_GROUP_SUCCESS';
export const FETCH_GROUP_FAILURE = 'FETCH_GROUP_FAILURE';
export const FETCH_API_REQUEST = 'FETCH_API_REQUEST';
export const FETCH_API_SUCCESS = 'FETCH_API_SUCCESS';
export const FETCH_API_FAILURE = 'FETCH_API_FAILURE';
export const FETCH_FULLTEXT_FAILURE = 'FETCH_FULLTEXT_FAILURE';
export const FETCH_FULLTEXT_REQUEST = 'FETCH_FULLTEXT_REQUEST';
export const FETCH_FULLTEXT_SUCCESS = 'FETCH_FULLTEXT_SUCCESS';
... ...
... ... @@ -14,11 +14,13 @@ module.exports = {
env: {
NODE_ENV: '"dev"'
},
port: 6010,
port: 7002,
autoOpenBrowser: true,
assetsSubDirectory: 'static',
assetsPublicPath: '/',
proxyTable: {},
proxyTable: {
'/api': 'http://localhost:7001'
},
cssSourceMap: false,
}
};
... ...
... ... @@ -70,10 +70,6 @@ app.use(devMiddleware);
// compilation error display
app.use(hotMiddleware);
// serve pure static assets
let staticPath = path.posix.join(config.dev.assetsPublicPath, config.dev.assetsSubDirectory);
app.use(staticPath, express.static('./static'));
let uri = 'http://localhost:' + port;
... ...
'use strict';
const path = require('path');
const webpack = require('webpack');
let vueLoaderConfig = require('./vue-loader.conf');
let config = require('./config');
... ... @@ -7,11 +8,11 @@ let utils = require('./utils');
function resolve(dir) {
return path.join(__dirname, '../src', dir);
return path.join(__dirname, '../app', dir);
}
module.exports = {
entry: {
app: './src/app.js'
app: './app/app.js'
},
devtool: 'cheap-module-source-map',
output: {
... ... @@ -37,7 +38,7 @@ module.exports = {
{
test: /\.js$/,
loader: 'babel-loader',
include: [/vue-json-viewer.*?js$/, path.join(__dirname, '../src')],
include: [/vue-json-viewer.*?js$/, path.join(__dirname, '../api')],
exclude: /node_modules/
},
{
... ... @@ -73,5 +74,8 @@ module.exports = {
}]
}
]
}
},
plugins: [
new webpack.IgnorePlugin(/^\.\/locale$/, /moment$/),
]
};
... ...
... ... @@ -25,7 +25,7 @@ module.exports = merge(baseConfig, {
new webpack.IgnorePlugin(/^\.\/locale$/, /moment$/),
new HtmlWebpackPlugin({
filename: 'index.html',
template: './src/index.html',
template: './app/index.html',
inject: true
}),
new FriendlyErrorsPlugin(),
... ...
... ... @@ -38,7 +38,7 @@ let webpackConfig = merge(baseConfig, {
}),
new HtmlWebpackPlugin({
filename: 'index.html',
template: './src/index.html',
template: './app/index.html',
inject: true,
minify: {
removeComments: true,
... ...
... ... @@ -4,7 +4,9 @@
"description": "",
"main": "app.js",
"scripts": {
"dev": "nodemon --watch server server.js"
"dev": "nodemon --watch server server.js",
"static": "node ./build/dev-server.js",
"build": "node ./build/build.js"
},
"repository": {
"type": "git",
... ... @@ -13,16 +15,70 @@
"author": "",
"license": "ISC",
"dependencies": {
"axios": "^0.16.2",
"body-parser": "^1.18.2",
"clipboard": "^1.7.1",
"compression": "^1.7.1",
"cookie-parser": "^1.4.3",
"express": "^4.16.2",
"iview": "^2.4.0",
"iview-loader": "^1.0.0-beta.4",
"lodash": "^4.17.4",
"moment": "^2.19.1",
"mongoose": "^4.12.3",
"serve-favicon": "^2.4.5",
"yoho-node-lib": "^0.5.7"
"vue": "^2.5.2",
"vue-json-viewer": "^1.0.2",
"vue-loader": "^13.3.0",
"vue-markdown": "^2.2.4",
"vue-router": "^3.0.1",
"vue-template-compiler": "^2.5.2",
"vuex": "^2.4.1",
"yoho-cookie": "^1.2.0",
"yoho-node-lib": "^0.5.7",
"yoho-store": "^1.3.20"
},
"devDependencies": {
"nodemon": "^1.12.1"
"autoprefixer": "^7.0.1",
"autoprefixer-loader": "^3.2.0",
"babel-core": "^6.24.1",
"babel-eslint": "^7.2.3",
"babel-loader": "^7.0.0",
"babel-plugin-syntax-dynamic-import": "^6.18.0",
"babel-plugin-syntax-jsx": "^6.18.0",
"babel-plugin-transform-object-rest-spread": "^6.23.0",
"babel-plugin-transform-runtime": "^6.22.0",
"babel-plugin-transform-vue-jsx": "^3.4.3",
"babel-preset-env": "^1.4.0",
"babel-preset-es2015": "^6.14.0",
"babel-runtime": "^6.11.6",
"css-loader": "^0.28.1",
"eslint": "^3.3.1",
"eslint-config-yoho": "^1.0.1",
"eslint-plugin-html": "^1.5.2",
"extract-text-webpack-plugin": "^2.1.0",
"file-loader": "^1.1.5",
"friendly-errors-webpack-plugin": "^1.6.1",
"html-webpack-plugin": "^2.28.0",
"node-sass": "^4.5.3",
"nodemon": "^1.12.1",
"optimize-css-assets-webpack-plugin": "^3.2.0",
"postcss-loader": "^2.0.5",
"postcss-pxtorem": "^3.3.1",
"postcss-scss": "^1.0.0",
"precss": "^1.4.0",
"sass-loader": "^6.0.6",
"style-loader": "^0.17.0",
"stylelint": "^7.1.0",
"stylelint-config-yoho": "^1.2.7",
"stylelint-processor-html": "^1.0.0",
"url-loader": "^0.6.2",
"vue-style-loader": "^3.0.1",
"webpack": "3.3",
"webpack-dev-middleware": "^1.10.2",
"webpack-dev-server": "^2.6.1",
"webpack-hot-middleware": "^2.18.0",
"webpack-merge": "^4.1.0",
"yoho-lint": "^1.0.1"
}
}
... ...
... ... @@ -12,7 +12,6 @@ const Express = require('express');
const mongoose = require('mongoose');
const pkg = require('./package.json');
const favicon = require('serve-favicon');
const path = require('path');
global.env = {
... ... @@ -30,7 +29,7 @@ const helpers = require('yoho-node-lib/lib/helpers');
global.yoho = {
logger,
helpers,
helpers,
config
};
... ... @@ -44,13 +43,21 @@ app.use(cookieParser());
const middleware = require('./server/middleware');
const controllers = require('./server/controllers');
require('./server/db'); // register db
mongoose.connect('mongodb://172.16.6.108:27017/app_collect_fulltext');
mongoose.connect('mongodb://172.16.6.108:27017/app_collect_fulltext', {
useMongoClient: true,
});
mongoose.Promise = global.Promise;
try {
app.use((req, res, next) => {
next();
});
// controller
app.use(controllers);
app.use('/api', controllers);
// 异常捕获中间件
app.use(middleware.error);
} catch (err) {
... ...
... ... @@ -8,7 +8,7 @@
//
const config = {
app: 'mongo-search',
port: 8080,
port: 7001,
cookieDomain: '.yohobuy.com',
loggers: {
infoFile: {
... ...
const mongoose = require("mongoose");
const mongoose = require('mongoose');
const list = (req, res, next) => {
const col_fulltext = mongoose.model('col_fulltext');
const {start_time, end_time, uid, os, pt, pn, av, page = 1, rows = 10} = req.query;
const {ts_start, ts_end, uid, os, pt, pn, av, page = 1, rows = 10} = req.query;
let params = {
uid,
os,
... ... @@ -12,23 +11,28 @@ const list = (req, res, next) => {
av,
ts: {}
};
if (start_time) {
params.ts.$gte = Date.parse(start_time) / 1000;
if (ts_start) {
params.ts.$gte = ts_start;
}
if (end_time) {
params.ts.$lte = Date.parse(end_time) / 1000;
if (ts_end) {
params.ts.$lte = ts_end;
}
Object.keys(params).forEach(k => {
if (!params[k] || (typeof params[k] === 'object' && !Object.keys(params[k]).length)) {
delete params[k];
}
})
return col_fulltext.find(params).skip((page-1) * rows).limit(rows).then(result => {
return res.json(result);
});
console.log(params)
return Promise.all([
col_fulltext.find(params).count(),
col_fulltext.find(params).skip((page - 1) * rows).limit(parseInt(rows, 0))]).then(resultAll => {
return res.json({
code: 200,
data: resultAll[1],
count: resultAll[0]
});
}).catch(next);
};
module.exports = {
... ...
... ... @@ -8,8 +8,9 @@
const express = require('express');
const fulltextController = require('./fulltext-controller');
let router = express.Router();
let router = express.Router(); // eslint-disable-line
router.post('/list', fulltextController.list);
router.get('/list', fulltextController.list);
module.exports = router;
... ...
const mongoose = require("mongoose");
const mongoose = require('mongoose');
const ColFullText = new mongoose.Schema({
uid: String,
... ...
This diff could not be displayed because it is too large.