Browse Source

排班系统

qin_v13
hreenshan112 11 months ago
parent
commit
878307e483
  1. 12
      src/api/calendar/Calendar.ts
  2. 50
      src/api/hr/org/index.ts
  3. 109
      src/api/hr/people/index.ts
  4. 38
      src/api/hr/people/type.ts
  5. 327
      src/components/DesignForm/app/calendar/calendar1/monthPage.vue
  6. 103
      src/views/hr/archives/index.vue
  7. 152
      src/views/hr/teams/batchImportTimePeople.vue
  8. 398
      src/views/hr/teams/classTime/addClass.vue
  9. 194
      src/views/hr/teams/classTime/dayInfoPage.vue
  10. 121
      src/views/hr/teams/classTime/dayPage.vue
  11. 366
      src/views/hr/teams/classTime/editClass.vue
  12. 200
      src/views/hr/teams/classTime/monthInfoPage.vue
  13. 156
      src/views/hr/teams/classTime/monthPage.vue
  14. 249
      src/views/hr/teams/classTime/setupShiftRules.vue
  15. 195
      src/views/hr/teams/classTime/weekInfoPage.vue
  16. 119
      src/views/hr/teams/classTime/weekPage.vue
  17. 186
      src/views/hr/teams/classes.vue
  18. 439
      src/views/hr/teams/index.vue
  19. 419
      src/views/hr/teams/scheduling.vue

12
src/api/calendar/Calendar.ts

@ -83,7 +83,7 @@ class Calendar {
const y = date[1] === 1 ? date[0] - 1 : date[0]; const y = date[1] === 1 ? date[0] - 1 : date[0];
const m = date[1] === 1 ? 12 : date[1] - 1; const m = date[1] === 1 ? 12 : date[1] - 1;
let w = DateClass.solarMonth(y, m); let w = DateClass.solarMonth(y, m);
console.log("获取当月前面需补齐的数组-->",y,m,w,last) // console.log("获取当月前面需补齐的数组-->",y,m,w,last)
const arr: dateBase[] = []; const arr: dateBase[] = [];
for (let i = 0; i < last; i++) { for (let i = 0; i < last; i++) {
const lun = DateClass.getLunars(y, m, w - i); const lun = DateClass.getLunars(y, m, w - i);
@ -104,7 +104,7 @@ class Calendar {
animal: DateClass.getAnimal(Number(l[0])), animal: DateClass.getAnimal(Number(l[0])),
astro: DateClass.toAstro(y, m, w - i), astro: DateClass.toAstro(y, m, w - i),
term: getTerm(Number(l[0]), m, w - i), term: getTerm(Number(l[0]), m, w - i),
isWeek: i === 6 || i === 7,
}); });
} }
return arr; return arr;
@ -172,13 +172,13 @@ class Calendar {
const result = this.validateDate(date); const result = this.validateDate(date);
const currentDay = DateClass.solarWeeks(result[0], result[1]); const currentDay = DateClass.solarWeeks(result[0], result[1]);
console.log("获取当月的完整数据",currentDay,result) // console.log("获取当月的完整数据",currentDay,result)
// 获取当月的完整数据 // 获取当月的完整数据
const beforDays = this.beforDays(date, currentDay).reverse(); const beforDays = this.beforDays(date, currentDay).reverse();
const m = this.getDay(date, beforDays); const m = this.getDay(date, beforDays);
console.log("获取当月的完整数据--->",m,date) // console.log("获取当月的完整数据--->",m,date)
const afterDays = this.afterDays(m, date); const afterDays = this.afterDays(m, date);
@ -199,6 +199,7 @@ class Calendar {
gainOneDay(y: number, m: number, d: number){ gainOneDay(y: number, m: number, d: number){
let dateStr = y + "-" + m + "-" + d; // 要转换的日期字符串 let dateStr = y + "-" + m + "-" + d; // 要转换的日期字符串
let now = new Date(dateStr); //当前日期字符串转换成Date对象 let now = new Date(dateStr); //当前日期字符串转换成Date对象
let nowDayOfWeek = now.getDay()==0?7:now.getDay(); //今天本周的第几天
const lun = DateClass.getLunars(y, m, d); const lun = DateClass.getLunars(y, m, d);
const l = lun.split('-'); const l = lun.split('-');
let currentTime = DateClass.getCurrent() let currentTime = DateClass.getCurrent()
@ -218,7 +219,7 @@ class Calendar {
animal: DateClass.getAnimal(Number(l[0])), animal: DateClass.getAnimal(Number(l[0])),
astro: DateClass.toAstro(y, m, d), astro: DateClass.toAstro(y, m, d),
term: getTerm(Number(l[0]), m, d), term: getTerm(Number(l[0]), m, d),
isWeek: nowDayOfWeek === 6 || nowDayOfWeek === 7,
} }
} }
@ -255,6 +256,7 @@ class Calendar {
animal: DateClass.getAnimal(Number(l[0])), animal: DateClass.getAnimal(Number(l[0])),
astro: DateClass.toAstro(y, m, d), astro: DateClass.toAstro(y, m, d),
term: getTerm(Number(l[0]), m, d), term: getTerm(Number(l[0]), m, d),
isWeek: i === 6 || i === 7,
}); });
} }

50
src/api/hr/org/index.ts

@ -202,3 +202,53 @@ export function getTeamListCont(data: searchTeamList): AxiosPromise<orgTeamListC
data: data data: data
}); });
} }
/**
*
*/
export function teamcontlist(data:any){
return request({
url: '/hrapi/org/teamcontlist',
method: 'post',
data: data
});
}
/**
*
*/
export function getteamcont(data:any){
return request({
url: '/hrapi/org/getteamcont',
method: 'post',
data: data
});
}
/**
*
*/
export function addteamcont(data:any){
return request({
url: '/hrapi/org/addteamcont',
method: 'post',
data: data
});
}
/**
*
*/
export function eiteteamcont(data:any){
return request({
url: '/hrapi/org/eiteteamcont',
method: 'post',
data: data
});
}
/**
*
*/
export function eidtdelteamcont(data:any){
return request({
url: '/hrapi/org/eidtdelteamcont',
method: 'post',
data: data
});
}

109
src/api/hr/people/index.ts

@ -719,3 +719,112 @@ export function nineResultToken(data: any){
params: data params: data
}); });
} }
//解析人员信息!并写入数据库
export function analysisRedisTimesExelect(data?: any): AxiosPromise {
return request({
url: '/hrapi/staff/analysisRedisTimesExelect',
method: 'post',
data: data
});
}
//获取工作时间列表
export function teamTimeList(data?: any):AxiosPromise {
return request({
url: '/hrapi/rostering/team_time_list',
method: 'post',
data: data
})
}
//添加工作时间段设定
export function addTeamTime(data?: any):AxiosPromise {
return request({
url: '/hrapi/rostering/add_team_time',
method: 'post',
data: data
})
}
//编辑工作时间段状态
export function editWorkTimeState(data?: any):AxiosPromise {
return request({
url: '/hrapi/rostering/edit_work_time_state',
method: 'post',
data: data
})
}
//编辑工作时间段内容
export function editWorkTimeCont(data?: any):AxiosPromise {
return request({
url: '/hrapi/rostering/edit_work_time_cont',
method: 'post',
data: data
})
}
//获取工作时段及轮询规则列表
export function getPeriodAndRuleList(data?: any):AxiosPromise {
return request({
url: '/hrapi/rostering/get_period_rule_list',
method: 'post',
data: data
})
}
//写入轮询源点
export function setOirginCont(data?: any):AxiosPromise {
return request({
url: '/hrapi/rostering/set_oirgin_cont',
method: 'post',
data: data
})
}
//获取排班表
export function getSchedule(data?: any):AxiosPromise {
return request({
url: '/hrapi/rostering/get_schedule',
method: 'post',
data: data
})
}
/**
*
*/
export function accordRoleGiveOrg(data?: any){
return request({
url: '/systemapi/menus/accordRoleGiveOrg',
method: 'post',
data: data
});
}
/**
*
*/
export function gainShiftRules(data?: any){
return request({
url: '/systemapi/menus/gainShiftRules',
method: 'post',
data: data
});
}
/**
*
*/
export function gainTemsTypeAndRuler(data?: any){
return request({
url: '/systemapi/menus/gainTemsTypeAndRuler',
method: 'post',
data: data
});
}
/**
*
*/
export function analysisMonthRulers(data?: any){
return request({
url: '/systemapi/menus/analysisMonthRulers',
method: 'post',
data: data
});
}

38
src/api/hr/people/type.ts

