47 2 weeks ago
parent
commit
9b5956f0a5

+ 17 - 12
src/views/system/studentSelectSupervisorRecord/index.vue

@@ -138,8 +138,8 @@
         <template #default="scope">
           <el-button
             v-if="scope.row.introduction"
-            type="primary"
-            @click="handleDownload(scope.row.introduction)"
+            type="text"
+            @click="handleDownload(scope.row)"
           >
             下载简历
           </el-button>
@@ -305,6 +305,7 @@ const getList = async () => {
   loading.value = true
   try {
     const data = await studentSelectSupervisorRecordApi.getStudentSelectSupervisorRecordPage(queryParams)
+    console.log('data',data); 
     list.value = data.list
     total.value = data.total
   } finally {
@@ -398,16 +399,20 @@ const getRecordList = async () => {
   }
 }
 
-const handleDownload = (url: string, filename: string = '学生简历') => {
-  // download.pdf(url)
-  // const link = document.createElement('a');
-  // link.href = url;
-  // link.setAttribute('download', filename);
-  // document.body.appendChild(link);
-  // link.click();
-  // document.body.removeChild(link);
-  // download.pdf(url,filename)
-  window.open(url, '_blank');
+const handleDownload = (row) => {
+  // window.open(url, '_blank');
+  const url = row.introduction;
+    if (url) {
+      // 创建一个 a 标签并模拟点击,实现下载
+      const link = document.createElement('a');
+      link.href = url;
+      link.download = '学生简历'; // 提示浏览器下载文件
+      document.body.appendChild(link);
+      link.click();
+      document.body.removeChild(link);
+    } else {
+      console.error('下载地址无效');
+    }
 };
 
 const handelPrint = async (id:number) => {

+ 11 - 4
src/views/system/studentSelectSupervisorRecord/record.vue

@@ -140,15 +140,21 @@
           prop="supervisorType"
           :formatter="userTypeFormatter"
         />
-
-
       <el-table-column label="申请状态" align="center" prop="selectType" >
         <template #default="scope">
           <dict-tag :type="DICT_TYPE.SYSTEM_STUDENT_SELECT_RECORD_SELECT_TYPE" :value="scope.row.selectType" />
         </template>
       </el-table-column>
-      <el-table-column label="学生电子签名" align="center" prop="studentSignature" />
-      <el-table-column label="导师电子签名" align="center" prop="supervisorSignature" />
+      <el-table-column label="学生电子签名" align="center" prop="studentSignature">
+        <template #default="scope">
+          <img v-if="scope.row.studentSignature" :src="scope.row.studentSignature" style="width: 100px; height: 50px;" />
+        </template>
+      </el-table-column>
+      <el-table-column label="导师电子签名" align="center" prop="supervisorSignature">
+        <template #default="scope">
+          <img v-if="scope.row.supervisorSignature" :src="scope.row.supervisorSignature" style="width: 100px; height: 50px;" />
+        </template>
+      </el-table-column>
       <el-table-column
         label="提交时间"
         align="center"
@@ -284,6 +290,7 @@ const getRecordList = async () => {
   try {
     const data = await studentSelectSupervisorRecordApi.getStudentSelectSupervisorRecordPage(queryParams)
     selectionList.value = data
+    console.log("selectionList", selectionList.value);
     selectionList.value = data.list
     total.value = data.total
   } finally {

+ 168 - 26
src/views/system/studentSelectSupervisorRecord/studentSelectSupervisorRecordForm.vue

@@ -10,6 +10,7 @@
       label-width="120px"
       v-loading="formLoading"
       class="form-container"
+      @submit.prevent="handleFormSubmit"
     >
       <!-- 学生信息 -->
       <div class="section"  v-if="userInfo.userType==='4' ||userInfo.userType==='3'" >
@@ -40,7 +41,7 @@
       </div>
 
       <!-- 学生志愿 -->
-      <div class="section">
+      <div class="section" v-if="userInfo.userType !== '4'">
         <h4>学生志愿</h4>
         <el-row>
           <el-col :span="12">
@@ -65,25 +66,82 @@
           <el-col :span="24">
             <el-form-item label="志愿填报">
               <p>本人已知晓{{supervisorData.nickname}}对研究生毕业时学术成果的发表要求,特申请加入{{supervisorData.nickname}}课题组进行研究生阶段的学习和研究。</p>
-              <p v-if="userInfo.userType=='1'">★ 本人签字 <el-input v-model="formData.studentSignature" placeholder="" /></p>
-              <p v-if="userInfo.userType==='3'|| userInfo.userType==='4'">★ 本人签字 <el-input v-model="formData.studentSignature" placeholder="" disabled/></p>
-              <p v-if="userInfo.userType==='3'|| userInfo.userType==='4'">日期:{{formData.studentSignDate}}</p>
+              <p v-if="userInfo.userType=='1'">★ 本人签字
+                <!-- <el-input v-model="formData.studentSignature" placeholder="" /> -->
+              </p>
+              <div v-if="userInfo.userType=='1'">
+                <canvas 
+                  id="canvas" 
+                  ref="canvas" 
+                  width="300px" 
+                  height="100px" 
+                  @mousedown="handleMouseDown"
+                  @mousemove="handleMouseMove"
+                  @mouseup="handleMouseUp"
+                  style="border:1px solid #e0e0e0; border-radius: 4px; background-color: white;"
+                ></canvas>
+                <div style="display: flex; justify-content: flex-end;">
+                  <button type="button" @click="handleStudentSignatureSave" style="padding: 2px 5px; margin-right: 10px;">保存</button>
+                  <button type="button" @click="ClearStudentSignature" style="padding: 2px 5px;">清空</button>
+                </div>
+              </div>
+              <p v-if="userInfo.userType==='3'">★ 本人签字</p>
+              <img v-if="userInfo.userType==='3'" :src="formData.studentSignature" alt="学生签名" style="width: 300px; height: 100px; margin-right: 10px; background-color: white;"/>
+              <p v-if="userInfo.userType==='3'">日期:{{formData.studentSignDate}}</p>
             </el-form-item>
           </el-col>
         </el-row>
       </div>
-
       <!-- 导师意见 -->
-      <div class="section" v-if="userInfo.userType==='4'||userInfo.userType==='3'">
-        <p>导师意见:同意</p>
-        <p>导师签字 <el-input v-model="formData.supervisorSignature" placeholder="" /></p>
-        <p v-if="userInfo.userType==='4'">日期:{{formData.supervisorSignDate}}</p>
+      <div class="section" v-if="userInfo.userType==='3'">
+        <p style="margin-bottom: 10px;">导师意见:同意</p>
+        <p style="margin-bottom: 10px;">导师签字</p>
+        <div>
+          <canvas 
+            id="canvas" 
+            ref="canvas" 
+            width="400px" 
+            height="100px" 
+            @mousedown="handleMouseDown"
+            @mousemove="handleMouseMove"
+            @mouseup="handleMouseUp"
+            style="border:1px solid #e0e0e0; border-radius: 4px; background-color: white;"
+          ></canvas>
+          <div style="display: flex; justify-content: flex-start; margin-top: 10px;">
+            <button type="button" @click="handleSupervisorSignatureSave" style="padding: 2px 5px; margin-right: 10px;">保存</button>
+            <button type="button" @click="ClearSupervisorSignature" style="padding: 2px 5px;">清空</button>
+          </div>
+        </div>
+        <!-- <p v-if="userInfo.userType==='4'">日期:{{formData.supervisorSignDate}}</p> -->
       </div>
-
-<!--      <template #footer>-->
-        <el-button @click="submitForm" type="primary" :disabled="formLoading">确认填报</el-button>
+      <!-- <div class="section" v-if="userInfo.userType ==='4' && formData.selectType === 2">
+        <p v-if="userInfo.userType==='4'" style="font-weight: bold;">★ 导师签字</p>
+        <img v-if="userInfo.userType==='4'" :src="formData.supervisorSignature" alt="导师签名" style="width: 300px; height: 100px; margin-right: 10px; background-color: white;"/>
+        <p v-if="userInfo.userType==='4'">日期:{{formData.supervisorSignDate}}</p>
+      </div> -->
+      <!-- <div class="section" v-if="userInfo.userType==='4'">
+        <el-form-item label="参与导师" prop="supervisorIds">
+          <el-select
+            v-model="queryParams.supervisorId"
+            @change="getRecordList"
+            placeholder="请选择参与导师"
+            clearable
+            filterable
+            class="!w-240px"
+          >
+            <el-option
+              v-for="supervisor in supervisors"
+              :key="supervisor.id"
+              :label="supervisor.nickname"
+              :value="supervisor.id"
+            />
+          </el-select>
+        </el-form-item>
+      </div> -->
+      <div style="display: flex; justify-content: center;">
+        <el-button @click="submitForm" type="primary" :disabled="formLoading">{{ submitFormText }}</el-button>
         <el-button @click="dialogVisible = false">取消</el-button>
-<!--      </template>-->
+      </div>
     </el-form>
   </Dialog>
 </template>
@@ -92,8 +150,7 @@
 import { studentSelectSupervisorRecordApi, studentSelectSupervisorRecordVO } from '@/api/system/studentSelectSupervisorRecord'
 import { CommonStatusEnum } from '@/utils/constants'
 import * as UserApi from '@/api/system/user'
-import { defineOptions, defineExpose, ref, reactive } from 'vue'
-import {data} from "autoprefixer";
+import { defineOptions, defineExpose, ref, reactive, nextTick, onMounted, computed } from 'vue'
 import { getUserProfile, ProfileVO } from '@/api/system/user/profile'
 import {supervisorSelectionSettingApi} from '@/api/system/supervisorSelectionSetting'
 
@@ -105,6 +162,7 @@ const message = useMessage() // 消息弹窗
 
 const dialogVisible = ref(false) // 弹窗的是否展示
 const dialogTitle = ref('') // 弹窗的标题
+const submitFormText = ref('') // 提交按钮的文字
 const formLoading = ref(false) // 表单的加载中:1)修改时的数据加载;2)提交的按钮禁用
 const formType = ref('') // 表单的类型:create - 新增;update - 修改
 const formData = ref({
@@ -152,11 +210,11 @@ const getUserInfo = async () => {
 }
 
 /** 打开弹窗 */
-
 const open = async (type: string, projectId?: number ,supervisorId?:number, id?:number,studentId?:number) => {
-  dialogVisible.value = true
+  dialogVisible.value = true;
   if (type === 'create'){
     dialogTitle.value = '志愿填报'
+    submitFormText.value = '选择'
     formType.value = type
     resetForm()
     if (supervisorId) {
@@ -168,7 +226,6 @@ const open = async (type: string, projectId?: number ,supervisorId?:number, id?:
         //需要传的
         formData.value.supervisorId =supervisorId;
         formData.value.projectId = projectId;
-
         //显示的
         supervisorData.value.nickname = supervisor.supervisorName;
         supervisorData.value.title =supervisor.title;
@@ -181,6 +238,8 @@ const open = async (type: string, projectId?: number ,supervisorId?:number, id?:
   }
   if (type === 'update'){
     dialogTitle.value = '志愿编辑'
+    // dialogTitle.value = '详情'
+    submitFormText.value = '编辑'
     formType.value = type
     resetForm()
     if (id) {
@@ -194,6 +253,7 @@ const open = async (type: string, projectId?: number ,supervisorId?:number, id?:
   }
   if (type === 'agree'){
     dialogTitle.value = '通过志愿'
+    submitFormText.value = '接受'
     formType.value = type
     resetForm()
     if (studentId) {
@@ -218,16 +278,83 @@ const open = async (type: string, projectId?: number ,supervisorId?:number, id?:
       }
     }
   }
+  await nextTick();
+  if (canvas.value) {
+    context.value = canvas.value.getContext('2d');
+    context.value.lineWidth = 2; // 设置线条宽度
+    context.value.lineCap = 'round'; // 设置线条末端样式
+    context.value.strokeStyle = 'black'; // 设置线条颜色
+  } else {
+    console.error('Canvas element is not found');
+  }
+}
+
+const canvas = ref() // 签名画布
+const isDrawing = ref(false) // 是否正在画
+const context = ref() // 签名画布的上下文
+
+const handleMouseDown = (event: MouseEvent) => {
+  if (!canvas.value || !context.value) {
+    console.warn('Canvas or context is not initialized yet');
+    return;
+  }
+  isDrawing.value = true;
+  const { offsetX, offsetY } = event;
+  context.value.beginPath();
+  context.value.moveTo(offsetX, offsetY);
+}
+
+const handleMouseMove = (event: MouseEvent) => {
+  if (!isDrawing.value || !canvas.value || !context.value) return;
+  const { offsetX, offsetY } = event;
+  context.value.lineTo(offsetX, offsetY);
+  context.value.stroke();
+}
+
+const handleMouseUp = () => {
+  isDrawing.value = false
 }
 
-const handleStudentSignatureSave = (data: string) => {
-  console.log("Student Signature Data:", data); // 调试输出签名数据
-  formData.value.studentSignature = data;  // 保存学生签名数据
+const ClearStudentSignature = () => {
+  if (context.value) {
+    formData.value.studentSignature = "";
+    context.value.clearRect(0, 0, canvas.value.width, canvas.value.height);
+    message.success('签名已清空');
+  } else {
+    console.warn('Canvas context is not initialized yet');
+  }
+}
+
+const handleStudentSignatureSave = () => {
+  if (canvas.value) {
+    const dataURL = canvas.value.toDataURL();
+    console.log(dataURL);
+    formData.value.studentSignature = dataURL; // 保存学生签名数据
+    message.success('学生签名保存成功');
+  } else {
+    console.warn('Canvas element is not initialized yet');
+  }
 };
 
-const handleSupervisorSignatureSave = (data: string) => {
-  console.log("Supervisor Signature Data:", data); // 调试输出签名数据
-  formData.value.supervisorSignature = data;  // 保存导师签名数据
+const ClearSupervisorSignature = () => {
+  if (context.value) {
+    formData.value.supervisorSignature = "";
+    context.value.clearRect(0, 0, canvas.value.width, canvas.value.height);
+    message.success('签名已清空');
+  } else {
+    console.warn('Canvas context is not initialized yet');
+  }
+}
+
+const handleSupervisorSignatureSave = () => {
+  if (canvas.value) {
+    const dataURL = canvas.value.toDataURL();
+    console.log(dataURL);
+    formData.value.supervisorSignature = dataURL; // 保存学生签名数据
+    message.success('导师签名保存成功');
+  } else {
+    console.warn('Canvas element is not initialized yet');
+  }
 };
 
 defineExpose({ open }) // 提供 open 方法,用于打开弹窗
@@ -237,6 +364,18 @@ const emit = defineEmits(['success']) // 定义 success 事件,用于操作成
 const submitForm = async () => {
   formLoading.value = true;
   try {
+    const isStudentSignatureSaved = formData.value.studentSignature.startsWith('data:image/png;base64,');
+    const isSupervisorSignatureSaved = formData.value.supervisorSignature.startsWith('data:image/png;base64,');
+    if (!isStudentSignatureSaved && (userInfo.value.userType === '1')) {
+      message.error('请先保存签名');
+      formLoading.value = false;
+      return;
+    }
+    if (!isSupervisorSignatureSaved && (userInfo.value.userType === '3' || userInfo.value.userType === '4')) {
+      message.error('请先保存签名');
+      formLoading.value = false;
+      return;
+    }
     const data = formData.value as unknown as studentSelectSupervisorRecordVO;
     console.log(data)
     if (formType.value === 'create') {
@@ -256,6 +395,10 @@ const submitForm = async () => {
   }
 };
 
+const handleFormSubmit = () => {
+  console.log('Form submit prevented');
+};
+
 const isSupervisor = computed(() => userInfo.value.userType === '3');
 
 //获取所有导师
@@ -273,7 +416,6 @@ const handleSupervisorChange = (values) => {
   formData.value.supervisorIds = values;  // values 是选择的导师ID数组
 }
 
-
 /** 重置表单 */
 const resetForm = () => {
   formData.value = {
@@ -289,6 +431,7 @@ const resetForm = () => {
   }
   formRef.value?.resetFields()
 }
+
 /** 初始化 **/
 onMounted(() => {
   getSupervisor()
@@ -349,4 +492,3 @@ onMounted(() => {
   border-color: #66b1ff;
 }
 </style>
-