Archer_cdm 2 years ago
parent
commit
fad003fae4
  1. 40
      api/app/lib/controllers/resourceRepository/index.js
  2. 7
      api/app/lib/routes/resourceRepository/index.js
  3. 9
      web/client/src/sections/humanAffairs/actions/resourceRepository.js
  4. 99
      web/client/src/sections/humanAffairs/components/resourceRepository/folder-model.jsx
  5. 107
      web/client/src/sections/humanAffairs/containers/resourceRepository.jsx
  6. 4
      web/client/src/utils/webapi.js

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

@ -6,7 +6,7 @@ async function getResourceClassify(ctx) {
const { models } = ctx.fs.dc; const { models } = ctx.fs.dc;
let rlst = []; let rlst = [];
rlst = [{ rlst = [{
label: "公司培训资料", value: "company", key: "公司培训资料", operation: true, children: [] label: "公司培训资料", value: "company", key: "公司培训资料", operation: false, children: []
}, { label: "部门培训资料", value: 'dept', key: '部门培训资料', operation: false, children: [] }]; }, { label: "部门培训资料", value: 'dept', key: '部门培训资料', operation: false, children: [] }];
const findObj = { order: [["departmentName", "asc"]] } const findObj = { order: [["departmentName", "asc"]] }
const filterData = (arrayData, arrIndex, operation) => { const filterData = (arrayData, arrIndex, operation) => {
@ -173,20 +173,50 @@ async function postResourceClassify(ctx) {
if (trainDate && '' != trainDate) { if (trainDate && '' != trainDate) {
where.trainDate = trainDate; where.trainDate = trainDate;
} }
const oldData = await models.TrainingInformation.findOne(where); const oldData = await models.TrainingInformation.findOne({ where });
if (oldData) {
ctx.throw("该文件夹已存在");
} else {
await models.TrainingInformation.create({
departmentName: departmentName,
trainDate: trainDate
})
}
}
ctx.status = 204;
} catch (err) {
ctx.status = 400;
ctx.body = { message: err.message || '新增培训资源储备库文件夹失败' }
}
}
async function putResourceClassify(ctx) {
try {
const { models } = ctx.fs.dc;
const { oldDepName, oldTrainDate, departmentName, trainDate } = ctx.request.body;
if (departmentName && '' != departmentName && oldDepName && '' != oldDepName) {
const where = { departmentName: oldDepName };
if (trainDate && '' != trainDate && oldTrainDate && '' != oldTrainDate) {
where.trainDate = oldTrainDate;
await models.TrainingInformation.update({ trainDate: trainDate }, { where });
//三级目录
} else {
//二级目录
await models.TrainingInformation.update({ departmentName: departmentName }, { where });
}
} }
ctx.status = 204; ctx.status = 204;
} catch (err) { } catch (err) {
ctx.fs.logger.error(`path: ${ctx.path}, error: ${error}`);
ctx.status = 400; ctx.status = 400;
ctx.body = { message: err.message || '查询培训资源储备库文件列表失败' } ctx.body = { message: err.message || '编辑培训资源储备库文件夹失败' };
} }
} }
module.exports = { module.exports = {
getResourceClassify, getResourceClassify,
getResourceFileList, getResourceFileList,
postResourceClassify postResourceClassify,
putResourceClassify
} }

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

@ -9,4 +9,11 @@ module.exports = function (app, router, opts) {
app.fs.api.logAttr['GET/train/trainFiles/resourceRepository/fileList'] = { content: '查询培训资源储备库文件列表', visible: false }; app.fs.api.logAttr['GET/train/trainFiles/resourceRepository/fileList'] = { content: '查询培训资源储备库文件列表', visible: false };
router.get('/train/trainFiles/resourceRepository/fileList', resourceRepository.getResourceFileList); router.get('/train/trainFiles/resourceRepository/fileList', resourceRepository.getResourceFileList);
app.fs.api.logAttr['POST/train/trainFiles/resourceRepository/classify'] = { content: '新增培训资源储备库文件夹', visible: false };
router.post('/train/trainFiles/resourceRepository/classify', resourceRepository.postResourceClassify);
app.fs.api.logAttr['PUT/train/trainFiles/resourceRepository/classify'] = { content: '编辑培训资源储备库文件夹', visible: false };
router.put('/train/trainFiles/resourceRepository/classify', resourceRepository.putResourceClassify);
}; };

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

