Commit 69411c9a by yuananting

feat:初步联调

parent fea42dc1
/*
* @Author: yuananting
* @Date: 2021-03-03 15:13:12
* @LastEditors: yuananting
* @LastEditTime: 2021-03-13 20:46:54
* @Description: 助学工具接口
* @Copyrigh: © 2020 杭州杰竞科技有限公司 版权所有
*/
import Service from "@/common/js/service";
export function queryCategoryTree(params: object) {
return Service.Hades("anon/hades/category/queryCategoryTree", params);
}
export function addCategory(params: object) {
return Service.Hades("anon/hades/category/addCategory", params);
}
export function delCategory(params: object) {
return Service.Hades("anon/hades/category/delCategory", params);
}
export function editCategory(params: object) {
return Service.Hades("anon/hades/category/editCategory", params);
}
export function editCategoryTree(params: object) {
return Service.Hades("anon/hades/category/editCategoryTree", params);
}
export function queryQuestionCategoryTree(params: object) {
return Service.Hades("anon/hades/question/queryCategoryTree", params);
}
export function queryQuestionPageList(params: object) {
return Service.Hades("anon/hades/question/queryQuestionPageList", params);
}
export function addQuestion(params: object) {
return Service.Hades("anon/hades/question/addQuestion", params);
}
export function deleteQuestion(params: object) {
return Service.Hades("anon/hades/question/deleteQuestion", params);
}
\ No newline at end of file
/*
* @Author: yuananting
* @Date: 2021-03-03 15:13:12
* @LastEditors: yuananting
* @LastEditTime: 2021-03-03 15:18:30
* @Description: 助学工具接口
* @Copyrigh: © 2020 杭州杰竞科技有限公司 版权所有
*/
import Service from "@/common/js/service";
export function queryCategoryTree(params: object) {
return Service.Hades("/private/lesson/queryCategoryTree", params);
}
/* /*
* @Author: 陈剑宇 * @Author: 陈剑宇
* @Date: 2020-05-07 14:43:01 * @Date: 2020-05-07 14:43:01
* @LastEditTime: 2021-02-21 17:24:08 * @LastEditTime: 2021-03-11 11:43:59
* @LastEditors: yuananting * @LastEditors: yuananting
* @Description: * @Description:
* @FilePath: /wheat-web-demo/src/domains/basic-domain/constants.ts * @FilePath: /wheat-web-demo/src/domains/basic-domain/constants.ts
...@@ -9,7 +9,7 @@ ...@@ -9,7 +9,7 @@
import { MapInterface } from '@/domains/basic-domain/interface' import { MapInterface } from '@/domains/basic-domain/interface'
// 默认是 dev 环境 // 默认是 dev 环境
const ENV: string = process.env.DEPLOY_ENV || 'dev'; const ENV: string = process.env.DEPLOY_ENV || 'dev1';
console.log("process.env.DEPLOY_ENV",process) console.log("process.env.DEPLOY_ENV",process)
const BASIC_HOST_MAP: MapInterface = { const BASIC_HOST_MAP: MapInterface = {
dev: 'https://dev-heimdall.xiaomai5.com/', dev: 'https://dev-heimdall.xiaomai5.com/',
......
/*
* @Author: yuananting
* @Date: 2021-03-11 11:34:37
* @LastEditors: yuananting
* @LastEditTime: 2021-03-13 20:46:28
* @Description: 描述一下咯
* @Copyrigh: © 2020 杭州杰竞科技有限公司 版权所有
*/
import { queryCategoryTree, addCategory, delCategory, editCategory, editCategoryTree, queryQuestionCategoryTree, addQuestion, queryQuestionPageList, deleteQuestion } from '@/data-source/questionBank/request-apis';
export default class QuestionBankService {
// 获取题目分类树
static queryCategoryTree(params: any) {
return queryCategoryTree(params);
}
// 新增题目分类
static addCategory(params: any) {
return addCategory(params);
}
// 删除分类
static delCategory(params: any) {
return delCategory(params);
}
// 编辑分类
static editCategory(params: any) {
return editCategory(params);
}
// 编辑分类树(拖拽)
static editCategoryTree(params: any) {
return editCategoryTree(params);
}
// 查询分类树列表
static queryQuestionCategoryTree(params: any) {
return queryQuestionCategoryTree(params);
}
// 查询题目列表
static queryQuestionPageList(params: any) {
return queryQuestionPageList(params);
}
// 添加题目
static addQuestion(params: any) {
return addQuestion(params);
}
// 删除题目
static deleteQuestion(params: any) {
return deleteQuestion(params);
}
}
\ No newline at end of file
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
* @Author: yuananting * @Author: yuananting
* @Date: 2021-02-25 13:46:35 * @Date: 2021-02-25 13:46:35
* @LastEditors: yuananting * @LastEditors: yuananting
* @LastEditTime: 2021-03-09 11:19:01 * @LastEditTime: 2021-03-13 20:12:14
* @Description: 助学工具-题库-题目管理-新增题目 * @Description: 助学工具-题库-题目管理-新增题目
* @Copyrigh: © 2020 杭州杰竞科技有限公司 版权所有 * @Copyrigh: © 2020 杭州杰竞科技有限公司 版权所有
*/ */
...@@ -12,40 +12,79 @@ import Breadcrumbs from "@/components/Breadcrumbs"; ...@@ -12,40 +12,79 @@ import Breadcrumbs from "@/components/Breadcrumbs";
import ShowTips from "@/components/ShowTips"; import ShowTips from "@/components/ShowTips";
import "./AddNewQuestion.less"; import "./AddNewQuestion.less";
import NewQuestionTab from "./components/NewQuestionTab"; import NewQuestionTab from "./components/NewQuestionTab";
import { defineQuestionData } from "./components/model"; import { defineQuestionInfo } from "./components/model";
import QuestionBankService from "@/domains/question-bank-domain/QuestionBankService";
import User from "@/common/js/user";
const { TabPane } = Tabs; const { TabPane } = Tabs;
class AddNewQuestion extends Component { class AddNewQuestion extends Component {
constructor(props) { constructor(props) {
super(props); super(props);
this.state = { this.state = {
activeKey: "THE_RADIO", activeKey: "SINGLE_CHOICE",
singleContent: defineQuestionData("THE_RADIO"), // 单选题内容 // 构建题目基本结构
multipleContent: defineQuestionData("MULTI_SELECT"), // 多选题内容 singleChoiceContent: defineQuestionInfo("SINGLE_CHOICE"), // 单选题
judgeContent: defineQuestionData("JUDGE"), // 多选题内容 multiChoiceContent: defineQuestionInfo("MULTI_CHOICE"), // 多选题
completionContent: defineQuestionData("COMPLETION"), // 填空题内容 judgeContent: defineQuestionInfo("JUDGE"), // 判断题
indefiniteContent: defineQuestionData("INDEFINITE_SELECT"), // 不定项选择题内容 gapFillingContent: defineQuestionInfo("GAP_FILLING"), // 填空题
indefiniteChoiceContent: defineQuestionInfo("INDEFINITE_CHOICE"), // 不定项选择题
}; };
} }
componentDidMount() {} componentDidMount() {}
saveCurrentQuestion = () => { saveCurrentQuestion = (content) => {
content.questionStemList.map((item, index)=> {
item.sort = index;
return item;
})
content.optionList.map((item)=> {
item.questionOptionContentList.map((childItem, childIndex) => {
childItem.sort = childIndex;
return childItem;
})
return item;
})
content.questionAnswerDescList.map((item, index)=> {
item.sort = index;
return item;
})
let params = {
...content,
categoryId: getParameterByName("categoryId"),
source: 0,
tenantId: User.getStoreId(),
userId: User.getUserId(),
};
QuestionBankService.addQuestion(params).then((res) => {
console.log(res);
});
};
confirmSaveQuestion = () => {
const {
singleChoiceContent,
multiChoiceContent,
judgeContent,
gapFillingContent,
indefiniteChoiceContent,
} = this.state;
switch (this.state.activeKey) { switch (this.state.activeKey) {
case "THE_RADIO": case "SINGLE_CHOICE":
console.log(this.singleRef) if (this.singleRef.checkInput() === 0) {
this.singleRef.checkInput(); this.saveCurrentQuestion(singleChoiceContent);
}
break; break;
case "MULTI_SELECT": case "MULTI_CHOICE":
this.multipleRef.checkInput(); this.multipleRef.checkInput();
break; break;
case "JUDGE": case "JUDGE":
this.judgeRef.checkInput(); this.judgeRef.checkInput();
break; break;
case "COMPLETION": case "GAP_FILLING":
this.CompletionRef.checkInput(); this.CompletionRef.checkInput();
break; break;
case "INDEFINITE_SELECT": case "INDEFINITE_CHOICE":
this.indefiniteRef.checkInput(); this.indefiniteRef.checkInput();
break; break;
} }
...@@ -56,9 +95,14 @@ class AddNewQuestion extends Component { ...@@ -56,9 +95,14 @@ class AddNewQuestion extends Component {
activeKey, activeKey,
singleContent, singleContent,
multipleContent, multipleContent,
judgeContent, judgeContent1,
completionContent, completionContent,
indefiniteContent, indefiniteContent,
singleChoiceContent,
multiChoiceContent,
judgeContent,
gapFillingContent,
indefiniteChoiceContent,
} = this.state; } = this.state;
return ( return (
<div className="page add-new-question"> <div className="page add-new-question">
...@@ -76,31 +120,32 @@ class AddNewQuestion extends Component { ...@@ -76,31 +120,32 @@ class AddNewQuestion extends Component {
> >
<TabPane <TabPane
tab={<span className="icon iconfont">&#xe7fa; 单选题</span>} tab={<span className="icon iconfont">&#xe7fa; 单选题</span>}
key="THE_RADIO" key="SINGLE_CHOICE"
> >
<NewQuestionTab <NewQuestionTab
questionTypeKey="THE_RADIO" questionTypeKey="SINGLE_CHOICE"
onRef={(ref) => { onRef={(ref) => {
this.singleRef = ref; this.singleRef = ref;
}} }}
questionContent={singleContent} questionInfo={singleChoiceContent}
onSetState={(newContent) => { onSetState={(newContent) => {
Object.assign(singleContent, newContent); console.log(newContent);
Object.assign(singleChoiceContent, newContent);
}} }}
/> />
</TabPane> </TabPane>
<TabPane <TabPane
tab={<span className="icon iconfont">&#xe7fb; 多选题</span>} tab={<span className="icon iconfont">&#xe7fb; 多选题</span>}
key="MULTI_SELECT" key="MULTI_CHOICE"
> >
<NewQuestionTab <NewQuestionTab
questionTypeKey="MULTI_SELECT" questionTypeKey="MULTI_CHOICE"
onRef={(ref) => { onRef={(ref) => {
this.multipleRef = ref; this.multipleRef = ref;
}} }}
questionContent={multipleContent} questionInfo={multiChoiceContent}
onSetState={(newContent) => { onSetState={(newContent) => {
Object.assign(multipleContent, newContent); Object.assign(multiChoiceContent, newContent);
}} }}
/> />
</TabPane> </TabPane>
...@@ -113,7 +158,7 @@ class AddNewQuestion extends Component { ...@@ -113,7 +158,7 @@ class AddNewQuestion extends Component {
onRef={(ref) => { onRef={(ref) => {
this.judgeRef = ref; this.judgeRef = ref;
}} }}
questionContent={judgeContent} questionInfo={judgeContent}
onSetState={(newContent) => { onSetState={(newContent) => {
Object.assign(judgeContent, newContent); Object.assign(judgeContent, newContent);
}} }}
...@@ -121,16 +166,16 @@ class AddNewQuestion extends Component { ...@@ -121,16 +166,16 @@ class AddNewQuestion extends Component {
</TabPane> </TabPane>
<TabPane <TabPane
tab={<span className="icon iconfont">&#xe7fd; 填空题</span>} tab={<span className="icon iconfont">&#xe7fd; 填空题</span>}
key="COMPLETION" key="GAP_FILLING"
> >
<NewQuestionTab <NewQuestionTab
questionTypeKey="COMPLETION" questionTypeKey="GAP_FILLING"
onRef={(ref) => { onRef={(ref) => {
this.CompletionRef = ref; this.CompletionRef = ref;
}} }}
questionContent={completionContent} questionInfo={gapFillingContent}
onSetState={(newContent) => { onSetState={(newContent) => {
Object.assign(completionContent, newContent); Object.assign(gapFillingContent, newContent);
}} }}
/> />
</TabPane> </TabPane>
...@@ -143,16 +188,16 @@ class AddNewQuestion extends Component { ...@@ -143,16 +188,16 @@ class AddNewQuestion extends Component {
</Tooltip> </Tooltip>
</span> </span>
} }
key="INDEFINITE_SELECT" key="INDEFINITE_CHOICE"
> >
<NewQuestionTab <NewQuestionTab
questionTypeKey="INDEFINITE_SELECT" questionTypeKey="INDEFINITE_CHOICE"
onRef={(ref) => { onRef={(ref) => {
this.indefiniteRef = ref; this.indefiniteRef = ref;
}} }}
questionContent={indefiniteContent} questionInfo={indefiniteChoiceContent}
onSetState={(newContent) => { onSetState={(newContent) => {
Object.assign(indefiniteContent, newContent); Object.assign(indefiniteChoiceContent, newContent);
}} }}
/> />
</TabPane> </TabPane>
...@@ -164,7 +209,7 @@ class AddNewQuestion extends Component { ...@@ -164,7 +209,7 @@ class AddNewQuestion extends Component {
<Button <Button
type="primary" type="primary"
onClick={() => { onClick={() => {
this.saveCurrentQuestion(); this.confirmSaveQuestion();
}} }}
> >
保存 保存
......
...@@ -2,27 +2,23 @@ ...@@ -2,27 +2,23 @@
* @Author: yuananting * @Author: yuananting
* @Date: 2021-02-21 17:51:01 * @Date: 2021-02-21 17:51:01
* @LastEditors: yuananting * @LastEditors: yuananting
* @LastEditTime: 2021-03-05 13:41:32 * @LastEditTime: 2021-03-13 16:48:23
* @Description: 助学工具-题库-题库主页面 * @Description: 助学工具-题库-题库主页面
* @Copyrigh: © 2020 杭州杰竞科技有限公司 版权所有 * @Copyrigh: © 2020 杭州杰竞科技有限公司 版权所有
*/ */
import React, { Component } from "react"; import React, { Component } from "react";
import { Layout } from "antd";
import "./QuestionBankIndex.less"; import "./QuestionBankIndex.less";
import QuestionBankSider from "./components/QuestionBankSider"; import QuestionBankSider from "./components/QuestionBankSider";
import QuestionManageFilter from "./components/QuestionManageFilter"; import QuestionManageList from "./components/QuestionManageContent";
import QuestionManageOpt from "./components/QuestionManageOpt"; import User from "@/common/js/user";
import QuestionManageList from "./components/QuestionManageList"; import QuestionBankService from "@/domains/question-bank-domain/QuestionBankService";
class QuestionBankIndex extends Component { class QuestionBankIndex extends Component {
constructor(props) { constructor(props) {
super(props); super(props);
this.state = { this.state = {
query: { selectedCategoryId: "",
current: 1,
size: 10,
},
loading: true, loading: true,
dataSource: [], // 题库列表数据 dataSource: [], // 题库列表数据
totalCount: 1, // 题库数据总条数 totalCount: 1, // 题库数据总条数
...@@ -32,46 +28,26 @@ class QuestionBankIndex extends Component { ...@@ -32,46 +28,26 @@ class QuestionBankIndex extends Component {
componentDidMount() { componentDidMount() {
// TODO // TODO
// 接口请求 初始化数据 // 接口请求 初始化数据
this.getQuestionBankList();
} }
getQuestionBankList = (_query = {}) => { getCategoryIdFromSider = (selectedCategoryId) => {
const query = { if (selectedCategoryId && selectedCategoryId.length > 0) {
...this.state.query, this.setState({ selectedCategoryId: selectedCategoryId[0] });
..._query, }
};
// 更新请求参数
this.setState({ query });
// CourseService.videoSchedulePage(query).then((res) => {
// const { result = {} } = res || {};
// const { records = [], total = 0 } = result;
// this.setState({
// dataSource: records,
// totalCount: Number(total)
// });
// });
}; };
render() { render() {
const { query, dataSource, totalCount } = this.state;
return ( return (
<div className="question-bank-index page"> <div className="question-bank-index page">
<div className="content-header">题目</div> <div className="content-header">题目</div>
<div className="box content-body"> <div className="box content-body">
<div className="sider"> <div className="sider">
<QuestionBankSider /> <QuestionBankSider
getSelectedCategoryId={this.getCategoryIdFromSider.bind(this)}
/>
</div> </div>
<div className="content"> <div className="content">
<QuestionManageFilter /> <QuestionManageList selectedCategoryId={this.state.selectedCategoryId} />
<QuestionManageOpt />
<QuestionManageList
query={query}
dataSource={dataSource}
totalCount={totalCount}
onChange={this.getQuestionList}
/>
</div> </div>
</div> </div>
</div> </div>
......
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
* @Author: yuananting * @Author: yuananting
* @Date: 2021-02-21 18:27:43 * @Date: 2021-02-21 18:27:43
* @LastEditors: yuananting * @LastEditors: yuananting
* @LastEditTime: 2021-03-02 17:26:30 * @LastEditTime: 2021-03-11 19:10:44
* @Description: 助学工具-题库-题库主页面样式 * @Description: 助学工具-题库-题库主页面样式
* @Copyrigh: © 2020 杭州杰竞科技有限公司 版权所有 * @Copyrigh: © 2020 杭州杰竞科技有限公司 版权所有
*/ */
...@@ -18,6 +18,7 @@ ...@@ -18,6 +18,7 @@
.content { .content {
width: 100%; width: 100%;
margin-left: 24px; margin-left: 24px;
height: calc(100vh - 160px);
} }
} }
} }
/*
* @Author: yuananting
* @Date: 2021-02-25 09:45:11
* @LastEditors: yuananting
* @LastEditTime: 2021-02-25 11:35:10
* @Description: 助学工具-题库-题目管理主页面
* @Copyrigh: © 2020 杭州杰竞科技有限公司 版权所有
*/
import React, { Component } from "react";
import Breadcrumbs from "@/components/Breadcrumbs";
import { Space } from "antd";
import QuestionManageFilter from "./components/QuestionManageFilter";
import QuestionManageOpt from "./components/QuestionManageOpt";
import QuestionManageList from "./components/QuestionManageList";
import "./QuestionManageIndex.less";
class QuestionManageIndex extends Component {
constructor(props) {
super(props);
this.state = {
query: {
current: 1,
size: 10,
},
loading: true,
dataSource: [], // 题目列表数据
totalCount: 1, // 题目数据总条数
};
}
componentDidMount() {
// TODO
// 接口请求 初始化数据
this.getQuestionList();
}
getQuestionList = (_query = {}) => {
const query = {
...this.state.query,
..._query,
};
// 更新请求参数
this.setState({ query });
};
render() {
const { query, dataSource, totalCount } = this.state;
return (
<div className="question-manage-index page">
<Breadcrumbs navList="课程分类" goBack={() => RCHistory.goBack()} />
<div className="box">
<Space className="question-basic-info" size={100}>
<span>题库名称:{"业务培训"}</span>
<span>题目数量:{100}</span>
</Space>
<QuestionManageFilter />
<QuestionManageOpt />
<QuestionManageList
query={query}
dataSource={dataSource}
totalCount={totalCount}
onChange={this.getQuestionList}
/>
</div>
</div>
);
}
}
export default QuestionManageIndex;
/*
* @Author: yuananting
* @Date: 2021-02-25 10:49:16
* @LastEditors: yuananting
* @LastEditTime: 2021-02-25 10:53:58
* @Description: 助学工具-题库-题目管理主页面样式
* @Copyrigh: © 2020 杭州杰竞科技有限公司 版权所有
*/
.question-manage-index {
position: relative;
.question-basic-info {
margin-bottom: 16px;
}
}
...@@ -45,61 +45,41 @@ class CompletionStem extends Component { ...@@ -45,61 +45,41 @@ class CompletionStem extends Component {
} }
watchStemContent = () => { watchStemContent = () => {
var currentBlanksList = this.saveCurrentBlanks(); // 获取当前填空列表 var _blanksList = [];
console.log("originBlanksList:", this.state.originBlanksList); const stemInput = document.getElementById("editor-box_content");
console.log("currentBlanksList:", currentBlanksList);
// console.log(JSON.stringify(currentBlanksList)===JSON.stringify(this.state.originBlanksList))
if (
JSON.stringify(currentBlanksList) !==
JSON.stringify(this.state.originBlanksList)
) {
console.log("修改")
this.setState({ originBlanksList: this.saveCurrentBlanks() }); // 保存修改前的填空列表
this.sortBlanks();
}
this.handleStemStyle();
this.props.changeBlankCount(currentBlanksList);
};
sortBlanks = () => {
const _blanksList = JSON.parse(JSON.stringify(this.saveCurrentBlanks()));
_blanksList.map((item, index) => {
item.innerHTML = "填空" + (index + 1);
return item;
});
this.setState({ blanksList: _blanksList });
};
saveCurrentBlanks = () => {
var currentBlanksList = [];
var stemInput = document.getElementById("editor-box_content");
stemInput.childNodes.forEach((item) => { stemInput.childNodes.forEach((item) => {
if (item.nodeName === "SPAN") { if (item.nodeName === "SPAN") {
currentBlanksList.push(item); _blanksList.push(item);
} }
}); });
return currentBlanksList; this.setState({blanksList:_blanksList})
this.handleStemStyle();
this.props.changeBlankCount(this.state.blanksList);
}; };
handleInsertBlanks = (id) => { /**
* 插入占位符
*
* @memberof QuestionInputItem
*/
insertBlanks = () => {
document.getElementById("editor-box_content").focus(); document.getElementById("editor-box_content").focus();
const { blanksList } = this.state; const _blanksList = this.state.blanksList;
blanksList.map((item, index) => { var blanks = document.createElement("span");
item.innerHTML = "填空" + (index + 1); blanks.className = "fill-line";
}); blanks.innerHTML = "填空";
var templateBlanks = blanksList.filter((item) => item.id === id); blanks.id = window.random_string(16); // 填空id
var insertBlanks = document.createElement("span"); blanks.contentEditable = false;
insertBlanks.className = "fill-line"; _blanksList.push(blanks);
insertBlanks.innerHTML = templateBlanks[0].innerHTML; this.setState({ blanksList: _blanksList });
insertBlanks.id = templateBlanks[0].id; // 填空id;
insertBlanks.contentEditable = false;
var sel, range; var sel, range;
sel = window.getSelection(); sel = window.getSelection();
if (sel.getRangeAt && sel.rangeCount) { if (sel.getRangeAt && sel.rangeCount) {
range = sel.getRangeAt(0); range = sel.getRangeAt(0);
range.deleteContents(); range.deleteContents();
var el = document.createElement("div"); var el = document.createElement("div");
el.appendChild(insertBlanks); el.appendChild(blanks);
var frag = document.createDocumentFragment(), var frag = document.createDocumentFragment(),
node, node,
lastNode; lastNode;
...@@ -117,24 +97,6 @@ class CompletionStem extends Component { ...@@ -117,24 +97,6 @@ class CompletionStem extends Component {
} }
}; };
/**
* 插入占位符
*
* @memberof QuestionInputItem
*/
insertBlanks = () => {
const _blanksList = this.state.blanksList;
var blanks = document.createElement("span");
blanks.className = "fill-line";
blanks.innerHTML = "填空";
blanks.id = window.random_string(16); // 填空id
blanks.contentEditable = false;
_blanksList.push(blanks);
this.setState({ blanksList: _blanksList });
this.handleInsertBlanks(blanks.id);
};
// 输入框样式 // 输入框样式
handleStemStyle = () => { handleStemStyle = () => {
const stemInput = document.getElementById("editor-box_content"); const stemInput = document.getElementById("editor-box_content");
......
...@@ -2,13 +2,15 @@ ...@@ -2,13 +2,15 @@
* @Author: yuananting * @Author: yuananting
* @Date: 2021-02-22 10:59:43 * @Date: 2021-02-22 10:59:43
* @LastEditors: yuananting * @LastEditors: yuananting
* @LastEditTime: 2021-03-05 09:39:47 * @LastEditTime: 2021-03-13 20:29:29
* @Description: 助学工具-题库-题库主页面侧边栏 * @Description: 助学工具-题库-题库主页面侧边栏
* @Copyrigh: © 2020 杭州杰竞科技有限公司 版权所有 * @Copyrigh: © 2020 杭州杰竞科技有限公司 版权所有
*/ */
import React, { Component } from "react"; import React, { Component } from "react";
import { Input, Button, Tree } from "antd"; import { Input, Button, Tree } from "antd";
import "./QuestionBankSider.less"; import "./QuestionBankSider.less";
import User from "@/common/js/user";
import QuestionBankService from "@/domains/question-bank-domain/QuestionBankService";
const { Search } = Input; const { Search } = Input;
const { DirectoryTree } = Tree; const { DirectoryTree } = Tree;
...@@ -17,140 +19,59 @@ class QuestionBankSider extends Component { ...@@ -17,140 +19,59 @@ class QuestionBankSider extends Component {
constructor(props) { constructor(props) {
super(props); super(props);
this.state = { this.state = {
selectedKeys: ["0"],
searchValue: null, searchValue: null,
NewEditQuestionBankCategory: null, //新增或编辑分类模态框 NewEditQuestionBankCategory: null, //新增或编辑分类模态框
ImportCourseCategory: null, // 引用课程分类模态框 ImportCourseCategory: null, // 引用课程分类模态框
treeData: [ treeData: this.props.treeData || [],
{
tenantId: "1122334455667788",
userId: "12345678",
source: 0,
id: "1367023655839768500",
parentId: "0",
rootId: "1367023655839768500",
categoryLevel: 0,
categoryName: "未分类",
sort: 0,
},
{
tenantId: "1122334455667788",
userId: "12345678",
source: 0,
id: "1367023655839768577",
parentId: "0",
rootId: "1367023655839768577",
categoryLevel: 0,
categoryName: "分类1",
subList: [
{
tenantId: "1122334455667788",
userId: "12345678",
source: 0,
id: "1367023709942095873",
parentId: "1367023655839768577",
rootId: "1367023655839768577",
categoryLevel: 1,
categoryName: "test",
sort: 0,
},
{
tenantId: "1122334455667788",
userId: "12345678",
source: 0,
id: "1367023725184196609",
parentId: "1367023655839768577",
rootId: "1367023655839768577",
categoryLevel: 1,
categoryName: "分类2",
subList: [
{
tenantId: "1122334455667788",
userId: "12345678",
source: 0,
id: "1367023805563838466",
parentId: "1367023725184196609",
rootId: "1367023655839768577",
categoryLevel: 2,
categoryName: "test",
sort: 0,
},
],
sort: 1,
},
],
sort: 1,
},
{
tenantId: "1122334455667788",
userId: "12345678",
source: 0,
id: "1367049864988516353",
parentId: "0",
rootId: "1367049864988516353",
categoryLevel: 0,
categoryName: "分类2",
subList: [
{
tenantId: "1122334455667788",
userId: "12345678",
source: 0,
id: "1367049931656978433",
parentId: "1367049864988516353",
rootId: "1367049864988516353",
categoryLevel: 1,
categoryName: "分类2",
subList: [
{
tenantId: "1122334455667788",
userId: "12345678",
source: 0,
id: "1367049973746819074",
parentId: "1367049931656978433",
rootId: "1367049864988516353",
categoryLevel: 2,
categoryName: "分类3",
subList: [
{
tenantId: "1122334455667788",
userId: "12345678",
source: 0,
id: "1367050021431861249",
parentId: "1367049973746819074",
rootId: "1367049864988516353",
categoryLevel: 3,
categoryName: "分类4",
subList: [
{
tenantId: "1122334455667788",
userId: "12345678",
source: 0,
id: "1367050063035162626",
parentId: "1367050021431861249",
rootId: "1367049864988516353",
categoryLevel: 4,
categoryName: "分类5",
sort: 0,
},
],
sort: 0,
},
],
sort: 0,
},
],
sort: 0,
},
],
sort: 2,
},
],
}; };
} }
componentDidMount() { componentDidMount() {
this.setState({ treeData: this.renderTreeNodes(this.state.treeData) }); this.queryCategoryTree();
} }
/** 获取树状第一级key 设置默认展开第一项 */
getFirstLevelKeys = (data) => {
let firstLevelKeys = [];
data.forEach((item) => {
if (item.categoryLevel === 0) {
firstLevelKeys.push(item.key);
}
});
return firstLevelKeys;
};
/** 树状展开事件 */
onExpand = (expandedKeys) => {
this.setState({ expandedKeys });
};
/** 树状选中事件 */
onSelect = (selectedKeys) => {
this.setState({ selectedKeys });
this.props.getSelectedCategoryId(selectedKeys)
};
// 查询分类树
queryCategoryTree = (categoryName) => {
let query = {
source: 0,
categoryName,
userId: User.getUserId(),
tenantId: User.getStoreId(),
};
QuestionBankService.queryQuestionCategoryTree(query).then((res) => {
const { categoryList = [] } = res.result;
const defaultNode = { id: "0", categoryName:"未分类", categoryCount: 0}
categoryList.unshift(defaultNode);
this.setState({ treeData: this.renderTreeNodes(categoryList, categoryName) });
this.setState({
expandedKeys: this.getFirstLevelKeys(categoryList),
});
});
};
renderTreeNodes = (data, value) => { renderTreeNodes = (data, value) => {
return data.map((item) => { return data.map((item) => {
item.title = item.categoryName; item.title = item.categoryName;
...@@ -166,7 +87,7 @@ class QuestionBankSider extends Component { ...@@ -166,7 +87,7 @@ class QuestionBankSider extends Component {
</span> </span>
); );
item.icon = item.icon =
item.id === "default" ? ( item.categoryName === "未分类" ? (
<span className="icon iconfont" style={{ color: "#FBD140" }}> <span className="icon iconfont" style={{ color: "#FBD140" }}>
&#xe7f6; &#xe7f6;
</span> </span>
...@@ -175,15 +96,15 @@ class QuestionBankSider extends Component { ...@@ -175,15 +96,15 @@ class QuestionBankSider extends Component {
&#xe7f1; &#xe7f1;
</span> </span>
); );
if (item.subList) { if (item.sonCategoryList) {
item.children = this.renderTreeNodes(item.subList, value); item.children = this.renderTreeNodes(item.sonCategoryList, value);
} }
return item; return item;
}); });
}; };
render() { render() {
const { treeData } = this.state; const { treeData, expandedKeys, selectedKeys } = this.state;
return ( return (
<div className="question-bank-sider"> <div className="question-bank-sider">
<div className="sider-title">题目分类</div> <div className="sider-title">题目分类</div>
...@@ -192,9 +113,7 @@ class QuestionBankSider extends Component { ...@@ -192,9 +113,7 @@ class QuestionBankSider extends Component {
placeholder="搜索名称分类" placeholder="搜索名称分类"
onSearch={(value) => { onSearch={(value) => {
// TODO 调用查询分类接口 // TODO 调用查询分类接口
this.setState({ this.queryCategoryTree(value);
treeData: this.renderTreeNodes(treeData, value),
});
}} }}
/> />
<div className="sider-btn"> <div className="sider-btn">
...@@ -208,17 +127,16 @@ class QuestionBankSider extends Component { ...@@ -208,17 +127,16 @@ class QuestionBankSider extends Component {
分类管理 分类管理
</Button> </Button>
</div> </div>
<div className="sider-tree">
<DirectoryTree <DirectoryTree
defaultSelectedKeys={["1367023655839768500"]} expandedKeys={expandedKeys}
onExpand={this.onExpand}
selectedKeys={selectedKeys}
onSelect={this.onSelect}
showIcon showIcon
treeData={treeData} treeData={treeData}
/> />
{treeData.length === 1 && (
<div className="empty-tree-tip">
还没有分类,需<span className="empty-tree-btn">引用课程分类</span>
哦~
</div> </div>
)}
{this.state.NewEditQuestionBankCategory} {this.state.NewEditQuestionBankCategory}
{this.state.ImportCourseCategory} {this.state.ImportCourseCategory}
</div> </div>
......
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
* @Author: yuananting * @Author: yuananting
* @Date: 2021-02-22 12:02:34 * @Date: 2021-02-22 12:02:34
* @LastEditors: yuananting * @LastEditors: yuananting
* @LastEditTime: 2021-03-04 16:59:07 * @LastEditTime: 2021-03-11 20:29:44
* @Description: 助学工具-题库-题库主页面侧边栏样式 * @Description: 助学工具-题库-题库主页面侧边栏样式
* @Copyrigh: © 2020 杭州杰竞科技有限公司 版权所有 * @Copyrigh: © 2020 杭州杰竞科技有限公司 版权所有
*/ */
...@@ -22,6 +22,11 @@ ...@@ -22,6 +22,11 @@
.sider-btn { .sider-btn {
margin-bottom: 16px; margin-bottom: 16px;
} }
.sider-tree {
width: 266px;
overflow: scroll;
height: calc(100vh - 300px);
.empty-tree-tip { .empty-tree-tip {
text-align: center; text-align: center;
margin-top: 100%; margin-top: 100%;
...@@ -34,6 +39,7 @@ ...@@ -34,6 +39,7 @@
font-size: 14px; font-size: 14px;
font-weight: 400; font-weight: 400;
color: #666666; color: #666666;
width: 260px;
.anticon { .anticon {
color: #666666; color: #666666;
} }
...@@ -42,14 +48,12 @@ ...@@ -42,14 +48,12 @@
padding: 0; padding: 0;
span { span {
line-height: 44px; line-height: 44px;
white-space: nowrap;
} }
.ant-tree-node-content-wrapper.ant-tree-node-selected { .ant-tree-node-content-wrapper.ant-tree-node-selected {
color: #666666; color: #666666;
} }
} }
// .ant-tree-treenode-selected:hover::before, }
// .ant-tree-treenode-selected::before {
// background: rgb(255 251 240);
// }
} }
} }
...@@ -73,7 +73,7 @@ class QuestionEditor extends Component { ...@@ -73,7 +73,7 @@ class QuestionEditor extends Component {
renderEditor() { renderEditor() {
const { editorId } = this.state; const { editorId } = this.state;
const { detail = {}, onChange, bindChangeContent } = this.props; const { detail = {}, detailInfo = {}, onChange, bindChangeContent } = this.props;
const editorRoot = new E( const editorRoot = new E(
`#editor${editorId}_tabbar`, `#editor${editorId}_tabbar`,
`#editor${editorId}_content` `#editor${editorId}_content`
...@@ -103,15 +103,15 @@ class QuestionEditor extends Component { ...@@ -103,15 +103,15 @@ class QuestionEditor extends Component {
str = str.replace(/<\/?[^>]*>/g, ""); str = str.replace(/<\/?[^>]*>/g, "");
str = str.replace(/[ | ]*\n/g, "\n"); str = str.replace(/[ | ]*\n/g, "\n");
str = str.replace(/\&nbsp\;/gi, " "); str = str.replace(/\&nbsp\;/gi, " ");
str = str.replace(/[\r\n]/g,"");
if (str.length > 1000) { if (str.length > 1000) {
str = str.substring(0, 1000); str = str.substring(0, 1000);
message.error("内容过长,不能超过1000字"); message.error("内容过长,不能超过1000字");
} }
return str; return str
}; };
editorRoot.customConfig.onchange = (html) => { editorRoot.customConfig.onchange = (html) => {
console.log(html)
const { focusFlag } = this.state; const { focusFlag } = this.state;
const textLength = editorRoot.txt.text().replace(/\&nbsp\;/gi, " ") const textLength = editorRoot.txt.text().replace(/\&nbsp\;/gi, " ")
.length; .length;
...@@ -119,15 +119,14 @@ class QuestionEditor extends Component { ...@@ -119,15 +119,14 @@ class QuestionEditor extends Component {
? html.match(/<img/g).length * 2 ? html.match(/<img/g).length * 2
: 0; : 0;
const contentLength = imgLength + textLength; const contentLength = imgLength + textLength;
const pHeight = document.getElementById(`editor${editorId}_content`) const divHeight = document.getElementById(`editor${editorId}_content`)
.firstChild.firstChild.offsetHeight; .firstChild.offsetHeight;
if (pHeight > 30 || imgLength > 0) { if (divHeight > 30 || imgLength > 0) {
this.setState({ isShowSingleInput: false }); this.setState({ isShowSingleInput: false });
} else { } else {
this.setState({ isShowSingleInput: true }); this.setState({ isShowSingleInput: true });
} }
this.setState({ errorInput: contentLength > 1000 });
this.setState( this.setState(
{ contentLength, visiblePlacehold: contentLength === 0 && !focusFlag }, { contentLength, visiblePlacehold: contentLength === 0 && !focusFlag },
() => { () => {
...@@ -152,16 +151,37 @@ class QuestionEditor extends Component { ...@@ -152,16 +151,37 @@ class QuestionEditor extends Component {
visibleMediaBox: true, visibleMediaBox: true,
visiblePlacehold: false, visiblePlacehold: false,
}); });
bindChangeContent && bindChangeContent(this.handleChangeContent, editorRoot.textElemId)
}; };
editorRoot.create(); editorRoot.create();
this.editorRoot = editorRoot; this.editorRoot = editorRoot;
// 初始化设置内容
if (detail.content) { if (detail.content) {
const contentHtml = /^\<p/.test(detail.content) const contentHtml = /^\<p/.test(detail.content)
? detail.content ? detail.content
: `<p>${detail.content}</p>`; : `<p>${detail.content}</p>`;
editorRoot.txt.html(contentHtml); editorRoot.txt.html(detail.content);
const textLength = editorRoot.txt.text().replace(/\&nbsp\;/gi, " ")
.length;
const imgLength = contentHtml.match(/<img/g)
? contentHtml.match(/<img/g).length * 2
: 0;
const contentLength = imgLength + textLength;
this.setState(
{
contentLength,
visiblePlacehold: contentLength === 0 && !this.state.focusFlag,
},
() => {
onChange && onChange(contentHtml, this.state.contentLength);
}
);
}
if (detailInfo.content) {
const contentHtml = /^\<p/.test(detailInfo.content)
? detailInfo.content
: `<p>${detailInfo.content}</p>`;
editorRoot.txt.html(detailInfo.content);
const textLength = editorRoot.txt.text().replace(/\&nbsp\;/gi, " ") const textLength = editorRoot.txt.text().replace(/\&nbsp\;/gi, " ")
.length; .length;
const imgLength = contentHtml.match(/<img/g) const imgLength = contentHtml.match(/<img/g)
...@@ -178,7 +198,7 @@ class QuestionEditor extends Component { ...@@ -178,7 +198,7 @@ class QuestionEditor extends Component {
} }
); );
} }
bindChangeContent && bindChangeContent(this.handleChangeContent, editorRoot.textElemId); bindChangeContent && bindChangeContent(this.handleChangeContent);
} }
render() { render() {
...@@ -219,6 +239,7 @@ class QuestionEditor extends Component { ...@@ -219,6 +239,7 @@ class QuestionEditor extends Component {
}); });
}} }}
> >
<div <div
className="editor-box" className="editor-box"
id={`editor${editorId}_tabbar`} id={`editor${editorId}_tabbar`}
...@@ -287,4 +308,5 @@ class QuestionEditor extends Component { ...@@ -287,4 +308,5 @@ class QuestionEditor extends Component {
); );
} }
} }
export default QuestionEditor; export default QuestionEditor;
/* /*
* @Author: yuananting * @Author: yuananting
* @Date: 2021-02-25 10:42:51 * @Date: 2021-02-25 11:26:28
* @LastEditors: yuananting * @LastEditors: yuananting
* @LastEditTime: 2021-02-25 11:11:10 * @LastEditTime: 2021-03-13 16:42:41
* @Description: 助学工具-题库-题目管理主页面头部搜索样式 * @Description: 助学工具-题库-题目管理右侧内容样式
* @Copyrigh: © 2020 杭州杰竞科技有限公司 版权所有 * @Copyrigh: © 2020 杭州杰竞科技有限公司 版权所有
*/ */
.question-manage-filter { .question-manage-content {
.question-manage-filter {
position: relative; position: relative;
.search-condition { .search-condition {
width: calc(100% - 80px); width: calc(100% - 80px);
...@@ -44,7 +45,37 @@ ...@@ -44,7 +45,37 @@
} }
} }
} }
} }
.data-icon { .data-icon {
cursor: pointer;
}
.question-manage-list {
position: relative;
margin-top: 16px;
.empty-list-tip {
color: #ffb714;
cursor: pointer;
}
.record-name {
word-break: break-all;
overflow: hidden;
text-overflow: ellipsis;
display: -webkit-box;
-webkit-line-clamp: 5;
-webkit-box-orient: vertical;
}
.record-operate {
display: flex;
&__item {
color: #5289fa;
cursor: pointer; cursor: pointer;
&.split {
margin: 0 8px;
color: #bfbfbf;
}
}
}
}
} }
/*
* @Author: yuananting
* @Date: 2021-02-25 10:30:52
* @LastEditors: yuananting
* @LastEditTime: 2021-02-25 10:44:46
* @Description: 助学工具-题库-题目管理主页面头部搜索
* @Copyrigh: © 2020 杭州杰竞科技有限公司 版权所有
*/
import React, { Component } from "react";
import "./QuestionManageFilter.less";
import { Row, Input, Select, Tooltip } from "antd";
const { Search } = Input;
const DEFAULT_QUERY = {
questionName: null, // 题目名称
questionType: null, // 题型
};
class QuestionManageFilter extends Component {
constructor(props) {
super(props);
this.state = {
query: { ...DEFAULT_QUERY }, // 查询条件
questionTypeList: [], // 题型列表
};
}
render() {
const {
query: { questionName, questionType },
questionTypeList,
} = this.state;
return (
<div className="question-manage-filter">
<Row type="flex" justify="space-between" align="top">
<div className="search-condition">
<div className="search-condition__item">
<span className="search-label">题目:</span>
<Search
value={questionName}
placeholder="搜索题目名称"
style={{ width: "calc(100% - 84px)" }}
onChange={(value) => {
console.log(value);
}}
/>
</div>
<div className="search-condition__item">
<span className="search-label">题型:</span>
<Select
value={questionType}
placeholder="请选择题目类型"
style={{ width: "calc(100% - 70px)" }}
showSearch
allowClear
filterOption={(input, option) => option}
onChange={(value) => {
console.log(value);
}}
>
{_.map(questionTypeList, (item, index) => {
return (
<Select.Option value={item.id} key={item.id}>
{item}
</Select.Option>
);
})}
</Select>
</div>
</div>
<div className="reset-fold-area">
<Tooltip title="清空筛选">
<span
className="resetBtn iconfont icon"
onClick={this.handleReset}
>
&#xe61b;{" "}
</span>
</Tooltip>
</div>
</Row>
</div>
);
}
}
export default QuestionManageFilter;
/*
* @Author: yuananting
* @Date: 2021-02-25 11:23:47
* @LastEditors: yuananting
* @LastEditTime: 2021-03-04 16:55:55
* @Description: 助学工具-题库-题目管理主页面列表数据
* @Copyrigh: © 2020 杭州杰竞科技有限公司 版权所有
*/
import React, { Component } from "react";
import { Table, Switch, ConfigProvider, Empty } from "antd";
import { PageControl } from "@/components";
import "./QuestionManageList.less";
class QuestionManageList extends Component {
// 表头设置
parseColumns = () => {
const columns = [
{
title: "题目",
key: "questionName",
dataIndex: "questionName",
width: 300,
render: (val, record) => {
return <div className="record-name">{val}</div>;
},
},
{
title: "题型",
key: "questionType",
dataIndex: "questionType",
},
{
title: "正确率",
key: "accuracy",
dataIndex: "accuracy",
sorter: true,
},
{
title: "更新时间",
key: "updated",
dataIndex: "updated",
sorter: true,
render: (val) => {
return formatDate("YYYY-MM-DD H:i:s", val);
},
},
{
title: "操作",
key: "operate",
dataIndex: "operate",
fixed: "right",
render: (val, record) => {
return (
<div className="record-operate">
<div
className="operate__item"
onClick={() => console.log("预览")}
>
预览
</div>
<span className="operate__item split"> | </span>
<div
className="operate__item"
onClick={() => console.log("编辑")}
>
编辑
</div>
<span className="operate__item split"> | </span>
<div
className="operate__item"
onClick={() => console.log("删除")}
>
删除
</div>
</div>
);
},
},
];
return columns;
};
// 自定义表格空状态
customizeRenderEmpty = () => {
return (
<Empty
image="https://image.xiaomaiketang.com/xm/emptyTable.png"
imageStyle={{
height: 100,
}}
description={
<div>
还没有题目,快去
<span
className="empty-list-tip"
onClick={() => {
window.RCHistory.push({
pathname: "/create-question-bank",
});
}}
>
新建一个
</span>
吧!
</div>
}
></Empty>
);
};
onShowSizeChange = (current, size) => {
if (current == size) {
return;
}
let _query = this.props.query;
_query.size = size;
this.props.onChange(_query);
};
render() {
const { dataSource = [], totalCount, query } = this.props;
const { current, size } = query;
return (
<div className="question-manage-list">
<ConfigProvider renderEmpty={this.customizeRenderEmpty}>
<Table
rowKey={(record) => record.id}
dataSource={dataSource}
columns={this.parseColumns()}
onChange={this.handleChangeTable}
pagination={false}
bordered
/>
</ConfigProvider>
{totalCount > 0 && (
<div className="box-footer">
<PageControl
current={current - 1}
pageSize={size}
total={totalCount}
toPage={(page) => {
const _query = { ...query, current: page + 1 };
this.props.onChange(_query);
}}
onShowSizeChange={this.onShowSizeChange}
/>
</div>
)}
</div>
);
}
}
export default QuestionManageList;
/*
* @Author: yuananting
* @Date: 2021-02-25 11:26:28
* @LastEditors: yuananting
* @LastEditTime: 2021-02-25 11:39:08
* @Description: 助学工具-题库-题目管理主页面列表数据样式
* @Copyrigh: © 2020 杭州杰竞科技有限公司 版权所有
*/
.question-manage-list {
position: relative;
margin-top: 16px;
.empty-list-tip {
color: #ffb714;
cursor: pointer;
}
.record-name {
word-break: break-all;
overflow: hidden;
text-overflow: ellipsis;
display: -webkit-box;
-webkit-line-clamp: 5;
-webkit-box-orient: vertical;
}
.record_operate {
display: flex;
&__item {
color: #5289fa;
cursor: pointer;
&.split {
margin: 0 8px;
color: #bfbfbf;
}
}
}
}
\ No newline at end of file
/*
* @Author: yuananting
* @Date: 2021-02-25 11:01:06
* @LastEditors: yuananting
* @LastEditTime: 2021-03-04 17:31:45
* @Description: 描述一下咯
* @Copyrigh: © 2020 杭州杰竞科技有限公司 版权所有
*/
import React, { Component } from "react";
import { Space, Button } from "antd";
class QuestionManageOpt extends Component {
handleCreateQuestionBank = () => {
window.RCHistory.push({
pathname: "/create-new-question",
});
};
render() {
return (
<Space size="large">
<Button type="primary" onClick={this.handleCreateQuestionBank}>
新建题目
</Button>
<Button
onClick={() => {
console.log("批量导入");
}}
>
批量导入
</Button>
</Space>
);
}
}
export default QuestionManageOpt;
...@@ -226,11 +226,11 @@ const XMAudio = (props) => { ...@@ -226,11 +226,11 @@ const XMAudio = (props) => {
<div className="process-area"> <div className="process-area">
<div <div
className="complete-area" className="complete-area"
style={{ width: `${(playedTime / totalTime) * 180}px ` }} style={{ width: `${(playedTime / totalTime) * 150}px ` }}
/> />
<div <div
className="flag" className="flag"
style={{ left: `${(playedTime / totalTime) * 180}px ` }} style={{ left: `${(playedTime / totalTime) * 150}px ` }}
onMouseDown={(e) => putDownFlag(e)} onMouseDown={(e) => putDownFlag(e)}
onMouseOver={(e)=> mouseOver(e)} onMouseOver={(e)=> mouseOver(e)}
onMouseLeave={(e)=>mouseLeave(e)} onMouseLeave={(e)=>mouseLeave(e)}
......
/* /*
* @Author: chenjianyu * @Author: chenjianyu
* @Date: 2020-09-12 17:00:44 * @Date: 2020-09-12 17:00:44
* @LastEditTime: 2021-03-01 17:25:37 * @LastEditTime: 2021-03-13 11:19:38
* @LastEditors: yuananting * @LastEditors: yuananting
* @Description: 答题模式模板 * @Description: 答题模式模板
* @Copyright © 2020 杭州杰竞科技有限公司 版权所有 * @Copyright © 2020 杭州杰竞科技有限公司 版权所有
...@@ -44,6 +44,46 @@ export function defineQuestionData(questionType) { ...@@ -44,6 +44,46 @@ export function defineQuestionData(questionType) {
} }
} }
export function defineQuestionInfo(questionType) {
return {
questionTypeEnum: questionType, // 题目类型
questionStemList:[
{
contentType: "QUESTION_STEM", // 内容类型(默认题干)
content: "", // 内容
type: "RICH_TEXT", // 内容项形式(0:富文本 1:文字 2:图片 3:语音 4:视频 5文件 6.课件)
}
], // 题干
optionList: [], // 非填空题选项
gapFillingAnswerList: [
{
correctAnswerList: []
}
], //填空题填空项
questionAnswerDescList: [
{
contentType: "QUESTION_ANSWER_DESC", // 内容类型(默认解析)
content: "", // 内容
type: "RICH_TEXT", // 内容项形式(0:富文本 1:文字 2:图片 3:语音 4:视频 5文件 6.课件)
}
], //答案解析
showBox: true, // 显示录音弹窗
}
}
export function defineOptionInfo() {
return {
isCorrectAnswer: false, // 是否为正确答案选项
questionOptionContentList: [ // 选项内容
{
contentType: "QUESTION_OPTION", // 内容类型(默认选项)
content: "", // 内容
type: "RICH_TEXT", // 内容项形式(0:富文本 1:文字 2:图片 3:语音 4:视频 5文件 6.课件)
}
]
}
}
export function defineOptionData(content = '') { export function defineOptionData(content = '') {
return { return {
itemContentVOList: [{ itemContentVOList: [{
......
/*
* @Author: yuananting
* @Date: 2021-02-23 11:43:43
* @LastEditors: yuananting
* @LastEditTime: 2021-02-25 10:32:53
* @Description: 助学工具-题库-题库引用课程分类模态框
* @Copyrigh: © 2020 杭州杰竞科技有限公司 版权所有
*/
import React, { Component } from "react";
import { Modal, Tree, Card } from "antd";
import { PageControl } from "@/components";
import "./ImportCourseCategory.less";
class ImportCourseCategory extends Component {
constructor(props) {
super(props);
this.state = {
query: {
current: 1,
size: 1,
},
totalCount: 0,
};
}
onSelect = (selectedKeys, info) => {
console.log("selected", selectedKeys, info);
};
onCheck = (checkedKeys, info) => {
console.log("onCheck", checkedKeys, info);
};
onShowSizeChange = (current, size) => {
if (current == size) {
return;
}
const _query = { ...this.props.query };
_query.size = size;
// 更新请求参数
this.setState({ _query });
// TODO请求
};
confirmImport = () => {
// 判断是否已经选择
// TODO save
this.props.close();
};
render() {
const treeData = [
{
title: "parent 1",
key: "0-0",
children: [
{
title: "parent 1-0",
key: "0-0-0",
disabled: true,
children: [
{
title: "leaf",
key: "0-0-0-0",
disableCheckbox: true,
},
{
title: "leaf",
key: "0-0-0-1",
},
],
},
{
title: "parent 1-1",
key: "0-0-1",
children: [
{
title: <span style={{ color: "#1890ff" }}>sss</span>,
key: "0-0-1-0",
},
],
},
],
},
];
const { query, totalCount } = this.state;
const { current, size } = query;
return (
<Modal
title="引用课程分类"
visible={true}
onOk={this.confirmImport}
onCancel={() => this.props.close()}
>
<div className="import-course-title">请选择需要的分类</div>
<Card size="small" title="分类名称">
<Tree
checkable
blockNode
height={200}
defaultExpandedKeys={["0-0-0", "0-0-1"]}
defaultSelectedKeys={["0-0-0", "0-0-1"]}
defaultCheckedKeys={["0-0-0", "0-0-1"]}
onSelect={this.onSelect}
onCheck={this.onCheck}
treeData={treeData}
/>
</Card>
<div className="box-footer">
<PageControl
current={current - 1}
pageSize={size}
total={totalCount}
toPage={(page) => {
const _query = { ...query, current: page + 1 };
this.props.onChange(_query);
}}
onShowSizeChange={this.onShowSizeChange}
/>
</div>
</Modal>
);
}
}
export default ImportCourseCategory;
/*
* @Author: yuananting
* @Date: 2021-02-23 14:15:07
* @LastEditors: yuananting
* @LastEditTime: 2021-02-23 14:23:19
* @Description: 助学工具-题库-题库引用课程分类模态框样式
* @Copyrigh: © 2020 杭州杰竞科技有限公司 版权所有
*/
.ant-modal .ant-modal-content .ant-modal-body {
padding-top: 16px !important;
}
.import-course-title {
margin-bottom: 16px;
}
...@@ -2,35 +2,90 @@ ...@@ -2,35 +2,90 @@
* @Author: yuananting * @Author: yuananting
* @Date: 2021-02-22 17:51:28 * @Date: 2021-02-22 17:51:28
* @LastEditors: yuananting * @LastEditors: yuananting
* @LastEditTime: 2021-03-04 11:47:20 * @LastEditTime: 2021-03-13 14:26:31
* @Description: 助学工具-题库-题库新建或编辑题库分类模态框 * @Description: 助学工具-题库-题库新建或编辑题库分类模态框
* @Copyrigh: © 2020 杭州杰竞科技有限公司 版权所有 * @Copyrigh: © 2020 杭州杰竞科技有限公司 版权所有
*/ */
import React, { Component } from "react"; import React, { Component } from "react";
import { Modal, Form, Input, message } from "antd"; import { Modal, Form, Input, message } from "antd";
import User from "@/common/js/user";
import QuestionBankService from "@/domains/question-bank-domain/QuestionBankService";
import { node } from "prop-types";
class NewEditQuestionBankCategory extends Component { class NewEditQuestionBankCategory extends Component {
formRef = React.createRef(); formRef = React.createRef();
constructor(props) { constructor(props) {
super(props); super(props);
this.state = { this.state = {
categoryName: null, // 分类名称 treeData: [],
categoryName:
this.props.type === "edit" ? this.props.node.categoryName : null,
}; };
} }
componentDidMount() { componentDidMount() {
this.queryCategoryTree();
// this.getSameLevelNodes(this.props.treeData); // this.getSameLevelNodes(this.props.treeData);
} }
// 查询分类树
queryCategoryTree = () => {
let query = {
source: 0,
userId: User.getUserId(),
tenantId: User.getStoreId(),
};
QuestionBankService.queryCategoryTree(query).then((res) => {
const { result = [] } = res;
this.setState({ treeData: result });
});
};
// 确定新增或编辑 // 确定新增或编辑
confirmOperate = async () => { confirmOperate = async () => {
const { categoryName } = this.state;
const { node, addLevelType, type } = this.props;
let params = {
source: 0,
tenantId: User.getStoreId(),
userId: User.getUserId(),
};
if (type === "new") {
//新增
params.categoryName = categoryName;
if (addLevelType === "equal") {
params.parentId = node ? node.parentId : 0
params.categoryLevel = node ? node.categoryLevel : 0;
} else {
params.parentId = node.id;
params.categoryLevel = node.categoryLevel + 1;
}
try {
await this.formRef.current.validateFields();
QuestionBankService.addCategory(params).then((res) => {
if (res.success) {
this.props.close();
}
});
} catch (e) {
console.log(e);
}
} else {
// 编辑
params.categoryId = node.id;
params.parentId = node.parentId;
params.categoryLevel = node.categoryLevel;
params.categoryName = categoryName;
try { try {
await this.formRef.current.validateFields(); await this.formRef.current.validateFields();
// TODO save QuestionBankService.editCategory(params).then((res) => {
if (res.success) {
this.props.close(); this.props.close();
}
});
} catch (e) { } catch (e) {
console.log(e); console.log(e);
} }
}
}; };
getEqualLevelNodes = (data, parentId) => { getEqualLevelNodes = (data, parentId) => {
...@@ -40,32 +95,32 @@ class NewEditQuestionBankCategory extends Component { ...@@ -40,32 +95,32 @@ class NewEditQuestionBankCategory extends Component {
nodes.push(item); nodes.push(item);
} }
if (item.children) { if (item.children) {
nodes.push(...this.getEqualLevelNodes(item.children, parentId)) nodes.push(...this.getEqualLevelNodes(item.children, parentId));
} }
}) });
return nodes; return nodes;
} };
getChildLevelNodes = (data, id) => { getChildLevelNodes = (data, id) => {
let nodes = []; let nodes = [];
data.forEach((item) => { data.forEach((item) => {
if(item.id === id && item.children) { if (item.id === id && item.children) {
nodes.push(...item.children); nodes.push(...item.children);
} }
if (item.children) { if (item.children) {
nodes.push(...this.getChildLevelNodes(item.children, id)) nodes.push(...this.getChildLevelNodes(item.children, id));
} }
}) });
return nodes; return nodes;
} };
getSameLevelNodes = (data, type) => { getSameLevelNodes = (data, type) => {
let sameLevelNodes = []; let sameLevelNodes = [];
const { id, parentId } = this.props;
if (type === "equal") { if (type === "equal") {
let parentId = this.props.node ? this.props.node.parentId : "0";
sameLevelNodes = this.getEqualLevelNodes(data, parentId); sameLevelNodes = this.getEqualLevelNodes(data, parentId);
} else { } else {
sameLevelNodes = this.getChildLevelNodes(data, id); sameLevelNodes = this.getChildLevelNodes(data, this.props.node.id);
} }
return sameLevelNodes; return sameLevelNodes;
}; };
...@@ -107,7 +162,10 @@ class NewEditQuestionBankCategory extends Component { ...@@ -107,7 +162,10 @@ class NewEditQuestionBankCategory extends Component {
}, },
({ getFieldValue }) => ({ ({ getFieldValue }) => ({
validator(_, value) { validator(_, value) {
let sameLevelNodes = _that.getSameLevelNodes(treeData, addLevelType); let sameLevelNodes = _that.getSameLevelNodes(
treeData,
addLevelType
);
if (_that.checkExist(sameLevelNodes, value)) { if (_that.checkExist(sameLevelNodes, value)) {
return Promise.reject("此分类名称已存在"); return Promise.reject("此分类名称已存在");
} else { } else {
...@@ -118,7 +176,7 @@ class NewEditQuestionBankCategory extends Component { ...@@ -118,7 +176,7 @@ class NewEditQuestionBankCategory extends Component {
]} ]}
> >
<Input <Input
value={categoryName} defaultValue={categoryName}
placeholder={`请输入${title},最多10个字`} placeholder={`请输入${title},最多10个字`}
maxLength={10} maxLength={10}
onChange={(e) => { onChange={(e) => {
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment