Files
fe-manage/src/views/projectcenter/SonProject.vue
2024-01-31 18:26:02 +08:00

931 lines
24 KiB
Vue
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<!---- 创建单层子项目页面 --->
<template>
<div class="sonproject">
<div class="header">
<span class="title">创建/编辑单层子项目</span>
<div
@click="backPage"
style="cursor: pointer"
to="/projectmanage"
class="goback"
>
<span class="return"></span><span class="returntext">返回</span>
</div>
</div>
<div class="content">
<div class="main">
<div class="name" v-if="projectInfo.parentName">
<div class="namebox">
<img
class="nameimg"
src="../../assets/images/basicinfo/asterisk.png"
/>
<div class="inname">项目归属</div>
</div>
<div class="in">
<div style="color: #c7cbd2; font-size: 14px; margin-left: 15px">
{{ projectInfo.parentName }}
</div>
</div>
</div>
<div class="name">
<div class="namebox">
<img
class="nameimg"
src="../../assets/images/basicinfo/asterisk.png"
/>
<div class="inname">项目名称</div>
</div>
<div class="in">
<NameInput
placeholder="请输入项目名称"
v-model:value="projectInfo.name"
v-model:validate="projectInfo.validate"
:maxlength="30"
show-count
:id="projectInfo.projectId"
></NameInput>
</div>
</div>
<div class="name flex-top">
<div class="namebox" style="margin-top: 10px">
<img
class="nameimg"
src="../../assets/images/basicinfo/asterisk.png"
/>
<div class="inname">封面图</div>
</div>
<div class="in select" style="flex: 1; display: flex">
<div
:class="`box ${projectInfo.picUrl === src.value ? 'active' : ''}`"
style="
width: 100px;
height: 100px;
border-radius: 5px;
cursor: pointer;
position: relative;
overflow: hidden;
"
v-for="(src, index) in projectPic"
:key="index"
:style="{
display: index >= 3 ? 'none' : 'flex',
}"
@click="() => (projectInfo.picUrl = src.value)"
>
<img
style="
width: 100px;
height: 100px;
margin-bottom: 4px;
margin-right: 4px;
"
:src="src.value"
alt="avatar"
/>
</div>
<div
@click="showLearnBgMore"
v-if="projectPic.length > 3"
style="
width: 100px;
height: 100px;
padding-left: 15px;
border-radius: 5px;
cursor: pointer;
position: relative;
overflow: hidden;
display: flex;
align-items: center;
justify-content: center;
border: 1px solid #c7cbd2;
font-size: 14px;
font-weight: 400;
color: #4ea6ff;
line-height: 36px;
"
>
查看更多
<img src="../../assets/images/projectadd/go.png" alt="" />
</div>
</div>
</div>
<div class="name">
<div class="namebox">
<img
class="nameimg"
src="../../assets/images/basicinfo/asterisk.png"
/>
<div class="inname">项目时间</div>
</div>
<div class="in">
<a-range-picker
:show-time="{ format: 'HH:mm' }"
separator="至"
:placeholder="[' 开始时间', ' 结束时间']"
v-model:value="projectInfo.rangeTime"
style="width: 100%; height: 40px; border-radius: 5px"
valueFormat="YYYY-MM-DD HH:mm"
@change="timeChange"
:disabled="viewDetail ? true : false"
/>
</div>
</div>
<div class="name">
<div class="namebox">
<img
class="nameimg"
src="../../assets/images/basicinfo/asterisk.png"
/>
<div class="inname">项目经理</div>
</div>
<div class="in">
<ProjectManager
v-model:value="projectInfo.managerId"
v-model:name="projectInfo.manager"
@onChange="managerChange"
mode="multiple"
></ProjectManager>
</div>
</div>
<div class="name">
<div class="namebox">
<img
class="nameimg"
src="../../assets/images/basicinfo/asterisk.png"
/>
<div class="inname">资源归属</div>
</div>
<div class="in select">
<OrgClass
v-model:value="projectInfo.sourceBelongId"
v-model:name="projectInfo.sourceBelongName"
v-model:fullName="projectInfo.sourceBelongFullName"
></OrgClass>
</div>
</div>
<div class="name">
<div class="namebox">
<img
class="nameimg"
src="../../assets/images/basicinfo/asterisk.png"
/>
<div class="inname">项目级别</div>
</div>
<div class="in select">
<ProjectLevel v-model:value="projectInfo.level"></ProjectLevel>
</div>
</div>
<div class="name">
<div class="namebox">
<img
class="nameimg"
src="../../assets/images/basicinfo/asterisk.png"
/>
<div class="inname">培训分类</div>
</div>
<div class="in select">
<TrainClass v-model:value="projectInfo.systemId"></TrainClass>
</div>
</div>
<div class="name">
<div class="namebox">
<img
class="nameimg"
src="../../assets/images/basicinfo/asterisk.png"
/>
<div class="inname">是否BOEU实施</div>
</div>
<div class="in">
<a-radio-group
v-model:value="projectInfo.boeFlag"
:disabled="viewDetail ? true : false"
>
<a-radio :style="radioStyle" :value="1"></a-radio>
<a-radio :style="radioStyle" :value="0"></a-radio>
</a-radio-group>
</div>
</div>
<div class="name name2">
<div class="namebox">
<div class="inname">同步学习记录</div>
</div>
<div class="in">
<a-checkbox
v-model:checked="courseSyncFlag"
:disabled="viewDetail ? true : false"
><span
style="
width: 100%;
color: rgba(109, 117, 132, 1);
font-size: 14px;
"
>同步课程学习记录如学员在课程库中拥有课程的学习记录自动免修该课程</span
></a-checkbox
>
</div>
</div>
<div class="name name2">
<div class="namebox">
<div class="inname">积分排行榜</div>
</div>
<div class="in">
<a-checkbox
v-model:checked="rankFlag"
:disabled="viewDetail ? true : false"
><span
style="
width: 100%;
color: rgba(109, 117, 132, 1);
font-size: 14px;
"
>是否显示积分</span
></a-checkbox
>
</div>
</div>
<div class="name name2">
<div class="namebox">
<div class="inname" style="margin-top: 13px">项目说明</div>
</div>
<div class="in">
<a-textarea
v-model:value="projectInfo.remark"
style="height: 80px"
placeholder="请输入说明"
show-count
:maxlength="200"
:disabled="viewDetail ? true : false"
/>
</div>
</div>
<div v-if="projectInfo.status == -5" class="name name2">
<div class="namebox">
<div class="inname" style="margin-top: 13px">审核意见</div>
</div>
<div class="description">
{{ auditDescription }}
</div>
</div>
</div>
</div>
<div class="footer">
<div class="btn">
<a-button
:loading="loading"
v-on:click="createProject"
type="primary"
class="btn1"
>确定
</a-button>
<a-button type="primary" @click="backPage" class="btn1">取消</a-button>
</div>
</div>
<!-- 更多背景图 v-model:visible="learnBgMore" -->
<a-modal
:closable="sh"
centered="true"
v-model:visible="learnBgMore"
:footer="null"
:width="650"
wrapClassName="learnBgMoreModal"
:z-index="9999"
>
<div class="main">
<div class="top">
<div class="topc">封面图</div>
</div>
<div class="imagesBox">
<!-- <div
@click="() => (projectInfo.picUrl = src.value)"
v-for="item in projectPic"
:key="item.code"
class="learnBgItem"
> -->
<div
@click="chooseImg2(item)"
v-for="item in projectPic"
:key="item.code"
class="learnBgItem"
:style="{
border:
projectInfo.picUrl === item.value
? '3px solid rgba(78, 166, 255, 1)'
: '1px solid #ccc',
'background-image': 'url(' + item.value.split(',')[0] + ')',
}"
>
<!-- <img class="im" :src="item.source" /> -->
</div>
</div>
<div class="btn">
<button class="samtn btn2" @click="closeLearnBgMore">取消</button>
<button class="samtn btn2" @click="closeLearnBgMore">确定</button>
</div>
</div>
</a-modal>
</div>
</template>
<script>
import { reactive, toRefs, ref, onMounted } from "vue";
import { message } from "ant-design-vue";
import { useRouter, useRoute } from "vue-router";
import * as api from "../../api/index";
import { useStore } from "vuex";
import ProjectManager from "@/components/project/ProjectManagerNew";
import ProjectLevel from "@/components/project/ProjectLevel";
import TrainClass from "@/components/project/TrainClass";
import NameInput from "@/components/project/NameInput";
import OrgClass from "@/components/project/OrgClass";
import { validateName } from "../../api/index1";
import dayjs from "dayjs";
export default {
name: "projectAdd",
components: {
ProjectManager,
ProjectLevel,
TrainClass,
NameInput,
OrgClass,
},
setup() {
const store = useStore();
// 编辑页面跳转过来时候,自动填充表格
const routers = useRoute();
const router = useRouter();
const isEdit = ref(false);
const state = reactive({
classifySelect: null,
classifySelectId: null,
checked: false,
checked1: false,
valueE: null,
valueE1: null,
valueE2: null,
classifySelect1: [],
classifySelect2: null, //选中的资源归属信息
classifySelect3: null, //选中的项目级别信息
classifySelect4: null, //选中的培训分类信息
rangevalue: [],
projectAscription: "",
viewDetail: routers.query.viewDetail ? routers.query.viewDetail : null,
currentPage: 1, //当前页
tableDataTotal: -1, //模版列表总数
pageSize: 10, //每页10条数据
totalPages: 0, //总页数
currentPage1: 1, //项目经理
pageSize1: 10, //项目经理
projectInfo: {},
courseSyncFlag: false,
rankFlag:false,
learnBgMore: false,
projectPic: [],
loading: false,
});
// const projectPic = computed(() =>
// store.state.project_pic.map((e) => ({
// code: e.id,
// value: e.dictValue,
// label: e.dictName,
// }))
// );
onMounted(() => {
state.projectPic = store.state.project_pic.map((e) => ({
code: e.id,
value: e.value,
label: e.name,
}));
state.viewDetail = routers.query.viewDetail;
getProjectInfo();
});
function getProjectInfo() {
state.projectInfo.parentName = routers.query.parentName;
state.projectInfo.parentId = routers.query.parentId;
state.projectInfo.projectId = routers.query.projectId;
(state.projectInfo.projectId || state.projectInfo.parentId) &&
api
.getProjectDetail({
projectId: state.projectInfo.projectId,
})
.then((res) => {
state.projectInfo = res.data.data.projectInfo;
state.projectInfo.rangeTime = [
state.projectInfo.beginTime,
state.projectInfo.endTime,
];
state.courseSyncFlag = !!state.projectInfo.courseSyncFlag;
state.rankFlag = !!state.projectInfo.rankFlag
});
}
const backPage = () => {
setTimeout(() => {
router.push({
path: "/projectmanage",
});
}, 400);
};
const errorMsgs = {
name: "请输入项目名称",
picUrl: "请选择项目封面图",
beginTime: "请选择项目开始时间",
endTime: "请选择项目结束时间",
manager: "请选择项目经理",
managerId: "请选择项目经理",
sourceBelongId: "请选择资源归属",
level: "请填写项目级别",
systemId: "请填写项目培训体系",
boeFlag: "请选择是否BOEU实施",
};
function timeChange(e) {
if (e && e.length === 2) {
state.projectInfo.beginTime = e[0];
state.projectInfo.endTime = e[1];
}
}
function validate(obj, errorMsgs) {
for (let i in errorMsgs) {
if (!obj[i] && obj[i] !== 0) {
message.destroy();
message.warning(errorMsgs[i]);
return false;
}
}
return true;
}
const createProject = async () => {
state.loading = true;
console.log("我是否要编辑项目", isEdit.value);
if (!validate(state.projectInfo, errorMsgs)) {
state.loading = false;
return;
}
/**
if (!state.projectInfo.validate) {
message.destroy();
message.warning('项目名称重复,请修改名称!');
return;
}*/
console.log("state.projectInfo", state.projectInfo);
const offName = await validateName({
name: state.projectInfo.name,
type: 1,
id: state.projectInfo.id,
}).then((res) => {
return res.data.data == 1;
});
if (offName) {
message.destroy();
state.loading = false;
return message.warning("项目名称重复,请重新填写");
}
state.projectInfo.courseSyncFlag = state.courseSyncFlag ? 1 : 0;
state.projectInfo.rankFlag = state.rankFlag ? 1 : 0;
api.createProject(state.projectInfo).then(() => {
state.loading = false;
message.destroy();
message.success(state.projectInfo.id ? "编辑成功" : "创建成功");
router.back();
});
};
function managerChange(e, l, d, t, orgName) {
state.projectInfo.sourceBelongId = d;
state.projectInfo.sourceBelongName = t;
state.projectInfo.sourceBelongFullName = orgName;
}
const disabledDate = (current) => {
return current && current < dayjs().startOf("day");
};
//显示更多路径背景弹窗
const showLearnBgMore = () => {
state.learnBgMore = true;
};
//关闭更多路径背景弹窗
const closeLearnBgMore = () => {
state.learnBgMore = false;
};
const chooseImg2 = (item) => {
console.log("itemmmmmmm", item);
state.projectInfo.picUrl = item.value;
};
return {
...toRefs(state),
disabledDate,
managerChange,
timeChange,
createProject,
isEdit,
backPage,
showLearnBgMore,
closeLearnBgMore,
chooseImg2,
};
},
};
</script>
<style lang="scss">
.active {
border: 2px solid rgba(78, 166, 255, 1);
}
.sonproject {
width: 100%;
// height: inherit;
// flex: 1;
// flex-shrink: 0;
// overflow-y: auto;
.header {
width: 100%;
display: flex;
justify-content: space-between;
.title {
color: #000000;
font-size: 18px;
//line-height: 36px;
padding-top: 30px;
padding-left: 37px;
//font-weight: 500;
}
.goback {
padding-right: 70px;
//padding-top: 37px;
position: relative;
.return {
display: inline-block;
width: 42px;
height: 42px;
margin-top: 17px;
margin-right: 10px;
background-image: url("../../assets/images/projectadd/return.png");
}
.returntext {
display: inline-block;
position: absolute;
top: 27px;
color: #4ea6ff;
font-size: 14px;
}
}
}
// 修改 antd upload 样式
.ant-upload {
border-width: 0px;
}
.content {
display: flex;
.main {
width: 50%;
display: flex;
flex-direction: column;
align-items: center;
//justify-content: center;
float: left;
border-right: 1px solid rgba(153, 155, 163, 0.3);
.name {
width: 78%;
// background-color: lightcoral;
display: flex;
margin-top: 20px;
align-items: center;
//height: 40px;
// border: 1px solid black;
.namebox {
width: 120px;
display: flex;
align-items: center;
justify-content: flex-end;
flex-shrink: 0;
.nameimg {
width: 10px;
height: 10px;
}
}
.d {
margin-top: 8px;
font-size: 25px;
color: #ff4e4e;
}
.box {
position: relative;
margin-left: 14px;
.box1 {
position: absolute;
left: 50%;
top: 50%;
width: 50px;
margin-left: -25px;
margin-top: -5px;
border-top: 2px solid rgba(78, 166, 255, 1);
}
.box2 {
position: absolute;
left: 50%;
top: 50%;
height: 50px;
//margin-left: -5px;
margin-top: -25px;
border-left: 2px solid rgba(78, 166, 255, 1);
}
}
.inname {
color: #6f6f6f;
font-size: 14px;
margin-left: 7px;
}
.in {
margin-left: 14px;
flex: 1;
// .ant-radio-wrapper {
// }
.ant-input-textarea-show-count {
position: relative;
height: 88px;
}
.ant-input-textarea-show-count::after {
position: absolute;
right: 10px;
bottom: 0px;
}
.ant-input {
border-radius: 8px;
// height: 120%;
width: 100%;
height: 40px;
}
.ant-input-affix-wrapper {
padding: 0 11px;
border-radius: 8px;
}
.ant-select-selector {
border-radius: 5px;
// height: 120%;
width: 100%;
height: 40px;
}
}
.filebox {
margin-left: 14px;
flex: 1;
.fileimg {
width: 15px;
height: 15px;
margin-right: 6px;
}
.filetext {
font-size: 14px;
font-weight: 400;
color: #4ea6ff;
line-height: 36px;
}
.support {
font-size: 14px;
font-weight: 400;
color: #999ba3;
line-height: 36px;
margin-top: 8px;
word-break: break-all;
}
}
}
.name2 {
display: flex;
align-items: flex-start;
.ant-input-textarea {
.ant-input {
height: 88px;
}
}
}
}
.template {
width: 50%;
display: flex;
flex-direction: column;
align-items: center;
//justify-content: center;
float: right;
.name {
width: 78%;
// background-color: lightcoral;
display: flex;
margin-top: 20px;
align-items: center;
height: 40px;
// border: 1px solid black;
.d {
margin-top: 8px;
font-size: 25px;
color: #ff4e4e;
}
.inname {
color: #6f6f6f;
font-size: 14px;
margin-left: 7px;
width: 65px;
}
.in {
margin-left: 14px;
width: 81%;
.ant-input {
border-radius: 5px;
// height: 120%;
width: 100%;
height: 40px;
}
.ant-select-selector {
border-radius: 5px;
// height: 120%;
width: 100%;
height: 40px;
}
}
}
}
}
.footer {
width: 100%;
margin-top: 31px;
margin-bottom: 14px;
padding-bottom: 20px;
.btn {
display: flex;
justify-content: center;
.btn1 {
display: flex;
justify-content: center;
align-items: center;
width: 100px;
height: 40px;
border-radius: 8px;
background: #4ea6ff;
color: #ffffff;
margin-right: 14px;
}
.btn2 {
display: flex;
justify-content: center;
align-items: center;
width: 100px;
height: 40px;
border-radius: 8px;
border: 1px solid #4ea6ff;
background: #ffffff;
color: #4ea6ff;
}
}
.text {
color: rgba(153, 155, 163, 1);
font-size: 14px;
margin-left: 223px;
}
}
}
.learnBgMoreModal {
.ant-modal {
width: 680px !important;
height: 528px !important;
.ant-modal-content {
width: 680px !important;
height: 528px !important;
.ant-modal-body {
width: 680px !important;
height: 528px !important;
padding: 0 !important;
.main {
display: flex;
flex-direction: column;
.top {
padding-left: 51px;
padding-right: 51px;
padding-top: 28px;
display: flex;
align-items: center;
justify-content: space-between;
cursor: pointer;
.topc {
font-size: 16px;
font-weight: bold;
color: #000000;
line-height: 36px;
}
}
.imagesBox {
display: flex;
// justify-content: space-between;
flex-wrap: wrap;
padding-left: 51px;
padding-right: 39px;
margin-top: 20px;
height: 350px;
overflow-y: auto;
.learnBgItem {
border-radius: 8px;
width: 136px;
height: 106px;
background-size: 100%;
background-repeat: no-repeat;
margin-bottom: 20px;
margin-right: 10px;
}
}
.btn {
width: 100%;
position: absolute;
bottom: 30px;
margin-top: 30px;
display: flex;
justify-content: center;
.samtn {
width: 100px;
height: 40px;
font-size: 14px;
border: 1px solid #4ea6ff;
border-radius: 8px;
cursor: pointer;
}
.btn1 {
background-color: #fff;
color: #4ea6ff;
}
.btn2 {
background-color: #4ea6ff;
color: #fff;
margin-left: 16px;
}
}
}
}
}
}
}
</style>