@ -32,8 +32,7 @@ export function postResourceClassify(data) {
data, data,
actionType: "POST_RESOURCE_CLASSIFY", actionType: "POST_RESOURCE_CLASSIFY",
url: `${ApiTable.postResourceClassify}`, url: `${ApiTable.postResourceClassify}`,
msg: { option: "新增" }, msg: { success: "新建成功" },
reducer: { name: "" },
}); });
} }
@ -45,8 +44,7 @@ export function putResourceClassify(data) {
data, data,
actionType: "PUT_RESOURCE_CLASSIFY", actionType: "PUT_RESOURCE_CLASSIFY",
url: `${ApiTable.putResourceClassify}`, url: `${ApiTable.putResourceClassify}`,
msg: { option: "修改" }, msg: { option: "编辑" },
reducer: {},
}); });
} }
@ -58,7 +56,6 @@ export function delResourceClassify(data) {
dispatch: dispatch, dispatch: dispatch,
actionType: "DEL_RESOURCE_CLASSIFY", actionType: "DEL_RESOURCE_CLASSIFY",
url: `${ApiTable.delResourceClassify}`, url: `${ApiTable.delResourceClassify}`,
msg: { option: "删除" }, //删除 msg: { option: "删除" },
reducer: {},
}); });
} }

99
web/client/src/sections/humanAffairs/components/resourceRepository/folder-model.jsx

@ -0,0 +1,99 @@
import React, { useRef } from 'react';
import { Modal, Form, Button, Input } from '@douyinfe/semi-ui';
const FolderModal = (props) => {
const { modalData, oldData, onCancel, onOk } = props;
const { title, childFolder, departmentName, trainDate } = modalData;
const add = title.includes("新建");
const form = useRef();//
const validatName = (val) => {
if (val && '' == val.trim()) {
return '不可以为空';
} else
if (val.length > 20) {
return '最大20字符';
} else {
if (oldData.children) {
if (childFolder) {//
let deptChild = oldData.children.find(r => r.label == departmentName).children;
if (!add) {
deptChild = deptChild.filter(r => trainDate != r.label);
}
const old = deptChild.find(r => r.label == val.trim());
if (old) {
return ("该文件已存在");
} else {
return '';
}
} else { //
let deptData = oldData.children;
if (!add) {
deptData = deptData.filter(r => departmentName != r.label);
}
const old = deptData.find(r => r.label == val.trim());
if (old) {
return ("该文件已存在");
} else {
return '';
}
}
}
}
return '';
}
const handleOk = () => {
form.current.validate().then((values) => {
if (!add) {
values.oldDepName = departmentName;
values.oldTrainDate = trainDate;
}
onOk(add, values);
});
}
return (<Modal
title={`${title}文件夹`}
visible={true}
maskClosable={false}
onOk={handleOk}
onCancel={onCancel}>
<Form
getFormApi={(formApi) => (form.current = formApi)}
labelPosition={'left'}
labelAlign={'right'}
labelCol={{ span: 6 }}
wrapperCol={{ span: 18 }}
>
{!childFolder && <Form.Input
field="name"
label="主文件夹"
initValue="公司档案"
disabled={true}
/>}
<Form.Input
field="departmentName"
label="二级文件夹"
initValue={departmentName}
disabled={childFolder}
validate={validatName}
trigger='blur'
rules={[{ required: true, message: "请输入二级文件夹" },
{ whitespace: true, message: '不允许输入空格' },
// { max: 20, message: "20" }
]}
/>
{childFolder &&
< Form.Input
field="trainDate"
label="子文件夹"
initValue={trainDate}
validate={validatName}
trigger='blur'
rules={[{ required: true, message: "请输入子文件夹" }]}
/>}
</Form>
</Modal >
)
}
export default FolderModal

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

