index.vue 7.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214
  1. <template>
  2. <div class="system-holidayConfig-container layout-pd">
  3. <el-card shadow="never">
  4. <el-calendar v-model="today" :range="dateRange" v-loading="loading">
  5. <template #header="{ date }">
  6. <div class="flex-center-center">
  7. <span class="mr5">选择月份:</span
  8. ><el-date-picker v-model="month" type="month" :clearable="false" placeholder="请选择月份" @change="selectMonth" />
  9. </div>
  10. <el-button-group v-auth="'system:holiday:workDay'">
  11. <el-button type="primary" @click="setHoliday" :disabled="!multipleDates.length">
  12. <SvgIcon name="ele-Sunny" class="mr3" /> 设定休息日<span v-if="multipleDates?.length">({{ multipleDates.length }})</span></el-button
  13. >
  14. <el-button type="primary" @click="setWorkDay" :disabled="!multipleDates.length">
  15. <SvgIcon name="ele-Monitor" class="mr3" /> 设定工作日<span v-if="multipleDates?.length">({{ multipleDates.length }})</span></el-button
  16. >
  17. <el-button type="primary" @click="clearSelect" :disabled="!multipleDates.length"
  18. ><SvgIcon name="ele-Delete" class="mr3" /> 清空选择<span v-if="multipleDates?.length">({{ multipleDates.length }})</span></el-button
  19. >
  20. </el-button-group>
  21. <!-- <el-button-group>
  22. <el-button @click="setWorkTime"><SvgIcon name="ele-AlarmClock" class="mr3" /> 设定工作时间</el-button>
  23. </el-button-group>-->
  24. </template>
  25. <template #date-cell="{ data }">
  26. <template v-for="item in state.calendarData">
  27. <div v-if="data.day === item.currantTime" class="h100">
  28. <el-checkbox v-model="item.checked" class="w100 h100">
  29. <div>
  30. {{ dayjs(data.day).format('D')
  31. }}<span :class="item.isWorkDay ? 'color-primary' : 'color-success'">({{ item.isWorkDay ? '工作日' : '休息日' }})</span>
  32. </div>
  33. <div class="lunar" :class="{ 'color-danger font-bold': isFestival(data) }">{{ solarToLunar(data) }}</div>
  34. </el-checkbox>
  35. </div>
  36. </template>
  37. </template>
  38. </el-calendar>
  39. </el-card>
  40. <!-- 工作时间设置 -->
  41. <el-dialog title="设定工作时间" v-model="dialogVisible" width="600px" draggable>
  42. <el-form :model="state.ruleForm" ref="ruleFormRef" label-width="120px">
  43. <el-row :gutter="35">
  44. <el-col>
  45. <el-form-item label="休息日工作时间" prop="time" :rules="[{ required: true, message: '请选择休息日工作时间', trigger: 'change' }]">
  46. <el-time-picker v-model="state.ruleForm.time" is-range range-separator="至" start-placeholder="开始时间" end-placeholder="结束时间" />
  47. </el-form-item>
  48. </el-col>
  49. <el-col>
  50. <el-form-item label="工作日工作时间" prop="time1" :rules="[{ required: true, message: '请选择工作日工作时间', trigger: 'change' }]">
  51. <el-time-picker v-model="state.ruleForm.time1" is-range range-separator="至" start-placeholder="开始时间" end-placeholder="结束时间" />
  52. </el-form-item>
  53. </el-col>
  54. </el-row>
  55. </el-form>
  56. <template #footer>
  57. <span class="dialog-footer">
  58. <el-button @click="dialogVisible = false" class="default-button">取 消</el-button>
  59. <el-button type="primary" @click="onSubmit(ruleFormRef)" :loading="loading">确 定 </el-button>
  60. </span>
  61. </template>
  62. </el-dialog>
  63. </div>
  64. </template>
  65. <script setup lang="ts" name="holidayConfig">
  66. import { ref, reactive, onMounted, computed } from 'vue';
  67. import { ElMessage, ElMessageBox, FormInstance } from 'element-plus';
  68. import dayjs from 'dayjs';
  69. import calendar from '@/utils/calendar.js';
  70. import { getDaysSetting, setHolidayApi } from '@/api/system/holiday';
  71. const state = reactive<any>({
  72. ruleForm: {
  73. time: '',
  74. time1: '',
  75. },
  76. calendarData: [], // 日历数据
  77. });
  78. const today = ref(new Date()); // 当前日期
  79. const month = ref(new Date()); // 月份
  80. const dialogVisible = ref(false); // 是否显示弹窗
  81. const loading = ref(false); // 加载状态
  82. // 选择月份
  83. const selectMonth = async (val: Date) => {
  84. state.calendarData = [];
  85. const days: number = dayjs(val).daysInMonth();
  86. state.calendarData = Array.from({ length: days }, (_, i) => ({
  87. currantTime: dayjs(val).startOf('month').add(i, 'day').format('YYYY-MM-DD'),
  88. checked: false,
  89. isWorkDay: ![0, 6].includes(dayjs(val).startOf('month').add(i, 'day').day()),
  90. }));
  91. dateRange.value = [new Date(dayjs(val).startOf('month').format('YYYY-MM-DD')), new Date(dayjs(val).endOf('month').format('YYYY-MM-DD'))];
  92. await getSetting(dayjs(val).format('YYYY'), dayjs(val).format('MM'));
  93. today.value = val;
  94. };
  95. // 日期范围
  96. const dateRange = ref([
  97. new Date(dayjs(today.value).startOf('month').format('YYYY-MM-DD')),
  98. new Date(dayjs(today.value).endOf('month').format('YYYY-MM-DD')),
  99. ]); // 日期范围
  100. // 设置休息日
  101. const setHoliday = () => {
  102. ElMessageBox.confirm(`您确定要将【${multipleDates.value.map((item: any) => dayjs(item).format('YYYY-MM-DD')).join(',')}】设为休息日吗?`, '提示', {
  103. type: 'warning',
  104. draggable: true,
  105. })
  106. .then(() => {
  107. setHolidayApi({
  108. list: multipleDates.value,
  109. isWorkDay: false,
  110. }).then(() => {
  111. ElMessage.success('设置成功');
  112. selectMonth(today.value);
  113. });
  114. })
  115. .catch(() => {});
  116. };
  117. // 设置工作日
  118. const setWorkDay = () => {
  119. ElMessageBox.confirm(`您确定要将【${multipleDates.value.map((item: any) => dayjs(item).format('YYYY-MM-DD')).join(',')}】设为工作日吗?`, '提示', {
  120. type: 'warning',
  121. draggable: true,
  122. })
  123. .then(() => {
  124. setHolidayApi({
  125. list: multipleDates.value,
  126. isWorkDay: true,
  127. }).then(() => {
  128. ElMessage.success('设置成功');
  129. selectMonth(today.value);
  130. });
  131. })
  132. .catch(() => {});
  133. };
  134. /*// 设置工作时间
  135. const setWorkTime = () => {
  136. dialogVisible.value = true;
  137. };*/
  138. // 清除选择
  139. const clearSelect = () => {
  140. state.calendarData.forEach((item: any) => {
  141. item.checked = false;
  142. });
  143. };
  144. // 获取所选中的日期
  145. const multipleDates = computed(() => {
  146. return state.calendarData.filter((item: any) => item.checked).map((item: any) => item.currantTime);
  147. });
  148. // 表单ref
  149. const ruleFormRef = ref<RefType>();
  150. // 表单提交
  151. const onSubmit = (formEl: FormInstance | undefined) => {
  152. if (!formEl) return;
  153. formEl.validate((valid: boolean) => {
  154. if (!valid) return;
  155. });
  156. };
  157. // 获取休息日设置
  158. const getSetting = async (dateYear: string, dateMoth: string) => {
  159. loading.value = true;
  160. try {
  161. const { result } = await getDaysSetting(dateYear, dateMoth);
  162. result.forEach((i: any) => {
  163. const item = state.calendarData.find((j: any) => dayjs(i.day).format('YYYY-MM-DD') === j.currantTime);
  164. if (item) {
  165. item.isWorkDay = i.isWorkDay;
  166. }
  167. });
  168. } catch {
  169. // handle error if needed
  170. } finally {
  171. loading.value = false;
  172. }
  173. };
  174. // 是否休息日
  175. const isFestival = (slotData: any) => {
  176. let solarDayArr = slotData.day.split('-');
  177. let lunarDay: any = calendar.solar2lunar(solarDayArr[0], solarDayArr[1], solarDayArr[2]);
  178. return lunarDay.lunarFestival || lunarDay.festival;
  179. };
  180. // 公历转农历
  181. const solarToLunar = (slotData: any) => {
  182. let solarDayArr = slotData.day.split('-');
  183. let lunarDay: any = calendar.solar2lunar(solarDayArr[0], solarDayArr[1], solarDayArr[2]);
  184. // 农历日期
  185. let lunarMD = lunarDay.IMonthCn + lunarDay.IDayCn;
  186. return lunarDay.lunarFestival ? lunarDay.lunarFestival : lunarDay.festival ? lunarDay.festival : lunarMD;
  187. };
  188. onMounted(async () => {
  189. const days: number = dayjs(today.value).daysInMonth();
  190. state.calendarData = Array.from({ length: days }, (_, i) => ({
  191. currantTime: dayjs(today.value).startOf('month').add(i, 'day').format('YYYY-MM-DD'),
  192. isWorkDay: ![0, 6].includes(dayjs(today.value).startOf('month').add(i, 'day').day()),
  193. checked: false,
  194. }));
  195. await getSetting(dayjs(today.value).format('YYYY'), dayjs(today.value).format('MM'));
  196. });
  197. </script>
  198. <style scoped lang="scss">
  199. /**日期div的样式-农历*/
  200. .el-calendar-table .el-calendar-day > div .lunar {
  201. padding-top: 10px;
  202. }
  203. :deep(.el-checkbox) {
  204. align-items: center;
  205. justify-content: center;
  206. }
  207. :deep(.el-checkbox__input) {
  208. position: absolute;
  209. right: 0;
  210. top: 0;
  211. }
  212. </style>