@ -748,4 +748,40 @@ export interface CertificatesContAdd extends contId{
// 编辑证书信息 // 编辑证书信息
export interface CertificatesContEdit extends CertificatesCont{ export interface CertificatesContEdit extends CertificatesCont{
id?: string id?: string
} }
//班次列表数据结构
export interface TimesClassInfo{
id: string;
list:TimesTimeInfo[];
name: string;
rule: TimeRuleInfo[];
rulename: string;
state:number;
states:boolean;
}
//倒班规则
export interface TimeRuleInfo{
id: string;
sort: number;
teamid: string;
}
//工作时间段
export interface TimesTimeInfo{
id: string;
title: string;
startTime: string;
endTime: string;
}
//工作时间段
export interface workTimeInfo {
title: string;
startTime: string;
endTime: string;
}
//轮询规则
export interface ruleInfo {
id: number;
teamid: string;
}

327
src/components/DesignForm/app/calendar/calendar1/monthPage.vue

@ -3,69 +3,78 @@
@ 时间: 2024-07-13 09:34:05 @ 时间: 2024-07-13 09:34:05
@ 备注: 月日历 @ 备注: 月日历
--> -->
<script lang='ts' setup> <script lang="ts" setup>
import Calendar from '@/api/calendar/Calendar'; import Calendar from "@/api/calendar/Calendar";
import DateClass from '@/api/calendar/DateClass'; import DateClass from "@/api/calendar/DateClass";
import { dateBase } from '@/api/calendar/Calendar'; import { dateBase } from "@/api/calendar/Calendar";
import { clockFactory } from '@/api/calendar/utils'; import { clockFactory } from "@/api/calendar/utils";
import { gainCalendarList } from '@/api/calendar/request'; import { gainCalendarList } from "@/api/calendar/request";
import CalendarItem from './calendarItem.vue';
import CalendarItem from "./calendarItem.vue";
const props = defineProps({ const props = defineProps({
bodyHight:Number, bodyHight: Number,
taDay:{ taDay: {
type:Array, type: Array,
default() { default() {
return [2024,7,13]; return [2024, 7, 13];
}, },
}, },
searchSend:{ searchSend: {
type:Object, type: Object,
default(){ default() {
return {} return {};
} },
}, },
drawerWith:{ drawerWith: {
type:Number, type: Number,
default:0 default: 0,
}, },
viewSetup:{ viewSetup: {
type:Object, type: Object,
default(){ default() {
return {} return {};
} },
} },
});
const TBody = ref<any[]>([]);
const loadMonth = ref(false);
onMounted(() => {
TBody.value = Calendar.table(props.taDay);
searchatMonthList(props.searchSend);
nextTick(() => {
selectedTime.value =
props.taDay[0] +
"-" +
clockFactory(props.taDay[1]) +
"-" +
clockFactory(props.taDay[2]);
});
}); });
const TBody = ref<any[]>([])
const loadMonth = ref(false)
onMounted(()=>{
TBody.value = Calendar.table(props.taDay)
searchatMonthList(props.searchSend)
nextTick(()=>{
selectedTime.value = props.taDay[0] + "-" + clockFactory(props.taDay[1]) + "-" + clockFactory(props.taDay[2])
})
})
watch(()=>props.taDay,(val:any)=>{
TBody.value = Calendar.table(props.taDay)
searchatMonthList(props.searchSend)
},{
deep: true,
})
watch(
() => props.taDay,
(val: any) => {
TBody.value = Calendar.table(props.taDay);
searchatMonthList(props.searchSend);
},
{
deep: true,
}
);
const selectedTime = ref(props.taDay[0] + "-" + clockFactory(props.taDay[1]) + "-" + clockFactory(props.taDay[2])) const selectedTime = ref(
const emit = defineEmits(['getDate']); props.taDay[0] + "-" + clockFactory(props.taDay[1]) + "-" + clockFactory(props.taDay[2])
);
const emit = defineEmits(["getDate"]);
const changeDate = (time: dateBase) => { const changeDate = (time: dateBase) => {
selectedTime.value = time.date; selectedTime.value = time.date;
emit('getDate', time); emit("getDate", time);
} };
// //
const drawingBoardHeight = computed(()=>{ const drawingBoardHeight = computed(() => {
return props.bodyHight + 50 return props.bodyHight + 50;
}) });
// //
const THeader = Calendar.title(); const THeader = Calendar.title();
// //
@ -77,119 +86,113 @@ const THeader = Calendar.title();
@ 时间: 2024-07-16 11:53:35 @ 时间: 2024-07-16 11:53:35
@ 功能: 获取数据 @ 功能: 获取数据
*/ */
const searchatMonthList = (val:any) => { const searchatMonthList = (val: any) => {
loadMonth.value = true loadMonth.value = true;
val.viewClass = { val.viewClass = {
class:"date", class: "date",
sortWord:"", sortWord: "",
sort:1, sort: 1,
startTime:"", startTime: "",
endTime:"", endTime: "",
dayType:"", dayType: "",
mapWord:"" mapWord: "",
} };
console.log("获取每天数据",val) console.log("获取每天数据", val);
let sendInfo = { let sendInfo = {
search:val, search: val,
timeMonthAry:TBody.value, timeMonthAry: TBody.value,
types:1 types: 1,
} };
console.log("获取每天数据条件",sendInfo) console.log("获取每天数据条件", sendInfo);
gainCalendarList(sendInfo) gainCalendarList(sendInfo)
.then(({data})=>{ .then(({ data }) => {
// console.log("",data) // console.log("",data)
TBody.value = data TBody.value = data;
}) })
.finally(()=>{ loadMonth.value = false }) .finally(() => {
} loadMonth.value = false;
});
};
defineExpose({ defineExpose({
searchatMonthList searchatMonthList,
}) });
</script> </script>
<template> <template>
<div class="monthCalendarBox" :style="'height:calc(100vh - '+ drawingBoardHeight +'px)'"> <div
<ul class="t-calendar-header"> class="monthCalendarBox"
<li v-for="(item, index) in THeader" :key="index"> :style="'height:calc(100vh - ' + drawingBoardHeight + 'px)'"
{{ item }} >
</li> <ul class="t-calendar-header">
</ul> <li v-for="(item, index) in THeader" :key="index">
<div v-loading="loadMonth" class="t-calendar-day"> {{ item }}
<template v-if="TBody.length"> </li>
<div </ul>
class="t-calendar-row" <div v-loading="loadMonth" class="t-calendar-day">
v-for="(item, index) in TBody" <template v-if="TBody.length">
:key="index" <div class="t-calendar-row" v-for="(item, index) in TBody" :key="index">
> <div class="t-calendar-col" v-for="(col, colIdx) in item" :key="colIdx">
<div <CalendarItem
class="t-calendar-col" :col="col"
v-for="(col, colIdx) in item" :time="selectedTime"
:key="colIdx" :drawer-with="props.drawerWith"
> :view-setup="props.viewSetup"
<CalendarItem @changeTargetDate="changeDate"
:col="col" ></CalendarItem>
:time="selectedTime" </div>
:drawer-with="props.drawerWith" </div>
:view-setup="props.viewSetup" </template>
@changeTargetDate="changeDate" <template v-else>
></CalendarItem> <div class="no-date">抱歉,暂无数据</div>
</div> </template>
</div> </div>
</template> </div>
<template v-else>
<div class="no-date">抱歉,暂无数据</div>
</template>
</div>
</div>
</template> </template>
<style lang='scss' scoped> <style lang="scss" scoped>
.monthCalendarBox{ .monthCalendarBox {
width: 100%; width: 100%;
margin-top: 10px; margin-top: 10px;
.t-calendar-header { .t-calendar-header {
display: flex; display: flex;
width: 100%; width: 100%;
height: 42px; height: 42px;
padding: 0; padding: 0;
box-sizing: border-box;
li {
display: flex;
align-items: center;
justify-content: center;
flex: 1;
font-size: 0.95rem;
}
}
.t-calendar-day {
display: flex;
flex-direction: column;
width: 100%;
height: calc(100% - 42px);
.t-calendar-row {
width: 100%;
height: 60px;
display: flex;
flex: 1;
border-bottom: 1px solid #ebeef5;
.t-calendar-col {
box-sizing: border-box; box-sizing: border-box;
li { flex: 1;
display: flex; border-left: 1px solid #ebeef5;
align-items: center; padding: 2px;
justify-content: center; font-size: 16px;
flex: 1; transition: all 0.2s;
font-size: 0.95rem; width: calc(100% / 7);
} }
.t-calendar-col:last-child {
border-right: 1px solid #ebeef5;
}
}
.t-calendar-row:first-child {
border-top: 1px solid #ebeef5;
} }
.t-calendar-day { }
display: flex;
flex-direction: column;
width: 100%;
height: calc(100% - 42px);
.t-calendar-row {
width: 100%;
height: 60px;
display: flex;
flex: 1;
border-bottom: 1px solid #ebeef5;
.t-calendar-col{
box-sizing: border-box;
flex: 1;
border-left: 1px solid #ebeef5;
padding: 2px;
font-size: 16px;
transition: all 0.2s;
width: calc(100%/7);
}
.t-calendar-col:last-child {
border-right: 1px solid #ebeef5;
}
}
.t-calendar-row:first-child {
border-top: 1px solid #ebeef5;
}
}
} }
</style> </style>

103
src/views/hr/archives/index.vue

@ -13,6 +13,7 @@ import {
gainUserTemplateInfo, gainUserTemplateInfo,
editUserTemplateInfo, editUserTemplateInfo,
gainTempleateOrgList, gainTempleateOrgList,
teamcontlist,
} from "@/api/hr/org/index"; } from "@/api/hr/org/index";
import { archivesCont, searchCriteriaForPeople } from "@/api/hr/people/type"; import { archivesCont, searchCriteriaForPeople } from "@/api/hr/people/type";
import { emptypeOptions } from "@/api/hr/people/datacont"; import { emptypeOptions } from "@/api/hr/people/datacont";
@ -325,6 +326,7 @@ onMounted(() => {
haveOrgTreeInfo(); haveOrgTreeInfo();
getArchivesPage(); getArchivesPage();
scrollToBottom(); scrollToBottom();
gainTimeList();
}); });
const ruleForm = reactive({ const ruleForm = reactive({
@ -671,6 +673,22 @@ const insetPeopleContStall = () => {
excelUploadStaff.value.clearFiles(); excelUploadStaff.value.clearFiles();
} }
}; };
const tiemList = ref([]);
/**
@ 作者: 秦东
@ 时间: 2025-01-14 10:27:12
@ 功能: 获取班组列表
*/
const gainTimeList = () => {
let searchMap = {
page: 1,
pagesize: 2000,
name: "",
};
teamcontlist(searchMap).then((data) => {
tiemList.value = data.data.list;
});
};
</script> </script>
<template> <template>
<div class="app-container"> <div class="app-container">
@ -699,38 +717,54 @@ const insetPeopleContStall = () => {
</el-card> </el-card>
</el-aside> </el-aside>
<el-main style="padding: 0"> <el-main style="padding: 0">
<div style="padding: 0; margin: 0"> <div style="padding: 20px 0 0 0; margin: 0">
<el-row class="search"> <el-form
<el-col :span="16"> ref="searchOrgFormRef"
<el-form ref="searchOrgFormRef" :model="searchArchiveQuery" :inline="true"> :model="searchArchiveQuery"
<el-form-item label="工号 / 姓名" prop="keywords"> :inline="true"
<el-input style="margin-left: 20px"
v-model="searchArchiveQuery.keywords" >
placeholder="请输入工号 / 姓名" <el-form-item label="工号 / 姓名" prop="keywords">
clearable <el-input
/> v-model="searchArchiveQuery.keywords"
</el-form-item> placeholder="请输入工号 / 姓名"
<el-form-item label="用工关系" prop="number"> clearable
<el-select />
v-model="searchArchiveQuery.emptype" </el-form-item>
multiple <el-form-item label="用工关系" prop="number">
clearable <el-select
collapse-tags v-model="searchArchiveQuery.emptype"
placeholder="用工关系" multiple
style="width: 240px" clearable
> collapse-tags
<el-option placeholder="用工关系"
v-for="item in emptypeOptions" style="width: 240px"
:key="item.id" >
:label="item.name" <el-option
:value="item.id" v-for="item in emptypeOptions"
/> :key="item.id"
</el-select> :label="item.name"
</el-form-item> :value="item.id"
</el-form> />
</el-col> </el-select>
</el-form-item>
<el-col :span="8" style="text-align: right"> <el-form-item label="班组" prop="number">
<el-select
v-model="searchArchiveQuery.teamid"
clearable
collapse-tags
placeholder="员工班组"
style="width: 240px"
>
<el-option
v-for="item in tiemList"
:key="item.id"
:label="item.name"
:value="item.id"
/>
</el-select>
</el-form-item>
<el-form-item label="" prop="number">
<el-button type="primary" @click="getArchivesPage"> <el-button type="primary" @click="getArchivesPage">
<template #icon><i-ep-search /></template> <template #icon><i-ep-search /></template>
搜索 搜索
@ -739,8 +773,9 @@ const insetPeopleContStall = () => {
<template #icon><i-ep-refresh /></template> <template #icon><i-ep-refresh /></template>
重置 重置
</el-button> </el-button>
</el-col> </el-form-item>
</el-row> </el-form>
<el-card shadow="never" style="padding: 0"> <el-card shadow="never" style="padding: 0">
<div style="margin-bottom: 15px"> <div style="margin-bottom: 15px">
<el-space wrap> <el-space wrap>

152
src/views/hr/teams/batchImportTimePeople.vue

@ -0,0 +1,152 @@
<!--
@ 作者: 秦东
@ 时间: 2025-01-14 08:04:30
@ 备注: 批量导入班组人员
-->
<script lang="ts" setup>
import { analysisRedisTimesExelect } from "@/api/hr/people/index";
const props = defineProps({
id: {
type: String,
default: "",
},
isShow: {
type: Boolean,
default: false,
},
});
const excelUpload = ref<any>();
const emits = defineEmits(["update:isShow", "closeOpen"]);
//
const uploadFFurl =
import.meta.env.VITE_APP_BASE_API + "/hrapi/staff/uploadTiemsManFiles";
const excelLoading = ref(false);
const peopleMsg = ref<string[]>([]);
const progressSize = ref(0);
const redisListKey = ref<string>();
const totalNum = ref<number>();
/**
@ 作者: 秦东
@ 时间: 2025-01-14 08:20:49
@ 功能: 上传前先检查文件
*/
function handleExcelChangeTemp(file: UploadFile) {
excelLoading.value = true;
if (!/\.(xlsx|xls|XLSX|XLS)$/.test(file.name)) {
ElMessage.warning("上传Excel只能为xlsx、xls格式");
excelLoading.value = false;
return false;
}
}
/**
@ 作者: 秦东
@ 时间: 2025-01-14 08:22:50
@ 功能: 上传文件错误处理
*/
const uploadError = (response: any, uploadFile: UploadFile, uploadFiles: UploadFiles) => {
excelLoading.value = false;
peopleMsg.value.push(
"响应时间过长,系统自动转为后台静默处理,可先关闭窗口!完成时间大约90分钟。请于90分钟后刷新信息"
);
};
/**
@ 作者: 秦东
@ 时间: 2025-01-14 08:28:35
@ 功能: 监控弹窗状态
*/
watch(
() => props.isShow,
(val: boolean) => {
if (!val) {
peopleMsg.value = [];
excelLoading.value = false;
progressSize.value = 0;
}
},
{ deep: true }
);
let jiBuQiVal = 0;
/**
@ 作者: 秦东
@ 时间: 2025-01-14 08:31:36
@ 功能: 上传成功
*/
const uploadTrue = (response: any, uploadFile: UploadFile, uploadFiles: UploadFiles) => {
// excelLoading.value = false;
console.log("上传完成此次乘车", response);
jiBuQiVal = 0;
progressSize.value = 0;
if (response.code == 0) {
peopleMsg.value.push("文件上传成功!开始解析数据并写入数据库!");
redisListKey.value = response.data.redisListKey;
totalNum.value = response.data.totalNum;
inintTimeDatas();
} else {
peopleMsg.value.push("文件上传失败!请重新上传文件!");
}
};
/**
@ 作者: 秦东
@ 时间: 2025-01-14 10:02:26
@ 功能: 写入数据
*/
const inintTimeDatas = () => {
if (jiBuQiVal < totalNum.value) {
let sendInfo = {
timeId: props.id.toString(),
redisListKey: redisListKey.value,
number: jiBuQiVal,
};
analysisRedisTimesExelect(sendInfo).then((data: any) => {
peopleMsg.value.push(data.data.msgStr);
jiBuQiVal++;
progressSize.value = Math.round((jiBuQiVal / totalNum.value) * 10000) / 100;
inintTimeDatas();
});
} else {
excelLoading.value = false;
progressSize.value = 100;
excelUpload.value.clearFiles();
}
};
</script>
<template>
<el-row>
<el-col
:span="24"
v-loading="excelLoading"
element-loading-text="文档解析中,请稍候..."
>
<el-upload
ref="excelUpload"
class="upload-demo"
drag
:action="uploadFFurl"
:data="{ timeId: props.id.toString() }"
:before-upload="handleExcelChangeTemp"
:on-success="uploadTrue"
:on-error="uploadError"
:show-file-list="false"
multiple
>
<el-icon class="el-icon--upload"><upload-filled /></el-icon>
<div class="el-upload__text">将电子表格拖到此处或 <em>单击上载</em></div>
</el-upload>
</el-col>
<el-col :span="24">
<el-progress :text-inside="true" :stroke-width="20" :percentage="progressSize">
<span>已完成{{ progressSize }}%</span>
</el-progress>
</el-col>
</el-row>
<el-scrollbar height="300px" ref="scrollbarRef" always>
<div ref="innerRef">
<p v-for="(item, index) in peopleMsg" :key="index" class="scrollbar-demo-item">
{{ item }}
</p>
</div>
</el-scrollbar>
</template>
<style lang="scss" scoped></style>

398
src/views/hr/teams/classTime/addClass.vue

@ -0,0 +1,398 @@
<!--
@ 作者: 秦东
@ 时间: 2025-01-14 13:33:45
@ 备注: 添加班组轮询规则
-->
<script lang="ts" setup>
import { workTimeInfo, ruleInfo, TimesClassInfo } from "@/api/hr/people/type";
import { teamcontlist } from "@/api/hr/org/index";
import { addTeamTime } from "@/api/hr/people/index";
const props = defineProps({
open: {
type: Boolean,
default: false,
},
teamInfo: {
type: Object,
default() {
return {};
},
},
});
const tiemList = ref<string[]>([]);
const emits = defineEmits(["update:open", "restdata"]);
const sunmitBut = ref(false);
const formInfo = reactive({
name: "",
});
const worktimeList = ref<workTimeInfo[]>([
{
title: "",
startTime: "",
endTime: "",
},
]);
let countNum = 1;
const ruleList = ref<ruleInfo[]>([
{
teamid: "",
sort: countNum,
},
]);
/**
* 弹窗显示控制
*/
const isShow = computed({
get: () => {
if (props.open) {
getTimeClassList();
}
return props.open;
},
set: (val) => {
emits("update:open", val);
},
});
/**
@ 作者: 秦东
@ 时间: 2025-01-14 13:57:36
@ 功能: 关闭弹窗
*/
const closeDialog = () => {
emits("update:open", false);
countNum = 1;
worktimeList.value = [
{
title: "",
startTime: "",
endTime: "",
},
];
ruleList.value = [
{
teamid: "",
sort: countNum,
},
];
formInfo.name = "";
sunmitBut.value = false;
emits("restdata");
};
/**
@ 作者: 秦东
@ 时间: 2025-01-14 11:34:57
@ 功能: 获取班次列表
*/
const getTimeClassList = () => {
teamcontlist().then((data: any) => {
tiemList.value = data.data.list;
});
};
/**
@ 作者: 秦东
@ 时间: 2025-01-14 15:16:33
@ 功能: 添加工作时间段安排
*/
const addTimeSet = () => {
worktimeList.value.push({
title: "",
startTime: "",
endTime: "",
});
};
/**
@ 作者: 秦东
@ 时间: 2025-01-14 15:34:42
@ 功能: 删除时间片段
*/
const delTimeSet = (val: any) => {
console.log("删除时间片段", val.$index, worktimeList.value.length);
if (worktimeList.value.length > 1) {
worktimeList.value.splice(val.$index, 1);
console.log("删除时间片段", val.$index);
} else {
val.title = "";
val.startTime = "";
val.title = "";
}
};
/**
@ 作者: 秦东
@ 时间: 2025-01-14 16:00:54
@ 功能: 添加轮询规则
*/
const addTimeRuleSet = () => {
countNum++;
ruleList.value.push({
sort: countNum,
teamid: "",
});
};
/**
@ 作者: 秦东
@ 时间: 2025-01-14 16:06:44
@ 功能: 删除轮询规则
*/
const delTimeRuleSet = (val: any) => {
if (ruleList.value.length > 1) {
ruleList.value.splice(val.$index, 1);
} else {
val.sort = 1;
val.titteamidle = "";
}
};
/**
@ 作者: 秦东
@ 时间: 2025-01-14 16:19:51
@ 功能: 提交数据
*/
const addContsubmit = () => {
sunmitBut.value = true;
if (!formInfo.name) {
ElMessage.error("请输入名称");
sunmitBut.value = false;
return false;
} else {
if (formInfo.name == "" || formInfo.name == null) {
ElMessage.error("请输入名称");
sunmitBut.value = false;
return false;
}
}
let workList = new Array();
let ruleAry = new Array();
if (worktimeList.value.length < 1) {
ElMessage.error("请输入工作时间安排!");
sunmitBut.value = false;
return false;
} else {
let isTrue = false;
worktimeList.value.forEach((item: any) => {
if (!item.title) {
isTrue = true;
} else {
if (item.title == "" || item.title == null) {
isTrue = true;
}
}
if (!item.startTime) {
isTrue = true;
} else {
if (item.startTime == "" || item.startTime == null) {
isTrue = true;
}
}
if (!item.endTime) {
isTrue = true;
} else {
if (item.endTime == "" || item.endTime == null) {
isTrue = true;
}
}
workList.push(item);
});
if (isTrue) {
ElMessage.error("请输入工作时间安排!");
sunmitBut.value = false;
return false;
}
}
if (ruleList.value.length < 1) {
ElMessage.error("请输入轮询规则!");
sunmitBut.value = false;
return false;
} else {
let isOk = false;
ruleList.value.forEach((item: any) => {
// if (!item.id) {
// isOk = true;
// } else {
// if (item.id == "" || item.id == null) {
// isOk = true;
// }
// }
if (!item.teamid) {
isOk = true;
} else {
if (item.teamid == "" || item.teamid == null) {
isOk = true;
}
}
ruleAry.push({
sort: item.sort,
teamid: item.teamid.toString(),
});
});
if (isOk) {
ElMessage.error("请输入轮询规则!");
sunmitBut.value = false;
return false;
}
}
var sendData = {
name: formInfo.name,
rule: ruleAry,
list: workList,
};
console.log("上传规则", sendData);
addTeamTime(sendData)
.then((data) => {
console.log("上传规则-------<", data);
if (data.code == 0) {
ElMessageBox.confirm("新增成功!是否继续添加?", "提示", {
confirmButtonText: "确定",
cancelButtonText: "取消",
type: "warning",
})
.then(() => {
countNum = 1;
worktimeList.value = [
{
title: "",
startTime: "",
endTime: "",
},
];
ruleList.value = [
{
teamid: "",
sort: countNum,
},
];
formInfo.name = "";
sunmitBut.value = false;
})
.catch(() => {
closeDialog();
});
} else {
ElMessage.error(data.msg || "添加失败!");
closeDialog();
}
})
.finally(() => {
sunmitBut.value = false;
});
};
</script>
<template>
<el-dialog
v-model="isShow"
width="60%"
title="添加班组轮询规则"
append-to-body
:before-close="closeDialog"
>
<el-form ref="addForm" :model="formInfo" label-width="120px" class="demo-ruleForm">
<el-form-item label="名称" prop="name">
<el-input v-model="formInfo.name" placeholder="请输入名称"></el-input>
</el-form-item>
<el-form-item label="工作时间段安排" prop="rule">
<el-table :data="worktimeList" border style="width: 100%">
<el-table-column align="center" prop="title" label="时段名称" width="180">
<template #default="scope">
<el-input v-model="scope.row.title" placeholder="请输入时段名称"></el-input>
</template>
</el-table-column>
<el-table-column align="center" label="开始与结束时间">
<template #default="scope">
<el-time-select
style="width: 120px"
placeholder="起始时间"
v-model="scope.row.startTime"
start="00:00"
step="00:01"
end="23:59"
>
</el-time-select>
<el-time-select
style="width: 120px"
placeholder="结束时间"
v-model="scope.row.endTime"
:min-time="scope.row.startTime"
start="00:00"
step="00:01"
end="23:59"
>
</el-time-select>
</template>
</el-table-column>
<el-table-column align="center" width="100">
<template #header>
<el-button type="primary" size="small" @click="addTimeSet()"
><i class="fa fa-plus iconLeft"></i> 新增</el-button
>
</template>
<template #default="scope">
<el-button
v-if="worktimeList.length > 1"
type="danger"
size="small"
@click="delTimeSet(scope)"
><i class="fa fa-trash-o iconLeft"></i>删除</el-button
>
</template>
</el-table-column>
</el-table>
</el-form-item>
<el-form-item label="轮询规则" prop="rule">
<el-table :data="ruleList" border style="width: 100%">
<el-table-column align="center" prop="sort" label="排序" width="180">
<template #default="scope">
<el-input
v-model="scope.row.sort"
placeholder="请输入序号"
disabled
></el-input>
</template>
</el-table-column>
<el-table-column align="center" prop="name" label="班组">
<template #default="scope">
<el-select v-model="scope.row.teamid" clearable placeholder="请选择">
<el-option
v-for="item in tiemList"
:key="item.id"
:label="item.name"
:value="item.id"
>
</el-option>
</el-select>
</template>
</el-table-column>
<el-table-column align="center" width="100">
<template #header>
<el-button type="primary" size="small" @click="addTimeRuleSet()"
><i class="fa fa-plus iconLeft"></i> 新增</el-button
>
</template>
<template #default="scope">
<el-button
v-if="ruleList.length > 1"
type="danger"
size="small"
@click="delTimeRuleSet(scope)"
><i class="fa fa-trash-o iconLeft"></i>删除</el-button
>
</template>
</el-table-column>
</el-table>
</el-form-item>
</el-form>
<template #footer class="el_dialog__footer">
<div class="dialog-footer">
<el-button size="small" type="primary" @click="addContsubmit" :loading="sunmitBut"
> </el-button
>
<el-button size="small" @click="closeDialog"> </el-button>
</div>
</template>
</el-dialog>
</template>
<style lang="scss" scoped>
.iconLeft {
margin-right: 10px;
}
</style>

194
src/views/hr/teams/classTime/dayInfoPage.vue

@ -0,0 +1,194 @@
<!--
@ 作者: 秦东
@ 时间: 2025-01-16 14:39:18
@ 备注: 周内容
-->
<script lang="ts" setup>
import { PropType } from "vue";
import DateClass from "@/api/calendar/DateClass";
import { dateBase } from "@/api/calendar/Calendar";
import FormPageCont from "@/components/DesignForm/tableListPage/formPageCont.vue";
const props = defineProps({
col: {
type: Object as PropType<dateBase>,
default: () => {
return {};
},
},
time: {
type: String,
default: "",
},
});
const isCurrentMonth = (time: string) => {
console.log("分割时间", time);
const months = time.split("-")[1];
return DateClass.getCurrent()[1] === Number(months);
};
const emit = defineEmits(["changeTargetDate"]);
const changeTargetDate = (time: dateBase) => {
emit("changeTargetDate", time);
};
/**
@ 作者: 秦东
@ 时间: 2024-07-16 10:32:41
@ 功能: 搜索数据
*/
const searchtData = (val: any, time?: any) => {
return time;
};
</script>
<template>
<div
class="calendar-item-container"
:class="[
{
'is-current': col.isCurrent,
'is-holidays': col.isHolidays,
'is-week': col.isWeek,
'is-selected': col.date === props.time,
'is-current-month': isCurrentMonth(col.date),
},
]"
@click="changeTargetDate(col)"
>
<div class="dayStyle">
<span>{{ col.title }}</span>
<div v-if="col.isHolidays"></div>
<span>{{ col.lunarsChina }}</span>
</div>
</div>
</template>
<style lang="scss" scoped></style>
<style scoped lang="less">
.calendar-item-container {
width: 100%;
height: 100%;
flex-direction: column;
box-sizing: border-box;
border-radius: 6px;
border: 2px solid #ffffff;
.dayList {
height: calc(100% - 20px);
overflow-y: auto;
}
.dayLogCont {
white-space: nowrap; /* 确保文本在一行内显示 */
overflow: hidden; /* 隐藏溢出的内容 */
text-overflow: ellipsis; /* 使用省略号表示文本溢出 */
font-size: 0.95rem;
border: 1px solid #bcbcbc;
border-radius: 5px;
margin-bottom: 5px;
padding: 0 5px;
}
.dayStyle {
display: flex;
// align-items: top;
justify-content: space-between;
font-size: 12px;
color: #999999;
}
.calendar-title {
font-size: 1.2rem;
color: #999999;
}
.calendar-lunar {
margin-top: 6px;
font-size: 0.85rem;
color: #bcbcbc;
}
transition: all 0.2s;
}
.calendar-item-container:hover {
cursor: pointer;
border: 2px solid #409eff;
}
.is-holidays {
.holidays-text {
position: absolute;
top: 6px;
left: 14px;
font-size: 0.85rem;
color: #ffa2a2;
}
.calendar-title {
color: #ffa2a2;
}
.dayStyle {
color: #ffa2a2;
}
background-color: #feeeef;
}
.is-selected {
border: 2px solid #409eff;
}
.is-holidays.is-selected {
border: 2px solid #ffa2a2;
}
.is-selected.is-current-month {
border: 2px solid #409eff;
}
.is-holidays.is-selected.is-current-month {
border: 2px solid #f62b2b;
}
.is-week {
.calendar-title {
color: #ffa2a2;
}
.dayStyle {
color: #ffa2a2;
}
}
.calendar-item-container.is-current {
.calendar-title {
color: #333333;
}
.dayStyle {
color: #333333;
}
.calendar-lunar {
color: #666666;
}
}
.calendar-item-container.is-current.is-holidays {
.holidays-text {
position: absolute;
top: 6px;
left: 14px;
font-size: 0.85rem;
color: #f62b2b;
}
background-color: #fbe3e4;
}
.calendar-item-container.is-current.is-holidays,
.calendar-item-container.is-current.is-week {
.calendar-title {
color: #f62b2b;
}
.dayStyle {
color: #f62b2b;
}
}
.calendar-item-container.is-current.is-holidays {
.holidays-text {
position: absolute;
top: 6px;
left: 14px;
font-size: 0.85rem;
color: #fb4949;
}
.calendar-title {
color: #fb6e6e;
}
.dayStyle {
color: #fb6e6e;
}
background-color: #ffe4e7;
}
.calendar-item-container.is-holidays:hover {
border: 2px solid #f62b2b;
}
</style>

121
src/views/hr/teams/classTime/dayPage.vue

@ -0,0 +1,121 @@
<!--
@ 作者: 秦东
@ 时间: 2025-01-16 14:08:44
@ 备注: 日历天
-->
<script lang="ts" setup>
import Calendar from "@/api/calendar/Calendar";
import DateClass from "@/api/calendar/DateClass";
import { dateBase } from "@/api/calendar/Calendar";
import { clockFactory } from "@/api/calendar/utils";
import { gainCalendarList } from "@/api/calendar/request";
import DayInfoPage from "@/views/hr/teams/classTime/dayInfoPage.vue";
const props = defineProps({
taDay: {
type: Array,
default() {
return [2024, 7, 13];
},
},
});
const curttWeek = computed(() => {
// console.log("---------->",props.taDay[0])
return DateClass.getWeek(
DateClass.solarWeek(props.taDay[0], props.taDay[1], props.taDay[2])
);
});
const dayInfo = ref<any>();
const selectedTime = ref(
props.taDay[0] + "-" + clockFactory(props.taDay[1]) + "-" + clockFactory(props.taDay[2])
);
onMounted(() => {
dayInfo.value = Calendar.gainOneDay(props.taDay[0], props.taDay[1], props.taDay[2]);
// console.log("",dayInfo.value,props.searchSend)
nextTick(() => {
let ddTime = DateClass.getCurrent();
selectedTime.value =
ddTime[0] + "-" + clockFactory(ddTime[1]) + "-" + clockFactory(ddTime[2]);
});
});
watch(
() => props.taDay,
(val: any) => {
dayInfo.value = Calendar.gainOneDay(val[0], val[1], val[2]);
// console.log("",dayInfo.value)
},
{
deep: true,
}
);
const emit = defineEmits(["getDate"]);
const changeDate = (time: dateBase) => {
selectedTime.value = time.date;
emit("getDate", time);
};
const loadDay = ref(false);
</script>
<template>
<div
class="monthCalendarBox"
:style="'height:calc(100vh - ' + drawingBoardHeight + 'px)'"
>
<ul class="t-calendar-header">
<li>
{{ curttWeek }}
</li>
</ul>
<div class="t-calendar-day" v-loading="loadDay">
<template v-if="dayInfo">
<div class="t-calendar-row">
<DayInfoPage
:col="dayInfo"
:time="selectedTime"
@changeTargetDate="changeDate"
></DayInfoPage>
</div>
</template>
<template v-else>
<div class="no-date">抱歉,暂无数据</div>
</template>
</div>
</div>
</template>
<style lang="scss" scoped>
.monthCalendarBox {
width: 100%;
margin-top: 10px;
height: calc(100vh - 340px);
.t-calendar-header {
display: flex;
width: 100%;
height: 42px;
padding: 0;
box-sizing: border-box;
li {
display: flex;
align-items: center;
justify-content: center;
flex: 1;
font-size: 0.95rem;
}
}
.t-calendar-day {
display: flex;
width: 100%;
height: calc(100% - 42px);
padding: 0;
box-sizing: border-box;
border-right: 1px solid #ebeef5;
.t-calendar-row {
width: 100%;
font-size: 0.95rem;
border-bottom: 1px solid #ebeef5;
border-top: 1px solid #ebeef5;
border-left: 1px solid #ebeef5;
}
}
}
</style>

366
src/views/hr/teams/classTime/editClass.vue

@ -0,0 +1,366 @@
<!--
@ 作者: 秦东
@ 时间: 2025-01-15 09:20:43
@ 备注: 编辑班组轮询规则
-->
<script lang="ts" setup>
import { teamcontlist } from "@/api/hr/org/index";
import { editWorkTimeCont } from "@/api/hr/people/index";
const props = defineProps({
open: {
type: Boolean,
default: false,
},
teamInfo: {
type: Object,
default() {
return {};
},
},
});
const emits = defineEmits(["update:open", "restdata"]);
const tiemList = ref<string[]>([]);
const editBut = ref(false);
const editFormInfo = reactive({
id: props.teamInfo.id,
name: props.teamInfo.name,
});
let countEditNum = 1;
const editWorktimeList = ref<workTimeInfo[]>([]);
const editRuleList = ref<ruleInfo[]>([]);
/**
* 弹窗显示控制
*/
const isOpen = computed({
get: () => {
if (props.open) {
editFormInfo.id = props.teamInfo.id.toString();
editFormInfo.name = props.teamInfo.name;
editWorktimeList.value = props.teamInfo.list;
editRuleList.value = props.teamInfo.rule;
countEditNum = props.teamInfo.rule.length;
getTimeClassList();
}
return props.open;
},
set: (val) => {
emits("update:open", val);
},
});
/**
@ 作者: 秦东
@ 时间: 2025-01-14 11:34:57
@ 功能: 获取班次列表
*/
const getTimeClassList = () => {
teamcontlist().then((data: any) => {
if (data.data.list && data.data.list.length > 0) {
data.data.list.forEach((item: any) => {
tiemList.value.push({
id: item.id.toString(),
name: item.name,
state: item.state,
status: item.status,
time: item.time,
});
});
}
// tiemList.value = data.data.list;
console.log("props.teamInfo", tiemList.value);
});
};
/**
@ 作者: 秦东
@ 时间: 2025-01-15 13:01:03
@ 功能: 关闭修改轮询
*/
const closeEditDialog = () => {
editFormInfo.id = "";
editFormInfo.name = "";
editWorktimeList.value = [];
editRuleList.value = [];
emits("update:open", false);
};
/**
@ 作者: 秦东
@ 时间: 2025-01-14 15:16:33
@ 功能: 添加工作时间段安排
*/
const addTimeSet = () => {
editWorktimeList.value.push({
title: "",
startTime: "",
endTime: "",
});
};
/**
@ 作者: 秦东
@ 时间: 2025-01-14 15:34:42
@ 功能: 删除时间片段
*/
const delTimeSet = (val: any) => {
console.log("删除时间片段", val.$index, editWorktimeList.value.length);
if (editWorktimeList.value.length > 1) {
editWorktimeList.value.splice(val.$index, 1);
console.log("删除时间片段", val.$index);
} else {
val.title = "";
val.startTime = "";
val.title = "";
}
};
/**
@ 作者: 秦东
@ 时间: 2025-01-14 16:00:54
@ 功能: 添加轮询规则
*/
const addTimeRuleSet = () => {
countEditNum++;
editRuleList.value.push({
id: "",
sort: countEditNum,
teamid: "",
});
};
/**
@ 作者: 秦东
@ 时间: 2025-01-14 16:06:44
@ 功能: 删除轮询规则
*/
const delTimeRuleSet = (val: any) => {
if (editRuleList.value.length > 1) {
editRuleList.value.splice(val.$index, 1);
} else {
val.sort = 1;
val.titteamidle = "";
}
};
/**
@ 作者: 秦东
@ 时间: 2025-01-15 13:13:43
@ 功能: 提交编辑轮询规则
*/
const editContsubmit = () => {
editBut.value = true;
if (!editFormInfo.name) {
ElMessage.error("请输入名称");
editBut.value = false;
return false;
} else {
if (editFormInfo.name == "" || editFormInfo.name == null) {
ElMessage.error("请输入名称");
editBut.value = false;
return false;
}
}
let workList = new Array();
let ruleAry = new Array();
if (editWorktimeList.value.length < 1) {
ElMessage.error("请输入工作时间安排!");
editBut.value = false;
return false;
} else {
let isTrue = false;
editWorktimeList.value.forEach((item: any) => {
if (!item.title) {
isTrue = true;
} else {
if (item.title == "" || item.title == null) {
isTrue = true;
}
}
if (!item.startTime) {
isTrue = true;
} else {
if (item.startTime == "" || item.startTime == null) {
isTrue = true;
}
}
if (!item.endTime) {
isTrue = true;
} else {
if (item.endTime == "" || item.endTime == null) {
isTrue = true;
}
}
workList.push(item);
});
if (isTrue) {
ElMessage.error("请输入工作时间安排!");
editBut.value = false;
return false;
}
}
if (editRuleList.value.length < 1) {
ElMessage.error("请输入轮询规则!");
editBut.value = false;
return false;
} else {
let isEditOk = false;
editRuleList.value.forEach((item: any) => {
// console.log("====3===>", item.teamid);
if (!item.teamid) {
isEditOk = true;
// console.log("====2===>", item.teamid);
} else {
// console.log("====1===>", item.teamid == "");
if (item.teamid == "" || item.teamid == null) {
isEditOk = true;
}
}
ruleAry.push({
id: item.id.toString(),
sort: item.sort,
teamid: item.teamid.toString(),
});
});
// console.log("", isEditOk);
if (isEditOk) {
ElMessage.error("请输入轮询规则!");
editBut.value = false;
return false;
}
}
var sendData = {
id: editFormInfo.id,
name: editFormInfo.name,
rule: ruleAry,
list: workList,
};
console.log("上传规则", sendData);
editBut.value = false;
editWorkTimeCont(sendData)
.then((data) => {
ElMessage.success(data.msg);
closeEditDialog();
})
.finally(() => {
editBut.value = false;
});
};
</script>
<template>
<el-dialog
v-model="isOpen"
width="60%"
title="添加班组轮询规则"
append-to-body
:before-close="closeEditDialog"
>
<el-form
ref="addForm"
:model="editFormInfo"
label-width="120px"
class="demo-ruleForm"
>
<el-form-item label="名称" prop="name">
<el-input v-model="editFormInfo.name" placeholder="请输入名称"></el-input>
</el-form-item>
<el-form-item label="工作时间段安排" prop="rule">
<el-table :data="editWorktimeList" border style="width: 100%">
<el-table-column align="center" prop="title" label="时段名称" width="180">
<template #default="scope">
<el-input v-model="scope.row.title" placeholder="请输入时段名称"></el-input>
</template>
</el-table-column>
<el-table-column align="center" label="开始与结束时间">
<template #default="scope">
<el-time-select
style="width: 120px"
placeholder="起始时间"
v-model="scope.row.startTime"
start="00:00"
step="00:01"
end="23:59"
>
</el-time-select>
<el-time-select
style="width: 120px"
placeholder="结束时间"
v-model="scope.row.endTime"
:min-time="scope.row.startTime"
start="00:00"
step="00:01"
end="23:59"
>
</el-time-select>
</template>
</el-table-column>
<el-table-column align="center" width="100">
<template #header>
<el-button type="primary" size="small" @click="addTimeSet()"
><i class="fa fa-plus iconLeft"></i> 新增</el-button
>
</template>
<template #default="scope">
<el-button
v-if="editWorktimeList.length > 1"
type="danger"
size="small"
@click="delTimeSet(scope)"
><i class="fa fa-trash-o iconLeft"></i>删除</el-button
>
</template>
</el-table-column>
</el-table>
</el-form-item>
<el-form-item label="轮询规则" prop="rule">
<el-table :data="editRuleList" border style="width: 100%">
<el-table-column align="center" prop="sort" label="排序" width="180">
<template #default="scope">
<el-input
v-model="scope.row.sort"
placeholder="请输入序号"
disabled
></el-input>
</template>
</el-table-column>
<el-table-column align="center" prop="name" label="班组">
<template #default="scope">
<el-select v-model="scope.row.teamid" clearable placeholder="请选择">
<el-option
v-for="item in tiemList"
:key="item.id"
:label="item.name"
:value="item.id"
>
</el-option>
</el-select>
</template>
</el-table-column>
<el-table-column align="center" width="100">
<template #header>
<el-button type="primary" size="small" @click="addTimeRuleSet()"
><i class="fa fa-plus iconLeft"></i> 新增</el-button
>
</template>
<template #default="scope">
<el-button
v-if="editRuleList.length > 1"
type="danger"
size="small"
@click="delTimeRuleSet(scope)"
><i class="fa fa-trash-o iconLeft"></i>删除</el-button
>
</template>
</el-table-column>
</el-table>
</el-form-item>
</el-form>
<template #footer class="el_dialog__footer">
<div class="dialog-footer">
<el-button size="small" type="primary" @click="editContsubmit" :loading="editBut"
> </el-button
>
<el-button size="small" @click="closeEditDialog"> </el-button>
</div>
</template>
</el-dialog>
</template>
<style lang="scss" scoped></style>

200
src/views/hr/teams/classTime/monthInfoPage.vue

@ -0,0 +1,200 @@
<!--
@ 作者: 秦东
@ 时间: 2025-01-16 14:18:28
@ 备注: 日历详情
-->
<script lang="ts" setup>
import { PropType } from "vue";
import DateClass from "@/api/calendar/DateClass";
import { dateBase } from "@/api/calendar/Calendar";
import FormPageCont from "@/components/DesignForm/tableListPage/formPageCont.vue";
const props = defineProps({
col: {
type: Object as PropType<dateBase>,
default: () => {
return {};
},
},
time: {
type: String,
default: "",
},
});
const isCurrentMonth = (time: string) => {
// console.log("",time)
const months = time.split("-")[1];
return DateClass.getCurrent()[1] === Number(months);
};
const emit = defineEmits(["changeTargetDate"]);
const changeTargetDate = (time: dateBase) => {
emit("changeTargetDate", time);
};
/**
@ 作者: 秦东
@ 时间: 2024-07-16 10:32:41
@ 功能: 搜索数据
*/
const searchtData = (val: any, time?: any) => {
return time;
};
</script>
<template>
<div
class="calendar-item-container"
:class="[
{
'is-current': col.isCurrent,
'is-holidays': col.isHolidays,
'is-week': col.isWeek,
'is-selected': col.date === props.time,
'is-current-month': isCurrentMonth(col.date),
},
]"
@click="changeTargetDate(col)"
>
<div class="dayStyle">
<span>{{ col.title }}</span>
<div v-if="col.isHolidays"></div>
<span>{{ col.lunarsChina }}</span>
</div>
<div class="dayList">
<div v-if="false" class="dayLogCont" @click="lookPageInfo">白班</div>
<div v-if="col.list != bull" v-for="itemCol in col.list" @click="lookPageInfo">
{{ itemCol.rankName }}---{{ itemCol.rulesName }}
</div>
</div>
</div>
</template>
<style lang="scss" scoped></style>
<style scoped lang="less">
.calendar-item-container {
width: 100%;
height: 100%;
flex-direction: column;
box-sizing: border-box;
border-radius: 6px;
border: 2px solid #ffffff;
.dayList {
height: calc(100% - 20px);
overflow-y: auto;
}
.dayLogCont {
white-space: nowrap; /* 确保文本在一行内显示 */
overflow: hidden; /* 隐藏溢出的内容 */
text-overflow: ellipsis; /* 使用省略号表示文本溢出 */
font-size: 0.95rem;
border: 1px solid #bcbcbc;
border-radius: 5px;
margin-bottom: 5px;
padding: 0 5px;
}
.dayStyle {
display: flex;
// align-items: top;
justify-content: space-between;
font-size: 12px;
color: #999999;
}
.calendar-title {
font-size: 1.2rem;
color: #999999;
}
.calendar-lunar {
margin-top: 6px;
font-size: 0.85rem;
color: #bcbcbc;
}
transition: all 0.2s;
}
.calendar-item-container:hover {
cursor: pointer;
border: 2px solid #409eff;
}
.is-holidays {
.holidays-text {
position: absolute;
top: 6px;
left: 14px;
font-size: 0.85rem;
color: #ffa2a2;
}
.calendar-title {
color: #ffa2a2;
}
.dayStyle {
color: #ffa2a2;
}
background-color: #feeeef;
}
.is-selected {
border: 2px solid #409eff;
}
.is-holidays.is-selected {
border: 2px solid #ffa2a2;
}
.is-selected.is-current-month {
border: 2px solid #409eff;
}
.is-holidays.is-selected.is-current-month {
border: 2px solid #f62b2b;
}
.is-week {
.calendar-title {
color: #ffa2a2;
}
.dayStyle {
color: #ffa2a2;
}
}
.calendar-item-container.is-current {
.calendar-title {
color: #333333;
}
.dayStyle {
color: #333333;
}
.calendar-lunar {
color: #666666;
}
}
.calendar-item-container.is-current.is-holidays {
.holidays-text {
position: absolute;
top: 6px;
left: 14px;
font-size: 0.85rem;
color: #f62b2b;
}
background-color: #fbe3e4;
}
.calendar-item-container.is-current.is-holidays,
.calendar-item-container.is-current.is-week {
.calendar-title {
color: #f62b2b;
}
.dayStyle {
color: #f62b2b;
}
}
.calendar-item-container.is-current.is-holidays {
.holidays-text {
position: absolute;
top: 6px;
left: 14px;
font-size: 0.85rem;
color: #fb4949;
}
.calendar-title {
color: #fb6e6e;
}
.dayStyle {
color: #fb6e6e;
}
background-color: #ffe4e7;
}
.calendar-item-container.is-holidays:hover {
border: 2px solid #f62b2b;
}
</style>

156
src/views/hr/teams/classTime/monthPage.vue

@ -0,0 +1,156 @@
<!--
@ 作者: 秦东
@ 时间: 2025-01-16 14:06:22
@ 备注: 日历月
-->
<script lang="ts" setup>
import Calendar from "@/api/calendar/Calendar";
import DateClass from "@/api/calendar/DateClass";
import { dateBase } from "@/api/calendar/Calendar";
import { clockFactory } from "@/api/calendar/utils";
import { gainCalendarList } from "@/api/calendar/request";
import { analysisMonthRulers } from "@/api/hr/people/index";
import MonthInfoPage from "@/views/hr/teams/classTime/monthInfoPage.vue";
const props = defineProps({
taDay: {
type: Array,
default() {
return [2024, 7, 13];
},
},
orgId: {
type: Number,
default: 0,
},
});
const TBody = ref<any[]>([]);
const loadMonth = ref(false);
const selectedTime = ref(
props.taDay[0] + "-" + clockFactory(props.taDay[1]) + "-" + clockFactory(props.taDay[2])
);
//
const analyban = () => {
let sendData = {
orgId: props.orgId.toString() != "0" ? props.orgId.toString() : "103",
monthAllDay: TBody.value,
};
console.log("获取每天数据条件", sendData);
analysisMonthRulers(sendData).then((data: any) => {
console.log("获取排班", data);
TBody.value = data.data;
});
};
onMounted(() => {
TBody.value = Calendar.table(props.taDay);
console.log("初始加载", TBody.value);
analyban();
nextTick(() => {
selectedTime.value =
props.taDay[0] +
"-" +
clockFactory(props.taDay[1]) +
"-" +
clockFactory(props.taDay[2]);
});
});
watch(
() => props.taDay,
(val: any) => {
TBody.value = Calendar.table(props.taDay);
// analyban();
console.log("初始加载----》", TBody.value);
},
{
deep: true,
}
);
const emit = defineEmits(["getDate"]);
const changeDate = (time: dateBase) => {
selectedTime.value = time.date;
emit("getDate", time);
};
//
const THeader = Calendar.title();
</script>
<template>
<div
class="monthCalendarBox"
:style="'height:calc(100vh - ' + drawingBoardHeight + 'px)'"
>
<ul class="t-calendar-header">
<li v-for="(item, index) in THeader" :key="index">
{{ item }}
</li>
</ul>
<div v-loading="loadMonth" class="t-calendar-day">
<template v-if="TBody.length">
<div class="t-calendar-row" v-for="(item, index) in TBody" :key="index">
<div class="t-calendar-col" v-for="(col, colIdx) in item" :key="colIdx">
<MonthInfoPage
:col="col"
:time="selectedTime"
@changeTargetDate="changeDate"
></MonthInfoPage>
</div>
</div>
</template>
<template v-else>
<div class="no-date">抱歉,暂无数据</div>
</template>
</div>
</div>
</template>
<style lang="scss" scoped>
.monthCalendarBox {
width: 100%;
margin-top: 10px;
height: calc(100vh - 340px);
.t-calendar-header {
display: flex;
width: 100%;
height: 42px;
padding: 0;
box-sizing: border-box;
li {
display: flex;
align-items: center;
justify-content: center;
flex: 1;
font-size: 0.95rem;
}
}
.t-calendar-day {
display: flex;
flex-direction: column;
width: 100%;
height: calc(100% - 42px);
.t-calendar-row {
width: 100%;
height: 60px;
display: flex;
flex: 1;
border-bottom: 1px solid #ebeef5;
.t-calendar-col {
box-sizing: border-box;
flex: 1;
border-left: 1px solid #ebeef5;
padding: 2px;
font-size: 16px;
transition: all 0.2s;
width: calc(100% / 7);
}
.t-calendar-col:last-child {
border-right: 1px solid #ebeef5;
}
}
.t-calendar-row:first-child {
border-top: 1px solid #ebeef5;
}
}
}
</style>

249
src/views/hr/teams/classTime/setupShiftRules.vue

@ -0,0 +1,249 @@
<!--
@ 作者: 秦东
@ 时间: 2025-01-16 15:26:29
@ 备注: 行政组织绑定倒班规则及设置源点
-->
<script lang="ts" setup>
import { gainTemsTypeAndRuler, setOirginCont } from "@/api/hr/people/index";
const props = defineProps({
open: {
type: Boolean,
default: false,
},
orgId: {
type: Number,
default: 0,
},
orgName: {
type: String,
default: "",
},
rulerInfo: {
type: Object,
default() {
return {};
},
},
});
const emits = defineEmits(["update:open", "updateShiftRules"]);
const loadRules = ref(false);
const rulesInfo = ref({
id: props.rulerInfo.id.toString(),
starttime: props.rulerInfo.begainTime,
setIsm: props.rulerInfo.typeIdStr,
shifttime: props.rulerInfo.periodid.toString(),
rule: props.rulerInfo.rules.toString(),
orgId: props.orgId.toString(),
});
const workTimeRules = ref<any>([]);
const timeSelect = ref<any>([]);
const rulesSelect = ref<any>([]);
const editOriginForm = ref(ElForm); //
watch(
() => props.rulerInfo,
(val: any) => {
rulesInfo.value.id = props.rulerInfo.id.toString();
rulesInfo.value.starttime = props.rulerInfo.begainTime;
rulesInfo.value.setIsm = props.rulerInfo.typeIdStr;
rulesInfo.value.shifttime = props.rulerInfo.periodid.toString();
rulesInfo.value.rule = props.rulerInfo.rules.toString();
rulesInfo.value.orgId = props.orgId.toString();
},
{ deep: true }
);
/**
* 弹窗显示控制
*/
const isShow = computed({
get: () => {
if (props.open) {
rulesInfo.value.orgId = props.orgId.toString();
getWorkRules();
}
return props.open;
},
set: (val) => {
emits("update:open", val);
},
});
/**
* 表单验证规则
*/
const addOriginRules = reactive({
starttime: [{ required: true, message: "请选择源点时间", trigger: "blur" }],
setIsm: [{ required: true, message: "请选择执行制度", trigger: "blur" }],
shifttime: [{ required: true, message: "请选择起始工作时间段", trigger: "blur" }],
rule: [{ required: true, message: "请选择起始轮询班组", trigger: "blur" }],
});
/**
@ 作者: 秦东
@ 时间: 2025-01-16 16:52:44
@ 功能: 关闭弹窗
*/
const closeRulesDialog = () => {
emits("update:open", false);
editOriginForm.value.resetFields();
};
/**
@ 作者: 秦东
@ 时间: 2025-01-17 11:02:38
@ 功能: 获取排班类别及轮询制度
*/
const getWorkRules = () => {
gainTemsTypeAndRuler().then((data: any) => {
console.log("获取排班类别及轮询制度--->", data);
if (data.data && data.data.length > 0) {
workTimeRules.value = data.data;
for (let i = 0; i < data.data.length; i++) {
if (props.rulerInfo.typeIdStr == data.data[i].id) {
if (
data.data[i].pollingRules &&
data.data[i].pollingRules.length > 0 &&
data.data[i].workingTimePeriod &&
data.data[i].workingTimePeriod.length > 0
) {
console.log("获取排班类别及轮询制度-3-->", data.data[i].id);
// rulesInfo.value.setIsm = data.data[i].id.toString();
timeSelect.value = data.data[i].workingTimePeriod;
// rulesInfo.value.shifttime = data.data[i].workingTimePeriod[0].id.toString();
rulesSelect.value = data.data[i].pollingRules;
// rulesInfo.value.rule = data.data[i].pollingRules[0].id.toString();
return true;
}
}
}
}
});
};
/**
@ 作者: 秦东
@ 时间: 2025-01-17 13:36:59
@ 功能: 选定制度
*/
watch(
() => rulesInfo.value.setIsm,
(val: string) => {
// console.log("", val);
if (workTimeRules.value && workTimeRules.value.length > 0) {
workTimeRules.value.forEach((item: any) => {
// console.log("------2--------->", item.id == val, item, val);
if (item.id == val) {
// console.log("----3------->", item);
timeSelect.value = item.workingTimePeriod;
rulesSelect.value = item.pollingRules;
rulesInfo.value.shifttime = item.workingTimePeriod[0].id.toString();
rulesInfo.value.rule = item.pollingRules[0].id.toString();
}
});
}
},
{
deep: true,
}
);
/**
@ 作者: 秦东
@ 时间: 2025-01-17 13:58:12
@ 功能: 提交数据
*/
const setOrgRulessubmit = () => {
loadRules.value = true;
editOriginForm.value.validate((isValid: boolean) => {
if (isValid) {
console.log("提交数据", rulesInfo.value);
setOirginCont(rulesInfo.value)
.then((data: any) => {
console.log("提交数据", data);
if (data.code == 0) {
rulesInfo.value.id = data.data.id.toString();
}
emits("updateShiftRules");
closeRulesDialog();
})
.finally(() => {
loadRules.value = false;
});
} else {
loadRules.value = false;
}
});
};
</script>
<template>
<el-dialog
v-model="isShow"
width="500"
:title="'设置<' + orgName + '>倒班制度及执行源点数据'"
append-to-body
:before-close="closeRulesDialog"
>
<el-form
ref="editOriginForm"
:model="rulesInfo"
:rules="addOriginRules"
label-width="125px"
class="demo-ruleForm"
>
<el-form-item label="源点日期" prop="starttime">
<el-date-picker
v-model="rulesInfo.starttime"
format="YYYY 年 MM 月 DD 日"
type="date"
placeholder="选择日期"
value-format="YYYY-MM-DD"
clearable
>
</el-date-picker>
</el-form-item>
<el-form-item label="执行制度" prop="setIsm">
<el-select v-model="rulesInfo.setIsm" placeholder="请选择执行制度" clearable>
<el-option
v-for="item in workTimeRules"
:key="item.id"
:label="item.name"
:value="item.id"
/>
</el-select>
</el-form-item>
<el-form-item label="起始工作时间段" prop="shifttime">
<el-select
v-model="rulesInfo.shifttime"
placeholder="请选择起始工作时间段"
clearable
>
<el-option
v-for="item in timeSelect"
:key="item.id"
:label="item.name + ' [' + item.startTime + '-' + item.endTime + ']'"
:value="item.id"
/>
</el-select>
</el-form-item>
<el-form-item label="起始轮询班组" prop="rule">
<el-select v-model="rulesInfo.rule" placeholder="请选择起始轮询班组" clearable>
<el-option
v-for="item in rulesSelect"
:key="item.id"
:label="item.name + ' [NO.' + item.sort + ']'"
:value="item.id"
/>
</el-select>
</el-form-item>
</el-form>
<template #footer class="el_dialog__footer">
<div class="dialog-footer">
<el-button
size="small"
type="primary"
@click="setOrgRulessubmit"
:loading="loadRules"
> </el-button
>
<el-button size="small" @click="closeRulesDialog"> </el-button>
</div>
</template>
</el-dialog>
</template>
<style lang="scss" scoped></style>

195
src/views/hr/teams/classTime/weekInfoPage.vue

@ -0,0 +1,195 @@
<!--
@ 作者: 秦东
@ 时间: 2025-01-16 14:39:18
@ 备注: 周内容
-->
<script lang="ts" setup>
import { PropType } from "vue";
import DateClass from "@/api/calendar/DateClass";
import { dateBase } from "@/api/calendar/Calendar";
import FormPageCont from "@/components/DesignForm/tableListPage/formPageCont.vue";
const props = defineProps({
col: {
type: Object as PropType<dateBase>,
default: () => {
return {};
},
},
time: {
type: String,
default: "",
},
});
const isCurrentMonth = (time: string) => {
console.log("分割时间", time);
const months = time.split("-")[1];
return DateClass.getCurrent()[1] === Number(months);
};
const emit = defineEmits(["changeTargetDate"]);
const changeTargetDate = (time: dateBase) => {
emit("changeTargetDate", time);
};
/**
@ 作者: 秦东
@ 时间: 2024-07-16 10:32:41
@ 功能: 搜索数据
*/
const searchtData = (val: any, time?: any) => {
return time;
};
</script>
<template>
<div
class="calendar-item-container"
:class="[
{
'is-current': col.isCurrent,
'is-holidays': col.isHolidays,
'is-week': col.isWeek,
'is-selected': col.date === props.time,
'is-current-month': isCurrentMonth(col.date),
},
]"
@click="changeTargetDate(col)"
>
<div class="dayStyle">
{{ col }}
<span>{{ col.title }}</span>
<div v-if="col.isHolidays"></div>
<span>{{ col.lunarsChina }}</span>
</div>
</div>
</template>
<style lang="scss" scoped></style>
<style scoped lang="less">
.calendar-item-container {
width: 100%;
height: 100%;
flex-direction: column;
box-sizing: border-box;
border-radius: 6px;
border: 2px solid #ffffff;
.dayList {
height: calc(100% - 20px);
overflow-y: auto;
}
.dayLogCont {
white-space: nowrap; /* 确保文本在一行内显示 */
overflow: hidden; /* 隐藏溢出的内容 */
text-overflow: ellipsis; /* 使用省略号表示文本溢出 */
font-size: 0.95rem;
border: 1px solid #bcbcbc;
border-radius: 5px;
margin-bottom: 5px;
padding: 0 5px;
}
.dayStyle {
display: flex;
// align-items: top;
justify-content: space-between;
font-size: 12px;
color: #999999;
}
.calendar-title {
font-size: 1.2rem;
color: #999999;
}
.calendar-lunar {
margin-top: 6px;
font-size: 0.85rem;
color: #bcbcbc;
}
transition: all 0.2s;
}
.calendar-item-container:hover {
cursor: pointer;
border: 2px solid #409eff;
}
.is-holidays {
.holidays-text {
position: absolute;
top: 6px;
left: 14px;
font-size: 0.85rem;
color: #ffa2a2;
}
.calendar-title {
color: #ffa2a2;
}
.dayStyle {
color: #ffa2a2;
}
background-color: #feeeef;
}
.is-selected {
border: 2px solid #409eff;
}
.is-holidays.is-selected {
border: 2px solid #ffa2a2;
}
.is-selected.is-current-month {
border: 2px solid #409eff;
}
.is-holidays.is-selected.is-current-month {
border: 2px solid #f62b2b;
}
.is-week {
.calendar-title {
color: #ffa2a2;
}
.dayStyle {
color: #ffa2a2;
}
}
.calendar-item-container.is-current {
.calendar-title {
color: #333333;
}
.dayStyle {
color: #333333;
}
.calendar-lunar {
color: #666666;
}
}
.calendar-item-container.is-current.is-holidays {
.holidays-text {
position: absolute;
top: 6px;
left: 14px;
font-size: 0.85rem;
color: #f62b2b;
}
background-color: #fbe3e4;
}
.calendar-item-container.is-current.is-holidays,
.calendar-item-container.is-current.is-week {
.calendar-title {
color: #f62b2b;
}
.dayStyle {
color: #f62b2b;
}
}
.calendar-item-container.is-current.is-holidays {
.holidays-text {
position: absolute;
top: 6px;
left: 14px;
font-size: 0.85rem;
color: #fb4949;
}
.calendar-title {
color: #fb6e6e;
}
.dayStyle {
color: #fb6e6e;
}
background-color: #ffe4e7;
}
.calendar-item-container.is-holidays:hover {
border: 2px solid #f62b2b;
}
</style>

