diff --git a/api/Dockerfile b/api/Dockerfile
index 74ac3c3..1cf0525 100644
--- a/api/Dockerfile
+++ b/api/Dockerfile
@@ -25,12 +25,14 @@
FROM repository.anxinyun.cn/base-images/nodejs12:20.10.12.2
+MAINTAINER liuxinyi "liu.xinyi@free-sun.com.cn"
+
COPY . /var/app
WORKDIR /var/app
-EXPOSE 8080
+RUN npm cache clean -f && npm install --production --force --registry http://10.8.30.22:7000
-CMD ["-u", "http://localhost:8088"]
+RUN rm -rf package-lock.json
-ENTRYPOINT [ "node", "server.js" ]
\ No newline at end of file
+CMD [ "node", "server.js" ]
\ No newline at end of file
diff --git a/api/app/lib/controllers/resourceRepository/index.js b/api/app/lib/controllers/resourceRepository/index.js
index d5ec279..53edb19 100644
--- a/api/app/lib/controllers/resourceRepository/index.js
+++ b/api/app/lib/controllers/resourceRepository/index.js
@@ -6,7 +6,7 @@ async function getResourceClassify(ctx) {
const { models } = ctx.fs.dc;
let rlst = [];
rlst = [{
- label: "公司培训资料", value: "company", key: "公司培训资料", operation: true, children: []
+ label: "公司培训资料", value: "company", key: "公司培训资料", operation: false, children: []
}, { label: "部门培训资料", value: 'dept', key: '部门培训资料', operation: false, children: [] }];
const findObj = { order: [["departmentName", "asc"]] }
const filterData = (arrayData, arrIndex, operation) => {
@@ -147,6 +147,11 @@ async function getResourceFileList(ctx, next) {
findObj.where = where;
}
if ("公司培训资料" == type) {
+ if (findObj.where) {
+ findObj.where.fileName = { $not: null };
+ } else {
+ findObj.where = { fileName: { $not: null } };
+ }
rlst = await models.TrainingInformation.findAndCountAll(findObj);
} else {
rlst = await models.DeptTraining.findAndCountAll(findObj);
@@ -163,6 +168,7 @@ async function getResourceFileList(ctx, next) {
}
}
async function postResourceClassify(ctx) {
+ const transaction = await ctx.fs.dc.orm.transaction();
try {
const { models } = ctx.fs.dc;
const { departmentName, trainDate } = ctx.request.body;
@@ -173,20 +179,78 @@ async function postResourceClassify(ctx) {
if (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
+ }, { transaction })
+ }
+ }
+ await transaction.commit();
+ ctx.status = 204;
+ } catch (err) {
+ await transaction.rollback();
+ ctx.status = 400;
+ ctx.body = { message: err.message || '新增培训资源储备库文件夹失败' }
+ }
+}
+async function putResourceClassify(ctx) {
+ const transaction = await ctx.fs.dc.orm.transaction();
+ 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, transaction });
+ //三级目录
+ } else {
+ //二级目录
+ await models.TrainingInformation.update({ departmentName: departmentName }, { where, transaction });
+ }
}
+ await transaction.commit();
ctx.status = 204;
} catch (err) {
- ctx.fs.logger.error(`path: ${ctx.path}, error: ${error}`);
+ await transaction.rollback();
ctx.status = 400;
- ctx.body = { message: err.message || '查询培训资源储备库文件列表失败' }
+ ctx.body = { message: err.message || '编辑培训资源储备库文件夹失败' };
+ }
+}
+
+async function delResourceClassify(ctx) {
+ const transaction = await ctx.fs.dc.orm.transaction();
+ try {
+ const { departmentName, trainDate } = ctx.query;
+ const { models } = ctx.fs.dc;
+
+ if (departmentName && '' != departmentName) {
+ const where = { departmentName };
+ if (trainDate && '' != trainDate) {
+ where.trainDate = trainDate;
+ }
+ await models.TrainingInformation.destroy({ where, transaction });
+ }
+
+ await transaction.commit();
+ ctx.status = 204;
+ } catch (err) {
+ await transaction.rollback();
+ ctx.status = 400;
+ ctx.body = { message: err.message || '新增培训资源储备库文件夹失败' }
}
}
module.exports = {
getResourceClassify,
getResourceFileList,
- postResourceClassify
+ postResourceClassify,
+ putResourceClassify,
+ delResourceClassify
}
\ No newline at end of file
diff --git a/api/app/lib/routes/resourceRepository/index.js b/api/app/lib/routes/resourceRepository/index.js
index 6a152e1..61716a7 100644
--- a/api/app/lib/routes/resourceRepository/index.js
+++ b/api/app/lib/routes/resourceRepository/index.js
@@ -9,4 +9,14 @@ module.exports = function (app, router, opts) {
app.fs.api.logAttr['GET/train/trainFiles/resourceRepository/fileList'] = { content: '查询培训资源储备库文件列表', visible: false };
router.get('/train/trainFiles/resourceRepository/fileList', resourceRepository.getResourceFileList);
+
+ app.fs.api.logAttr['POST/train/trainFiles/resourceRepository/classify'] = { content: '新增培训资源储备库文件夹', visible: true };
+ router.post('/train/trainFiles/resourceRepository/classify', resourceRepository.postResourceClassify);
+
+ app.fs.api.logAttr['PUT/train/trainFiles/resourceRepository/classify'] = { content: '编辑培训资源储备库文件夹', visible: true };
+ router.put('/train/trainFiles/resourceRepository/classify', resourceRepository.putResourceClassify);
+
+ app.fs.api.logAttr['DELETE/train/trainFiles/resourceRepository/classify'] = { content: '删除培训资源储备库文件夹', visible: true };
+ router.delete('/train/trainFiles/resourceRepository/classify', resourceRepository.delResourceClassify);
+
};
\ No newline at end of file
diff --git a/doc/scripts/3.2.0/schema/dept_training.sql b/doc/scripts/3.2.0/schema/dept_training.sql
new file mode 100644
index 0000000..9ee4b71
--- /dev/null
+++ b/doc/scripts/3.2.0/schema/dept_training.sql
@@ -0,0 +1,18 @@
+CREATE TABLE PUBLIC.dept_training (
+ ID serial NOT NULL CONSTRAINT dept_training_pkey PRIMARY KEY,
+ departmentname VARCHAR ( 255 ) NOT NULL,
+ trainingtype VARCHAR ( 255 ) NOT NULL,
+ traindate TIMESTAMP NOT NULL,
+ traincontent VARCHAR ( 255 ) NOT NULL,
+ trainwho VARCHAR ( 255 ),
+ trainer VARCHAR ( 255 ),
+ trainmethod VARCHAR ( 255 ) NOT NULL,
+ appraisalmethod VARCHAR ( 255 ) NOT NULL,
+ traintime VARCHAR ( 255 ) NOT NULL,
+ attachpath VARCHAR ( 255 ),
+ origin VARCHAR ( 255 ),
+ filesize VARCHAR ( 255 ),
+ filename VARCHAR ( 255 ),
+ filetype VARCHAR ( 255 ),
+updatedate TIMESTAMP WITH TIME ZONE
+);
\ No newline at end of file
diff --git a/doc/scripts/3.2.0/schema/personal_training_create.sql b/doc/scripts/3.2.0/schema/personal_training_create.sql
new file mode 100644
index 0000000..e81e4ba
--- /dev/null
+++ b/doc/scripts/3.2.0/schema/personal_training_create.sql
@@ -0,0 +1,17 @@
+CREATE TABLE personal_training (
+ ID serial PRIMARY KEY NOT NULL,
+ personalName VARCHAR ( 255 ) NOT NULL,-- 姓名
+ departmentName VARCHAR ( 255 ) NOT NULL,-- 部门名称
+ trainingType VARCHAR ( 255 ) NOT NULL,-- 培训类型
+ topic VARCHAR ( 255 ) NOT NULL,-- 课程主题
+ trainer VARCHAR ( 255 ) NOT NULL,-- 培训讲师
+ trainDate TIMESTAMP NOT NULL,-- 培训时间
+ trainTime VARCHAR ( 255 ) NOT NULL,-- 培训时长
+ trainMethod VARCHAR ( 255 ) NOT NULL,-- 培训方式
+ attendanceScore VARCHAR ( 255 ),-- 考勤分数
+ appraisalMethod VARCHAR ( 255 ) NOT NULL,-- 考核形式
+ appraisalScore VARCHAR ( 255 ),-- 考核分数
+ totalScore VARCHAR ( 255 ),-- 总分
+ origin VARCHAR ( 255 ) --来源
+
+);
\ No newline at end of file
diff --git a/doc/scripts/PEP V3.2.0/schema/01 create_training_information.sql b/doc/scripts/PEP V3.2.0/schema/01 create_training_information.sql
new file mode 100644
index 0000000..19006c7
--- /dev/null
+++ b/doc/scripts/PEP V3.2.0/schema/01 create_training_information.sql
@@ -0,0 +1,29 @@
+create table training_information
+(
+ id serial not null
+ constraint training_information_record_pkey
+ primary key,
+ departmentname varchar(255) not null,
+ traindate varchar(255),
+ filetype varchar(255),
+ filename varchar(255),
+ filesize varchar(255),
+ updatedate timestamp,
+ attachpath varchar(255)
+);
+
+comment on table training_information is '公司培训资源库';
+
+comment on column training_information.departmentname is '部门分类';
+
+comment on column training_information.traindate is '时间(三级目录)';
+
+comment on column training_information.filetype is '文件类型';
+
+comment on column training_information.filename is '文件名';
+
+comment on column training_information.filesize is '文件大小';
+
+comment on column training_information.updatedate is '更新时间';
+
+comment on column training_information.attachpath is '文件路径';
diff --git a/jenkinsfile_poms_api b/jenkinsfile_poms_api
index c9291bd..671e0e5 100644
--- a/jenkinsfile_poms_api
+++ b/jenkinsfile_poms_api
@@ -6,13 +6,12 @@ pipeline {
}
stages {
- stage('Testing poms ......') {
+ stage('Testing hrm api......') {
steps {
- sh 'switch-auth.sh anxinyun'
- buildName "#${BUILD_NUMBER} ~/fs-cloud/${JOB_NAME}:${IMAGE_VERSION}"
- buildDescription "registry.cn-hangzhou.aliyuncs.com/${CLOUD}/${JOB_NAME}:${IMAGE_VERSION}"
- sh 'docker build -t registry.cn-hangzhou.aliyuncs.com/${CLOUD}/${JOB_NAME}:${IMAGE_VERSION} ./api'
- sh 'docker push registry.cn-hangzhou.aliyuncs.com/${CLOUD}/${JOB_NAME}:${IMAGE_VERSION}'
+ buildName '#${BUILD_NUMBER} ~/pep/${JOB_NAME}:${IMAGE_VERSION}'
+ buildDescription 'harbor.anxinyun.cn/pep/${JOB_NAME}:${IMAGE_VERSION}'
+ sh 'nerdctl build -t harbor.anxinyun.cn/pep/${JOB_NAME}:${IMAGE_VERSION} ./api'
+ sh 'nerdctl push harbor.anxinyun.cn/pep/${JOB_NAME}:${IMAGE_VERSION}'
}
}
}
diff --git a/jenkinsfile_poms_web b/jenkinsfile_poms_web
index 9d43c6e..8f06fda 100644
--- a/jenkinsfile_poms_web
+++ b/jenkinsfile_poms_web
@@ -6,13 +6,12 @@ pipeline {
}
stages {
- stage('Testing poms ......') {
+ stage('Testing hrm-web ......') {
steps {
- sh 'switch-auth.sh anxinyun'
- buildName "#${BUILD_NUMBER} ~/fs-cloud/${JOB_NAME}:${IMAGE_VERSION}"
- buildDescription "registry.cn-hangzhou.aliyuncs.com/${CLOUD}/${JOB_NAME}:${IMAGE_VERSION}"
- sh 'docker build -t registry.cn-hangzhou.aliyuncs.com/${CLOUD}/${JOB_NAME}:${IMAGE_VERSION} ./web'
- sh 'docker push registry.cn-hangzhou.aliyuncs.com/${CLOUD}/${JOB_NAME}:${IMAGE_VERSION}'
+ buildName "#${BUILD_NUMBER} ~/pep/${JOB_NAME}:${IMAGE_VERSION}"
+ buildDescription "harbor.anxinyun.cn/pep/${JOB_NAME}:${IMAGE_VERSION}"
+ sh 'nerdctl build -t harbor.anxinyun.cn/pep/${JOB_NAME}:${IMAGE_VERSION} ./web'
+ sh 'nerdctl push harbor.anxinyun.cn/pep/${JOB_NAME}:${IMAGE_VERSION}'
}
}
}
diff --git a/web/Dockerfile b/web/Dockerfile
index 3991885..a9a3af6 100644
--- a/web/Dockerfile
+++ b/web/Dockerfile
@@ -27,14 +27,19 @@
# 旧版本构建方式
-FROM repository.anxinyun.cn/base-images/nodejs12:20.10.12.2
-
+FROM registry.cn-hangzhou.aliyuncs.com/fs-devops/node:12-dev as builder
COPY . /var/app
-
WORKDIR /var/app
-
EXPOSE 8080
-
-CMD ["-u", "http://localhost:8088"]
-
-ENTRYPOINT [ "node", "server.js" ]
\ No newline at end of file
+RUN npm config set registry=http://10.8.30.22:7000
+RUN echo "{\"time\":\"$BUILD_TIMESTAMP\",\"build\": \"$BUILD_NUMBER\",\"revision\": \"$SVN_REVISION_1\",\"URL\":\"$SVN_URL_1\"}" > version.json
+RUN npm cache clean -f
+RUN npm install --registry http://10.8.30.22:7000
+RUN npm run build
+RUN rm -rf client/src
+RUN rm -rf node_modules
+RUN npm install --production --force --registry http://10.8.30.22:7000
+FROM registry.cn-hangzhou.aliyuncs.com/fs-devops/node-16:7.22-06-20
+COPY --from=builder --chown=node /var/app /home/node/app
+WORKDIR /home/node/app
+CMD ["node", "server.js"]
\ No newline at end of file
diff --git a/web/client/src/sections/humanAffairs/actions/resourceRepository.js b/web/client/src/sections/humanAffairs/actions/resourceRepository.js
index 970f1da..1ecdd42 100644
--- a/web/client/src/sections/humanAffairs/actions/resourceRepository.js
+++ b/web/client/src/sections/humanAffairs/actions/resourceRepository.js
@@ -32,8 +32,7 @@ export function postResourceClassify(data) {
data,
actionType: "POST_RESOURCE_CLASSIFY",
url: `${ApiTable.postResourceClassify}`,
- msg: { option: "新增" },
- reducer: { name: "" },
+ msg: { success: "新建成功" },
});
}
@@ -45,20 +44,18 @@ export function putResourceClassify(data) {
data,
actionType: "PUT_RESOURCE_CLASSIFY",
url: `${ApiTable.putResourceClassify}`,
- msg: { option: "修改" },
- reducer: {},
+ msg: { option: "编辑" },
});
}
-export function delResourceClassify(data) {
+export function delResourceClassify(query) {
return (dispatch) =>
basicAction({
type: "del",
- query: data,
+ query: query,
dispatch: dispatch,
actionType: "DEL_RESOURCE_CLASSIFY",
url: `${ApiTable.delResourceClassify}`,
- msg: { option: "删除" }, //删除
- reducer: {},
+ msg: { option: "删除" },
});
}
\ No newline at end of file
diff --git a/web/client/src/sections/humanAffairs/components/resourceRepository/folder-model.jsx b/web/client/src/sections/humanAffairs/components/resourceRepository/folder-model.jsx
new file mode 100644
index 0000000..eaa7178
--- /dev/null
+++ b/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 (