47 1 week ago
parent
commit
1431c8d420

+ 8 - 0
public/templates/templete.docx

@@ -0,0 +1,8 @@
+名字: {name}
+条件:
+{#conditionCons}
+  条件组: {groupName}
+  内容: {cont}
+{/conditionCons}
+
+ 

+ 0 - 16
public/templete.docx

@@ -1,16 +0,0 @@
-ibj: {
-    name: '',
-    conditionCons: [
-        {
-            groupName: '',
-            cont: ''
-        }
-    ]    
-}
- 
- 
-{#conditionCons}
-{groupName}
-{cont}
-{/conditionCons}
- 

+ 11 - 0
src/App.vue

@@ -4,6 +4,7 @@ import { useAppStore } from '@/store/modules/app'
 import { useDesign } from '@/hooks/web/useDesign'
 import { CACHE_KEY, useCache } from '@/hooks/web/useCache'
 import routerSearch from '@/components/RouterSearch/index.vue'
+import { ref, computed } from 'vue'
 
 defineOptions({ name: 'APP' })
 
@@ -14,6 +15,11 @@ const currentSize = computed(() => appStore.getCurrentSize)
 const greyMode = computed(() => appStore.getGreyMode)
 const { wsCache } = useCache()
 
+// 设备判断
+const isMobile = computed(() => {
+  return window.innerWidth >= 768 // 假设768px以下为移动端
+})
+
 // 根据浏览器当前主题设置系统主题色
 const setDefaultTheme = () => {
   let isDarkTheme = wsCache.get(CACHE_KEY.IS_DARK)
@@ -26,6 +32,11 @@ setDefaultTheme()
 </script>
 <template>
   <ConfigGlobal :size="currentSize">
+    <div v-if="!isMobile">
+      <Menu /> <!-- 菜单组件 -->
+      <Breadcrumb /> <!-- 面包屑组件 -->
+      <Navbar /> <!-- 导航栏组件 -->
+    </div>
     <RouterView :class="greyMode ? `${prefixCls}-grey-mode` : ''" />
     <routerSearch />
   </ConfigGlobal>

+ 24 - 1
src/components/ConfigGlobal/src/ConfigGlobal.vue

@@ -8,7 +8,7 @@ import { useAppStore } from '@/store/modules/app'
 import { setCssVar } from '@/utils'
 import { useDesign } from '@/hooks/web/useDesign'
 
-const { variables } = useDesign()
+const { getPrefixCls,variables } = useDesign()
 
 const appStore = useAppStore()
 
@@ -33,6 +33,29 @@ watch(
       !appStore.getMobile ? appStore.setMobile(true) : undefined
       setCssVar('--left-menu-min-width', '0')
       appStore.setCollapse(true)
+      const prefixCls = getPrefixCls('tool-header')
+      // await document.getElementsByClassName(prefixCls)[0].style.display = 'none'
+      // document.getElementById(prefixCls)?.style.display = 'none'
+      const callback = (mutationsList, observer) => {
+        for (let mutation of mutationsList) {
+          if (mutation.type === 'childList' && mutation.addedNodes.length) {
+            const elements = document.getElementsByClassName(prefixCls);
+            const tagsView = document.getElementById("v-tags-view");
+            
+            if (elements.length > 0 && tagsView != null) {
+              // console.log(prefixCls, elements, elements[0]);
+              elements[0].style.display = 'none';
+              tagsView.style.display = 'none';
+              // 执行你需要的操作
+              observer.disconnect(); // 停止观察
+              return;
+            }
+          }
+        }
+      };
+
+      const observer = new MutationObserver(callback);
+      observer.observe(document, { childList: true, subtree: true });
       appStore.getLayout !== 'classic' ? appStore.setLayout('classic') : undefined
     } else {
       appStore.getMobile ? appStore.setMobile(false) : undefined

+ 2 - 1
src/styles/var.css

@@ -53,6 +53,7 @@
   --app-footer-height: 50px;
 
   --transition-time-02: 0.2s;
+
 }
 
 .dark {
@@ -71,4 +72,4 @@ body {
   margin: 0;
   padding: 0;
   box-sizing: border-box;
-}
+}

+ 2 - 0
src/utils/htmlToPDF.js

@@ -58,6 +58,8 @@ export const htmlPdf = (title, html, fileList, type) => {// type传有效值pdf
     }
     // 保存文件
     pdf.save(title + '.pdf');
+    // const pdfBlob = pdf.output('blob'); // 生成 Blob
+    // resolve(pdfBlob); // 返回 Blob
   });
 }
 // pdf截断需要一个空白位置来补充

