Merge branch 'develop' of ssh://gitlab.dongwu-inc.com:10022/BOE/fe-manage into develop

This commit is contained in:
zhangyc
2022-12-08 09:00:00 +08:00
12 changed files with 10056 additions and 9483 deletions

View File

@@ -43,7 +43,7 @@ export default defineComponent({
const store = useStore(); const store = useStore();
const isLogin = ref(false); const isLogin = ref(false);
// console.log("router", router.getRoutes(), route); // console.log("router", router.getRoutes(), route);
console.log("版本0.9.4------------"); console.log("版本0.9.5------------");
const routes = computed(() => { const routes = computed(() => {
return router.getRoutes().filter((e) => e.meta?.isLink); return router.getRoutes().filter((e) => e.meta?.isLink);
}); });

View File

@@ -2,7 +2,7 @@
* @Author: lixg lixg@dongwu-inc.com * @Author: lixg lixg@dongwu-inc.com
* @Date: 2022-11-21 14:32:52 * @Date: 2022-11-21 14:32:52
* @LastEditors: lixg lixg@dongwu-inc.com * @LastEditors: lixg lixg@dongwu-inc.com
* @LastEditTime: 2022-12-07 13:41:47 * @LastEditTime: 2022-12-08 08:48:26
* @FilePath: /fe-manage/src/api/config.js * @FilePath: /fe-manage/src/api/config.js
* @Description: 这是默认设置,请设置`customMade`, 打开koroFileHeader查看配置 进行设置: https://github.com/OBKoro1/koro1FileHeader/wiki/%E9%85%8D%E7%BD%AE * @Description: 这是默认设置,请设置`customMade`, 打开koroFileHeader查看配置 进行设置: https://github.com/OBKoro1/koro1FileHeader/wiki/%E9%85%8D%E7%BD%AE
*/ */
@@ -56,7 +56,7 @@ http.interceptors.response.use(
return response; return response;
} else { } else {
if (code === 1000) { if (code === 1000) {
// window.open("https://u-pre.boe.com/web/", '_self'); window.open("https://u-pre.boe.com/web/", '_self');
// window.open("http://111.231.196.214:12013/manage/login", '_self'); // window.open("http://111.231.196.214:12013/manage/login", '_self');
} }
console.log("api %o", msg); console.log("api %o", msg);

View File

@@ -0,0 +1,85 @@
<template>
<a-upload
:file-list="files"
action="/manageApi/file/upload"
:show-upload-list="showUploadList"
:multiple="multiple"
:before-upload="beforeUpload"
@change="handleChange"
ref="imageRef"
>
<template v-for="(_, key, index) in $slots" :key="index" v-slot:[key]>
<slot :name="key"></slot>
</template>
</a-upload>
</template>
<script setup>
import {defineProps, defineEmits, defineExpose, ref, watch} from "vue";
import {message} from "ant-design-vue";
const props = defineProps({
value: {
type: Array,
default: () => []
},
multiple: {
type: Boolean,
default: false
},
showUploadList: {
type: Boolean,
default: false
},
fileType: {
type: Array,
default: () => []
}
})
const emit = defineEmits({})
const files = ref([])
const imageRef = ref()
watch(props, () => {
props.value.length !== files.value.length && (files.value = props.value)
})
function handleChange({file, fileList}) {
file.response && file.response.code === 200 && (file.url = file.response.data)
files.value = fileList
emit('update:value', fileList)
}
function beforeUpload(file) {
if (!props.fileType.includes(file.name.split(".").slice(-1).join(''))) {
message.error(
"不支持该格式"
);
return false;
}
}
function remove(i) {
files.value.splice(i, 1)
emit('update:value', files.value)
}
function reUpload(i) {
if (files.value[i].status === 'ready' || files.value[i].status === 'uploading') {
imageRef.value.abort(files.value[i].raw)
files.value[i].status = 'abort';
} else if (files.value[i].status === 'fail' || files.value[i].status === 'abort') {
imageRef.value.handleStart(files.value[i].raw)
imageRef.value.submit()
}
}
function abort(i) {
imageRef.value.abort(files.value[i].raw)
}
defineExpose({reUpload, remove, abort})
</script>

View File

@@ -0,0 +1,202 @@
<template>
<div>
<div>
<Upload v-model:value="files" ref="uploadRef" :file-type="fileType">
<div class="accessory" style="cursor: pointer">
<span class="accessory_icon">
<img
src="@/assets/images/coursewareManage/enclosure.png"
alt="enclosure"
/>
</span>
<span style="color: #4ea6ff;margin-left:10px">添加附件</span>
</div>
</Upload>
<div>支持.pdf,.ppt,.pptx,.doc,.docx,.xls,.xlsx,.jpg,.jpeg,.png,.gif,.zip</div>
</div>
<div class="mbl_items12" style="margin-left: 0">
<div
class="i12_box1"
v-for="(item, index) in files"
style="align-items: flex-end"
:key="index"
>
<div class="file_img"></div>
<div class="file_detail">
<div class="file_name">
<span style="color: #6f6f6f">{{ item.name }}</span>
</div>
<!-- <div class="file_size">-->
<!-- <span style="color: #999ba3">{{ item.size }}</span>-->
<!-- </div>-->
<div class="file_updata">
<div class="updatabox">
<div
:class="`${{uploading: 'updatacolor3', done: 'updatacolor' ,error: 'updatacolor2'}[item.status] || 'updatacolor'}`"
:style="{width:`${item.status==='uploading'?parseInt(item.percent):100}%`}"></div>
<div v-if="item.status"
:class="`${{uploading: 'updataxq1', done: 'updataxq' ,error: 'updataxq2'}[item.status] || 'updataxq'}`">
{{ {uploading: '正在上传', done: '上传完成', error: '上传失败'}[item.status] || '' }}
</div>
</div>
<div class="upjd" v-if="item.percent">
<span style="margin: auto 5px">{{ item.status === 'uploading' ? parseInt(item.percent) : 100 }}%</span>
</div>
</div>
</div>
<div class="file_operation" @click="del(index)" style="color: #4ea6ff">
删除
</div>
</div>
</div>
</div>
</template>
<script setup>
import {defineEmits, defineProps, ref, watch, onMounted} from "vue";
import Upload from "./BaseUpload.vue";
const emit = defineEmits({})
const props = defineProps({
value: String,
})
const files = ref([])
const uploadRef = ref()
const fileType = ref([
"jpg",
"jpeg",
"png",
"gif",
"pdf",
"ppt",
"pptx",
"doc",
"docx",
"xls",
"xlsx",
"zip",
])
onMounted(() => {
init()
})
watch(files, () => {
files.value && files.value.length && emit('update:value', files.value.filter(e => e.url).map(e => e.url).join(','))
})
watch(props, init)
function init() {
if (props.value !== files.value.map(e => e.url).join(',')) {
files.value = props.value ? props.value.split(',').map(e => ({name: e, url: e})) : []
}
}
function del(i) {
uploadRef.value.remove(i)
}
</script>
<style lang="scss">
.mbl_items12 {
width: 440px;
margin-left: 100px;
.i12_box1 {
display: flex;
align-items: center;
padding: 17px 0px 17px 21px;
border: 1px solid #eff4fc;
border-radius: 8px;
margin-bottom: 10px;
.file_img {
width: 27px;
height: 32px;
background-image: url(@/assets/images/coursewareManage/imgs.png);
margin-right: 22px;
img {
width: 100%;
height: 100%;
}
}
.file_detail {
width: 250px;
margin-right: 21px;
.file_updata {
display: flex;
align-items: center;
.updatabox {
position: relative;
width: 230px;
height: 5px;
background-color: rgba(192, 192, 192, 0.25);
border-radius: 3px;
.updatacolor {
position: absolute;
left: 0;
width: 100%;
height: 5px;
background-color: #57c887;
border-radius: 3px;
}
.updatacolor2 {
position: absolute;
left: 0;
width: 80%;
height: 5px;
background-color: #ff7474;
border-radius: 3px;
}
.updatacolor3 {
position: absolute;
left: 0;
width: 60%;
height: 5px;
background-color: #388be1;
border-radius: 3px;
}
.updataxq {
position: absolute;
right: 2px;
top: -30px;
color: #57c887;
}
.updataxq1 {
position: absolute;
right: 2px;
top: -30px;
color: #388be1;
}
.updataxq2 {
position: absolute;
right: 2px;
top: -30px;
color: #ff7474;
}
}
}
}
.file_operation {
display: flex;
.fobox {
margin-right: 5px;
cursor: pointer;
}
}
}
}
</style>

View File

@@ -1,9 +0,0 @@
<template>
<div>12312</div>
</template>
<script setup>
import {reactive} from "vue";
const options = reactive([]);
</script>

View File

@@ -1,17 +1,22 @@
<template> <template>
<a-select <template v-if="tag">
:getPopupContainer=" <div>{{ options?.find(e => e.value == id)?.label || '' }}</div>
</template>
<template v-else>
<a-select
:getPopupContainer="
(triggerNode) => { (triggerNode) => {
return triggerNode.parentNode || document.body; return triggerNode.parentNode || document.body;
} }
" "
v-model:value="id" v-model:value="id"
:options="options" :options="options"
style="width: 100%" style="width: 100%"
placeholder="请选择项目级别" placeholder="请选择项目级别"
@change="change" @change="change"
:disabled="disabled" :disabled="disabled"
/> />
</template>
</template> </template>
<script setup> <script setup>
import {computed, defineEmits, defineProps, onMounted, ref} from "vue"; import {computed, defineEmits, defineProps, onMounted, ref} from "vue";
@@ -21,7 +26,11 @@ import {useStore} from "vuex";
const store = useStore(); const store = useStore();
const props = defineProps({ const props = defineProps({
value: String, value: String,
disabled: String disabled: String,
tag: {
type: Boolean,
default: false
}
}) })
const id = computed(() => { const id = computed(() => {

View File

@@ -1,17 +1,23 @@
<template> <template>
<a-select <template v-if="tag">
:getPopupContainer=" <div>{{ options.find(e => e.value == id)?.label || '' }}</div>
</template>
<template v-else>
<a-select
:getPopupContainer="
(triggerNode) => { (triggerNode) => {
return triggerNode.parentNode || document.body; return triggerNode.parentNode || document.body;
} }
" "
v-model:value="id" v-model:value="id"
:options="options" :options="options"
style="width: 100%" style="width: 100%"
placeholder="请选择分类" placeholder="请选择分类"
@change="change" @change="change"
:disabled="disabled" :disabled="disabled"
/> />
</template>
</template> </template>
<script setup> <script setup>
import {computed, defineEmits, defineProps, onMounted, ref} from "vue"; import {computed, defineEmits, defineProps, onMounted, ref} from "vue";
@@ -21,7 +27,11 @@ const store = useStore();
const props = defineProps({ const props = defineProps({
value: String, value: String,
disabled: String disabled: String,
tag: {
type: Boolean,
default: false
}
}) })
const id = computed(() => { const id = computed(() => {

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -283,33 +283,24 @@
v-model:checked="checked" v-model:checked="checked"
@click="changeopclo" @click="changeopclo"
/> />
<div v-if="(checked==true)" <div
class="opclo"> class="opclo"
:style="{ display: hideshow ? 'block' : 'none' }"
>
<span>关闭</span> <span>关闭</span>
</div> </div>
<div v-if="(checked==false)" <div
class="opclo" > class="opclo"
:style="{ display: hideshow ? 'none' : 'block' }"
>
<span>开启</span> <span>开启</span>
</div> </div>
</div> </div>
<div v-if="(checked==true)" <div
class="ntc_content"> class="ntc_content"
<div class="ntcc_tit">当前公告内容</div> :style="{ display: hideshow ? 'block' : 'none' }"
<div class="textarea"> >
{{noticeContent==""?"暂无公告":noticeContent}} <div class="ntcc_tit">公告内容</div>
<div v-if="(editFlag == false)" class="btnarea" >
<div>&nbsp;</div>
<div class="area_btn" @click="editNotice">
<div class="btnText">编辑</div>
</div>
</div>
</div>
<template v-if="(editFlag==true)">
<div>&nbsp;</div>
<div class="ntcc_tit" >编辑公告</div>
<div class="textarea"> <div class="textarea">
<a-textarea <a-textarea
v-model:value="projectInfo.notice" v-model:value="projectInfo.notice"
@@ -324,8 +315,7 @@
<div class="btnText">发布</div> <div class="btnText">发布</div>
</div> </div>
</div> </div>
</div> </div>
</template>
</div> </div>
</div> </div>
</div> </div>
@@ -845,8 +835,6 @@ export default defineComponent({
edit: true, edit: true,
fileList:[], fileList:[],
attachSwitch:true, attachSwitch:true,
editFlag:false,
noticeContent:"",
// 共享文档列表 // 共享文档列表
docList: [ docList: [
{ {
@@ -864,25 +852,29 @@ export default defineComponent({
], ],
isEdit: false, // 是否处于编辑状态 isEdit: false, // 是否处于编辑状态
// 基本信息 // 基本信息
projectInfo: {}, projectInfo: {
beginTime: null,
endTime: null,
name: null,
manager: null,
notice: null,
sourceBelongId: null,
remark: "",
courseSyncFlag: false,
level: null,
systemId: null,
boeFlag: false,
status: null,
picUrl: null,
noticeFlag: null,
},
}); });
const value = ref(""); const value = ref("");
const textnum = "150"; const textnum = "150";
const routered = useRouter(); const routered = useRouter();
const changeopclo = () => { const changeopclo = () => {
state.projectInfo.noticeFlag = state.checked?1:0; state.hideshow = !state.hideshow;
api
.templateEdit( state.projectInfo)
.then((res) => {
console.log(res);
})
.catch((err) => {
console.log(err);
});
}; };
const editNotice =()=>{
state.editFlag = true ;
}
const changecheck2 = () => { const changecheck2 = () => {
state.checked2 = !state.checked2; state.checked2 = !state.checked2;
}; };
@@ -945,13 +937,25 @@ export default defineComponent({
state.taskSyllabus = []; state.taskSyllabus = [];
console.log(res); console.log(res);
state.projectInfo = res.data.data.projectTemplateInfo; state.projectInfo.name = res.data.data.projectTemplateInfo.name;
state.projectInfo.beginTime = res.data.data.projectTemplateInfo.beginTime;
state.noticeContent = state.projectInfo.notice; state.projectInfo.endTime = res.data.data.projectTemplateInfo.endTime;
state.checked = state.projectInfo.noticeFlag==1?true:false; state.projectInfo.manager = res.data.data.projectTemplateInfo.manager;
console.log("state.checked", state.checked); state.projectInfo.notice = res.data.data.projectTemplateInfo.notice;
console.log("state.projectInfo",state.projectInfo); state.projectInfo.sourceBelongId = res.data.data.projectTemplateInfo.sourceBelongId;
console.log("res.data.data.projectTemplateInfo",res.data.data.projectTemplateInfo); state.projectInfo.managerId = res.data.data.projectTemplateInfo.managerId;
state.projectInfo.remark = res.data.data.projectTemplateInfo.remark;
state.projectInfo.courseSyncFlag = res.data.data.projectTemplateInfo.courseSyncFlag;
state.projectInfo.level = res.data.data.projectTemplateInfo.level;
state.projectInfo.systemId = res.data.data.projectTemplateInfo.systemId;
state.projectInfo.boeFlag = res.data.data.projectTemplateInfo.boeFlag;
state.projectInfo.noticeFlag = res.data.data.projectTemplateInfo.noticeFlag;
state.projectInfo.remark = res.data.data.projectTemplateInfo.remark;
state.projectInfo.status = res.data.data.projectTemplateInfo.status;
state.projectInfo.picUrl = res.data.data.projectTemplateInfo.picUrl;
state.picUrl = res.data.data.projectTemplateInfo.picUrl;
state.projectInfo.attach = res.data.data.projectTemplateInfo.attach;
state.projectInfo.category = res.data.data.projectTemplateInfo.category;
try{ try{
state.fileList = JSON.parse(res.data.data.projectTemplateInfo.attach); state.fileList = JSON.parse(res.data.data.projectTemplateInfo.attach);
}catch{ }catch{
@@ -984,14 +988,29 @@ export default defineComponent({
// 发布公告 // 发布公告
const addNotice = () => { const addNotice = () => {
// state.projectInfo.notice= console.log("ok====s");
if(!state.projectInfo.notice){ let obj = {
return message.warning("请输入公告内容"); name: state.projectInfo.name,
} category: state.projectInfo.category,
picUrl: state.projectInfo.picUrl,
manager: state.projectInfo.manager,
managerId: state.projectInfo.managerId || 0,
sourceBelongId: state.projectInfo.sourceBelongId,
level: state.projectInfo.level,
systemId: state.projectInfo.systemId,
boeFlag: state.projectInfo.boeFlag ? 1 : 0,
courseSyncFlag: state.projectInfo.courseSyncFlag ? 1 : 0,
notice: state.projectInfo.notice,
noticeFlag: state.projectInfo.noticeFlag,
projectTemplateId: localStorage.getItem("projectTemplateId"),
remark: state.projectInfo.remark,
status: state.projectInfo.status,
attach: state.projectInfo.attach,
};
console.log("obj======", obj);
api api
.templateEdit( state.projectInfo) .templateEdit(obj)
.then((res) => { .then((res) => {
state.noticeContent = state.projectInfo.notice;
message.success("公告发布成功"); message.success("公告发布成功");
console.log(res); console.log(res);
}) })
@@ -999,7 +1018,6 @@ export default defineComponent({
message.error("公告发布失败" + err); message.error("公告发布失败" + err);
console.log(err); console.log(err);
}); });
state.editFlag =false;
}; };
// 删除阶段 // 删除阶段
const stateDel = (id) => { const stateDel = (id) => {
@@ -1270,8 +1288,7 @@ export default defineComponent({
editRule, editRule,
handleChange2, handleChange2,
scoresum, scoresum,
checkedClose, checkedClose
editNotice
}; };
}, },
}); });
@@ -2200,7 +2217,6 @@ export default defineComponent({
.ntc_content { .ntc_content {
.ntcc_tit { .ntcc_tit {
margin-bottom: 16px; margin-bottom: 16px;
font-weight: 600;
} }
.textarea { .textarea {
display: flex; display: flex;

View File

@@ -4,10 +4,10 @@
<div class="header"> <div class="header">
<span class="title">创建/编辑单层模板</span> <span class="title">创建/编辑单层模板</span>
<div <div
@click="backPage" @click="backPage"
style="cursor: pointer" style="cursor: pointer"
to="/manage/libraryAdd" to="/manage/libraryAdd"
class="goback" class="goback"
> >
<span class="return"></span><span class="returntext">返回</span> <span class="return"></span><span class="returntext">返回</span>
</div> </div>
@@ -17,164 +17,119 @@
<div class="name"> <div class="name">
<div class="namebox"> <div class="namebox">
<img <img
class="nameimg" class="nameimg"
src="../../assets/images/basicinfo/asterisk.png" src="../../assets/images/basicinfo/asterisk.png"
/> />
<div class="inname">模板名称</div> <div class="inname">模板名称</div>
</div> </div>
<div class="in"> <div class="in">
<a-input <a-input
v-model:value="projectInfo.name" v-model:value="projectInfo.name"
placeholder="请输入模板名称" placeholder="请输入模板名称"
show-count show-count
:maxlength="30" :maxlength="30"
/> />
</div> </div>
</div> </div>
<div class="name"> <div class="name">
<div class="namebox"> <div class="namebox">
<img <img
class="nameimg" class="nameimg"
src="../../assets/images/basicinfo/asterisk.png" src="../../assets/images/basicinfo/asterisk.png"
/> />
<div class="inname">分类</div> <div class="inname">分类</div>
</div> </div>
<div class="in select"> <div class="in select">
<a-select <ProjectClass v-model:value="projectInfo.category"></ProjectClass>
:getPopupContainer="
(triggerNode) => {
return triggerNode.parentNode || document.body;
}
"
v-model:value="projectInfo.category"
style="width: 100%"
:options="classifyList"
@change="classificationChange"
allowClear
showSearch
>
</a-select>
</div> </div>
</div> </div>
<div class="name"> <div class="name" style="align-items: flex-start;">
<div class="namebox"> <div class="namebox" style="margin-top: 10px">
<img <img
class="nameimg" class="nameimg"
src="../../assets/images/basicinfo/asterisk.png" src="../../assets/images/basicinfo/asterisk.png"
/> />
<div class="inname">封面图</div> <div class="inname">封面图</div>
</div> </div>
<div <div class="in select" style="flex:1">
class="box" <a-select
style=" :getPopupContainer="
width: 100px; (triggerNode) => {
height: 100px; return triggerNode.parentNode || document.body;
border: 1px solid rgba(78, 166, 255, 1); }
border-radius: 5px; "
cursor: pointer; v-model:value="projectInfo.picUrl"
position: relative; dropdownClassName="dropdown-style"
overflow: hidden; style="width: 440px"
" placeholder="请选择"
> :options="projectPic"
<a-upload @change="handleChangeSelect"
v-model:file-list="fileList" allowClear
name="file" ></a-select>
list-type="picture-card" <img
class="avatar-uploader" style="width:100px;height:100px;margin-top:20px;border-radius: 8px"
:show-upload-list="false" v-if="projectInfo.picUrl"
action="/api/file/upload" :src="projectInfo.picUrl"
:before-upload="beforeUpload"
@change="handleChange"
>
<img
style="
width: 100px;
height: 100px;
margin-bottom: 4px;
margin-right: 4px;
"
v-if="imageUrl"
:src="imageUrl"
alt="avatar" alt="avatar"
/> />
<div v-else> <div class="i_bottom">
<!-- <loading-outlined v-if="loading"></loading-outlined> --> <span style="color: #999ba3">
<!-- <plus-outlined v-else></plus-outlined> --> 高宽比为16:9 (:800*450) png或jpg图片
<div class="box1"></div> </span>
<div class="box2"></div> </div>
<!-- <div class="ant-upload-text"></div> -->
</div>
</a-upload>
</div> </div>
</div> </div>
<div class="name"> <div class="name">
<div class="namebox"> <div class="namebox">
<img <img
class="nameimg" class="nameimg"
src="../../assets/images/basicinfo/asterisk.png" src="../../assets/images/basicinfo/asterisk.png"
/> />
<div class="inname">项目时间</div> <div class="inname">项目时间</div>
</div> </div>
<div class="in"> <div class="in">
<a-range-picker <a-range-picker
separator="至" separator="至"
:placeholder="[' 开始时间', ' 结束时间']" :placeholder="[' 开始时间', ' 结束时间']"
v-model:value="projectInfo.choosedTime" v-model:value="projectInfo.rangeTime"
format="YYYY-MM-DD" style="width: 100%; height: 40px; border-radius: 5px"
style="width: 100%; height: 40px; border-radius: 5px" valueFormat="YYYY-MM-DD HH:mm:ss"
@change="timeChange"
/> />
</div> </div>
</div> </div>
<div class="name"> <div class="name">
<div class="namebox"> <div class="namebox">
<img <img
class="nameimg" class="nameimg"
src="../../assets/images/basicinfo/asterisk.png" src="../../assets/images/basicinfo/asterisk.png"
/> />
<div class="inname">项目经理</div> <div class="inname">项目经理</div>
</div> </div>
<div class="in"> <div class="in">
<a-select <ProjectManager
:getPopupContainer=" v-model:value="projectInfo.managerId"
(triggerNode) => { v-model:name="projectInfo.manager"
return triggerNode.parentNode || document.body; @onChange="managerChange"
} mode="multiple"
" ></ProjectManager>
:value="classifySelect1"
mode="multiple"
placeholder="请选择项目经理"
style="width: 100%"
:options="classifyList1"
@change="classificationChange1"
allowClear
showSearch
>
</a-select>
</div> </div>
</div> </div>
<div class="name"> <div class="name">
<div class="namebox"> <div class="namebox">
<img <img
class="nameimg" class="nameimg"
src="../../assets/images/basicinfo/asterisk.png" src="../../assets/images/basicinfo/asterisk.png"
/> />
<div class="inname">资源归属</div> <div class="inname">资源归属</div>
</div> </div>
<div class="in select"> <div class="in select">
<a-select <OrgClass
:getPopupContainer=" v-model:value="projectInfo.sourceBelongId"
(triggerNode) => { v-model:name="projectInfo.sourceBelongName"
return triggerNode.parentNode || document.body; ></OrgClass>
}
"
v-model:value="projectInfo.sourceBelongId"
placeholder="项目一"
:options="classifyList2"
@change="classificationChange2"
/>
</div> </div>
</div> </div>
<div class="name name2"> <div class="name name2">
@@ -183,11 +138,11 @@
</div> </div>
<div class="in"> <div class="in">
<a-textarea <a-textarea
v-model:value="projectInfo.remark" v-model:value="projectInfo.remark"
style="height: 80px" style="height: 80px"
placeholder="请输入说明" placeholder="请输入说明"
show-count show-count
:maxlength="200" :maxlength="200"
/> />
</div> </div>
</div> </div>
@@ -196,523 +151,157 @@
<div class="inname">同步学习记录</div> <div class="inname">同步学习记录</div>
</div> </div>
<div class="in"> <div class="in">
<a-radio <a-checkbox
@click="changeChecked" v-model:checked="projectInfo.courseSyncFlag"
v-model:checked="projectInfo.courseSyncFlag" ><span
><span
style=" style="
width: 100%; width: 100%;
color: rgba(109, 117, 132, 1); color: rgba(109, 117, 132, 1);
font-size: 14px; font-size: 14px;
" "
>同步课程学习记录如学员在课程库中拥有课程的学习记录自动免修该课程</span >同步课程学习记录如学员在课程库中拥有课程的学习记录自动免修该课程</span
></a-radio ></a-checkbox
> >
</div> </div>
</div> </div>
<div class="name"> <div class="name">
<div class="namebox"> <div class="namebox">
<img <img
class="nameimg" class="nameimg"
src="../../assets/images/basicinfo/asterisk.png" src="../../assets/images/basicinfo/asterisk.png"
/> />
<div class="inname">项目级别</div> <div class="inname">项目级别</div>
</div> </div>
<div class="in select"> <div class="in select">
<a-select <ProjectLevel v-model:value="projectInfo.level"></ProjectLevel>
:getPopupContainer="
(triggerNode) => {
return triggerNode.parentNode || document.body;
}
"
v-model:value="projectInfo.level"
:options="classifyList3"
@change="classificationChange3"
placeholder="集团级/组织级/现地级/部门级"
:disabled="viewDetail ? true : false"
/>
</div> </div>
</div> </div>
<div class="name"> <div class="name">
<div class="namebox"> <div class="namebox">
<img <img
class="nameimg" class="nameimg"
src="../../assets/images/basicinfo/asterisk.png" src="../../assets/images/basicinfo/asterisk.png"
/> />
<div class="inname">培训体系</div> <div class="inname">培训体系</div>
</div> </div>
<div class="in select"> <div class="in select">
<a-select <TrainClass v-model:value="projectInfo.systemId"></TrainClass>
:getPopupContainer="
(triggerNode) => {
return triggerNode.parentNode || document.body;
}
"
v-model:value="projectInfo.systemId"
:options="classifyList4"
@change="classificationChange4"
placeholder="集团级/组织级/现地级/部门级"
:disabled="viewDetail ? true : false"
/>
</div> </div>
</div> </div>
<div class="name"> <div class="name">
<div class="namebox"> <div class="namebox">
<img <img
class="nameimg" class="nameimg"
src="../../assets/images/basicinfo/asterisk.png" src="../../assets/images/basicinfo/asterisk.png"
/> />
<div class="inname">是否BOEU实施</div> <div class="inname">是否BOEU实施</div>
</div> </div>
<div class="in"> <div class="in">
<a-radio <a-radio-group
@click="changeChecked1" v-model:value="projectInfo.boeFlag"
v-model:checked="projectInfo.boeFlag"
:disabled="viewDetail ? true : false"
><span
style="
width: 100%;
color: rgba(109, 117, 132, 1);
font-size: 14px;
"
>BOEU实施</span
></a-radio
> >
<a-radio :value="1"></a-radio>
<a-radio :value="0"></a-radio>
</a-radio-group>
</div> </div>
</div> </div>
<!-- <div class="name name2">
<div class="namebox" style="margin-top: 8px">
<img class="nameimg" src="../../assets/images/basicinfo/asterisk.png" />
<div class="inname">附件</div>
</div>
<div class="filebox">
<div>
<img v-if="fileList1.length < 6" class="fileimg" src="../../assets/images/projectadd/enclosure.png" />
<a-upload :disabled="fileList1.length > 5" :before-upload="beforeUpload1" v-model:file-list="fileList1"
@remove="removeFile" name="file" action="/api/file/upload" :headers="headers" @change="handleChange1">
<span v-if="fileList1.length > 5" class="filetext">上传数量已经达到最大值</span>
<span v-else class="filetext">上传附件</span>
</a-upload>
</div>
<div class="support">
支持.pdf,.ppt,.pptx,.doc,.docx,.xls,.xlsx,.jpg,.jpeg,.png,.gif,.zip
</div>
</div>
</div> -->
</div> </div>
</div> </div>
<div class="footer"> <div class="footer">
<div class="btn"> <div class="btn">
<a-button v-on:click="createProject" type="primary" class="btn1" <a-button v-on:click="createProject" type="primary" class="btn1"
>确定</a-button >确定
</a-button
> >
<a-button @click="backPage" class="btn2">取消</a-button> <a-button @click="backPage" class="btn2">取消</a-button>
</div> </div>
</div> </div>
</div> </div>
</template> </template>
<script> <script setup>
import { reactive, toRefs, ref,onMounted } from "vue";
import { message } from "ant-design-vue"; import {useStore} from "vuex";
import { useRouter, useRoute } from "vue-router"; import {ref, onMounted, watch} from "vue";
// import dayjs from "dayjs"; import {message} from "ant-design-vue";
import {useRouter, useRoute} from "vue-router";
import * as api from "../../api/indexTemplate"; import * as api from "../../api/indexTemplate";
import { storage } from "../../api/storage"; import ProjectClass from "@/components/project/ProjectClass";
// import { toDate } from "../../api/method"; import TrainClass from "@/components/project/TrainClass";
import dayjs from "dayjs"; import OrgClass from "@/components/project/OrgClass";
import ProjectManager from "@/components/project/ProjectManagerNew";
import ProjectLevel from "@/components/project/ProjectLevel";
export default { const route = useRoute();
name: "projectAdd", const router = useRouter();
setup() { const store = useStore();
// 编辑页面跳转过来时候,自动填充表格 const projectInfo = ref({})
const routers = useRoute(); const projectPic = ref([])
const isEdit = ref(false);
// let peojectID = "";
if (routers.query.projectId) { onMounted(() => {
storage.set("projectAddId", routers.query.projectId); getDetail()
isEdit.value = true; projectPic.value = store.state.projectPic.map((e) => ({value: e.dictValue, label: e.dictName}));
// peojectID = routers.query.projectId; })
} else {
if (storage.get("projectAddId")) {
isEdit.value = true;
// peojectID = storage.get("projectAddId");
}
}
const backPage = () => { watch(() => route.query.projectTemplateId, () => {
storage.remove("projectAddId"); getDetail()
setTimeout(() => { })
router.push({
path: "/libraryAdd",
});
}, 400);
};
const router = useRouter(); const getDetail = () => route.query.projectTemplateId && api.templateDetail(route.query.projectTemplateId)
const state = reactive({ .then((res) => {
classifySelect: null, projectInfo.value = res.data.data.projectTemplateInfo;
classifySelectId: null, projectInfo.value.rangeTime = [projectInfo.value.beginTime, projectInfo.value.endTime]
checked: false,
checked1: false,
valueE: null,
valueE1: null,
valueE2: null,
classifySelect1: ['李俊国'],
classifySelect2: [],
classifySelect3: [],
classifySelect4: [],
rangevalue: [],
currentPage: 1, //当前页
tableDataTotal: -1, //模版列表总数
pageSize: 10, //每页10条数据
totalPages: 0, //总页数
viewDetail: routers.query.viewDetail ? routers.query.viewDetail : null,
projectInfo:{
choosedTime:'',
name: null,
manager: null,
notice: null,
sourceBelongId: 1,
category:1,
remark: "",
courseSyncFlag: false,
level: 1,
systemId: 2,
boeFlag: false,
}
});
const projectName = ref("");
const classifyList = ref([
{ value: 1, label: "管理者" },
{ value: 2, label: "领军者" },
{ value: 3, label: "产业人" },
]);
// let projectType = "";
const classificationChange = (value) => {
console.log(`selected ${value}`);
// projectType = value;
};
function getBase64(img, callback) {
const reader = new FileReader();
reader.addEventListener("load", () => callback(reader.result));
reader.readAsDataURL(img);
}
const fileList = ref([]);
const fileList1 = ref([]);
const loading = ref(false);
const imageUrl = ref("");
// let picUrl = "";
const handleChange = (info) => {
if (info.file.status === "uploading") {
loading.value = true;
return;
}
if (info.file.status === "done") {
console.log("上传图片返回的信息 %o", info);
// picUrl = info.file.response.data;
// Get this url from response in real world.
getBase64(info.file.originFileObj, (base64Url) => {
imageUrl.value = base64Url;
loading.value = false;
});
}
if (info.file.status === "error") {
loading.value = false;
message.error("upload error");
}
};
let uplodaFileCount = false;
// let attach = "";
let attachData = "";
const handleChange1 = (info) => {
if (info.file.status === "uploading") {
loading.value = true;
return;
}
if (info.file.status === "done") {
console.log(
"上传附件返回的信息 %o",
info,
info.fileList.length,
uplodaFileCount
);
let attachStr = "";
attachData = info.fileList;
for (let i = 0; i < attachData.length; i++) {
if (attachData.length - 1 == i) {
attachStr += attachData[i].response.data;
} else {
attachStr += attachData[i].response.data + ",";
}
}
console.log(attachStr);
// attach = attachStr;
if (info.fileList.length > 5) {
uplodaFileCount = true;
} else {
uplodaFileCount = false;
}
}
if (info.file.status === "error") {
loading.value = false;
message.error("upload error");
}
};
const beforeUpload = (file) => {
const isJpgOrPng =
file.type === "image/jpeg" || file.type === "image/png";
if (!isJpgOrPng) {
message.error("You can only upload JPG file!");
}
const isLt2M = file.size / 1024 / 1024 < 1;
if (!isLt2M) {
message.error("Image must smaller than 1MB!");
}
return isJpgOrPng && isLt2M;
};
const beforeUpload1 = () => {
return new Promise((resovle, reject) => {
if (uplodaFileCount) {
message.warning("上传文件数量已达最大数量");
return reject(false);
}
return resovle(true);
});
};
const dateFormatList = ["YYYY/MM/DD"];
const onRangeChange = (value, dateString) => {
console.log("Selected Time: ", value);
// 项目时间选择函数
console.log("Formatted Selected Time: ", dateString);
console.log(
"Formatted Selected TimeStamp",
new Date(dateString[0]).getTime()
);
// beginTime = new Date(dateString[0]).getTime() / 1000;
// endTime = new Date(dateString[1]).getTime() / 1000;
};
// 项目经理 后续接口调用
const classifyList1 = ref([
{ value: 1, label: "李俊国" },
{ value: 2, label: "将小米" },
{ value: 3, label: "刘孟君" },
]);
const classificationChange1 = (key, options) => {
console.log(`selected ${key}`, options);
let mstr = "";
let midstr = "";
for (let i = 0; i < key.length; i++) {
if (key.length - 1 !== i) {
midstr += key[i] + ",";
mstr += classifyList1.value[i].label + ",";
} else {
midstr += key[i];
mstr += classifyList1.value[i].label;
}
}
console.log(mstr, midstr);
state.classifySelect1 = options;
let newoptions = [];
for (let i = 0; i < state.classifySelect1.length; i++) {
if (state.classifySelect1[i].value) {
newoptions.push(state.classifySelect1[i]);
}
}
state.classifySelect1 = newoptions;
// manager = mstr;
// managerId = midstr;
};
// 资源归属 sourceBelongId 后续给接口
const classifyList2 = ref([
{ value: 1, label: "项目一" },
{ value: 2, label: "项目二" },
{ value: 3, label: "项目三" },
]);
// let sourceBelongIdC = "";
const classificationChange2 = (key) => {
console.log(`selected ${key}`, classifyList2);
// sourceBelongIdC = key;
};
// 项目级别
const classifyList3 = ref([
{ value: 1, label: "集团级" },
{ value: 2, label: "组织级" },
{ value: 3, label: "现地级" },
{ value: 4, label: "部门级" },
]);
// let levels = "";
const classificationChange3 = (key) => {
console.log(`selected ${key}`, classifyList3);
// levels = key;
};
// 培训体系
const classifyList4 = ref([
{ value: 1, label: "集团级" },
{ value: 2, label: "组织级" },
{ value: 3, label: "现地级" },
{ value: 4, label: "部门级" },
]);
// let systemid = "";
const classificationChange4 = (key) => {
console.log(`selected ${key}`, classifyList4);
// systemid = key;
};
// const removeFile = (file) => {
// const index = fileList1.value.indexOf(file);
// const newFileList = fileList1.value.slice();
// newFileList.splice(index, 1);
// fileList1.value = newFileList;
// let attachStr = "";
// if (newFileList.length == 0) {
// attachStr = "";
// }
// for (let i = 0; i < fileList1["value"].length; i++) {
// console.log(fileList1["value"][i].response.data);
// if (fileList1["value"].length - 1 == i) {
// attachStr += fileList1["value"][i].response.data;
// } else {
// attachStr += fileList1["value"][i].response.data + ",";
// }
// }
// attach = attachStr;
// };
onMounted(() => {
}) })
const errorMsgs = { const backPage = () => {
name: "请输入模板名称", router.back();
category: "请选择模板分类",
picUrl: "请上传项目封面图",
beginTime: "请选择项目开始时间",
endTime: "请选择项目结束时间",
manager: "请选择项目经理",
managerId: "请选择项目经理",
sourceBelongId: "请选择资源归属",
level: "请填写项目级别",
systemId: "请填写项目培训体系",
boeFlag: "请选择是否BOE实施",
};
const createProject = () => {
console.log("我要编辑项目", isEdit.value);
let obj = {
"name": state.projectInfo.name,
"category": state.projectInfo.category,
"picUrl": "x",
"beginTime": Number(dayjs(state.projectInfo.choosedTime[0]).format("YYYY-MM-DD")) || 1,
"endTime": Number(dayjs(state.projectInfo.choosedTime[1]).format("YYYY-MM-DD")) || 1,
"manager": state.classifySelect1.toString(),
"managerId": state.projectInfo.managerId || 0,
"sourceBelongId": state.projectInfo.sourceBelongId,
"level": state.projectInfo.level,
"systemId": state.projectInfo.systemId,
"boeFlag": state.projectInfo.boeFlag ? 1:0,
"courseSyncFlag": state.projectInfo.courseSyncFlag? 1:0,
"notice": "",
"noticeFlag": 0,
"projectTemplateId": localStorage.getItem("projectTemplateId"),
"remark": "",
"status": 0,
};
console.log(obj);
for (let i in errorMsgs) {
console.log(obj[i]);
if (obj[i] === "" || obj[i] === undefined) {
message.destroy();
message.warning(errorMsgs[i]);
return;
}
}
api
.templateEdit(obj)
.then((res) => {
console.log(res);
if (res.status == 200 && res.data.code == 200) {
message.destroy();
message.success("编辑成功");
setTimeout(() => {
router.push({
path: "/projectmanage",
});
}, 1000);
} else {
message.destroy();
message.error("编辑失败,请检查当前网络状态。");
}
})
.catch((err) => {
console.log(err);
message.destroy();
message.error("编辑失败,请检查当前网络状态。");
});
};
return {
...toRefs(state),
projectName,
classifyList,
classificationChange,
classificationChange1,
classificationChange2,
classificationChange3,
classificationChange4,
fileList,
fileList1,
loading,
imageUrl,
handleChange,
handleChange1,
beforeUpload,
beforeUpload1,
onRangeChange,
classifyList1,
classifyList2,
classifyList3,
classifyList4,
uplodaFileCount,
createProject,
// removeFile,
isEdit,
backPage,
dateFormatList,
};
},
}; };
const handleChangeSelect = (value) => {
projectInfo.value.picUrl = value
}
function timeChange(e) {
if (e && e.length === 2) {
projectInfo.value.beginTime = e[0];
projectInfo.value.endTime = e[1];
}
}
const errorMsgs = {
name: "请输入模板名称",
category: "请选择模板分类",
picUrl: "请上传项目封面图",
beginTime: "请选择项目开始时间",
endTime: "请选择项目结束时间",
manager: "请选择项目经理",
managerId: "请选择项目经理",
sourceBelongId: "请选择资源归属",
level: "请填写项目级别",
systemId: "请填写项目培训体系",
boeFlag: "请选择是否BOE实施",
};
const createProject = () => {
for (let i in errorMsgs) {
if (projectInfo.value[i] === "" || projectInfo.value[i] === undefined) {
message.destroy();
message.warning(errorMsgs[i]);
return;
}
}
api.templateEdit({...projectInfo.value, courseSyncFlag: projectInfo.value.courseSyncFlag ? 1 : 0}).then(() => {
message.destroy();
message.success("编辑成功");
router.back()
})
};
function managerChange(e, l, d) {
projectInfo.value.valuesourceBelongId = d
}
</script> </script>
<style lang="scss"> <style lang="scss">
.projectAdd { .projectAdd {
width: 100%; width: 100%;
// height: inherit; // height: inherit;