@cqsjjb/course-res-design 0.0.4 → 0.0.6
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CourseInfo.js +17 -11
- package/Designable.d.ts +21 -27
- package/Designable.js +7 -7
- package/Preview.js +4 -4
- package/PreviewVideo.js +21 -21
- package/api/courseLibrary.js +1 -1
- package/package.json +1 -1
- package/utils/index.js +9 -9
- package/utils/request.js +76 -76
package/CourseInfo.js
CHANGED
|
@@ -78,22 +78,28 @@ export default class CourseInfo extends React.Component {
|
|
|
78
78
|
}, /*#__PURE__*/React.createElement(Descriptions.Item, {
|
|
79
79
|
label: "\u8BFE\u7A0B\u540D\u79F0"
|
|
80
80
|
}, courseInfo?.courseName || '--'), /*#__PURE__*/React.createElement(Descriptions.Item, {
|
|
81
|
-
label: "\
|
|
82
|
-
}, getLabelName(courseInfo?.courseTypeLabel)
|
|
83
|
-
label: "\
|
|
84
|
-
},
|
|
81
|
+
label: "\u7C7B\u76EE"
|
|
82
|
+
}, courseInfo?.categorizeName ? courseInfo.categorizeName : courseInfo?.courseTypeLabel ? getLabelName(courseInfo?.courseTypeLabel) : '--'), courseInfo?.year && /*#__PURE__*/React.createElement(Descriptions.Item, {
|
|
83
|
+
label: "\u5E74\u4EFD"
|
|
84
|
+
}, courseInfo.year), /*#__PURE__*/React.createElement(Descriptions.Item, {
|
|
85
|
+
label: "\u8BFE\u7A0B\u4ECB\u7ECD"
|
|
86
|
+
}, courseInfo?.courseDescription ? /*#__PURE__*/React.createElement("div", {
|
|
87
|
+
dangerouslySetInnerHTML: {
|
|
88
|
+
__html: courseInfo.courseDescription
|
|
89
|
+
}
|
|
90
|
+
}) : '--'), /*#__PURE__*/React.createElement(Descriptions.Item, {
|
|
85
91
|
label: "\u8BFE\u7A0B\u5C01\u9762"
|
|
86
92
|
}, courseInfo?.courseCover ? /*#__PURE__*/React.createElement("img", {
|
|
87
93
|
src: courseInfo.courseCover,
|
|
88
94
|
alt: "\u8BFE\u7A0B\u5C01\u9762",
|
|
89
95
|
width: 84,
|
|
90
96
|
height: 50
|
|
91
|
-
}) : '--'), /*#__PURE__*/React.createElement(Descriptions.Item, {
|
|
92
|
-
label: "\
|
|
93
|
-
}, courseInfo?.
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
})
|
|
97
|
+
}) : '--'), courseInfo?.star && /*#__PURE__*/React.createElement(Descriptions.Item, {
|
|
98
|
+
label: "\u661F\u7EA7"
|
|
99
|
+
}, courseInfo.star), courseInfo?.jobTypeName && /*#__PURE__*/React.createElement(Descriptions.Item, {
|
|
100
|
+
label: "\u5DE5\u79CD"
|
|
101
|
+
}, courseInfo.jobTypeName), /*#__PURE__*/React.createElement(Descriptions.Item, {
|
|
102
|
+
label: "\u8BFE\u7A0B\u6807\u7B7E"
|
|
103
|
+
}, getLabelName(courseInfo?.courseLabel) || '--')));
|
|
98
104
|
}
|
|
99
105
|
}
|
package/Designable.d.ts
CHANGED
|
@@ -5,7 +5,7 @@ import React from 'react';
|
|
|
5
5
|
*/
|
|
6
6
|
export interface DesignableCloseData {
|
|
7
7
|
/** 课程资源ID */
|
|
8
|
-
|
|
8
|
+
courseId: string;
|
|
9
9
|
}
|
|
10
10
|
|
|
11
11
|
/**
|
|
@@ -14,12 +14,28 @@ export interface DesignableCloseData {
|
|
|
14
14
|
export interface DesignableProps {
|
|
15
15
|
/** 自定义样式 */
|
|
16
16
|
style?: React.CSSProperties;
|
|
17
|
+
/** iframe 的样式 */
|
|
18
|
+
iframeStyle?: React.CSSProperties;
|
|
17
19
|
/** 主机地址(协议 + 域名 + 端口),用于构建 iframe 的源地址 */
|
|
18
20
|
host?: string;
|
|
19
|
-
/**
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
21
|
+
/** 课程资源设计器的数据 */
|
|
22
|
+
data?: {
|
|
23
|
+
// 课程ID
|
|
24
|
+
courseId: string;
|
|
25
|
+
// 课程类型 1: 公共资源课程 2: 私有资源课程
|
|
26
|
+
type?: 'public' | 'private';
|
|
27
|
+
// 是否禁用课程形式
|
|
28
|
+
resourceTypeDisabled?: boolean;
|
|
29
|
+
// 课程形式默认值
|
|
30
|
+
resourceTypeDefault?: string;
|
|
31
|
+
// 是否禁用学时规则
|
|
32
|
+
hourRuleDisabled?: boolean;
|
|
33
|
+
// 学时规则默认值
|
|
34
|
+
hourRuleDefault?: string;
|
|
35
|
+
// 接口前缀
|
|
36
|
+
apiBaseName?: 'res' | 'courseScd';
|
|
37
|
+
[key: string]: any;
|
|
38
|
+
};
|
|
23
39
|
/** 关闭事件回调 */
|
|
24
40
|
onClose?: (data: DesignableCloseData) => void;
|
|
25
41
|
/** iframe 的源地址,如果提供则优先级高于 host */
|
|
@@ -28,28 +44,6 @@ export interface DesignableProps {
|
|
|
28
44
|
visible?: boolean;
|
|
29
45
|
}
|
|
30
46
|
|
|
31
|
-
/**
|
|
32
|
-
* 打开课程资源设计器的消息类型
|
|
33
|
-
*/
|
|
34
|
-
export interface OpenCourseResDesignMessage {
|
|
35
|
-
/** 消息类型 */
|
|
36
|
-
type: 'EVENT_OPEN_COURSE_RES_DESIGN' | 'EVENT_CLOSE_COURSE_RES_DESIGN';
|
|
37
|
-
/** 课程资源ID */
|
|
38
|
-
id: string;
|
|
39
|
-
/** 额外参数 */
|
|
40
|
-
extraParams: Record<string, any>;
|
|
41
|
-
}
|
|
42
|
-
|
|
43
|
-
/**
|
|
44
|
-
* 关闭课程资源设计器的消息类型
|
|
45
|
-
*/
|
|
46
|
-
export interface CloseCourseResDesignMessage {
|
|
47
|
-
/** 消息类型 */
|
|
48
|
-
type: 'EVENT_CLOSE_COURSE_RES_DESIGN';
|
|
49
|
-
/** 课程资源ID */
|
|
50
|
-
id: string;
|
|
51
|
-
}
|
|
52
|
-
|
|
53
47
|
/**
|
|
54
48
|
* 课程资源设计器组件
|
|
55
49
|
*
|
package/Designable.js
CHANGED
|
@@ -4,9 +4,9 @@ const EVENT_OPEN_COURSE_RES_DESIGN = 'EVENT_OPEN_COURSE_RES_DESIGN';
|
|
|
4
4
|
const EVENT_CLOSE_COURSE_RES_DESIGN = 'EVENT_CLOSE_COURSE_RES_DESIGN';
|
|
5
5
|
export const Designable = ({
|
|
6
6
|
style,
|
|
7
|
+
iframeStyle,
|
|
7
8
|
host = window.location.origin,
|
|
8
|
-
|
|
9
|
-
extraParams = {},
|
|
9
|
+
data = {},
|
|
10
10
|
onClose,
|
|
11
11
|
src,
|
|
12
12
|
visible = true
|
|
@@ -22,8 +22,7 @@ export const Designable = ({
|
|
|
22
22
|
if (iframeRef.current?.contentWindow) {
|
|
23
23
|
iframeRef.current.contentWindow.postMessage({
|
|
24
24
|
type: EVENT_OPEN_COURSE_RES_DESIGN,
|
|
25
|
-
|
|
26
|
-
extraParams: extraParams || {}
|
|
25
|
+
data: data || {}
|
|
27
26
|
}, new URL(iframeSrc).origin);
|
|
28
27
|
}
|
|
29
28
|
};
|
|
@@ -38,12 +37,12 @@ export const Designable = ({
|
|
|
38
37
|
}
|
|
39
38
|
if (event.data && event.data.type === EVENT_CLOSE_COURSE_RES_DESIGN) {
|
|
40
39
|
const {
|
|
41
|
-
|
|
40
|
+
courseId
|
|
42
41
|
} = event.data;
|
|
43
42
|
// 调用 onClose 回调
|
|
44
43
|
if (onClose) {
|
|
45
44
|
onClose({
|
|
46
|
-
|
|
45
|
+
courseId: courseId || ''
|
|
47
46
|
});
|
|
48
47
|
}
|
|
49
48
|
}
|
|
@@ -52,7 +51,7 @@ export const Designable = ({
|
|
|
52
51
|
return () => {
|
|
53
52
|
window.removeEventListener('message', handleMessage);
|
|
54
53
|
};
|
|
55
|
-
}, [onClose, iframeSrc
|
|
54
|
+
}, [onClose, iframeSrc]);
|
|
56
55
|
if (!visible) {
|
|
57
56
|
return null;
|
|
58
57
|
}
|
|
@@ -63,6 +62,7 @@ export const Designable = ({
|
|
|
63
62
|
ref: iframeRef,
|
|
64
63
|
src: iframeSrc,
|
|
65
64
|
frameBorder: "0",
|
|
65
|
+
style: iframeStyle,
|
|
66
66
|
className: "course-res-designable-iframe",
|
|
67
67
|
title: "\u8BFE\u7A0B\u8D44\u6E90\u8BBE\u8BA1\u5668",
|
|
68
68
|
onLoad: handleIframeLoad
|
package/Preview.js
CHANGED
|
@@ -108,11 +108,11 @@ export default class FormPreview extends React.Component {
|
|
|
108
108
|
return;
|
|
109
109
|
}
|
|
110
110
|
// 总时长
|
|
111
|
-
const time = files.map(i => parseInt(i
|
|
111
|
+
const time = files.map(i => parseInt(i?.resourceTotalIden || 0)).reduce((i, j) => i + j, 0);
|
|
112
112
|
// 学时
|
|
113
113
|
const hours = [{
|
|
114
114
|
label: '总计',
|
|
115
|
-
value: files.map(i => parseFloat(i
|
|
115
|
+
value: files.map(i => parseFloat(i?.resourceHour || 0)).reduce((i, j) => i + j, 0).toFixed(2)
|
|
116
116
|
}];
|
|
117
117
|
files.forEach(i => {
|
|
118
118
|
if (i.resourceLabel) {
|
|
@@ -297,7 +297,7 @@ export default class FormPreview extends React.Component {
|
|
|
297
297
|
className: "course-preview__label"
|
|
298
298
|
}, "\u603B\u89C6\u9891\u65F6\u957F\uFF1A"), /*#__PURE__*/React.createElement("span", {
|
|
299
299
|
className: "course-preview__value"
|
|
300
|
-
}, total.time || '-')), /*#__PURE__*/React.createElement("div", {
|
|
300
|
+
}, total.time || '-')), this.state.courseInfo?.hourRuleStatusEnum === 'TRUE' && /*#__PURE__*/React.createElement("div", {
|
|
301
301
|
className: "course-preview__label-container"
|
|
302
302
|
}, /*#__PURE__*/React.createElement("span", {
|
|
303
303
|
className: "course-preview__label"
|
|
@@ -366,7 +366,7 @@ export default class FormPreview extends React.Component {
|
|
|
366
366
|
courseInfo: courseInfo
|
|
367
367
|
})), /*#__PURE__*/React.createElement("div", {
|
|
368
368
|
className: "course-preview__item-video-info"
|
|
369
|
-
}, /*#__PURE__*/React.createElement("a", null, "\u89C6\u9891\u65F6\u957F\uFF1A", secondToFormat(Number(item.resourceTotalIden))), /*#__PURE__*/React.createElement("a", null, "\u53C2\u8003\u5B66\u65F6\uFF1A", item.resourceHour || '--', "\u5B66\u65F6"), /*#__PURE__*/React.createElement("a", null, "\u8BD5\u770B\u5206\u949F\uFF1A", item.auditionTime || '--'), JSON.parse(item.testExamJson || '[]')?.length > 0 && /*#__PURE__*/React.createElement("a", {
|
|
369
|
+
}, /*#__PURE__*/React.createElement("a", null, "\u89C6\u9891\u65F6\u957F\uFF1A", secondToFormat(Number(item.resourceTotalIden))), this.state.courseInfo?.hourRuleStatusEnum === 'TRUE' ? /*#__PURE__*/React.createElement("a", null, "\u53C2\u8003\u5B66\u65F6\uFF1A", item.resourceHour || '--', "\u5B66\u65F6") : '', /*#__PURE__*/React.createElement("a", null, "\u8BD5\u770B\u5206\u949F\uFF1A", item.auditionTime || '--'), JSON.parse(item.testExamJson || '[]')?.length > 0 && /*#__PURE__*/React.createElement("a", {
|
|
370
370
|
onClick: () => {
|
|
371
371
|
this.setState({
|
|
372
372
|
showTestTable: true,
|
package/PreviewVideo.js
CHANGED
|
@@ -7,13 +7,13 @@ import VideoPlayer from './VideoPlayer';
|
|
|
7
7
|
import * as globalApi from './api/global';
|
|
8
8
|
import * as courseLibraryApi from './api/courseLibrary';
|
|
9
9
|
|
|
10
|
-
/**
|
|
11
|
-
* @description 预览视频组件
|
|
12
|
-
* @param {Object} props
|
|
13
|
-
* @param {Object} props.value - 视频资源数据
|
|
14
|
-
* @param {Object} props.courseInfo - 课程信息
|
|
15
|
-
* @param {boolean} props.disabled - 是否禁用
|
|
16
|
-
* @param {Function} props.onChange - 变化回调
|
|
10
|
+
/**
|
|
11
|
+
* @description 预览视频组件
|
|
12
|
+
* @param {Object} props
|
|
13
|
+
* @param {Object} props.value - 视频资源数据
|
|
14
|
+
* @param {Object} props.courseInfo - 课程信息
|
|
15
|
+
* @param {boolean} props.disabled - 是否禁用
|
|
16
|
+
* @param {Function} props.onChange - 变化回调
|
|
17
17
|
*/
|
|
18
18
|
const PreviewVideo = ({
|
|
19
19
|
value = {},
|
|
@@ -26,9 +26,9 @@ const PreviewVideo = ({
|
|
|
26
26
|
const [openPreviewVideo, setOpenPreviewVideo] = useState(false);
|
|
27
27
|
const [jjbWebResSelectorShow, setJjbWebResSelectorShow] = useState(false);
|
|
28
28
|
|
|
29
|
-
/**
|
|
30
|
-
* @description 重选资源库数据
|
|
31
|
-
* @param {Array} fileArr
|
|
29
|
+
/**
|
|
30
|
+
* @description 重选资源库数据
|
|
31
|
+
* @param {Array} fileArr
|
|
32
32
|
*/
|
|
33
33
|
const handleGetResLibrary = useCallback(async fileArr => {
|
|
34
34
|
if (fileArr.length === 0) {
|
|
@@ -91,37 +91,37 @@ const PreviewVideo = ({
|
|
|
91
91
|
onChange?.(obj);
|
|
92
92
|
}, [courseInfo, onChange]);
|
|
93
93
|
|
|
94
|
-
/**
|
|
95
|
-
* @description 处理预览视频点击
|
|
94
|
+
/**
|
|
95
|
+
* @description 处理预览视频点击
|
|
96
96
|
*/
|
|
97
97
|
const handlePreviewClick = useCallback(() => {
|
|
98
98
|
setOpenPreviewVideo(true);
|
|
99
99
|
}, []);
|
|
100
100
|
|
|
101
|
-
/**
|
|
102
|
-
* @description 处理重新选择点击
|
|
101
|
+
/**
|
|
102
|
+
* @description 处理重新选择点击
|
|
103
103
|
*/
|
|
104
104
|
const handleReselectClick = useCallback(() => {
|
|
105
105
|
setJjbWebResSelectorShow(true);
|
|
106
106
|
}, []);
|
|
107
107
|
|
|
108
|
-
/**
|
|
109
|
-
* @description 处理资源选择确认
|
|
108
|
+
/**
|
|
109
|
+
* @description 处理资源选择确认
|
|
110
110
|
*/
|
|
111
111
|
const handleResSelectorOk = useCallback((selectedRows = []) => {
|
|
112
112
|
setJjbWebResSelectorShow(false);
|
|
113
113
|
handleGetResLibrary(selectedRows);
|
|
114
114
|
}, [handleGetResLibrary]);
|
|
115
115
|
|
|
116
|
-
/**
|
|
117
|
-
* @description 处理资源选择取消
|
|
116
|
+
/**
|
|
117
|
+
* @description 处理资源选择取消
|
|
118
118
|
*/
|
|
119
119
|
const handleResSelectorCancel = useCallback(() => {
|
|
120
120
|
setJjbWebResSelectorShow(false);
|
|
121
121
|
}, []);
|
|
122
122
|
|
|
123
|
-
/**
|
|
124
|
-
* @description 处理预览视频关闭
|
|
123
|
+
/**
|
|
124
|
+
* @description 处理预览视频关闭
|
|
125
125
|
*/
|
|
126
126
|
const handlePreviewCancel = useCallback(() => {
|
|
127
127
|
setOpenPreviewVideo(false);
|
|
@@ -155,7 +155,7 @@ const PreviewVideo = ({
|
|
|
155
155
|
from: "https://cdn.cqjjb.cn/jjb1-web-jjb-web-saas-res-selector/latest/index.js",
|
|
156
156
|
componentKey: "jjbWebResSelector",
|
|
157
157
|
componentProps: {
|
|
158
|
-
|
|
158
|
+
sourceType: ['media'],
|
|
159
159
|
onOk: handleResSelectorOk,
|
|
160
160
|
onCancel: handleResSelectorCancel
|
|
161
161
|
}
|
package/api/courseLibrary.js
CHANGED
|
@@ -30,7 +30,7 @@ export const getCourseMenu = params => {
|
|
|
30
30
|
/**
|
|
31
31
|
* 获取课程基本信息数据(课程信息)
|
|
32
32
|
* @param {object} params - 请求参数,包含 id
|
|
33
|
-
* @returns {Promise}
|
|
33
|
+
* @returns {Promise}w
|
|
34
34
|
*/
|
|
35
35
|
export const getCourseInfo = params => {
|
|
36
36
|
return request.get(`/${params.apiBaseName || API_BASE_NAME}/course/${params.id}`);
|
package/package.json
CHANGED
package/utils/index.js
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* 获取API Host
|
|
3
|
-
* @returns {string} API Host地址,如果VITE_API_HOST为空则返回location.origin
|
|
4
|
-
*/
|
|
5
|
-
export function getApiHost() {
|
|
6
|
-
return process.env.NODE_ENV === 'development' ?
|
|
7
|
-
process.env?.app?.API_HOST || 'https://yjap.cqzxaq.com'
|
|
8
|
-
: window.location.origin;
|
|
9
|
-
}
|
|
1
|
+
/**
|
|
2
|
+
* 获取API Host
|
|
3
|
+
* @returns {string} API Host地址,如果VITE_API_HOST为空则返回location.origin
|
|
4
|
+
*/
|
|
5
|
+
export function getApiHost() {
|
|
6
|
+
return process.env.NODE_ENV === 'development' ?
|
|
7
|
+
process.env?.app?.API_HOST || 'https://yjap.cqzxaq.com'
|
|
8
|
+
: window.location.origin;
|
|
9
|
+
}
|
package/utils/request.js
CHANGED
|
@@ -1,76 +1,76 @@
|
|
|
1
|
-
import axios from 'axios';
|
|
2
|
-
import { getApiHost } from './index';
|
|
3
|
-
|
|
4
|
-
export const API_BASE_NAME = 'res';
|
|
5
|
-
|
|
6
|
-
// 创建 axios 实例
|
|
7
|
-
const request = axios.create({
|
|
8
|
-
// baseURL: 'http://192.168.3.47:3000',
|
|
9
|
-
// baseURL: 'http://10.43.82.219',
|
|
10
|
-
baseURL: getApiHost(),
|
|
11
|
-
// mock 阶段使用测试服务器
|
|
12
|
-
timeout: 10000 // 请求超时时间
|
|
13
|
-
});
|
|
14
|
-
|
|
15
|
-
// 请求拦截器 - 添加 token
|
|
16
|
-
request.interceptors.request.use(
|
|
17
|
-
config => {
|
|
18
|
-
// 从 sessionStorage 获取 token
|
|
19
|
-
const token = sessionStorage.getItem('token');
|
|
20
|
-
if (token) {
|
|
21
|
-
config.headers.token = token;
|
|
22
|
-
}
|
|
23
|
-
return config;
|
|
24
|
-
},
|
|
25
|
-
error => {
|
|
26
|
-
return Promise.reject(error);
|
|
27
|
-
}
|
|
28
|
-
);
|
|
29
|
-
|
|
30
|
-
// 响应拦截器
|
|
31
|
-
request.interceptors.response.use(
|
|
32
|
-
response => {
|
|
33
|
-
// 直接返回 response.data,因为 axios 默认返回 response.data
|
|
34
|
-
// 如果后端返回格式是 { respCode: '0000', data: {...} },则统一处理
|
|
35
|
-
if (response.data) {
|
|
36
|
-
// 统一处理响应格式,兼容不同的后端响应结构
|
|
37
|
-
const data = response.data;
|
|
38
|
-
// 如果响应中有 respCode,判断是否成功
|
|
39
|
-
if (data.respCode !== undefined) {
|
|
40
|
-
return {
|
|
41
|
-
success: data.respCode === '0000',
|
|
42
|
-
data: data.data || data,
|
|
43
|
-
...data
|
|
44
|
-
};
|
|
45
|
-
}
|
|
46
|
-
// 如果响应中有 success 字段,直接使用
|
|
47
|
-
if (data.success !== undefined) {
|
|
48
|
-
return {
|
|
49
|
-
success: data.success,
|
|
50
|
-
data: data.data || data,
|
|
51
|
-
...data
|
|
52
|
-
};
|
|
53
|
-
}
|
|
54
|
-
// 默认返回数据
|
|
55
|
-
return {
|
|
56
|
-
success: true,
|
|
57
|
-
data: data.data || data,
|
|
58
|
-
...data
|
|
59
|
-
};
|
|
60
|
-
}
|
|
61
|
-
return response;
|
|
62
|
-
},
|
|
63
|
-
error => {
|
|
64
|
-
console.error('请求失败:', error);
|
|
65
|
-
// 处理错误响应
|
|
66
|
-
if (error.response && error.response.data) {
|
|
67
|
-
return Promise.reject({
|
|
68
|
-
success: false,
|
|
69
|
-
message: error.response.data.message || error.message,
|
|
70
|
-
...error.response.data
|
|
71
|
-
});
|
|
72
|
-
}
|
|
73
|
-
return Promise.reject(error);
|
|
74
|
-
}
|
|
75
|
-
);
|
|
76
|
-
export default request;
|
|
1
|
+
import axios from 'axios';
|
|
2
|
+
import { getApiHost } from './index';
|
|
3
|
+
|
|
4
|
+
export const API_BASE_NAME = 'res';
|
|
5
|
+
|
|
6
|
+
// 创建 axios 实例
|
|
7
|
+
const request = axios.create({
|
|
8
|
+
// baseURL: 'http://192.168.3.47:3000',
|
|
9
|
+
// baseURL: 'http://10.43.82.219',
|
|
10
|
+
baseURL: getApiHost(),
|
|
11
|
+
// mock 阶段使用测试服务器
|
|
12
|
+
timeout: 10000 // 请求超时时间
|
|
13
|
+
});
|
|
14
|
+
|
|
15
|
+
// 请求拦截器 - 添加 token
|
|
16
|
+
request.interceptors.request.use(
|
|
17
|
+
config => {
|
|
18
|
+
// 从 sessionStorage 获取 token
|
|
19
|
+
const token = sessionStorage.getItem('token');
|
|
20
|
+
if (token) {
|
|
21
|
+
config.headers.token = token;
|
|
22
|
+
}
|
|
23
|
+
return config;
|
|
24
|
+
},
|
|
25
|
+
error => {
|
|
26
|
+
return Promise.reject(error);
|
|
27
|
+
}
|
|
28
|
+
);
|
|
29
|
+
|
|
30
|
+
// 响应拦截器
|
|
31
|
+
request.interceptors.response.use(
|
|
32
|
+
response => {
|
|
33
|
+
// 直接返回 response.data,因为 axios 默认返回 response.data
|
|
34
|
+
// 如果后端返回格式是 { respCode: '0000', data: {...} },则统一处理
|
|
35
|
+
if (response.data) {
|
|
36
|
+
// 统一处理响应格式,兼容不同的后端响应结构
|
|
37
|
+
const data = response.data;
|
|
38
|
+
// 如果响应中有 respCode,判断是否成功
|
|
39
|
+
if (data.respCode !== undefined) {
|
|
40
|
+
return {
|
|
41
|
+
success: data.respCode === '0000',
|
|
42
|
+
data: data.data || data,
|
|
43
|
+
...data
|
|
44
|
+
};
|
|
45
|
+
}
|
|
46
|
+
// 如果响应中有 success 字段,直接使用
|
|
47
|
+
if (data.success !== undefined) {
|
|
48
|
+
return {
|
|
49
|
+
success: data.success,
|
|
50
|
+
data: data.data || data,
|
|
51
|
+
...data
|
|
52
|
+
};
|
|
53
|
+
}
|
|
54
|
+
// 默认返回数据
|
|
55
|
+
return {
|
|
56
|
+
success: true,
|
|
57
|
+
data: data.data || data,
|
|
58
|
+
...data
|
|
59
|
+
};
|
|
60
|
+
}
|
|
61
|
+
return response;
|
|
62
|
+
},
|
|
63
|
+
error => {
|
|
64
|
+
console.error('请求失败:', error);
|
|
65
|
+
// 处理错误响应
|
|
66
|
+
if (error.response && error.response.data) {
|
|
67
|
+
return Promise.reject({
|
|
68
|
+
success: false,
|
|
69
|
+
message: error.response.data.message || error.message,
|
|
70
|
+
...error.response.data
|
|
71
|
+
});
|
|
72
|
+
}
|
|
73
|
+
return Promise.reject(error);
|
|
74
|
+
}
|
|
75
|
+
);
|
|
76
|
+
export default request;
|