119
src/views/hr/teams/classTime/weekPage.vue

@ -0,0 +1,119 @@
<!--
@ 作者: 秦东
@ 时间: 2025-01-16 14:08:25
@ 备注: 日历周
-->
<script lang="ts" setup>
import Calendar from "@/api/calendar/Calendar";
import DateClass from "@/api/calendar/DateClass";
import { dateBase } from "@/api/calendar/Calendar";
import { clockFactory } from "@/api/calendar/utils";
import { gainCalendarList } from "@/api/calendar/request";
import WeekInfoPage from "@/views/hr/teams/classTime/weekInfoPage.vue";
const props = defineProps({
taDay: {
type: Array,
default() {
return [2024, 7, 13];
},
},
});
//
const THeader = Calendar.title();
const WeekBody = ref<any>([]);
const selectedTime = ref(
props.taDay[0] + "-" + clockFactory(props.taDay[1]) + "-" + clockFactory(props.taDay[2])
);
onMounted(() => {
WeekBody.value = Calendar.gainDayOfWeek(
props.taDay.start[0],
props.taDay.start[1],
props.taDay.start[2]
);
nextTick(() => {
let ddTime = DateClass.getCurrent();
selectedTime.value =
ddTime[0] + "-" + clockFactory(ddTime[1]) + "-" + clockFactory(ddTime[2]);
});
});
const emit = defineEmits(["getDate"]);
const changeDate = (time: dateBase) => {
selectedTime.value = time.date;
emit("getDate", time);
};
watch(
() => props.taDay,
(val: any) => {
WeekBody.value = Calendar.gainDayOfWeek(
props.taDay.start[0],
props.taDay.start[1],
props.taDay.start[2]
);
},
{
deep: true,
}
);
const loadWeek = ref(false);
</script>
<template>
<div class="monthCalendarBox">
<ul class="t-calendar-header">
<li v-for="(item, index) in THeader" :key="index">
{{ item }}
</li>
</ul>
<div class="t-calendar-day" v-loading="loadWeek">
<template v-if="WeekBody.length">
<div class="t-calendar-row" v-for="(item, index) in WeekBody" :key="index">
<WeekInfoPage
:col="item"
:time="selectedTime"
@changeTargetDate="changeDate"
></WeekInfoPage>
</div>
</template>
<template v-else>
<div class="no-date">抱歉,暂无数据</div>
</template>
</div>
</div>
</template>
<style lang="scss" scoped>
.monthCalendarBox {
width: 100%;
margin-top: 10px;
height: calc(100vh - 340px);
.t-calendar-header {
display: flex;
width: 100%;
height: 42px;
padding: 0;
box-sizing: border-box;
li {
display: flex;
align-items: center;
justify-content: center;
flex: 1;
font-size: 0.95rem;
}
}
.t-calendar-day {
display: flex;
width: 100%;
height: calc(100% - 42px);
padding: 0;
box-sizing: border-box;
border-right: 1px solid #ebeef5;
.t-calendar-row {
width: calc(100% / 7);
font-size: 0.95rem;
border-bottom: 1px solid #ebeef5;
border-top: 1px solid #ebeef5;
border-left: 1px solid #ebeef5;
}
}
}
</style>

