diff --git a/.env.development b/.env.development index c77c0df..85876df 100644 --- a/.env.development +++ b/.env.development @@ -1,4 +1,2 @@ -# VITE_APP_URL = http://192.168.31.82:8771 -# VITE_APP_URL = http://18.167.251.121:10095 -VITE_APP_URL = https://www.lc-api.aida.com.hk -VITE_GOOGLE_CLIENT_ID = 216037134725-7q8vqp0ohtmohlosltkfg7bd2v29rm5a.apps.googleusercontent.com +VITE_USER_NODE_ENV = 'development' +VITE_APP_BASE_URL = 'https://develop.api.aida.com.hk' \ No newline at end of file diff --git a/.env.production b/.env.production index 54a50e7..4b56ff6 100644 --- a/.env.production +++ b/.env.production @@ -1,3 +1,4 @@ -VITE_APP_URL = https://www.lc-api.aida.com.hk -# VITE_APP_URL = http://18.167.251.121:10095 -VITE_GOOGLE_CLIENT_ID = 29310152396-nnsd3h533fld665oguu8ovrt1nukmt46.apps.googleusercontent.com +VITE_USER_NODE_ENV = 'production' +# VITE_APP_BASE_URL = 'http://18.167.251.121:10086' +# VITE_APP_BASE_URL = 'https://polyu.api.aida.com.hk' +VITE_APP_BASE_URL = 'https://www.api.aida.com.hk' \ No newline at end of file diff --git a/src/router/index.ts b/src/router/index.ts index 1c65b38..e3e876d 100644 --- a/src/router/index.ts +++ b/src/router/index.ts @@ -10,23 +10,25 @@ const router = createRouter({ history: createWebHistory('/'), // history: createWebHistory(import.meta.env.VITE_APP_URL), routes: [ + // { + // path: '/', + // }, { - path: '/', - name:'award', - component:()=>import('@/views/AwardPage/container.vue'), - children:[ + path: '/:lang?', + component: () => import('@/views/AwardPage/container.vue'), + children: [ { - path:'', - name:'AwardIndex', - component:()=>import('@/views/AwardPage/index.vue'), + path: '', + name: 'AwardIndex', + component: () => import('@/views/AwardPage/index.vue') }, { - path:'contestants', - component:()=>import('@/views/AwardPage/apply.vue') + path: 'contestants', + name: 'Contestants', + component: () => import('@/views/AwardPage/contestants.vue') } ] }, - { path: '/:pathMatch(.*)', diff --git a/src/router/router-config.ts b/src/router/router-config.ts index bff05c0..11d1714 100644 --- a/src/router/router-config.ts +++ b/src/router/router-config.ts @@ -1,7 +1,18 @@ import router from './index' router.beforeEach((to, from, next) => { - next() + const path = to.path + const list = { + zh: 'CHINESE_SIMPLIFIED', + en: 'ENGLISH' + } + if (path.startsWith('/zh') || (to.params.lang === 'zh')) { + localStorage.setItem('loginLanguage', 'CHINESE_SIMPLIFIED') + } else if (path.startsWith('/en') || (to.params.lang === 'en')) { + localStorage.setItem('loginLanguage', 'ENGLISH') + } + + next() }) router.afterEach(() => { diff --git a/src/utils/request.ts b/src/utils/request.ts index 7c4b1b1..bef5a4e 100644 --- a/src/utils/request.ts +++ b/src/utils/request.ts @@ -1,191 +1,203 @@ import axios from 'axios' +// import qs from 'qs' +// import message from '@/components/public/message/src' import router from '@/router/index' -import { useGlobalStore, useUserInfoStore } from '@/stores' +import { getCookie, clonAllCookie } from '@/utils/cookie' +// import cookie from '@/tools/cookie.js' -// 扩展 AxiosRequestConfig 接口 -declare module 'axios' { - interface AxiosRequestConfig { - loading?: boolean - loadingDom?: any - repeatRequest?: boolean - meta?: { - responseAll?: boolean - } - } -} - -// 创建axios实例 -// console.log(import.meta.env,123) - -const service = axios.create({ - // baseURL: import.meta.env.VITE_APP_URL, // api的base_url - timeout: 60000 // 请求超时时间 -}) -if (import.meta.env.MODE != 'development') { - service.defaults.baseURL = import.meta.env.VITE_APP_URL -} +axios.defaults.timeout = 60000 //响应时间 +// axios.defaults.headers.post['Content-Type'] = 'application/x-www-form-urlencoded;charset=UTF-8'; //配置请求头 axios.defaults.headers.post['Content-Type'] = 'application/json' + axios.defaults.headers.post['lang'] = 'en' //配置语言请求头 axios.defaults.withCredentials = true //跨域携带cookie +import { message } from 'ant-design-vue' -// request拦截器 -service.interceptors.request.use( - (config: any) => { - removePending(config) - // 如果repeatRequest不配置,那么默认该请求就取消重复接口请求 - !config.repeatRequest && addPending(config) - // 打开loading - if (config.loading) { - LoadingInstance._count++ - if (LoadingInstance._count === 1) { - openLoading(config.loadingDom) - } - } - // 如果登录了,有token,则请求携带token - // Do something before request is sent - const token = useUserInfoStore().state.token - if (token) { - config.headers.Authorization = token // 让每个请求携带token--['X-Token']为自定义key 请根据实际情况自行修改 - // config.headers['X-Token'] = getLocal('token') // 让每个请求携带token--['X-Token']为自定义key 请根据实际情况自行修改 +let httpIp = import.meta.env.VITE_USER_NODE_ENV == 'development' ? '' : '' +// let httpIp = import.meta.env.VITE_USER_NODE_ENV == 'development' ? "https://192.168.1.8:10086" : ""; + +axios.defaults.baseURL = httpIp //配置接口地址 +// console.log(axios.defaults.baseURL); +axios.defaults.baseURL = import.meta.env.VITE_APP_BASE_URL //配置接口地址 +console.log(import.meta.env.VITE_APP_BASE_URL) + +// 创建取消令牌 +const CancelToken = axios.CancelToken +const source = CancelToken.source() +// console.log(import.meta.env.VITE_APP_BASE_URL); +let isLoginTime = false +//POST传参序列化(添加请求拦截器) +axios.interceptors.request.use( + (config) => { + //在发送请求之前做某件事 + + if (config.method === 'post' || config.method === 'put' || config.method === 'delete') { + // config.data = qs.stringify(config.data); } + config.headers.Authorization = getCookie('token') return config }, (error) => { - // Do something with request error - console.log(error) // for debug - Promise.reject(error) - } -) - -// respone拦截器 -service.interceptors.response.use( - // response => response, - /** - * 下面的注释为通过response自定义code来标示请求状态,当code返回如下情况为权限有问题,登出并返回到登录页 - * 如通过xmlhttprequest 状态码标识 逻辑可写在下面error中 - */ - (response: any) => { - // 如果是llm/streamChat这样的流式接口,不走这样的处理 - if (response.config.url.includes('llm/streamChat')) { - return response - } - - // 已完成请求的删除请求中数组 - removePending(response.config) - // 关闭loading - if (response.config.loading) { - closeLoading() - } - const res = response.data - // 处理异常的情况 - // console.log(res) - if (res.code != 0) { - // showToast({ - // message: res.errMsg || res.message, - // // type: 'fail', - // duration: 5000, - // position: 'top', - // icon: 'none' - // }) - return Promise.reject(new Error(res.errMsg || res.message || 'error')) - } else { - // 默认只返回data,不返回状态码和message - // 通过 meta 中的 responseAll 配置来取决后台是否返回所有数据(包括状态码,message和data) - const isbackAll = response.config.meta && response.config.meta.responseAll - if (isbackAll) { - return res - } else { - return res.data - } - } - }, - (error) => { - if(error?.response){ - if (error.config?.loading) closeLoading() // 关闭loading - if(error?.response?.status === 401){//如果是记录浏览器页面就不跳转login - // showConfirmDialog({ - // title: '确定登出', - // message: '你已被登出,可以取消继续留在该页面,或者重新登录', - // confirmButtonText: '重新登录', - // cancelButtonText: '取消' - // }).then(() => { - // store.loginOut().then(() => { - // location.reload() // 为了重新实例化vue-router对象 避免bug - // }) - // }) - // showToast({ - // message: 'Please log in and try again.', - // duration: 5000 - // }) - // router.push('/login') - // useGenerateStore().clearGenerateData() - return Promise.reject(false) - } - error.config && removePending(error.config) - console.log('err' + error) // for debug - // showToast({ - // message: error.message, - // type: 'fail', - // duration: 5000 - // }) - } return Promise.reject(error) } ) - -// --------------------------------取消接口重复请求的函数----------------------------------- -// axios.js -const pendingMap = new Map() -/** - * 生成每个请求唯一的键 - * @param {*} config - * @returns string - */ -function getPendingKey(config: any) { - const { url, method, params } = config - let { data } = config - if (typeof data === 'string') data = JSON.parse(data) // response里面返回的config.data是个字符串对象 - return [url, method, JSON.stringify(params), JSON.stringify(data)].join('&') +const binaryToUrl = (binary, type = 'application/json', res) => { + let blob = new Blob([binary], { 'content-type': type }) + let url = URL.createObjectURL(blob) + return url } +//返回状态判断(添加响应拦截器) +axios.interceptors.response.use( + (res) => { + // 允许透传完整响应:请求时传 config.fullData = true -/** - * 储存每个请求唯一值, 也就是cancel()方法, 用于取消请求 - * @param {*} config - */ -function addPending(config: any) { - const pendingKey = getPendingKey(config) - config.cancelToken = - config.cancelToken || - new axios.CancelToken((cancel) => { - if (!pendingMap.has(pendingKey)) { - pendingMap.set(pendingKey, cancel) + // if(res.data.data == null){ + // message.warning(res.data.errMsg) + // return Promise.reject(res.data); + // }else + if (res?.config?.env?.binary) { + let url = binaryToUrl(res.data, res.config.env.binaryType, res) + return Promise.resolve({ url, data: res.data }) + } + if (res?.data) { + if (res?.data?.errCode === 0) { + // message.error(res?.data?.errMsg) + if (res?.config?.fullData) { + return Promise.resolve(res.data) + } + return Promise.resolve(res?.data?.data) + } else if (res?.data?.errCode === 1) { + message.warning(res?.data?.errMsg) + return Promise.reject(res?.data) + } else if (res?.data?.errCode === 2) { + return Promise.reject(res?.data) + } else if (res?.data?.errCode === -1) { + message.error(res?.data?.errMsg) + return Promise.reject(res?.data) } - }) -} -/** - * 删除重复的请求 - * @param {*} config - */ -function removePending(config: any) { - const pendingKey = getPendingKey(config) - if (pendingMap.has(pendingKey)) { - const cancelToken = pendingMap.get(pendingKey) - cancelToken(pendingKey) - pendingMap.delete(pendingKey) + } else { + if (res?.data?.errCode === 0) { + message.warning(res?.data?.errMsg) + return Promise.reject(res?.data) + } else if (res?.data?.errCode === 1) { + message.warning(res?.data?.errMsg) + return Promise.reject(res?.data) + } else if (res?.data?.errCode === 2) { + return Promise.reject(res?.data) + } else if (res?.data?.errCode === -1) { + message.error(res?.data?.errMsg) + return Promise.reject(res?.data) + } + } + }, + function (error) { + if (error?.response?.status === 401 && router.currentRoute._value.name != 'setIdentification') { + //如果是记录浏览器页面就不跳转login + clonAllCookie() + if (!isLoginTime) { + isLoginTime = true + let isSystemUserRouteList = ['/Square'] //如果是这两个页面就无需跳转未登录页 + let sSystemUser = false + for (let index = 0; index < isSystemUserRouteList.length; index++) { + if (router.currentRoute.value.path.indexOf(isSystemUserRouteList[index]) > -1) { + sSystemUser = true + break + } + } + if (!sSystemUser) { + router.replace('/') + } + message.warning('Please login and try again~') + setTimeout(() => [(isLoginTime = false)], 2000) + } + // source.cancel('取消后续接口调用'); + return Promise.reject() + } + let data_new = error?.response?.data + // message.error(data_new?.errMsg || 'Error: server exception') + return Promise.reject(data_new) } -} -// ----------------------------------loading的函数------------------------------- -const LoadingInstance: { _count: number } = { - _count: 0 -} -function openLoading(loadingDom: any) { - useGlobalStore().setLoading(true) -} -function closeLoading() { - if (LoadingInstance._count > 0) LoadingInstance._count-- - if (LoadingInstance._count === 0) { - useGlobalStore().setLoading(false) - } -} +) +export const Https = { + httpUrls: { + // award页面 + checkEmail: '/api/global-award/checkEmail', // 检查邮箱是否存在 + checkOTP: '/api/global-award/checkCode', // 检查验证码是否正确 + initPdfUpload: '/api/global-award/uploads/pdf/init', // 初始化pdf上传 + initVideoUpload: '/api/global-award/uploads/video/init', // 初始化video上传 + uploadPDF: '/api/global-award/uploads/pdf/chunk', // 上传pdf + uploadVideo: '/api/global-award/uploads/video/chunk', // 上传video + uploadPDFComplete: '/api/global-award/uploads/pdf/complete', // 上传pdf完成 + uploadVideoComplete: '/api/global-award/uploads/video/complete', // 上传video完成 + submitForm: '/api/global-award/contestants/save', // 提交表单 + getContestantByID: '/api/global-award/contestants/' // 获取表单 + }, -export default service + axiosGet(url, config) { + return new Promise((resolve, reject) => { + if (isLoginTime && url != '/api/portfolio/page') { + resolve('') + return + } + axios + .get(url, config) + .then((response) => { + resolve(response) + }) + .catch((error) => { + reject(error) + }) + }) + }, + + axiosPut(url, data) { + return new Promise((resolve, reject) => { + if (isLoginTime && url != '/api/portfolio/page') { + resolve('') + return + } + axios + .put(url, data) + .then((response) => { + resolve(response) + }) + .catch((error) => { + reject(error) + }) + }) + }, + + axiosPost(url, data, config) { + return new Promise((resolve, reject) => { + if (isLoginTime && url != '/api/portfolio/page') { + resolve('') + return + } + axios + .post(url, data, config) + .then((response) => { + resolve(response) + }) + .catch((error) => { + reject(error) + }) + }) + }, + + axiosDelete(url, newData) { + return new Promise((resolve, reject) => { + if (isLoginTime && url != '/api/portfolio/page') { + resolve('') + return + } + axios + .delete(url, { data: newData }) + .then((response) => { + resolve(response) + }) + .catch((error) => { + reject(error) + }) + }) + } +} diff --git a/src/views/AwardPage/apply.vue b/src/views/AwardPage/apply.vue deleted file mode 100644 index 2a6dfc9..0000000 --- a/src/views/AwardPage/apply.vue +++ /dev/null @@ -1,1686 +0,0 @@ - - - - - - diff --git a/src/views/AwardPage/container.vue b/src/views/AwardPage/container.vue index 6cf390d..8b46a2a 100644 --- a/src/views/AwardPage/container.vue +++ b/src/views/AwardPage/container.vue @@ -147,10 +147,11 @@ } ) const handleBtnClick = () => { + const lang = route.params.lang ? `/${route.params.lang}` : '' if (btnType.value === 'index') { - router.push('/award/contestants') + router.push(`${lang}/contestants`) } else { - router.push('/award/index') + router.push(`${lang}`) } } diff --git a/src/views/AwardPage/contestants.vue b/src/views/AwardPage/contestants.vue new file mode 100644 index 0000000..45e1f06 --- /dev/null +++ b/src/views/AwardPage/contestants.vue @@ -0,0 +1,1573 @@ + + + + + + diff --git a/src/views/AwardPage/index.vue b/src/views/AwardPage/index.vue index 923e622..5e1901e 100644 --- a/src/views/AwardPage/index.vue +++ b/src/views/AwardPage/index.vue @@ -65,7 +65,7 @@ }) const handleSubmitApplication = () => { - router.push('/award/contestants') + router.push('/contestants') }