<template> <div class="trainingPlan"> <h2 class="title">泵站培训计划</h2> <div class="searchBox"> <n-space> <n-select v-model:value="searchValue" filterable :options="options" style="width: 250px" /> </n-space> </div> <div class="content"> <div class="card_box"> <div class="card_list" v-for="(item, index) in cardList" :key="index"> <div class="card"> <h3>{{ item }}</h3> </div> <div class="empty"></div> </div> </div> <div class="quarter"> <div class="beng_details" v-for="(item, index) in quarterList" :key="index" > <div class="month_head"> <span>{{ index + 1 }}月 </span> </div> <div class="beng_body"> <span :class="[ item.plan == '未计划' ? 'unPlan' : item.plan == '已计划' ? 'plan' : 'done', ]" @click="chakanDetails(index)" >{{ item.plan }}</span > </div> </div> </div> </div> <div class="calendar"> <div class="container"> <div class="tabName">{{ searchValue }}{{ tacitly }}月份培训计划表</div> <div class="calendar"> <!-- 星期 --> <div class="week" v-for="(item, index) in dayArr" :key="index"> {{ item }} </div> </div> <!-- 天数 --> <div class="calenBox"> <div v-for="item in dateArr" :key="item" class="sumBox" :class="[ day == item.key ? 'active' : '', presentsum == item.key ? 'present' : '', ]" @click="sumClick(item)" > <div v-if="item.key > 0"> <n-popconfirm trigger="click" :show-icon="false"> <template #trigger> <span class="cKshow">{{ item.key }}</span> </template> <div class="origin" v-if="item.info"> <div class="info"> <div class="infoData"> <span class="each">讲师:{{ item.info.name }}</span> <span class="each">时间:{{ item.info.time }}</span> <span class="each">地点:{{ item.info.site }}</span> </div> </div> </div> <div v-else> <div class="form"> <n-form :label-width="80" :model="addFormValue" :rules="addFormRules" :size="medium" label-placement="left" ref="addFormRef" > <n-form-item label="培训讲师:" path="name"> <n-select v-model:value="queryForm.name" filterable :options="optionsName" style="width: 250px" /> </n-form-item> <n-form-item label="培训地点:" path="adress"> <n-select v-model:value="queryForm.adress" filterable :options="optionsAdress" style="width: 250px" /> </n-form-item> <n-form-item label="培训时间:" path="time"> <n-time-picker v-model:value="queryForm.time" style="width: 250px" /> </n-form-item> <n-form-item label="上传文件:" path=""> <n-upload @change="handleChange" action="https://www.mocky.io/v2/5e4bafc63100007100d8b70f" :default-upload="false" multiple ref="upload" > <n-button>选择文件</n-button> </n-upload> </n-form-item> </n-form> </div> </div> </n-popconfirm> </div> <span class="whether" v-if="item.info"> </span> </div> </div> <div><span class="labelRed"> </span>培训计划</div> </div> </div> </div> </template> <script> import { reactive, ref, toRefs, onMounted } from "vue"; export default { name: "trainingPlan", setup() { const state = reactive({ searchValue: "西渠闸门", options: [ { label: "西渠闸门", value: "荣军泵站" }, { label: "解放大道澳门路闸", value: "解放大道澳门路闸" }, { label: "中山大道前进四路闸", value: "中山大道前进四路闸" }, { label: "王家墩污水泵站", value: "王家墩污水泵站" }, { label: "后湖二期泵站", value: "后湖二期泵站" }, { label: "铁路桥泵站", value: "铁路桥泵站" }, { label: "机场河补水泵站", value: "机场河补水泵站" }, { label: "常青公园地下调蓄池", value: "常青公园地下调蓄池" }, { label: "黄孝河CSO调蓄", value: "黄孝河CSO调蓄" }, { label: "机场河CSO调蓄", value: "机场河CSO调蓄" }, ], cardList: [ "一季度培训计划", "二季度培训计划", "三季度培训计划", "四季度培训计划", ], quarterList: [ { plan: "已计划", }, { plan: "未计划", }, { plan: "已计划", }, { plan: "已计划", }, { plan: "未计划", }, { plan: "已计划", }, { plan: "未计划", }, { plan: "已计划", }, { plan: "未计划", }, { plan: "未计划", }, { plan: "已计划", }, { plan: "未计划", }, ], tacitly: 1, year: "", // 年 month: "", // 月 day: "", // 日 dayArr: ["日", "一", "二", "三", "四", "五", "六"], // 星期数组 dateArr: [], // 当前月份的天数 presentsum: null, // 添加计划相关 showModal: false, // queryForm: { // name: "", // adress: "", // time: "", // }, optionsName: [ { label: "讲师1", value: "0" }, { label: "讲师2", value: "1" }, { label: "讲师3", value: "2" }, { label: "讲师4", value: "3" }, ], optionsAdress: [ { label: "地点1", value: "0" }, { label: "地点2", value: "1" }, { label: "地点3", value: "2" }, { label: "地点4", value: "3" }, ], }); const queryForm = ref({ name: null, adress: null, time: null, }); const chakanDetails = (index) => { state.tacitly = index + 1; getDate(new Date(), index + 1); }; // 日历 const addZero = (date) => { // 月、日个位数 补零 return date.toString().padStart(2, "0"); }; const getDate = (newDate, i) => { state.dateArr = []; console.log(newDate); // 获得当前月份的所有天数 let date = new Date(newDate); state.year = date.getFullYear(); state.month = addZero(date.getMonth() + i); // 补零 state.day = addZero(date.getDate()); // 补零 let firstDay = new Date(state.year, state.month - 1, 1).getDay(); // 每月第一天星期几 let monthNum = new Date(state.year, state.month, -1).getDate() + 1; // 每月天数 for (let i = 1; i < monthNum + 1; i++) { state.dateArr.push(i); // 遍历添加当前月份的每一天 } for (let i = 0; i < firstDay; i++) { state.dateArr.unshift(""); // 根据第一天在数组前填充字符串,确定第一天是星期几 } let dateinfo = []; let task = [ { mark: 1, info: { name: "张三", site: "软件园", time: "13:00", }, }, { mark: 2, info: { name: "李四", site: "软件园C", time: "15:00", }, }, ]; state.dateArr.map((item, i) => { let data = { key: item, index: i, info: "", }; dateinfo.push(data); }); console.log(dateinfo); task.map((e, j) => { dateinfo.map((item, i) => { if (item.key == e.mark) { item.info = e.info; } }); }); state.dateArr = dateinfo; console.log(state.dateArr); }; const sumClick = (item) => { if (item.key) { state.presentsum = item.key; console.log(item); } }; const handleChange = (fileList) => { console.log(fileList); }; onMounted(() => { chakanDetails(0); }); return { ...toRefs(state), queryForm, chakanDetails, getDate, sumClick, handleChange, }; }, }; </script> <style lang="less" scoped> .trainingPlan { height: 100%; .title { padding-left: 20px; width: 100%; line-height: 50px; border-radius: 3px; background: linear-gradient(0deg, #163f7e, #3e79d5); font-size: 18px; font-weight: normal; color: #f4f8fb; } .searchBox { margin: 20px 0; } .content { position: relative; margin-top: 20px; height: 200px; .card_box { display: flex; height: 200px; .card_list { margin: 10px; flex: 1; box-shadow: 0px 1px 7px 0px #c8dcf5; .card { height: 100px; background: var(--color-card); h3 { padding-bottom: 15px; line-height: 50px; font-size: 18px; color: #f4f8fb; text-align: center; font-weight: normal; } } .empty { height: 80px; background: var(--bg-menu); } } } .quarter { position: absolute; top: 80px; left: 0; display: flex; width: 100%; .beng_details { flex: 1; display: flex; flex-direction: column; justify-content: center; align-items: center; .month_head { span { width: 52px; text-align: center; font-size: 16px; font-family: Source Han Sans CN; font-weight: 400; color: #f4f7fa; } } .beng_body { line-height: 100px; // background-color: var(--bg-menu); span { padding: 5px; font-size: 12px; font-family: Microsoft YaHei; color: #ffffff; border-radius: 3px; cursor: pointer; &.done { background: #549bfb; } &.plan { background: #71c38a; } &.unPlan { background: #ffada1; } } } } } } .container { margin: 20px 10px 0; padding: 20px 50px; width: 1000px; background-color: var(--bg-menu); box-shadow: 0px 1px 7px 0px #c8dcf5; .tabName { width: 100%; text-align: center; font-size: 14px; font-family: Microsoft YaHei; font-weight: bold; border-bottom: 1px solid #91a2ae; padding-bottom: 10px; // margin-bottom: 10px; } .calendar { width: 100%; height: 100%; display: flex; flex-wrap: wrap; .week { flex: 1; height: 50px; display: flex; align-items: center; justify-content: center; } } .calenBox { width: 100%; display: flex; flex-wrap: wrap; flex-direction: row; border-top: 1px solid #999; border-left: 1px solid #999; } .labelRed { margin-top: 20px; margin-right: 5px; display: inline-block; width: 10px; height: 10px; background: red; border-radius: 50%; } .sumBox { width: 128px; height: 55px; text-align: center; line-height: 50px; border-right: 1px solid #999; border-bottom: 1px solid #999; cursor: pointer; position: relative; &.present { border-bottom: 3px solid #16a25e; } &.active { background-color: skyblue; color: #fff; } } .whether { position: absolute; left: 10px; bottom: 10px; width: 10px; height: 10px; background: red; border-radius: 50%; } .cKshow { display: block; width: 100%; height: 100%; } } } .origin { .info { width: 159px; // background: #f4f7fa; // box-shadow: 0px 10px 53px 20px rgba(71, 94, 124, 0.24); opacity: 0.86; border-radius: 12px; z-index: 999; .infoData { display: flex; flex-direction: column; padding: 0 22px; .each { padding-top: 16px; } } } } .form { padding: 20px; } </style>