186
src/views/hr/teams/classes.vue

@ -0,0 +1,186 @@
<!--
@ 作者: 秦东
@ 时间: 2025-01-14 11:17:13
@ 备注: 班次管理
-->
<script lang="ts" setup>
import { TimesClassInfo } from "@/api/hr/people/type";
import { teamTimeList, editWorkTimeState } from "@/api/hr/people/index";
import AddClass from "@/views/hr/teams/classTime/addClass.vue";
import EditClass from "@/views/hr/teams/classTime/editClass.vue";
const searchData = reactive({
name: "",
});
const searchFormRef = ref(ElForm);
const timeClassList = ref<TimesClassInfo[]>([]);
const teamLookInfo = ref<TimesClassInfo>();
const addIsShow = ref(false);
const editIsShow = ref(false);
const setupIsShow = ref(false);
/**
@ 作者: 秦东
@ 时间: 2025-01-14 11:34:57
@ 功能: 获取班次列表
*/
const getTimeClassList = () => {
teamTimeList(searchData).then((data: any) => {
timeClassList.value = data.data;
});
};
/**
@ 作者: 秦东
@ 时间: 2025-01-14 11:39:01
@ 功能: 查询班次
*/
const searchSubmit = () => {
getTimeClassList();
};
/**
@ 作者: 秦东
@ 时间: 2025-01-14 13:14:17
@ 功能: 改变班次轮询规则状态
*/
const switchChange = (val: any) => {
// console.log("", val);
let setState = 2;
if (val.states) setState = 1;
let sendData = {
id: val.id.toString(),
state: setState,
constrain: 2,
};
editWorkTimeState(sendData).then((data: any) => {
getTimeClassList();
});
};
/**
@ 作者: 秦东
@ 时间: 2025-01-14 13:31:30
@ 功能: 新增班次轮询规则
*/
const addNewCont = () => {
// console.log("");
addIsShow.value = true;
// console.log("", addIsShow.value);
};
/**
@ 作者: 秦东
@ 时间: 2025-01-15 09:16:08
@ 功能: 编辑班次轮询
*/
const showEdit = (val: any) => {
teamLookInfo.value = val;
editIsShow.value = true;
};
/**
@ 作者: 秦东
@ 时间: 2025-01-15 09:12:06
@ 功能: 删除班次轮询
*/
const deleteOperate = (val: any) => {
ElMessageBox.confirm("您确定要删除此内容?一经删除!内容将不可恢复!", "Warning", {
confirmButtonText: "确定",
cancelButtonText: "取消",
type: "warning",
})
.then(() => {
let sendData = {
id: val.id.toString(),
state: 3,
constrain: 2,
};
editWorkTimeState(sendData).then((data: any) => {
getTimeClassList();
});
})
.catch(() => {});
};
//
onMounted(() => {
getTimeClassList();
});
</script>
<template>
<div class="app-container">
<AddClass v-model:open="addIsShow" @restdata="getTimeClassList" />
<EditClass
v-model:open="editIsShow"
:team-info="teamLookInfo"
@restdata="getTimeClassList"
/>
<el-card shadow="never">
<template #header>
<el-form ref="searchFormRef" :model="searchData" :inline="true">
<el-form-item label="班次名称">
<el-input v-model="searchData.name" clearable></el-input>
</el-form-item>
<el-form-item>
<el-button type="primary" @click="searchSubmit"
><i class="fa fa-search"></i>查询</el-button
>
</el-form-item>
<el-form-item>
<el-button type="warning" @click="addNewCont"
><i class="fa fa-plus"></i>新增</el-button
>
</el-form-item>
</el-form>
</template>
<el-table :data="timeClassList" style="width: 100%">
<el-table-column prop="name" label="名称" width="200"> </el-table-column>
<el-table-column prop="rulename" label="轮询规则"> </el-table-column>
<el-table-column label="工作时段安排">
<template #default="scope">
<el-row v-for="item in scope.row.list" :key="item.title">
<el-col :span="24"
>{{ item.title }} 工作时间{{ item.startTime }} -
{{ item.endTime }}</el-col
>
</el-row>
</template>
</el-table-column>
<el-table-column label="状态" width="100">
<template #default="scope">
<el-switch
@change="switchChange(scope.row)"
style="display: block"
v-model="scope.row.states"
active-color="#13ce66"
inactive-color="#ff4949"
active-text="启用"
inactive-text="禁用"
inline-prompt
>
</el-switch>
</template>
</el-table-column>
<el-table-column
align="center"
fixed="right"
label="操作"
width="160"
header-align="center"
>
<template #default="scope">
<el-button v-if="false" size="small" @click="setOrigin(scope.row)"
>设置源点</el-button
>
<el-button size="small" @click="showEdit(scope.row)">编辑</el-button>
<el-button size="small" @click="deleteOperate(scope.row)">删除</el-button>
</template>
</el-table-column>
</el-table>
</el-card>
</div>
</template>
<style lang="scss" scoped>
.app-container {
:deep .el-card__header {
padding-bottom: 0px;
}
}
</style>