@ -1,8 +1,9 @@
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, Spin } from '@douyinfe/semi-ui'; import { Button, Col, Row, Input, Tree, Table, Space, Tooltip, Spin, Notification } from '@douyinfe/semi-ui';
import { IconSearch, IconEditStroked, IconMinusCircleStroked, IconPlusCircleStroked } from '@douyinfe/semi-icons'; import { IconSearch, IconEditStroked, IconMinusCircleStroked, IconPlusCircleStroked } from '@douyinfe/semi-icons';
import { getResourceClassify, getResourceFileList } from '../actions/resourceRepository'; import { getResourceClassify, getResourceFileList, postResourceClassify, putResourceClassify, delResourceClassify } from '../actions/resourceRepository';
import FolderModal from '../components/resourceRepository/folder-model';
import '../style.less'; import '../style.less';
const ResourceRepository = (props) => { const ResourceRepository = (props) => {
@ -10,27 +11,12 @@ const ResourceRepository = (props) => {
const [treeData, setTreeData] = useState([]); const [treeData, setTreeData] = useState([]);
const [currentSelect, setCurrentSelect] = useState(); const [currentSelect, setCurrentSelect] = useState();
const [defaultExpandedKey, setDefaultExpandedKey] = useState(); const [defaultExpandedKey, setDefaultExpandedKey] = useState();
const [modelVisiable, setModelVisiable] = useState(false);
const [modalData, setModalData] = useState();
const ref = useRef(); const ref = useRef();
useEffect(() => { useEffect(() => {
dispatch(getResourceClassify()).then(res => { getClassify();
const { success, payload } = res;
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);
getFile(defaultKey);
}
});
}, []) }, [])
const style = { const style = {
@ -60,21 +46,50 @@ const ResourceRepository = (props) => {
} }
]; ];
const renderLabel = (label, data) => (<div> const renderLabel = (label, data) => {
<Tooltip content={label}><span >{label.length > 8 ? label.substring(0, 8) + '...' : label}</span></Tooltip> const child = data.children ? true : false;
{true == data.operation ? const key = data.key.split('/');
<span className='tree-icon'> return (<div>
<IconEditStroked size='default' onClick={() => alert("bianji")} /> <Tooltip content={label}><span >{label.length > 8 ? label.substring(0, 8) + '...' : label}</span></Tooltip>
<IconMinusCircleStroked size='default' onClick={() => alert("sahnchu")} /> {true == data.operation ?
{data.children ? <IconPlusCircleStroked size='default' onClick={() => alert("+")} /> : ''} <span className='tree-icon'>
</span> <IconEditStroked size='default' onClick={() => handleFolderClick(child ? '编辑' : '编辑子', !child, key[1], key[2] || undefined)} />
: ''} <IconMinusCircleStroked size='default' onClick={() => alert("sahnchu")} />
</div> {child ?
); <IconPlusCircleStroked
size='default'
onClick={() => handleFolderClick('新建子', true, label, undefined)}
/> : ''}
</span>
: ''}
</div>)
};
const handleFolderClick = (title, childFolder, departmentName, trainDate) => {
setModelVisiable(true);
setModalData({ title, childFolder, departmentName, trainDate });
}
const handleSelect = (e) => { const handleSelect = (e) => {
setCurrentSelect(e); setCurrentSelect(e);
getFile(e); getFile(e);
} }
const handleDataToSave = (add, body) => {
if (add) {
dispatch(postResourceClassify(body)).then(res => {
if (res.success) {
getClassify();
setModelVisiable(false);
}
});
} else {
dispatch(putResourceClassify(body)).then(res => {
if (res.success) {
getClassify();
setModelVisiable(false);
}
});
}
}
const getFile = (e) => { const getFile = (e) => {
const arr = e.split("/"); const arr = e.split("/");
const query = { type: arr[0] }; const query = { type: arr[0] };
@ -82,6 +97,26 @@ const ResourceRepository = (props) => {
if (arr[2]) { query.trainDate = arr[2]; } if (arr[2]) { query.trainDate = arr[2]; }
dispatch(getResourceFileList(query)); dispatch(getResourceFileList(query));
} }
const getClassify = () => {
dispatch(getResourceClassify()).then(res => {
const { success, payload } = res;
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);
getFile(defaultKey);
}
});
}
return ( return (
<> <>
@ -105,7 +140,7 @@ const ResourceRepository = (props) => {
<Row className='resourceRepository'> <Row className='resourceRepository'>
{/* 左侧 */} {/* 左侧 */}
<Col className='left' span={6}> <Col className='left' span={6}>
<Button theme='solid' type='primary' >新建文件夹</Button> <Button theme='solid' type='primary' onClick={() => handleFolderClick("新建", false)}>新建文件夹</Button>
<br /> <br />
<Input suffix={<IconSearch />} showClear onChange={v => ref.current.search(v)} placeholder="请输入"></Input> <Input suffix={<IconSearch />} showClear onChange={v => ref.current.search(v)} placeholder="请输入"></Input>
<Tree <Tree
@ -145,6 +180,14 @@ const ResourceRepository = (props) => {
</Row> </Row>
</Spin> </Spin>
</div> </div>
{modelVisiable ?
<FolderModal
oldData={resourceClassify && resourceClassify.find(r => '公司培训资料' == r.label)}
modalData={modalData}
onOk={handleDataToSave}
onCancel={() => { setModelVisiable(false) }}
/> : null
}
</div> </div>
</> </>
) )

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

@ -51,8 +51,8 @@ export const ApiTable = {
//-培训资料库 //-培训资料库
getResourceClassify: 'train/trainFiles/resourceRepository/classify', getResourceClassify: 'train/trainFiles/resourceRepository/classify',
postResourceClassify: 'train/trainFiles/resourceRepository/classify', postResourceClassify: 'train/trainFiles/resourceRepository/classify',
putResourceClassify: 'train/trainFiles/resourceRepository/classify/{id}', putResourceClassify: 'train/trainFiles/resourceRepository/classify',
delResourceClassify: 'train/trainFiles/resourceRepository/classify/{id}', delResourceClassify: 'train/trainFiles/resourceRepository/classify',
getResourceFileList: 'train/trainFiles/resourceRepository/fileList', getResourceFileList: 'train/trainFiles/resourceRepository/fileList',
}; };

Loading…
Cancel
Save