feat: 完善首页交互,完善上传页面分类及标签

This commit is contained in:
秋水浮尘
2023-10-19 00:56:23 +08:00
parent 9322d1b71b
commit 668d1e0a52
8 changed files with 119 additions and 393 deletions

View File

@@ -128,6 +128,8 @@ const CategoryList = ({ primaryCategoryId, categoryList, ...props }) => {
); );
}; };
const [currentLabelIndex, setCurrentLabelIndex] = useState([])
/** /**
* 选择标签-支持单选(多选) * 选择标签-支持单选(多选)
* @param {*} categoryId 一级分类id * @param {*} categoryId 一级分类id
@@ -145,20 +147,13 @@ const CategoryList = ({ primaryCategoryId, categoryList, ...props }) => {
setSecondCategoryList(list) setSecondCategoryList(list)
} else { } else {
// 三级标签支持单选 // 三级标签支持单选
let formatLabelList = list[secondCategoryIndex].children.map((item, index) => { if (currentLabelIndex.length) {
let flag = false; _.set(list, [currentLabelIndex[0], 'children', currentLabelIndex[1], 'active'], false)
if (index === thirdCategoryIndex) { }
flag = !active; // 将三级标签设置选中/未选中 _.set(list, [secondCategoryIndex, 'children', thirdCategoryIndex, 'active'], !active)
} setCurrentLabelIndex([secondCategoryIndex, thirdCategoryIndex])
return {
...item,
active: flag,
};
});
_.set(list, [secondCategoryIndex, 'children'], formatLabelList);
setSecondCategoryList(list) setSecondCategoryList(list)
} }
// console.log(currentActive, _.get(list, [secondCategoryIndex, 'children', thirdCategoryIndex, 'id']))
props.onChangeLabel(_.get(list, [secondCategoryIndex, 'id']), _.get(list, [secondCategoryIndex, 'children', thirdCategoryIndex, 'id'])) props.onChangeLabel(_.get(list, [secondCategoryIndex, 'id']), _.get(list, [secondCategoryIndex, 'children', thirdCategoryIndex, 'id']))
}; };
@@ -168,8 +163,9 @@ const CategoryList = ({ primaryCategoryId, categoryList, ...props }) => {
* @returns * @returns
*/ */
const onChangeOpenStatus = (secondCategoryIndex, isOpen) => () => { const onChangeOpenStatus = (secondCategoryIndex, isOpen) => () => {
_.set(secondCategoryList, [secondCategoryIndex, 'isOpen'], !isOpen); const _list = _.cloneDeep(secondCategoryList)
setSecondCategoryList(secondCategoryList) _.set(_list, [secondCategoryIndex, 'isOpen'], !isOpen);
setSecondCategoryList(_list)
}; };
/** /**
@@ -235,7 +231,7 @@ const CategoryList = ({ primaryCategoryId, categoryList, ...props }) => {
className="second-category-item-status" className="second-category-item-status"
onClick={onChangeOpenStatus( onClick={onChangeOpenStatus(
secondCategoryIndex, secondCategoryIndex,
secondCategoryItem.isOpen (secondCategoryItem.isOpen || false)
)}> )}>
<div className="second-category-item-type" style={{ fontSize: 12 }}> <div className="second-category-item-type" style={{ fontSize: 12 }}>
{secondCategoryItem.isOpen ? '收起' : '展开'} {secondCategoryItem.isOpen ? '收起' : '展开'}
@@ -296,331 +292,3 @@ const CategoryList = ({ primaryCategoryId, categoryList, ...props }) => {
export default CategoryList export default CategoryList
class CategoryList1 extends Component {
constructor(props) {
super(props);
this.state = {
secondCategoryList: [],
currentActive: null,
isPutAway: true, // 是否收起 默认收起状态
};
}
componentDidMount() {
// this.initCategoryList();
}
/**
* 初始化数据,默认选择第一个
*/
initCategoryList() {
const { categoryList, primaryCategoryId } = this.props;
let currentActive = primaryCategoryId ?? categoryList[0];
this.props.onChangeCategory(currentActive);
this.getSecondCategoryList(currentActive);
}
/**
* 获得二级三级分类数据
*/
getSecondCategoryList(currentActive) {
const { categoryListMap } = this.props;
// 调用接口返回二级三级数据
let params = {
parentId: currentActive.id,
categoryType: 2,
};
req({
method: 'post',
data: params,
url: apiName.getCategoryLabelInfo,
})
.then((res) => {
if (res.data && res.data.length > 0) {
let secondCategoryList = res.data;
let listLen =
categoryListMap &&
categoryListMap[currentActive] &&
categoryListMap[currentActive].length;
let objActive = {};
listLen > 0 &&
categoryListMap &&
categoryListMap[currentActive] &&
categoryListMap[currentActive].forEach((item) => {
objActive[item] = item;
});
secondCategoryList.forEach((categoryItem) => {
categoryItem.labelInfoList.forEach((item) => {
if (listLen > 0 && objActive[item.assembleId]) {
item.active = true;
} else {
item.active = false;
}
});
categoryItem.isOpen = false;
});
this.setState(
{
secondCategoryList,
currentActive,
},
() => {
let activeList = [];
secondCategoryList.forEach((categoryItem) => {
categoryItem.labelInfoList.forEach((item) => {
if (item.active) {
activeList.push(item.assembleId);
}
});
});
secondCategoryList.forEach((item, index) => {
let height = document.getElementById('id_' + index)?.scrollHeight;
let displayHeight = height > 43 ? 'flex' : 'none';
!this.props.isHideSec &&
(document.getElementById('second_id_' + index).style.display =
displayHeight);
});
}
);
}
})
.catch((err) => console.log(err));
}
/**
* 切换一级分类
* @param {*} item
* @returns
*/
onChangeCategory = (primaryCategoryId) => () => {
let { currentActive } = this.state;
if (currentActive === primaryCategoryId) {
return;
}
this.props.isHideSec &&
this.setState({
currentActive: primaryCategoryId,
});
this.props.onChangeCategory(primaryCategoryId);
!this.props.isHideSec && this.getSecondCategoryList(primaryCategoryId);
};
/**
* 选择标签-支持单选(多选)
* @param {*} categoryId 一级分类id
* @param {*} childrenLevelList 二级分类对象的标签列表
* @param {*} secondCategoryIndex 二级分类对象index
* @param {*} thirdCategoryIndex 三级标签index
* @param {*} active 三级标签当前的选中状态
* @returns
*/
onChangeLabel = (childrenLevelList, secondCategoryIndex, thirdCategoryIndex, active) => () => {
let { secondCategoryList, currentActive } = this.state;
const { isMultipleChoice } = this.props;
if (isMultipleChoice) {
// 三级标签支持多选
_.set(childrenLevelList, [thirdCategoryIndex, 'active'], !active);
_.set(secondCategoryList, [secondCategoryIndex, 'children'], childrenLevelList);
} else {
// 三级标签支持单选
let formatLabelList = childrenLevelList.map((item, index) => {
let flag = false;
if (index === thirdCategoryIndex) {
flag = !active; // 将三级标签设置选中/未选中
}
return {
...item,
active: flag,
};
});
_.set(secondCategoryList, [secondCategoryIndex, 'children'], formatLabelList);
}
this.setState(
{
secondCategoryList,
},
() => {
let activeList = [];
secondCategoryList.forEach((categoryItem) => {
categoryItem.children.forEach((item) => {
if (item.active) {
activeList.push(item.assembleId);
}
});
});
this.props.onChangeLabel(currentActive, activeList);
}
);
};
/**
* 展开/收起
* @param {*} secondCategoryIndex
* @returns
*/
onChangeOpenStatus = (secondCategoryIndex, isOpen) => () => {
let { secondCategoryList } = this.state;
_.set(secondCategoryList, [secondCategoryIndex, 'isOpen'], !isOpen);
this.setState({
secondCategoryList,
});
};
/**
* 展开/收起
*/
onChangePutAway = () => {
let { isPutAway } = this.state;
this.setState({
isPutAway: !isPutAway,
});
};
/**
* 一级分类模块
* @returns
*/
renderFirstContainer = () => {
return (
<div className="first-category-list">
{categoryList.slice(0, 7).map((categoryModuleItem, categoryModuleIndex) => {
return (
<div
className={`first-category-item ${categoryModuleItem.primaryCategoryId === currentActive &&
'first-category-item-active'
}`}
key={`first_category_${categoryModuleItem.id}`}
style={{
backgroundImage: `url(${categoryBackImg[categoryModuleIndex]})`,
}}
onClick={this.onChangeCategory(categoryModuleItem.primaryCategoryId)}>
<div className="first-category-item-title">
{categoryModuleItem.categoryName}
</div>
<div className="first-category-item-count">
{categoryModuleItem.count || 50}道题
</div>
</div>
);
})}
{categoryList.length > 7 && (
<div className="first-category-more">
更多
<RightOutlined />
</div>
)}
</div>
);
};
/**
* 二级分类模块
* @returns
*/
renderSecondContainer = () => {
const { secondCategoryList, isPutAway } = this.state;
return (
<div className="second-category-list">
{secondCategoryList.map((secondCategoryItem, secondCategoryIndex) => {
return (
<div
style={{
display:
secondCategoryIndex >= categoryShowCount && isPutAway
? 'none'
: 'flex',
}}
className="second-category-item"
key={`second_category_${secondCategoryItem.categoryId}`}>
<div className="second-category-item-title">
{secondCategoryItem.categoryName}
</div>
{secondCategoryItem?.labelInfoList?.length > 0 && (
<div className="second-category-item-box">
<div
style={{
height: secondCategoryItem.isOpen ? 'auto' : 43,
}}
className="second-category-item-list"
id={`id_${secondCategoryIndex}`}>
{secondCategoryItem.labelInfoList.map(
(thirdCategoryItem, thirdCategoryIndex) => {
return (
<div
className={`third-category-item ${thirdCategoryItem.active
? 'third-category-item-active'
: ''
}`}
key={`third_category_${thirdCategoryItem.id}`}
onClick={this.onChangeLabel(
secondCategoryItem.labelInfoList,
secondCategoryIndex,
thirdCategoryIndex,
thirdCategoryItem.active
)}>
{thirdCategoryItem.labelName}
</div>
);
}
)}
</div>
<div
id={`second_id_${secondCategoryIndex}`}
className="second-category-item-status"
onClick={this.onChangeOpenStatus(
secondCategoryIndex,
secondCategoryItem.isOpen
)}>
<div className="second-category-item-type" style={{ fontSize: 12 }}>
{secondCategoryItem.isOpen ? '收起' : '展开'}
</div>
<div className="second-category-item-icon" style={{ fontSize: 12 }}>
{secondCategoryItem.isOpen ? (
<UpOutlined />
) : (
<DownOutlined />
)}
</div>
</div>
</div>
)}
</div>
);
})}
{secondCategoryList?.length >= categoryShowCount && (
<Divider
onClick={this.onChangePutAway}
dashed
style={{
marginTop: 10,
fontSize: 13,
}}>
{isPutAway ? '展开' : '收起'}
{isPutAway ? (
<CaretDownOutlined style={{ marginLeft: 4 }} />
) : (
<CaretUpOutlined style={{ marginLeft: 4 }} />
)}
</Divider>
)}
</div>
);
};
render() {
const { categoryList } = this.props;
const { secondCategoryList } = this.state;
return (
<div className="category-box">
<Fragment>{categoryList?.length > 0 && this.renderFirstContainer()}</Fragment>
{!this.props.isHideSec && (
<Fragment>
{secondCategoryList?.length > 0 && this.renderSecondContainer()}
</Fragment>
)}
</div>
);
}
}