439
src/views/hr/teams/index.vue

@ -0,0 +1,439 @@
<!--
@ 作者: 秦东
@ 时间: 2025-01-13 11:44:11
@ 备注: 班组列表
-->
<script lang="ts" setup>
import {
teamcontlist,
eidtdelteamcont,
addteamcont,
eiteteamcont,
} from "@/api/hr/org/index";
import BatchImportTimePeople from "@/views/hr/teams/batchImportTimePeople.vue";
const searchFormRef = ref(ElForm);
const addFormRef = ref(ElForm);
const searchMap = reactive({
page: 1,
pagesize: 20,
name: "",
});
const loadLing = ref(false);
const totalCount = ref(0);
const tiemList = ref([]);
const selectTableLength = ref(0);
const tableIds = ref<string[]>([]); //ID
/**
@ 作者: 秦东
@ 时间: 2025-01-13 13:48:00
@ 功能: 获取班组列表
*/
const gainTimeList = () => {
loadLing.value = true;
teamcontlist(searchMap)
.then((data) => {
totalCount.value = data.data.total;
tiemList.value = data.data.list;
})
.finally(() => {
loadLing.value = false;
});
};
/**
@ 作者: 秦东
@ 时间: 2025-01-13 13:54:15
@ 功能: 加载完毕页面
*/
onMounted(() => {
gainTimeList();
});
/**
@ 作者: 秦东
@ 时间: 2025-01-13 15:00:20
@ 功能: 搜索班组
*/
const getOrgteimList = () => {
searchMap.page = 1;
gainTimeList();
};
/**
* 重置搜索表单
*/
function resetSearchQuery() {
searchFormRef.value.resetFields();
gainTimeList();
}
/**
@ 作者: 秦东
@ 时间: 2025-01-13 15:33:49
@ 功能: 改变状态
*/
const editOrgClassState = (id: number, state: any) => {
console.log("改变状态---", id, state);
if (state == 1) {
state = 2;
} else {
state = 1;
}
let send = {
id: id,
idstr: id.toString(),
state: state,
istrue: 2,
};
eidtdelteamcont(send).then((data) => {
console.log("改变状态结果--》,", data);
gainTimeList();
});
};
/**
@ 作者: 秦东
@ 时间: 2025-01-13 15:37:00
@ 功能: 批量选择
*/
const handleClassIdChange = (selection: any) => {
selectTableLength.value = selection.length;
tableIds.value = selection.map((item: any) => item.id);
};
/**
@ 作者: 秦东
@ 时间: 2025-01-13 16:04:47
@ 功能: 添加班组相关数据
*/
const addDiaShow = ref(false);
const addTiemInfo = reactive({
name: "",
});
/**
@ 作者: 秦东
@ 时间: 2025-01-13 16:09:06
@ 功能: 新增数据
*/
const addOrgClassDialog = () => {
addDiaShow.value = true;
};
/**
@ 作者: 秦东
@ 时间: 2025-01-13 16:10:57
@ 功能: 关闭添加班组
*/
const closeAddDiaShow = () => {
addDiaShow.value = false;
addFormRef.value.resetFields();
gainTimeList();
};
/**
@ 作者: 秦东
@ 时间: 2025-01-13 16:13:11
@ 功能: 重置添加表单
*/
const resetAddTime = () => {
addTiemInfo.name = "";
addFormRef.value.resetFields();
};
/**
@ 作者: 秦东
@ 时间: 2025-01-13 16:15:34
@ 功能: 提交新增班组
*/
const sendAddTime = () => {
addteamcont(addTiemInfo).then((data) => {
closeAddDiaShow();
});
};
/**
@ 作者: 秦东
@ 时间: 2025-01-13 16:19:26
@ 功能: 删除
*/
const handleDeleteOrgClass = (classId?: string) => {
const delOrgTypeIds = [classId || tableIds.value].join(",");
if (!delOrgTypeIds) {
ElMessage.warning("请勾选删除项");
return;
}
ElMessageBox.confirm("确认删除已选中的数据项?", "警告", {
confirmButtonText: "确定",
cancelButtonText: "取消",
type: "warning",
})
.then(() => {
let send = {
id: classId,
idstr: classId.toString(),
state: 3,
istrue: 2,
};
eidtdelteamcont(send).then((data) => {
gainTimeList();
});
})
.catch(() => ElMessage.info("已取消删除"));
};
/////////////////////////////////////
/**
@ 作者: 秦东
@ 时间: 2025-01-13 16:27:00
@ 功能: 修改
*/
const editDiaShow = ref(false);
const editTiemInfo = reactive({
id: "",
name: "",
});
/**
@ 作者: 秦东
@ 时间: 2025-01-13 16:46:54
@ 功能: 编辑班组
*/
const editOrgTypeDialog = (val: any) => {
editTiemInfo.id = val.id.toString();
editTiemInfo.name = val.name;
editDiaShow.value = true;
};
const editFormRef = ref(null);
/**
@ 作者: 秦东
@ 时间: 2025-01-13 16:51:07
@ 功能: 关闭编辑班组弹窗
*/
const closeEditDiaShow = () => {
editDiaShow.value = false;
editFormRef.value.resetFields();
gainTimeList();
};
/**
@ 作者: 秦东
@ 时间: 2025-01-13 16:53:25
@ 功能: 重置编辑按钮
*/
const resetEditTime = () => {
editTiemInfo.id = "";
editTiemInfo.name = "";
editFormRef.value.resetFields();
};
/**
@ 作者: 秦东
@ 时间: 2025-01-13 16:55:06
@ 功能: 发送修改数组数据
*/
const sendEditTime = () => {
eiteteamcont(editTiemInfo).then((data) => {
closeEditDiaShow();
});
};
const setupOpen = ref(false);
const setupTeimId = ref("");
const setupTeimTitle = ref("");
/**
@ 作者: 秦东
@ 时间: 2025-01-14 07:56:27
@ 功能: 设置班组人员
*/
const setupTimePeople = (val: any) => {
setupTeimId.value = val.id.toString();
setupTeimTitle.value = val.name;
setupOpen.value = true;
};
/**
@ 作者: 秦东
@ 时间: 2025-01-14 08:02:29
@ 功能: 关闭批量导入
*/
const closeBatchImport = () => {
setupTeimId.value = "";
setupTeimTitle.value = "";
setupOpen.value = false;
};
</script>
<template>
<div class="app-container">
<el-card shadow="never">
<template #header>
<el-form ref="searchFormRef" :model="searchMap" :inline="true">
<el-form-item label="班组名称" prop="keywords">
<el-input
v-model="searchMap.name"
placeholder="请输入关键字"
clearable
@keyup.enter="getOrgteimList"
/>
</el-form-item>
<el-form-item>
<el-button type="primary" @click="getOrgteimList">
<template #icon><i-ep-search /></template>
搜索
</el-button>
<el-button @click="resetSearchQuery">
<template #icon><i-ep-refresh /></template>
重置
</el-button>
</el-form-item>
</el-form>
</template>
<div style="margin-bottom: 15px; height: 32px; display: flex">
<el-button
type="primary"
@click="addOrgClassDialog()"
v-hasPerm="['339372544081539072']"
>
<i-ep-plus />
新增
</el-button>
<!-- <el-button
v-hasPerm="['339372760021086208']"
plain
type="primary"
:disabled="tiemList.length === 0"
@click="handleDeleteOrgClass()"
>
<i-ep-delete />删除
</el-button>
<span class="select-text">已选 {{ selectTableLength }} </span> -->
</div>
<el-table
v-loading="loadLing"
highlight-current-row
:data="tiemList"
stripe
@selection-change="handleClassIdChange"
:header-cell-style="{ background: '#F4F5F9' }"
>
<!-- <el-table-column type="selection" width="55" align="center" /> -->
<el-table-column label="班组名称" prop="name" />
<el-table-column
v-hasPerm="['339372659932409856']"
label="状态"
prop="state"
width="100"
align="center"
>
<template #default="scope">
<el-switch
v-model="scope.row.status"
class="ml-2"
inline-prompt
style="--el-switch-on-color: #1e5eff"
@change="editOrgClassState(scope.row.id, scope.row.state)"
/>
</template>
</el-table-column>
<el-table-column fixed="right" label="操作" align="center" width="250">
<template #default="scope">
<el-button
v-hasPerm="['339372597063987200']"
type="primary"
link
size="small"
@click.stop="setupTimePeople(scope.row)"
>设置班组人员</el-button
>
<el-button
v-hasPerm="['339372597063987200']"
type="primary"
link
size="small"
@click.stop="editOrgTypeDialog(scope.row)"
>编辑</el-button
>
<el-button
v-hasPerm="['339372708624084992']"
type="primary"
link
size="small"
@click.stop="handleDeleteOrgClass(scope.row.id)"
>删除</el-button
>
</template>
</el-table-column>
</el-table>
<pagination
v-if="total > 0"
v-model:total="totalCount"
v-model:page="searchMap.page"
v-model:limit="searchMap.pagesize"
@pagination="searchMap"
/>
</el-card>
<el-dialog
v-model="editDiaShow"
title="编辑班组"
width="300"
:before-close="closeEditDiaShow"
>
<el-form ref="editFormRef" :model="editTiemInfo">
<el-form-item label="班组名称" prop="keywords">
<el-input v-model="editTiemInfo.name" placeholder="请输入班组名称" clearable />
</el-form-item>
<el-form-item>
<el-button type="primary" @click="sendEditTime">
<template #icon><i-ep-search /></template>
确定
</el-button>
<el-button @click="resetEditTime">
<template #icon><i-ep-refresh /></template>
重置
</el-button>
</el-form-item>
</el-form>
</el-dialog>
<el-dialog
v-model="addDiaShow"
title="添加班组"
width="300"
:before-close="closeAddDiaShow"
>
<el-form ref="addFormRef" :model="addTiemInfo">
<el-form-item label="班组名称" prop="keywords">
<el-input v-model="addTiemInfo.name" placeholder="请输入班组名称" clearable />
</el-form-item>
<el-form-item>
<el-button type="primary" @click="sendAddTime">
<template #icon><i-ep-search /></template>
确定
</el-button>
<el-button @click="resetAddTime">
<template #icon><i-ep-refresh /></template>
重置
</el-button>
</el-form-item>
</el-form>
</el-dialog>
<el-dialog
v-model="setupOpen"
:title="'批量导入《' + setupTeimTitle + '》人员'"
width="500"
:before-close="closeBatchImport"
>
<BatchImportTimePeople
v-model:is-show="setupOpen"
:id="setupTeimId"
@closeOpen="closeBatchImport"
/>
</el-dialog>
</div>
</template>
<style lang="scss" scoped>
.select-text {
display: inline-block;
color: #999;
font-size: 16px;
padding-left: 15px;
line-height: 40px;
height: 32px;
}
</style>

