import Vue from 'vue'
import VueApollo from 'vue-apollo'
import { Message, Loading } from 'element-ui'
import { createApolloClient } from 'vue-cli-plugin-apollo/graphql-client'
import { ApolloLink, from } from 'apollo-link'
import { onError } from 'apollo-link-error'
import { getToken } from '@/utils/auth'
import router from '../router'
import store from '../store'
Vue.use(VueApollo)
let loadingInstance = null
const httpEndpoint = process.env.VUE_APP_GRAPHQL_HTTP
const httpEndpointS = process.env.VUE_APP_GRAPHQL_HTTPS
const httpGuide = process.env.VUE_APP_GRAPHQL_GUIDE
// 拦截器:显示统一加载动画
const loadingLink = new ApolloLink((operation, forward) => {
loadingInstance = Loading.service({
lock: true,
fullscreen: true
})
return forward(operation)
})
// 拦截器:统一响应处理
const afterwareLink = new ApolloLink((operation, forward) => {
return forward(operation).map(response => {
if (loadingInstance) {
loadingInstance.close()
}
console.log('[Afterware] response:', response)
return response
})
})
// 拦截器:统一错误处理
const errorLink = onError(({ graphQLErrors, networkError }) => {
if (loadingInstance) {
loadingInstance.close()
}
if (graphQLErrors) {
graphQLErrors.map(({ message, locations, path }) => {
console.log(`+++++ [GraphQL error]: Message: ${message}, Location: ${locations}, Path: ${path}`)
})
}
if (networkError) {
const code = networkError.result.message
console.log(`++++++ [Network error]: ${code}`)
if (code === '400' || code === '402' || code === '403') {
Message.error('还未登录或登录已失效')
store.dispatch('silentLogout')
router.replace('/login')
} else if (code === '401') {
Message.error('您没有足够的权限')
} else {
Message.error('服务器出现未知错误')
}
}
})
/**
* 创建Apollo客户端实例
*/
export function createProvider () {
const baseConfig = {
httpEndpoint,
getAuth: () => undefined
}
const linkWithLoading = from([loadingLink, afterwareLink, errorLink])
const linkWitoutLoading = from([afterwareLink, errorLink])
// 客户端:适用于需要授权的请求,带loading动画
const { apolloClient: animatedApiClient } = createApolloClient({
...baseConfig,
link: linkWithLoading,
getAuth: () => getToken()
})
// 客户端:适用于需要授权的请求,不带loading动画
const { apolloClient: plainClient } = createApolloClient({
...baseConfig,
link: linkWitoutLoading,
getAuth: () => getToken()
})
// 客户端:适用于无授权限制的请求,带loading动画
const { apolloClient: animatedBaseClient } = createApolloClient({
...baseConfig,
link: linkWithLoading
})
// 客户端:适用于无授权限制的请求,不带loading动画
const { apolloClient: plainBaseClient } = createApolloClient({
...baseConfig,
link: linkWitoutLoading
})
// 客户端:指南,带loading动画
const { apolloClient: guideClient } = createApolloClient({
httpEndpoint: httpEndpointS,
link: linkWithLoading
})
// 客户端:指南,不带loading动画
const { apolloClient: guideClients } = createApolloClient({
httpEndpoint: httpEndpointS,
link: linkWitoutLoading
})
// 客户端:指南,带loading动画
const { apolloClient: guideIdentity } = createApolloClient({
httpEndpoint: httpGuide,
link: linkWithLoading
})
// 客户端:指南,不带loading动画
const { apolloClient: guideIdentitys } = createApolloClient({
httpEndpoint: httpGuide,
link: linkWitoutLoading
})
return new VueApollo({
clients: {
'animatedApi': animatedApiClient,
'animatedBase': animatedBaseClient,
'api': plainClient,
'base': plainBaseClient,
'guide': guideClient,
'guides': guideClients,
'guideIdentity': guideIdentity,
'apiguideIdentity': guideIdentitys
},
defaultClient: animatedApiClient,
errorHandler (error) {
// eslint-disable-next-line no-console
console.log('%cError', 'background: red; color: white; padding: 2px 4px; border-radius: 3px; font-weight: bold;', error.message)
}
})
}