+ 133 - 0
src/views/system/studentExcused/index.vue

@@ -0,0 +1,133 @@
+<meta name="viewport" content="width=device-width, initial-scale=1.0" />
+<template class="visible-xs">
+  <el-form
+    ref="formRef"
+    :model="formData"
+    :rules="formRules"
+    v-loading="formLoading"
+    :id="userId"
+  >
+    <el-row style="margin-top: 5vw;">
+      <el-col :span="24">
+        <el-form-item label="日期" prop="date">
+          <el-date-picker
+            class="!w-full"
+            v-model="formData.date"
+            value-format="YYYY-MM-DD"
+            type="dates"
+            placeholder="选择日期"
+            :disabled-date="disabledDate"
+          />
+        </el-form-item>
+      </el-col>
+    </el-row>
+    <el-row>
+      <el-col :span="24">
+        <el-form-item label="备注原因" prop="remark">
+        <el-input v-model="formData.remark" placeholder="请输入备注原因" />
+      </el-form-item>
+      </el-col>
+    </el-row>
+    <el-row type="flex" justify="center" align="middle" style="margin-top: 5vw;">
+      <el-button @click="submitForm" type="primary" :disabled="formLoading">确 定</el-button>
+      <el-button style="margin-left: 10px;" @click="cancelForm">取 消</el-button>
+    </el-row>
+  </el-form>   
+</template>
+<script setup lang="ts">
+import { FormRules } from 'element-plus'
+import { getUserProfile, ProfileVO } from '@/api/system/user/profile'
+import { StudentAttendanceApi, StudentAttendanceVO } from '@/api/system/studentAttendance'
+
+/** 学生考勤记录 表单 */
+defineOptions({ name: 'StudentExcused' })
+
+//获取登录人员信息
+const userInfo = ref({} as ProfileVO)
+const getUserInfo = async () => {
+  const users = await getUserProfile()
+  userInfo.value = users;
+  userId.value = users.id;
+}
+const userId = ref('')
+
+const { t } = useI18n() // 国际化
+const message = useMessage() // 消息弹窗
+const formLoading = ref(false) // 表单的加载中:1)修改时的数据加载;2)提交的按钮禁用
+const formRef = ref() // 表单的 ref
+const formData = ref({
+  id: undefined,
+  studentId: undefined,
+  studentName: undefined,
+  userNumber: undefined,
+  supervisor: undefined,
+  deptId: undefined,
+  deptName: undefined,
+  date: undefined,
+  clockInTime: undefined,
+  clockInStatus: undefined,
+  remark: undefined,
+})
+const formRules = reactive<FormRules>({
+  date: [{ required: true, message: '日期不能为空', trigger: 'blur' }],
+  remark:[{ required: true, message: '备注原因不能为空', trigger: 'blur' }],
+})
+
+/** 日期选择器的禁用日期 */
+const disabledDate = (date) => {
+  return date.getTime() < new Date().setHours(0, 0, 0, 0); // 禁用今天之前的日期
+  // return date.getTime() <= new Date().setHours(0, 0, 0, 0); // 禁用今天之前的日期,包括今天
+};
+
+const clockInStatuE = ref('2') // 打卡状态
+/** 提交表单 */
+const emit = defineEmits(['success']) // 定义 success 事件,用于操作成功后的回调
+const submitForm = async () => {
+  formData.value.clockInStatus = clockInStatuE.value
+  // 校验表单
+  await formRef.value.validate()
+  // 提交请求
+  formLoading.value = true
+  try {
+    const data = formData.value as unknown as StudentAttendanceVO;
+    const dates = Array.isArray(formData.value.date) ? formData.value.date : [];
+    for (const date of dates) {
+      const submissionData = { ...data, date }; // 为每个日期创建新的提交数据
+      await StudentAttendanceApi.createStudentAttendance(submissionData);
+    }
+    message.success(t('提交成功'));
+    // 发送操作成功的事件
+    emit('success');
+  } finally {
+    formLoading.value = false;
+  }
+}
+
+/** 取消表单 */
+const cancelForm = () => {
+  formRef.value.resetFields()
+}
+
+onMounted(async () => {
+  await getUserInfo()
+  // await getStudentAttendance();
+})
+</script>
+
+<style lang="scss" scoped>
+.visible-xs{        //电脑端css
+
+display: none;
+
+}
+
+@media (max-width: 767px) {        //移动端css
+
+.visible-xs{
+
+display: block !important;
+
+}
+
+}
+</style>

