添加ai请求地址
This commit is contained in:
+18
-7
@@ -8,6 +8,7 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
/** ai-server 统一响应 */
|
/** ai-server 统一响应 */
|
||||||
|
import { request } from '../request/ai';
|
||||||
interface AiResp<T = any> {
|
interface AiResp<T = any> {
|
||||||
code: number;
|
code: number;
|
||||||
message: string;
|
message: string;
|
||||||
@@ -16,9 +17,7 @@ interface AiResp<T = any> {
|
|||||||
|
|
||||||
export class AiError extends Error {
|
export class AiError extends Error {
|
||||||
code: number;
|
code: number;
|
||||||
|
|
||||||
data: any;
|
data: any;
|
||||||
|
|
||||||
constructor(code: number, message: string, data?: any) {
|
constructor(code: number, message: string, data?: any) {
|
||||||
super(message || `AI 服务错误(${code})`);
|
super(message || `AI 服务错误(${code})`);
|
||||||
this.code = code;
|
this.code = code;
|
||||||
@@ -182,12 +181,24 @@ export interface RecognizeResult {
|
|||||||
materials_suggest: string[];
|
materials_suggest: string[];
|
||||||
}
|
}
|
||||||
|
|
||||||
export const aiRecognize = (content: string, deviceTags: string[] = []) =>
|
export function aiRecognize(content: string, deviceTags: string[] = []){
|
||||||
aiFetch<RecognizeResult>('/open/v1/moc/change/recognize', {
|
return request({
|
||||||
request_id: nextRequestId('rec'),
|
url: '/open/v1/moc/change/recognize',
|
||||||
content,
|
method: 'get',
|
||||||
device_tags: deviceTags
|
params: {
|
||||||
|
request_id: nextRequestId('rec'),
|
||||||
|
content,
|
||||||
|
device_tags: deviceTags
|
||||||
|
}
|
||||||
});
|
});
|
||||||
|
}
|
||||||
|
// aiFetch<RecognizeResult>('/open/v1/moc/change/recognize', {
|
||||||
|
// request_id: nextRequestId('rec'),
|
||||||
|
// content,
|
||||||
|
// device_tags: deviceTags
|
||||||
|
// });
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
export interface ApplicationResult {
|
export interface ApplicationResult {
|
||||||
name: string;
|
name: string;
|
||||||
|
|||||||
@@ -0,0 +1,68 @@
|
|||||||
|
import { request } from '../request';
|
||||||
|
|
||||||
|
/** 变更预识别查询
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
export function precheckApi(id: number) {
|
||||||
|
return request({
|
||||||
|
url: `/api/changes/${id}/precheck`,
|
||||||
|
method: 'get',
|
||||||
|
});
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* 变更预识别保存
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
export function precheckSaveApi(params: {
|
||||||
|
change_id: number,
|
||||||
|
title: string,
|
||||||
|
description: string,
|
||||||
|
severity: string,
|
||||||
|
probability: string,
|
||||||
|
protection: string,
|
||||||
|
compare_rows: {item: string, before_text: string, after_text: string}[]
|
||||||
|
}) {
|
||||||
|
return request({
|
||||||
|
url: '/api/changes/precheck',
|
||||||
|
method: 'post',
|
||||||
|
data: params
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/** 变更申请表查询
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
export function applicationApi(id: number) {
|
||||||
|
return request({
|
||||||
|
url: `/api/changes/${id}/apply-form`,
|
||||||
|
method: 'get',
|
||||||
|
});
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* 变更申请表保存
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
export function applicationSaveApi(id: number, params: {
|
||||||
|
change_type: number,
|
||||||
|
change_level: number,
|
||||||
|
duration_type: number,
|
||||||
|
restore_deadline: string,
|
||||||
|
org_id: number,
|
||||||
|
urgent: number,
|
||||||
|
purposes: string[],
|
||||||
|
effect: string,
|
||||||
|
main_changes: string[],
|
||||||
|
related_changes: string[],
|
||||||
|
materials: string,
|
||||||
|
update_docs: string[],
|
||||||
|
disciplines: string[],
|
||||||
|
manage_dept: string,
|
||||||
|
plan_use_date: string,
|
||||||
|
risk_tools: string[],
|
||||||
|
}) {
|
||||||
|
return request({
|
||||||
|
url: `/api/changes/${id}/apply-form`,
|
||||||
|
method: 'post',
|
||||||
|
data: params
|
||||||
|
});
|
||||||
|
}
|
||||||
@@ -0,0 +1,124 @@
|
|||||||
|
import type { AxiosResponse } from 'axios';
|
||||||
|
import { BACKEND_ERROR_CODE, createFlatRequest } from '@sa/axios';
|
||||||
|
import { useAuthStore } from '@/store/modules/auth';
|
||||||
|
import { getServiceAiURL } from '@/utils/service';
|
||||||
|
import { $t } from '@/locales';
|
||||||
|
import { getAiAuthorization, handleExpiredRequest, showErrorMsg } from './shared';
|
||||||
|
import type { RequestInstanceState } from './type';
|
||||||
|
|
||||||
|
const isHttpProxy = import.meta.env.DEV && import.meta.env.VITE_HTTP_PROXY === 'Y';
|
||||||
|
const { baseURL } = getServiceAiURL(import.meta.env, isHttpProxy);
|
||||||
|
|
||||||
|
export const request = createFlatRequest(
|
||||||
|
{
|
||||||
|
baseURL,
|
||||||
|
headers: {}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
defaultState: {
|
||||||
|
errMsgStack: [],
|
||||||
|
refreshTokenPromise: null
|
||||||
|
} as RequestInstanceState,
|
||||||
|
transform(response: AxiosResponse<App.Service.Response<any>>) {
|
||||||
|
return response.data.data;
|
||||||
|
},
|
||||||
|
async onRequest(config) {
|
||||||
|
const Authorization = getAiAuthorization();
|
||||||
|
Object.assign(config.headers, { Authorization });
|
||||||
|
|
||||||
|
return config;
|
||||||
|
},
|
||||||
|
isBackendSuccess(response) {
|
||||||
|
// when the backend response code is "0000"(default), it means the request is success
|
||||||
|
// to change this logic by yourself, you can modify the `VITE_SERVICE_SUCCESS_CODE` in `.env` file
|
||||||
|
return String(response.data.code) === import.meta.env.VITE_SERVICE_SUCCESS_CODE;
|
||||||
|
},
|
||||||
|
async onBackendFail(response, instance) {
|
||||||
|
const authStore = useAuthStore();
|
||||||
|
const responseCode = String(response.data.code);
|
||||||
|
|
||||||
|
function handleLogout() {
|
||||||
|
authStore.resetStore();
|
||||||
|
}
|
||||||
|
|
||||||
|
function logoutAndCleanup() {
|
||||||
|
handleLogout();
|
||||||
|
window.removeEventListener('beforeunload', handleLogout);
|
||||||
|
|
||||||
|
request.state.errMsgStack = request.state.errMsgStack.filter(msg => msg !== response.data.msg);
|
||||||
|
}
|
||||||
|
|
||||||
|
// when the backend response code is in `logoutCodes`, it means the user will be logged out and redirected to login page
|
||||||
|
const logoutCodes = import.meta.env.VITE_SERVICE_LOGOUT_CODES?.split(',') || [];
|
||||||
|
if (logoutCodes.includes(responseCode)) {
|
||||||
|
handleLogout();
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
// when the backend response code is in `modalLogoutCodes`, it means the user will be logged out by displaying a modal
|
||||||
|
const modalLogoutCodes = import.meta.env.VITE_SERVICE_MODAL_LOGOUT_CODES?.split(',') || [];
|
||||||
|
if (modalLogoutCodes.includes(responseCode) && !request.state.errMsgStack?.includes(response.data.msg)) {
|
||||||
|
request.state.errMsgStack = [...(request.state.errMsgStack || []), response.data.msg];
|
||||||
|
|
||||||
|
// prevent the user from refreshing the page
|
||||||
|
window.addEventListener('beforeunload', handleLogout);
|
||||||
|
|
||||||
|
window.$dialog?.error({
|
||||||
|
title: $t('common.error'),
|
||||||
|
content: response.data.msg,
|
||||||
|
positiveText: $t('common.confirm'),
|
||||||
|
maskClosable: false,
|
||||||
|
closeOnEsc: false,
|
||||||
|
onPositiveClick() {
|
||||||
|
logoutAndCleanup();
|
||||||
|
},
|
||||||
|
onClose() {
|
||||||
|
logoutAndCleanup();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
// when the backend response code is in `expiredTokenCodes`, it means the token is expired, and refresh token
|
||||||
|
// the api `refreshToken` can not return error code in `expiredTokenCodes`, otherwise it will be a dead loop, should return `logoutCodes` or `modalLogoutCodes`
|
||||||
|
const expiredTokenCodes = import.meta.env.VITE_SERVICE_EXPIRED_TOKEN_CODES?.split(',') || [];
|
||||||
|
if (expiredTokenCodes.includes(responseCode)) {
|
||||||
|
const success = await handleExpiredRequest(request.state);
|
||||||
|
if (success) {
|
||||||
|
const Authorization = getAuthorization();
|
||||||
|
Object.assign(response.config.headers, { Authorization });
|
||||||
|
|
||||||
|
return instance.request(response.config) as Promise<AxiosResponse>;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
|
},
|
||||||
|
onError(error) {
|
||||||
|
// when the request is fail, you can show error message
|
||||||
|
let message = error.message;
|
||||||
|
let backendErrorCode = '';
|
||||||
|
|
||||||
|
// get backend error message and code
|
||||||
|
if (error.code === BACKEND_ERROR_CODE) {
|
||||||
|
message = error.response?.data?.message || message;
|
||||||
|
backendErrorCode = String(error.response?.data?.code || '');
|
||||||
|
}
|
||||||
|
|
||||||
|
// the error message is displayed in the modal
|
||||||
|
const modalLogoutCodes = import.meta.env.VITE_SERVICE_MODAL_LOGOUT_CODES?.split(',') || [];
|
||||||
|
if (modalLogoutCodes.includes(backendErrorCode)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// when the token is expired, refresh token and retry request, so no need to show error message
|
||||||
|
const expiredTokenCodes = import.meta.env.VITE_SERVICE_EXPIRED_TOKEN_CODES?.split(',') || [];
|
||||||
|
if (expiredTokenCodes.includes(backendErrorCode)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
showErrorMsg(request.state, message);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
);
|
||||||
@@ -12,9 +12,7 @@ const { baseURL } = getServiceBaseURL(import.meta.env, isHttpProxy);
|
|||||||
export const request = createFlatRequest(
|
export const request = createFlatRequest(
|
||||||
{
|
{
|
||||||
baseURL,
|
baseURL,
|
||||||
headers: {
|
headers: {}
|
||||||
apifoxToken: 'XL299LiMEDZ0H5h3A29PxwQXdMJqWyY2'
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
defaultState: {
|
defaultState: {
|
||||||
|
|||||||
@@ -3,12 +3,20 @@ import { localStg } from '@/utils/storage';
|
|||||||
import { fetchRefreshToken } from '../api';
|
import { fetchRefreshToken } from '../api';
|
||||||
import type { RequestInstanceState } from './type';
|
import type { RequestInstanceState } from './type';
|
||||||
|
|
||||||
|
// 获取token
|
||||||
export function getAuthorization() {
|
export function getAuthorization() {
|
||||||
const token = localStg.get('token');
|
const token = localStg.get('token');
|
||||||
const Authorization = token ? `Bearer ${token}` : null;
|
const Authorization = token ? `Bearer ${token}` : null;
|
||||||
|
|
||||||
return Authorization;
|
return Authorization;
|
||||||
}
|
}
|
||||||
|
// 获取ai token
|
||||||
|
export function getAiAuthorization() {
|
||||||
|
const token = localStg.get('aiToken');
|
||||||
|
const Authorization = token ? `Bearer ${token}` : null;
|
||||||
|
|
||||||
|
return Authorization;
|
||||||
|
}
|
||||||
|
|
||||||
/** refresh token */
|
/** refresh token */
|
||||||
async function handleRefreshToken() {
|
async function handleRefreshToken() {
|
||||||
|
|||||||
@@ -45,6 +45,46 @@ export function createServiceConfig(env: Env.ImportMeta) {
|
|||||||
|
|
||||||
return config;
|
return config;
|
||||||
}
|
}
|
||||||
|
let aiUrl = '';
|
||||||
|
export function createAiServiceConfig(env: Env.ImportMeta) {
|
||||||
|
const { VITE_SERVICE_BASE_URL, VITE_OTHER_SERVICE_BASE_URL } = env;
|
||||||
|
|
||||||
|
let other = {} as Record<App.Service.OtherBaseURLKey, string>;
|
||||||
|
try {
|
||||||
|
other = json5.parse(VITE_OTHER_SERVICE_BASE_URL);
|
||||||
|
} catch {
|
||||||
|
// eslint-disable-next-line no-console
|
||||||
|
console.error('VITE_OTHER_SERVICE_BASE_URL is not a valid json5 string');
|
||||||
|
}
|
||||||
|
if(env.DEV){
|
||||||
|
aiUrl = 'http://192.168.0.230:8085/proxy-ai';
|
||||||
|
}else{
|
||||||
|
// url = window.location.origin;
|
||||||
|
aiUrl = '/api';
|
||||||
|
}
|
||||||
|
const httpConfig: App.Service.SimpleServiceConfig = {
|
||||||
|
baseURL: aiUrl,
|
||||||
|
other
|
||||||
|
};
|
||||||
|
|
||||||
|
const otherHttpKeys = Object.keys(httpConfig.other) as App.Service.OtherBaseURLKey[];
|
||||||
|
|
||||||
|
const otherConfig: App.Service.OtherServiceConfigItem[] = otherHttpKeys.map(key => {
|
||||||
|
return {
|
||||||
|
key,
|
||||||
|
baseURL: httpConfig.other[key],
|
||||||
|
proxyPattern: createProxyPattern(key)
|
||||||
|
};
|
||||||
|
});
|
||||||
|
|
||||||
|
const config: App.Service.ServiceConfig = {
|
||||||
|
baseURL: httpConfig.baseURL,
|
||||||
|
proxyPattern: createProxyPattern(),
|
||||||
|
other: otherConfig
|
||||||
|
};
|
||||||
|
|
||||||
|
return config;
|
||||||
|
}
|
||||||
export function getBaseUrl() {
|
export function getBaseUrl() {
|
||||||
return url;
|
return url;
|
||||||
}
|
}
|
||||||
@@ -69,6 +109,20 @@ export function getServiceBaseURL(env: Env.ImportMeta, isProxy: boolean) {
|
|||||||
otherBaseURL
|
otherBaseURL
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
export function getServiceAiURL(env: Env.ImportMeta, isProxy: boolean) {
|
||||||
|
const { baseURL, other } = createAiServiceConfig(env);
|
||||||
|
|
||||||
|
const otherBaseURL = {} as Record<App.Service.OtherBaseURLKey, string>;
|
||||||
|
|
||||||
|
other.forEach(item => {
|
||||||
|
otherBaseURL[item.key] = isProxy ? item.proxyPattern : item.baseURL;
|
||||||
|
});
|
||||||
|
|
||||||
|
return {
|
||||||
|
baseURL: isProxy ? createProxyPattern() : baseURL,
|
||||||
|
otherBaseURL
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get proxy pattern of backend service base url
|
* Get proxy pattern of backend service base url
|
||||||
|
|||||||
@@ -695,6 +695,19 @@ const onBack = () => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
const currentId = ref<number>(0);
|
||||||
|
// tab 切换
|
||||||
|
const tabChange = (id: string) => {
|
||||||
|
if(form.value.name.trim() === '') {
|
||||||
|
return window.$message?.warning('请先填写变更名称');
|
||||||
|
}
|
||||||
|
if(desc.value.trim() === '') {
|
||||||
|
return window.$message?.warning('请先填写变更内容描述');
|
||||||
|
}
|
||||||
|
tab.value = id;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
@@ -719,7 +732,7 @@ const onBack = () => {
|
|||||||
<NInput value="MOC-2026-R01-0041" disabled class="!w-44" />
|
<NInput value="MOC-2026-R01-0041" disabled class="!w-44" />
|
||||||
</div>
|
</div>
|
||||||
<div class="flex items-center gap-1 overflow-x-auto px-3 pt-2">
|
<div class="flex items-center gap-1 overflow-x-auto px-3 pt-2">
|
||||||
<div v-for="t in TABS" :key="t.id" @click="tab = t.id"
|
<div v-for="t in TABS" :key="t.id" @click="tabChange(t.id)"
|
||||||
class="flex items-center gap-1.5 whitespace-nowrap px-3 py-2 text-sm transition cursor-pointer border hover:bg-white/60 rounded-t-lg"
|
class="flex items-center gap-1.5 whitespace-nowrap px-3 py-2 text-sm transition cursor-pointer border hover:bg-white/60 rounded-t-lg"
|
||||||
:class="tab === t.id ? 'border-b-transparent border-[var(--border-color)] bg-white text-[var(--active-color)]':'border-transparent text-slate-500'"
|
:class="tab === t.id ? 'border-b-transparent border-[var(--border-color)] bg-white text-[var(--active-color)]':'border-transparent text-slate-500'"
|
||||||
:style="{
|
:style="{
|
||||||
|
|||||||
Reference in New Issue
Block a user