Browse Source

(*)培训资料库:左侧数据联动右侧

master
周沫沫历险记 2 years ago
parent
commit
9f5835230e
  1. 51
      api/app/lib/controllers/resourceRepository/index.js
  2. 0
      api/app/lib/models/training_information.js
  3. 3
      api/app/lib/routes/resourceRepository/index.js
  4. 14
      web/client/src/sections/humanAffairs/actions/resourceRepository.js
  5. 220
      web/client/src/sections/humanAffairs/containers/resourceRepository.jsx
  6. 1
      web/client/src/utils/webapi.js

51
api/app/lib/controllers/resourceRepository/index.js

@ -4,13 +4,7 @@ const moment = require('moment')
async function getResourceClassify(ctx) { async function getResourceClassify(ctx) {
try { try {
const { models } = ctx.fs.dc; const { models } = ctx.fs.dc;
// const { limit, offset } = ctx.query;
let rlst = []; let rlst = [];
// const findObj = {}
// if (Number(limit) > 0 && Number(offset) >= 0) {
// findObj.limit = Number(limit);
// findObj.offset = Number(offset);
// }
rlst = [{ rlst = [{
label: "公司培训资料", value: "company", key: "公司培训资料", operation: true, children: [] label: "公司培训资料", value: "company", key: "公司培训资料", operation: true, children: []
}, { label: "部门培训资料", value: 'dept', key: '部门培训资料', operation: false, children: [] }]; }, { label: "部门培训资料", value: 'dept', key: '部门培训资料', operation: false, children: [] }];
@ -99,17 +93,16 @@ async function getResourceClassify(ctx) {
} }
} }
} }
const deptTraining = await models.DeptTraining.findAll({}); const deptTraining = await models.DeptTraining.findAll({});
if (deptTraining.length) { if (deptTraining.length) {
filterData(deptTraining, 1, false); filterData(deptTraining, 1, false);
} }
const trainingInformation = await models.TrainingInformation.findAll({}); const trainingInformation = await models.TrainingInformation.findAll({});
if (trainingInformation.length) { if (trainingInformation.length) {
filterData(trainingInformation, 0, true); filterData(trainingInformation, 0, true);
} }
ctx.status = 200; ctx.status = 200;
ctx.body = rlst; ctx.body = rlst;
} catch (error) { } catch (error) {
@ -119,9 +112,49 @@ async function getResourceClassify(ctx) {
message: '查询培训资源储备库分类目录失败' message: '查询培训资源储备库分类目录失败'
} }
} }
}
async function getResourceFileList(ctx, next) {
try {
const { models } = ctx.fs.dc;
const { limit, offset, type, departmentName, trainDate } = ctx.query;
let rlst = [];
if (["公司培训资料", "部门培训资料"].includes(type)) {
const findObj = {
attributes: ["id", "fileType", "fileName", "fileSize", "updateDate", "attachPath"],
};
if (Number(limit) > 0 && Number(offset) >= 0) {
findObj.limit = Number(limit);
findObj.offset = Number(offset);
}
if (departmentName) {
const where = {
departmentName: departmentName
}
if (trainDate) {
//todo
// where.trainDate = trainDate
}
findObj.where = where;
}
if ("公司培训资料" == type) {
rlst = await models.TrainingInformation.findAndCountAll(findObj);
} else {
rlst = await models.DeptTraining.findAndCountAll(findObj);
}
} else {
ctx.throw("培训资料范围为公司或部门");
}
ctx.status = 200;
ctx.body = rlst;
} catch (err) {
ctx.fs.logger.error(`path: ${ctx.path}, error: ${error}`);
ctx.status = 400;
ctx.body = { message: err.message || '查询培训资源储备库文件列表失败' }
}
} }
module.exports = { module.exports = {
getResourceClassify getResourceClassify,
getResourceFileList
} }

0
api/app/lib/models/training_information_record.js → api/app/lib/models/training_information.js

3
api/app/lib/routes/resourceRepository/index.js

@ -6,4 +6,7 @@ module.exports = function (app, router, opts) {
app.fs.api.logAttr['GET/train/trainFiles/resourceRepository/classify'] = { content: '查询培训资源储备库分类目录', visible: false }; app.fs.api.logAttr['GET/train/trainFiles/resourceRepository/classify'] = { content: '查询培训资源储备库分类目录', visible: false };
router.get('/train/trainFiles/resourceRepository/classify', resourceRepository.getResourceClassify); router.get('/train/trainFiles/resourceRepository/classify', resourceRepository.getResourceClassify);
app.fs.api.logAttr['GET/train/trainFiles/resourceRepository/fileList'] = { content: '查询培训资源储备库文件列表', visible: false };
router.get('/train/trainFiles/resourceRepository/fileList', resourceRepository.getResourceFileList);
}; };