+ 35 - 17
src/views/system/studentSelectSupervisorRecord/record.vue

@@ -208,7 +208,7 @@ import {studentSelectSupervisorRecordApi, studentSelectSupervisorRecordVO} from
 import {DICT_TYPE} from "@/utils/dict";
 import studentSelectSupervisorRecordForm from './studentSelectSupervisorRecordForm.vue'
 import {studentSelectionProjectApi} from "@/api/system/studentSelectionProject"
-// import { exportDocx } from '@/utils/doc.js';
+import { exportDocx } from '@/utils/doc.js';
 // import docxtemplater from "docxtemplater"
 // import PizZip from "pizzip"
 // import JSZipUtils from "jszip-utils"
@@ -293,25 +293,43 @@ watch(selectedRows, (newSelection) => {
 });
 
 /** 导出按钮操作 */
-const exportWordTemplate = async () => {
-  if (selectedRows.value.length === 0) {
-    message.error('请先选择需要导出的数据!');
-    return;
-  }
-  // isLoading.value = true;
-  // 遍历所有选中的行
-  for (const row of selectedRows.value) {
-    openForm('end', row.projectId, row.supervisorId, row.id, row.studentId);
-    // 等待弹窗渲染完成
-    await nextTick();
-    // 调用弹窗中的导出方法
-    if (formRef.value && typeof formRef.value.handleExport === 'function') {
-      formRef.value.handleExport(); // 调用导出方法
+const ibj = ref({
+  name: '示例名称',
+  conditionCons: [
+    {
+      groupName: '条件组 1',
+      cont: '条件内容 1'
+    },
+    {
+      groupName: '条件组 2',
+      cont: '条件内容 2'
     }
-  }
-  // isLoading.value = false;
+  ]
+});
+const tempDocxPath = ref('/templates/template.docx');
+const exportWordTemplate = () => {
+  const fileName = '导出文档.docx'; // 导出文件的名称
+  exportDocx(tempDocxPath.value, ibj.value, fileName);
 };
 // const exportWordTemplate = async () => {
+//   if (selectedRows.value.length === 0) {
+//     message.error('请先选择需要导出的数据!');
+//     return;
+//   }
+//   // isLoading.value = true;
+//   // 遍历所有选中的行
+//   for (const row of selectedRows.value) {
+//     openForm('end', row.projectId, row.supervisorId, row.id, row.studentId);
+//     // 等待弹窗渲染完成
+//     await nextTick();
+//     // 调用弹窗中的导出方法
+//     if (formRef.value && typeof formRef.value.handleExport === 'function') {
+//       formRef.value.handleExport(); // 调用导出方法
+//     }
+//   }
+//   // isLoading.value = false;
+// };
+// const exportWordTemplate = async () => {
 //     const rows = selectedRows.value; 
 //     console.log("rows", rows);
 //     if (rows.length === 0) {

+ 4 - 4
src/views/system/studentSelectSupervisorRecord/studentSelectSupervisorRecordForm.vue

@@ -15,24 +15,24 @@
       <!-- 学生信息 -->
       <div class="section"  v-if="userInfo.userType==='4' ||userInfo.userType==='3'" >
         <el-row>
-          <el-col :span="10">
+          <el-col :span="11">
             <el-form-item label="学生姓名">
               <el-input v-model="studentData.nickname" placeholder="自动链接" disabled />
             </el-form-item>
           </el-col>
-          <el-col :span="14">
+          <el-col :span="13">
             <el-form-item label="学号">
               <el-input v-model="studentData.userNumber" placeholder="自动链接" disabled />
             </el-form-item>
           </el-col>
         </el-row>
         <el-row>
-          <el-col :span="10">
+          <el-col :span="11">
             <el-form-item label="专业">
               <el-input v-model="studentData.major" placeholder="自动链接" disabled />
             </el-form-item>
           </el-col>
-          <el-col :span="14">
+          <el-col :span="13">
             <el-form-item label="联系电话">
               <el-input v-model="studentData.mobile" placeholder="自动链接" disabled />
             </el-form-item>