View File

@@ -192,11 +192,10 @@ const QuestionList = (props) => {
columns={questionColumns} columns={questionColumns}
dataSource={questionList} dataSource={questionList}
rowKey={(record) => record.id} rowKey={(record) => record.id}
// bordered={false}
pagination={false} pagination={false}
rowClassName="question-table-row" rowClassName="question-table-row"
/> />
{total > 10 && ( {/* {total > 10 && (
<Pagination <Pagination
style={{ style={{
padding: "24px 0", padding: "24px 0",
@@ -207,7 +206,7 @@ const QuestionList = (props) => {
total={total} total={total}
onChange={onChangePagination} onChange={onChangePagination}
/> />
)} )} */}
</div> </div>
</div> </div>
</Fragment> </Fragment>

View File

@@ -41,7 +41,7 @@ export default class TagsEditor extends Component {
.then((res) => { .then((res) => {
if (res.data) { if (res.data) {
let list = categoryList.filter((item) => { let list = categoryList.filter((item) => {
return item.categoryId !== categoryId; return item.id !== categoryId;
}); });
this.props.onChangeLabel(list, this.formatList(list)); this.props.onChangeLabel(list, this.formatList(list));
} }
@@ -220,7 +220,7 @@ export default class TagsEditor extends Component {
// 数组中存在 -9999 表示暂无数据,需要支持新增 // 数组中存在 -9999 表示暂无数据,需要支持新增
if ( if (
categoryList.filter((item) => { categoryList.filter((item) => {
return item.categoryId === -9999; return item.id === -9999;
}).length > 0 }).length > 0
) { ) {
labelList = categoryList.slice(1, categoryList.length); labelList = categoryList.slice(1, categoryList.length);
@@ -229,7 +229,7 @@ export default class TagsEditor extends Component {
<div className="tags-editor-box"> <div className="tags-editor-box">
{labelList?.length > 0 && {labelList?.length > 0 &&
labelList.map((item, index) => { labelList.map((item, index) => {
const isLongTag = item.categoryName.length > 20; const isLongTag = item.categoryName?.length > 20;
const tagElem = ( const tagElem = (
<Tag <Tag
style={{ style={{
@@ -247,7 +247,7 @@ export default class TagsEditor extends Component {
closable={item.isShowClose && isDeleteTag} closable={item.isShowClose && isDeleteTag}
className={`tags-editor-item ${item.active ? 'tag-active' : ''}`} className={`tags-editor-item ${item.active ? 'tag-active' : ''}`}
onClick={this.onChangeLabel(index, item.active)} onClick={this.onChangeLabel(index, item.active)}
onClose={() => this.handleClose(index, item.categoryId)}> onClose={() => this.handleClose(index, item.id)}>
{isLongTag {isLongTag
? `${item.categoryName.slice(0, 20)}...` ? `${item.categoryName.slice(0, 20)}...`
: item.categoryName} : item.categoryName}

View File

@@ -3,9 +3,6 @@
display: flex; display: flex;
flex-wrap: wrap; flex-wrap: wrap;
.tag-active { .tag-active {
// @include box-backgroundColor(0.1);
// @include box-border();
// @include font-color();
background-color: rgba(60, 110, 238, 0.1); background-color: rgba(60, 110, 238, 0.1);
color: rgba(60, 110, 238, 1); color: rgba(60, 110, 238, 1);
border: 1px solid rgba(60, 110, 238, 1) border: 1px solid rgba(60, 110, 238, 1)

View File

@@ -52,16 +52,21 @@ const QuestionBank = () => {
const onChangeCategory = (item: Record<string, any>) => { const onChangeCategory = (item: Record<string, any>) => {
setLabelList('') setLabelList('')
setPromaryCategoryId(item.id) setPromaryCategoryId(item.id)
setQuestionList([])
setPageIndex(1) setPageIndex(1)
setTotal(0)
}; };
const [secondCategoryId, setSecondCategoryId] = useState('')
/** /**
* 选择标签时,请求列表数据 * 选择标签时,请求列表数据
* @param {*} primaryCategoryId 一级分类id * @param {*} primaryCategoryId 一级分类id
* @param {*} assembleIds 三级标签 assembleIds * @param {*} assembleIds 三级标签 assembleIds
*/ */
const onChangeLabel = (primaryCategory: any, assembleIds: string) => { const onChangeLabel = (secondCategoryId: any, assembleIds: string) => {
setPromaryCategoryId(primaryCategory) // setPromaryCategoryId(primaryCategory)
setSecondCategoryId(secondCategoryId)
setLabelList(assembleIds) setLabelList(assembleIds)
setPageIndex(1) setPageIndex(1)
}; };
@@ -71,7 +76,7 @@ const QuestionBank = () => {
pageNo: pageIndex, pageNo: pageIndex,
pageSize: 10, pageSize: 10,
labelId: labelList, labelId: labelList,
categoryId: primaryCategoryId, categoryId: secondCategoryId,
subjectDifficult: 1 subjectDifficult: 1
} }
req({ req({

View File

@@ -39,7 +39,7 @@ export default class BriefQuestions extends Component {
subjectName: str, subjectName: str,
}, },
() => { () => {
this.rankLabelBox.getThirdCategoryList(); // this.rankLabelBox.getThirdCategoryList();
let isDisabledSubmit = this.checkData(); let isDisabledSubmit = this.checkData();
this.setState({ this.setState({
isDisabledSubmit, isDisabledSubmit,

View File

@@ -11,6 +11,7 @@ const RankLabelBox = (props) => {
const [firstCategoryList, setFirstCategoryList] = useState([]) const [firstCategoryList, setFirstCategoryList] = useState([])
const [firstSelected, setFirstSelected] = useState(null) const [firstSelected, setFirstSelected] = useState(null)
const [secondCategoryList, setSecondCategoryList] = useState([]) const [secondCategoryList, setSecondCategoryList] = useState([])
const [thirdCategoryList, setThirdCategoryList] = useState([])
/** /**
* 获得一级分类数据 * 获得一级分类数据
@@ -23,11 +24,10 @@ const RankLabelBox = (props) => {
url: apiName.queryPrimaryCategory, url: apiName.queryPrimaryCategory,
}) })
.then((res) => { .then((res) => {
console.log(res)
const list = res.data.map((item, index) => { const list = res.data.map((item, index) => {
return { return {
...item, ...item,
active: index == 0 ? true : false, active: index == 0,
}; };
}); });
setFirstCategoryList(list) setFirstCategoryList(list)
@@ -46,9 +46,8 @@ const RankLabelBox = (props) => {
* @param {*} selectList * @param {*} selectList
*/ */
const onHandleChangeRank = (handleStatusList, selectList) => { const onHandleChangeRank = (handleStatusList, selectList) => {
// console.log(handleStatusList, selectList)
setRankList(handleStatusList) setRankList(handleStatusList)
// this.props.handleChangeRank(selectList); props.handleChangeRank(selectList);
}; };
/** /**
@@ -75,14 +74,22 @@ const RankLabelBox = (props) => {
); );
}; };
const listType = {
1: setFirstCategoryList,
2: setSecondCategoryList,
3: setThirdCategoryList
}
/** /**
* 选择一级分类-单选 * 选择一级分类-单选
* @param {*} handleStatusList 带有是否选中状态的原数组 * @param {*} handleStatusList 带有是否选中状态的原数组
* @param {*} selectList 选中id的数组 * @param {*} selectList 选中id的数组
*/ */
const onChangeFirst = (handleStatusList, selectList) => { const onChangeTags = (handleStatusList, selectList, type) => {
setFirstCategoryList(handleStatusList) listType[type](handleStatusList)
setFirstSelected(selectList[0]) if (type == 1) {
setFirstSelected(selectList[0])
}
}; };
/** /**
@@ -90,36 +97,43 @@ const RankLabelBox = (props) => {
* @param {*} id 一级分类id * @param {*} id 一级分类id
*/ */
const getSecondCategoryList = (id) => { const getSecondCategoryList = (id) => {
const params = { categoryType: 2, parentId: id };
req({
method: 'post',
data: params,
url: apiName.queryCategoryByPrimary,
}).then((res) => {
setSecondCategoryList(res.data)
}).catch((err) => console.log(err));
}
/**
* 获得标签数据
* @param {*} id 一级分类id
*/
const getLabelList = (id) => {
const params = { categoryId: id }; const params = { categoryId: id };
req({ req({
method: 'post', method: 'post',
data: params, data: params,
url: apiName.queryLabelByCategoryId, url: apiName.queryLabelByCategoryId,
}) }).then((res) => {
.then((res) => { setThirdCategoryList(res.data.map(item => {
setSecondCategoryList(res.data) return {
// this.firstCategoryValue = id; ...item,
// this.secondCategoryValue = []; categoryName: item.labelName
// this.thirdCategoryValue = []; }
// if (res.data && res.data.length > 0) { }))
// this.setState({ }).catch((err) => console.log(err));
// secondCategoryList: res.data,
// });
// } else {
// // 若需要新增时则需要将数组第一个item重置如下
// this.setState({
// secondCategoryList: [{ categoryName: '空', categoryId: -9999 }],
// });
// }
})
.catch((err) => console.log(err));
} }
useEffect(() => { useEffect(() => {
if (firstSelected) { if (firstSelected) {
getSecondCategoryList(firstSelected); getSecondCategoryList(firstSelected);
getLabelList(firstSelected)
} }
}, [firstSelected]) }, [firstSelected])
/** /**
@@ -137,7 +151,7 @@ const RankLabelBox = (props) => {
<TagsEditor <TagsEditor
categoryList={firstCategoryList} categoryList={firstCategoryList}
isSingleChoice={true} isSingleChoice={true}
onChangeLabel={onChangeFirst} onChangeLabel={(list, id) => onChangeTags(list, id, 1)}
isDisabledReverseSelection={true} isDisabledReverseSelection={true}
/> />
</div> </div>
@@ -147,16 +161,59 @@ const RankLabelBox = (props) => {
); );
}; };
/**
* 二级分类选择
* @param {*} secondCategoryList
* @returns
*/
const renderSecondModule = () => {
return (
<div className="upload-single-container">
<div className="upload-single-title">二级分类</div>
<div className="upload-single-main">
<TagsEditor
moduleType={ModuleType.second}
categoryList={secondCategoryList}
isSingleChoice={false}
onChangeLabel={(list, id) => onChangeTags(list, id, 2)}
/>
</div>
</div>
);
};
/**
* 三级标签选择
* @param {*} thirdCategoryList
* @returns
*/
const renderThirdModule = () => {
return (
<div className="upload-single-container">
<div className="upload-single-title">三级标签</div>
<div className="upload-single-main">
<TagsEditor
moduleType={ModuleType.third}
categoryList={thirdCategoryList}
isSingleChoice={false}
onChangeLabel={(list, id) => onChangeTags(list, id, 3)}
/>
</div>
</div>
);
};
return ( return (
<Fragment> <Fragment>
{rendeRrankModule()} {rendeRrankModule()}
{renderFirstModule(firstCategoryList)} {renderFirstModule(firstCategoryList)}
{/* {secondCategoryList?.length > 0 && ( {secondCategoryList?.length > 0 ? (
<Fragment> <Fragment>
{this.renderSecondModule(secondCategoryList)} {renderSecondModule()}
{thirdCategoryList?.length > 0 && this.renderThirdModule(thirdCategoryList)} {thirdCategoryList?.length > 0 && renderThirdModule()}
</Fragment> </Fragment>
)} */} ) : null}
</Fragment> </Fragment>
) )
} }

View File

@@ -7,13 +7,13 @@ export const apiName = {
*/ */
queryPrimaryCategory: '/category/queryPrimaryCategory', queryPrimaryCategory: '/category/queryPrimaryCategory',
// 根据一级分类查询二级及标签
// 查询二级分类
queryCategoryByPrimary: 'category/queryCategoryByPrimary',
// 根据一级分类查询标签
queryLabelByCategoryId: '/label/queryLabelByCategoryId', queryLabelByCategoryId: '/label/queryLabelByCategoryId',
/**
* 获取三级分类标签
*/
getRecommendLabel: '/admin/question/label/getRecommendLabel',
/** /**
* 新增题目 * 新增题目
*/ */