419
src/views/hr/teams/scheduling.vue

@ -0,0 +1,419 @@
<!--
@ 作者: 秦东
@ 时间: 2025-01-15 14:13:24
@ 备注: 排班管理
-->
<script lang="ts" setup>
import DateClass from "@/api/calendar/DateClass";
import { clockFactory } from "@/api/calendar/utils";
import { accordRoleGiveOrg, gainShiftRules } from "@/api/hr/people/index";
import MonthPage from "@/views/hr/teams/classTime/monthPage.vue";
import WeekPage from "@/views/hr/teams/classTime/weekPage.vue";
import DayPage from "@/views/hr/teams/classTime/dayPage.vue";
import SetupShiftRules from "@/views/hr/teams/classTime/setupShiftRules.vue";
const orgTreeLoading = ref(false);
const orgTreeList = ref([]); //
const orgTreeProps = {
children: "child",
label: "name",
}; //
const cureeOrgName = ref("");
const cureeOrgId = ref(0);
const taday = ref<any>([]); //
const curtteDayType = ref(1);
const curtteDay = ref(1);
const shiftRulesOpen = ref(false);
const teamRulerIsm = ref({
begainTime: "",
id: "",
orgId: "",
periodName: "",
periodid: "",
rules: "",
rulesTime: "长白班(1)",
starttime: "",
time: "",
typeIdStr: "",
typeName: "",
typeid: "",
});
/**
@ 作者: 秦东
@ 时间: 2025-01-16 09:46:35
@ 功能: 获取行政组织树
*/
const gainOrgTree = () => {
orgTreeLoading.value = true;
accordRoleGiveOrg()
.then((dada) => {
// console.log("", dada);
orgTreeList.value = dada.data.orgTree;
if (dada.data.orgName != "") {
cureeOrgName.value = dada.data.orgName;
cureeOrgId.value = dada.data.orgId;
} else if (dada.data.maindeparmentName != "") {
cureeOrgName.value = dada.data.maindeparmentName;
cureeOrgId.value = dada.data.maindeparment;
} else if (dada.data.companyName != "") {
cureeOrgName.value = dada.data.companyName;
cureeOrgId.value = dada.data.company;
}
getCurrOrgRules(cureeOrgId.value.toString());
})
.finally(() => {
orgTreeLoading.value = false;
});
};
/**
@ 作者: 秦东
@ 时间: 2025-01-16 09:57:20
@ 功能: 选中行政组织
*/
const handleOrgTreeNodeClick = (val: any) => {
// console.log("", val);
cureeOrgName.value = val.name;
cureeOrgId.value = val.id;
getCurrOrgRules(val.id.toString());
};
//
const curtteMonth = computed(() => {
if (taday.value.length <= 0) {
taday.value = DateClass.getCurrent();
}
// console.log("", taday.value);
if (curtteDayType.value != 2) {
if (taday.value.length >= 2) {
return taday.value[0] + "年" + taday.value[1] + "月";
}
} else {
if (taday.value.start != undefined) {
return taday.value.start[0] + "年";
} else {
return taday.value[0] + "年" + taday.value[1] + "月";
}
}
});
//
const curttWeek = computed(() => {
if (taday.value.length <= 0) {
taday.value = DateClass.getCurrent();
}
// console.log("", taday.value);
if (curtteDayType.value != 2) {
return DateClass.getWeek(
DateClass.solarWeek(taday.value[0], taday.value[1], taday.value[2])
);
} else {
return (
taday.value.start[1] +
"月" +
taday.value.start[2] +
"-" +
taday.value.end[1] +
"月" +
taday.value.end[2]
);
}
});
/**
@ 作者: 秦东
@ 时间: 2024-07-12 11:12:12
@ 功能: 后退时间
*/
const backTime = () => {
if (taday.value.length <= 0) {
taday.value = DateClass.getCurrent();
}
// console.log("退", taday.value);
if (curtteDayType.value != 2) {
taday.value = DateClass.gobackTime(
taday.value[0],
taday.value[1],
taday.value[2],
curtteDayType.value,
-1
);
} else {
let weekObject = DateClass.gobackTime(
taday.value.start[0],
taday.value.start[1],
taday.value.start[2],
curtteDayType.value,
-1
);
taday.value = weekObject;
}
};
/**
@ 作者: 秦东
@ 时间: 2024-07-12 14:04:06
@ 功能: 前进时间
*/
const forwardTime = () => {
// console.log("", curtteDayType.value);
if (taday.value.length <= 0) {
taday.value = DateClass.getCurrent();
}
if (curtteDayType.value != 2) {
taday.value = DateClass.moveTime(
taday.value[0],
taday.value[1],
taday.value[2],
curtteDayType.value
);
} else {
let weekObject = DateClass.moveTime(
taday.value.start[0],
taday.value.start[1],
taday.value.start[2],
curtteDayType.value
);
taday.value = weekObject;
}
};
/**
@ 作者: 秦东
@ 时间: 2024-07-13 16:58:07
@ 功能: 回到今日
*/
const goTady = () => {
taday.value = DateClass.getCurrent();
};
/**
@ 作者: 秦东
@ 时间: 2024-07-13 08:33:01
@ 功能: 选择时间
*/
const pickTime = (val: number) => {
curtteDayType.value = val;
switch (val) {
case 2:
taday.value = DateClass.getCurrent();
let weekObject = DateClass.gobackTime(
taday.value[0],
taday.value[1],
taday.value[2],
curtteDayType.value
);
taday.value = weekObject;
break;
case 3:
taday.value = DateClass.getCurrent();
break;
default:
taday.value = DateClass.getCurrent();
break;
}
};
/**
@ 作者: 秦东
@ 时间: 2025-01-16 16:39:32
@ 功能: 获取当前行政组织排班制度
*/
const getCurrOrgRules = (orgId: any) => {
gainShiftRules({ id: orgId }).then((data: any) => {
console.log("获取当前行政组织排班制度", data, data.code == 0);
if (data.code == 0) {
teamRulerIsm.value.begainTime = data.data.begainTime;
teamRulerIsm.value.id = data.data.id.toString();
teamRulerIsm.value.orgId = data.data.orgId.toString();
teamRulerIsm.value.periodName = data.data.periodName;
teamRulerIsm.value.periodid = data.data.periodid.toString();
teamRulerIsm.value.rules = data.data.rules.toString();
teamRulerIsm.value.rulesTime = data.data.rulesTime;
teamRulerIsm.value.starttime = data.data.starttime;
teamRulerIsm.value.time = data.data.time;
teamRulerIsm.value.typeIdStr = data.data.typeIdStr;
teamRulerIsm.value.typeName = data.data.typeName;
teamRulerIsm.value.typeid = data.data.typeid;
} else {
teamRulerIsm.value.begainTime = "";
teamRulerIsm.value.id = "";
teamRulerIsm.value.orgId = "";
teamRulerIsm.value.periodName = "";
teamRulerIsm.value.periodid = "";
teamRulerIsm.value.rules = "";
teamRulerIsm.value.rulesTime = "";
teamRulerIsm.value.starttime = "";
teamRulerIsm.value.time = "";
teamRulerIsm.value.typeIdStr = "";
teamRulerIsm.value.typeName = "";
teamRulerIsm.value.typeid = "";
}
});
};
/**
@ 作者: 秦东
@ 时间: 2025-01-16 15:30:43
@ 功能: 更新倒班制度及源点
*/
const updateShiftRules = (val?: any) => {
getCurrOrgRules(cureeOrgId.value.toString());
};
onMounted(() => {
gainOrgTree();
if (taday.value.length <= 0) {
taday.value = DateClass.getCurrent();
}
});
/**
@ 作者: 秦东
@ 时间: 2025-01-16 16:50:12
@ 功能: 设置执行倒班制度及源点数据
*/
const setupOrgRules = () => {
shiftRulesOpen.value = true;
};
</script>
<template>
<div class="app-container">
<el-container>
<el-aside width="300px" style="border-right: solid 1px #f0f0f0">
<el-scrollbar class="orgTreeBox">
<el-tree
ref="orgTreeRef"
v-loading="orgTreeLoading"
node-key="id"
class="orgTree"
:data="orgTreeList"
:props="orgTreeProps"
:expand-on-click-node="false"
:check-on-click-node="true"
:check-strictly="true"
:default-expand-all="false"
@node-click="handleOrgTreeNodeClick"
/>
</el-scrollbar>
</el-aside>
<el-container>
<el-header
class="contentBetween"
style="border-bottom: solid 1px #f0f0f0; padding-top: 5px"
>
<el-text>当前行政组织{{ cureeOrgName }}</el-text>
<div>
<el-text
>执行倒班制度及源点{{ teamRulerIsm.typeName }} [
{{ teamRulerIsm.begainTime }}{{ teamRulerIsm.periodName }}-{{
teamRulerIsm.rulesTime
}}]</el-text
>
<el-button type="primary" text @click="setupOrgRules">设置</el-button>
</div>
</el-header>
<el-main>
<div class="calBox">
<!--日历头部-->
<div class="calHead">
<div>
<i class="fa fa-calendar icont"></i>
<el-text class="day">{{ curtteMonth }}</el-text>
<el-text class="week">{{ curttWeek }}</el-text>
</div>
<div>
<el-button-group class="ml-4">
<el-button size="small" @click="goTady()">今天</el-button>
<el-button
:color="curtteDayType == 1 ? '#a0cfff' : ''"
@click="pickTime(1)"
size="small"
></el-button
>
<el-button
:color="curtteDayType == 2 ? '#a0cfff' : ''"
@click="pickTime(2)"
size="small"
></el-button
>
<el-button
:color="curtteDayType == 3 ? '#a0cfff' : ''"
@click="pickTime(3)"
size="small"
></el-button
>
<el-button
size="small"
class="fa fa-angle-left"
@click="backTime()"
></el-button>
<el-button
size="small"
class="fa fa-angle-right"
@click="forwardTime()"
></el-button>
</el-button-group>
</div>
</div>
<div class="weekNumber">
<MonthPage
ref="monthPageRef"
v-if="curtteDayType == 1"
:ta-day="taday"
:org-id="cureeOrgId"
/>
<WeekPage
ref="weekPageRef"
v-if="curtteDayType == 2"
:ta-day="taday"
:org-id="cureeOrgId"
/>
<DayPage
ref="dayPageRef"
v-if="curtteDayType == 3"
:ta-day="taday"
:org-id="cureeOrgId"
/>
</div>
</div>
<SetupShiftRules
v-model:open="shiftRulesOpen"
:org-id="cureeOrgId"
:org-name="cureeOrgName"
:ruler-info="teamRulerIsm"
@updateShiftRules="updateShiftRules"
/>
</el-main>
</el-container>
</el-container>
</div>
</template>
<style lang="scss" scoped>
.app-container {
:deep .el-tree-node__content {
padding: 16px 0;
}
}
.orgTreeBox {
height: calc(100vh - 210px);
}
.contentBetween {
display: flex;
justify-content: space-between;
align-items: center;
}
.calBox {
width: 100%;
height: calc(100vh - 290px);
.calHead {
padding: 10px 0;
border-bottom: 1px solid #ccc;
display: flex;
align-items: center;
justify-content: space-between;
.icont {
font-size: 20px;
}
.day {
font-size: 20px;
padding: 0 10px;
font-weight: bold;
}
}
}
</style>
Loading…
Cancel
Save