@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 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: "\u57F9\u8BAD\u9879\u76EE"
82
- }, getLabelName(courseInfo?.courseTypeLabel) || '--'), /*#__PURE__*/React.createElement(Descriptions.Item, {
83
- label: "\u8BFE\u7A0B\u6807\u7B7E"
84
- }, getLabelName(courseInfo?.courseLabel) || '--'), /*#__PURE__*/React.createElement(Descriptions.Item, {
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: "\u8BFE\u7A0B\u4ECB\u7ECD"
93
- }, courseInfo?.courseDescription ? /*#__PURE__*/React.createElement("div", {
94
- dangerouslySetInnerHTML: {
95
- __html: courseInfo.courseDescription
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
- id: string;
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
- /** 课程资源ID,未传则认为是新增,传入则认为是编辑 */
20
- id?: string | number;
21
- /** 额外参数,会传递给 iframe 内的编辑器 */
22
- extraParams?: Record<string, any>;
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
- id,
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
- id: id || '',
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
- id: returnedId
40
+ courseId
42
41
  } = event.data;
43
42
  // 调用 onClose 回调
44
43
  if (onClose) {
45
44
  onClose({
46
- id: returnedId || ''
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, id]);
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.resourceTotalIden)).reduce((i, j) => i + j, 0);
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.resourceHour)).reduce((i, j) => i + j, 0).toFixed(2)
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
- selectionType: 'radio',
158
+ sourceType: ['media'],
159
159
  onOk: handleResSelectorOk,
160
160
  onCancel: handleResSelectorCancel
161
161
  }
@@ -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
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@cqsjjb/course-res-design",
3
- "version": "0.0.4",
3
+ "version": "0.0.6",
4
4
  "description": "课程资源设计组件库",
5
5
  "main": "index.js",
6
6
  "author": "jiaoxiwei",
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;