14
web/client/src/sections/humanAffairs/actions/resourceRepository.js

@ -1,8 +1,7 @@
'use strict'; 'use strict';
import { ApiTable, basicAction } from '$utils' import { ApiTable, basicAction } from '$utils'
export function getResourceClassify() {//查询籍贯列表 export function getResourceClassify() {
return (dispatch) => basicAction({ return (dispatch) => basicAction({
type: "get", type: "get",
dispatch: dispatch, dispatch: dispatch,
@ -13,6 +12,17 @@ export function getResourceClassify() {//查询籍贯列表
reducer: { name: "resourceClassify" }, reducer: { name: "resourceClassify" },
}); });
} }
export function getResourceFileList(query) {
return (dispatch) => basicAction({
type: "get",
dispatch: dispatch,
actionType: "GET_RESOURCE_FILELIST",
query: query,
url: `${ApiTable.getResourceFileList}`,
msg: { option: "查询培训资源储备库文件列表" },
reducer: { name: "resourceFilelist" },
});
}
export function postResourceClassify(data) { export function postResourceClassify(data) {
return (dispatch) => return (dispatch) =>

220
web/client/src/sections/humanAffairs/containers/resourceRepository.jsx

@ -1,21 +1,35 @@
import React, { useEffect, useState, useRef } from 'react'; import React, { useEffect, useState, useRef } from 'react';
import { connect } from 'react-redux'; import { connect } from 'react-redux';
import { Button, Col, Row, Input, Tree, Table, Space, Tooltip } from '@douyinfe/semi-ui'; import { Button, Col, Row, Input, Tree, Table, Space, Tooltip, Spin } from '@douyinfe/semi-ui';
import { IconSearch, IconEditStroked, IconMinusCircleStroked, IconPlusCircleStroked } from '@douyinfe/semi-icons'; import { IconSearch, IconEditStroked, IconMinusCircleStroked, IconPlusCircleStroked } from '@douyinfe/semi-icons';
import { getResourceClassify } from '../actions/resourceRepository'; import { getResourceClassify, getResourceFileList } from '../actions/resourceRepository';
import '../style.less' import '../style.less';
const ResourceRepository = (props) => { const ResourceRepository = (props) => {
const { dispatch, actions, clientHeight, resourceClassify } = props; const { dispatch, clientHeight, resourceClassify, resourceFilelist, isRequesting } = props;
const [treeData, setTreeData] = useState([]); const [treeData, setTreeData] = useState([]);
const [currentSelect, setCurrentSelect] = useState();
const [defaultExpandedKey, setDefaultExpandedKey] = useState();
const ref = useRef(); const ref = useRef();
useEffect(() => { useEffect(() => {
dispatch(getResourceClassify()).then(res => { dispatch(getResourceClassify()).then(res => {
const { success, payload } = res; const { success, payload } = res;
if (success) if (success) {
let defaultKey = "";
if (payload.data.length) {
if (payload.data[0].children && payload.data[0].children.length) {
defaultKey = payload.data[0].children[0].key;
setDefaultExpandedKey([payload.data[0].key, payload.data[0].children[0].key]);
} else {
defaultKey = payload.data[0].key;
setDefaultExpandedKey([payload.data[0].key]);
}
}
setCurrentSelect([defaultKey]);
setTreeData(payload.data); setTreeData(payload.data);
getFile(defaultKey);
}
}); });
}, []) }, [])
@ -27,117 +41,25 @@ const ResourceRepository = (props) => {
const columns = [ const columns = [
{ {
title: '文件类型', title: '文件类型',
dataIndex: 'name', dataIndex: 'fileType',
}, },
{ {
title: '文件名称', title: '文件名称',
dataIndex: 'size', dataIndex: 'fileName',
}, },
{ {
title: '大小', title: '大小',
dataIndex: 'owner', dataIndex: 'fileSize',
}, },
{ {
title: '更新时间', title: '更新时间',
dataIndex: 'updateTime', dataIndex: 'updateDate',
}, { }, {
title: '操作', title: '操作',
dataIndex: 'action', dataIndex: 'action',
} }
]; ];
const data = [
// {
// key: '1',
// name: 'Semi Design 稿.fig',
// nameIconSrc: 'https://lf3-static.bytednsdoc.com/obj/eden-cn/ptlz_zlp/ljhwZthlaukjlkulzlp/figma-icon.png',
// size: '2M',
// owner: '',
// updateTime: '2020-02-02 05:13',
// avatarBg: 'grey',
// },
// {
// key: '2',
// name: 'Semi Design 稿',
// nameIconSrc: 'https://lf3-static.bytednsdoc.com/obj/eden-cn/ptlz_zlp/ljhwZthlaukjlkulzlp/docs-icon.png',
// size: '2M',
// owner: '',
// updateTime: '2020-01-17 05:31',
// avatarBg: 'red',
// },
// {
// key: '3',
// name: '',
// nameIconSrc: 'https://lf3-static.bytednsdoc.com/obj/eden-cn/ptlz_zlp/ljhwZthlaukjlkulzlp/docs-icon.png',
// size: '34KB',
// owner: 'Zoey Edwards',
// updateTime: '2020-01-26 11:01',
// avatarBg: 'light-blue',
// },
{
key: '4',
name: 'Semi Design 设计稿.fig',
nameIconSrc: 'https://lf3-static.bytednsdoc.com/obj/eden-cn/ptlz_zlp/ljhwZthlaukjlkulzlp/figma-icon.png',
size: '2M',
owner: '姜鹏志',
updateTime: '2020-02-02 05:13',
avatarBg: 'grey',
},
{
key: '5',
name: 'Semi Design 分享演示文稿',
nameIconSrc: 'https://lf3-static.bytednsdoc.com/obj/eden-cn/ptlz_zlp/ljhwZthlaukjlkulzlp/docs-icon.png',
size: '2M',
owner: '郝宣',
updateTime: '2020-01-17 05:31',
avatarBg: 'red',
},
{
key: '6',
name: '设计文档',
nameIconSrc: 'https://lf3-static.bytednsdoc.com/obj/eden-cn/ptlz_zlp/ljhwZthlaukjlkulzlp/docs-icon.png',
size: '34KB',
owner: 'Zoey Edwards',
updateTime: '2020-01-26 11:01',
avatarBg: 'light-blue',
},
{
key: '7',
name: 'Semi Design 设计稿.fig',
nameIconSrc: 'https://lf3-static.bytednsdoc.com/obj/eden-cn/ptlz_zlp/ljhwZthlaukjlkulzlp/figma-icon.png',
size: '2M',
owner: '姜鹏志',
updateTime: '2020-02-02 05:13',
avatarBg: 'grey',
},
{
key: '8',
name: 'Semi Design 分享演示文稿',
nameIconSrc: 'https://lf3-static.bytednsdoc.com/obj/eden-cn/ptlz_zlp/ljhwZthlaukjlkulzlp/docs-icon.png',
size: '2M',
owner: '郝宣',
updateTime: '2020-01-17 05:31',
avatarBg: 'red',
},
{
key: '9',
name: '设计文档',
nameIconSrc: 'https://lf3-static.bytednsdoc.com/obj/eden-cn/ptlz_zlp/ljhwZthlaukjlkulzlp/docs-icon.png',
size: '34KB',
owner: 'Zoey Edwards',
updateTime: '2020-01-26 11:01',
avatarBg: 'light-blue',
},
{
key: '10',
name: '设计文档',
nameIconSrc: 'https://lf3-static.bytednsdoc.com/obj/eden-cn/ptlz_zlp/ljhwZthlaukjlkulzlp/docs-icon.png',
size: '34KB',
owner: 'Zoey Edwards',
updateTime: '2020-01-26 11:01',
avatarBg: 'light-blue',
}
];
const renderLabel = (label, data) => (<div> const renderLabel = (label, data) => (<div>
<Tooltip content={label}><span >{label.length > 8 ? label.substring(0, 8) + '...' : label}</span></Tooltip> <Tooltip content={label}><span >{label.length > 8 ? label.substring(0, 8) + '...' : label}</span></Tooltip>
{true == data.operation ? {true == data.operation ?
@ -148,7 +70,17 @@ const ResourceRepository = (props) => {
</span> </span>
: ''} : ''}
</div> </div>
) );
const handleSelect = (e) => {
getFile(e);
}
const getFile = (e) => {
const arr = e.split("/");
const query = { type: arr[0] };
if (arr[1]) { query.departmentName = arr[1]; }
if (arr[2]) { query.trainDate = arr[2]; }
dispatch(getResourceFileList(query));
}
return ( return (
<> <>
@ -168,40 +100,48 @@ const ResourceRepository = (props) => {
<div style={{ marginLeft: 6, fontSize: 12, color: '#969799', fontFamily: "DINExp", }}>RESOURCE REPOSITORY</div> <div style={{ marginLeft: 6, fontSize: 12, color: '#969799', fontFamily: "DINExp", }}>RESOURCE REPOSITORY</div>
</div> </div>
</div> </div>
<Row className='resourceRepository'> <Spin spinning={isRequesting}>
{/* 左侧 */} <Row className='resourceRepository'>
<Col className='left' span={6}> {/* 左侧 */}
<Button theme='solid' type='primary' >新建文件夹</Button> <Col className='left' span={6}>
<br /> <Button theme='solid' type='primary' >新建文件夹</Button>
<Input suffix={<IconSearch />} showClear onChange={v => ref.current.search(v)} placeholder="请输入"></Input> <br />
<Tree <Input suffix={<IconSearch />} showClear onChange={v => ref.current.search(v)} placeholder="请输入"></Input>
ref={ref} <Tree
treeData={treeData} ref={ref}
defaultExpandAll defaultExpandAll={true}
filterTreeNode treeData={treeData}
searchRender={false} style={style}
blockNode={false} expandedKeys={defaultExpandedKey}
directory filterTreeNode={true}
style={style} searchRender={false}
renderLabel={renderLabel} directory={true}
/> showFilteredOnly={true}
</Col> renderLabel={renderLabel}
{/* 右侧内容 */} onExpand={(e) => setDefaultExpandedKey(e)}
<Col span={18} className='right'> onSelect={handleSelect}
<Row type="flex" justify="space-around" align="middle"> />
<Col span={18}> </Col>
<Space> {/* 右侧内容 */}
<Button theme='solid' type='primary' >上传文件</Button> <Col span={18} className='right'>
<span className="path-lable"><strong>当前文件夹公司培训资源/人力资源部2/2022-11</strong></span> <Row type="flex" justify="space-around" align="middle">
</Space> <Col span={18}>
</Col> <Space>
<Col span={6} > <Button theme='solid' type='primary' >上传文件</Button>
<Input suffix={<IconSearch />} showClear placeholder="文件名称、更新时间"></Input> <span className="path-lable"><strong>当前文件夹{currentSelect}</strong></span>
</Col> </Space>
</Row> </Col>
<Table columns={columns} dataSource={data} pagination={false} /> <Col span={6} >
</Col> <Input suffix={<IconSearch />} showClear placeholder="文件名称、更新时间"></Input>
</Row> </Col>
</Row>
<Table
columns={columns}
dataSource={resourceFilelist && resourceFilelist.rows || []}
pagination={false} />
</Col>
</Row>
</Spin>
</div> </div>
</div> </div>
</> </>
@ -209,12 +149,14 @@ const ResourceRepository = (props) => {
} }
function mapStateToProps(state) { function mapStateToProps(state) {
const { auth, global, resourceClassify } = state; const { auth, global, resourceClassify, resourceFilelist } = state;
return { return {
user: auth.user, user: auth.user,
actions: global.actions, actions: global.actions,
clientHeight: global.clientHeight, clientHeight: global.clientHeight,
resourceClassify: resourceClassify.data || [] resourceClassify: resourceClassify.data || [],
resourceFilelist: resourceFilelist.data && resourceFilelist.data,
isRequesting: resourceClassify.isRequesting || resourceFilelist.isRequesting
}; };
} }

1
web/client/src/utils/webapi.js

@ -52,6 +52,7 @@ export const ApiTable = {
postResourceClassify: 'train/trainFiles/resourceRepository/classify', postResourceClassify: 'train/trainFiles/resourceRepository/classify',
putResourceClassify: 'train/trainFiles/resourceRepository/classify/{id}', putResourceClassify: 'train/trainFiles/resourceRepository/classify/{id}',
delResourceClassify: 'train/trainFiles/resourceRepository/classify/{id}', delResourceClassify: 'train/trainFiles/resourceRepository/classify/{id}',
getResourceFileList: 'train/trainFiles/resourceRepository/fileList',
}; };
export const RouteTable = { export const RouteTable = {

Loading…
Cancel
Save