merge code pull
This commit is contained in:
@@ -433,6 +433,19 @@ export const changeMajor = (obj: any) => {
|
|||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 退档恢复
|
||||||
|
* @param obj
|
||||||
|
*/
|
||||||
|
export const resetSign = (obj: any) => {
|
||||||
|
return request({
|
||||||
|
url: '/recruit/recruitstudentsignup/resetSign',
|
||||||
|
method: 'post',
|
||||||
|
data: obj,
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 重新推送
|
* 重新推送
|
||||||
* @param obj
|
* @param obj
|
||||||
@@ -550,3 +563,11 @@ export const interview = (obj: any) => {
|
|||||||
data: obj,
|
data: obj,
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
export const queryAllRecruitUser = () => {
|
||||||
|
return request({
|
||||||
|
url: '/recruit/recruitstudentsignup/queryAllRecruitUser',
|
||||||
|
method: 'get'
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|||||||
@@ -52,8 +52,8 @@ export const delObj = (id: string | number) => {
|
|||||||
*/
|
*/
|
||||||
export const putObj = (obj: any) => {
|
export const putObj = (obj: any) => {
|
||||||
return request({
|
return request({
|
||||||
url: '/recruit/recruitstudentsignupturnover',
|
url: '/recruit/recruitstudentsignupturnover/edit',
|
||||||
method: 'put',
|
method: 'post',
|
||||||
data: obj,
|
data: obj,
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -2,7 +2,8 @@
|
|||||||
<el-tag
|
<el-tag
|
||||||
:type="type"
|
:type="type"
|
||||||
:size="size"
|
:size="size"
|
||||||
:class="['clickable-tag', { 'has-action': actualRightIcon !== null }]"
|
:class="['clickable-tag', { 'has-action': actualRightIcon !== null}]"
|
||||||
|
:style="{ width: width ? `${width}px` : 'auto' }"
|
||||||
@click="handleClick">
|
@click="handleClick">
|
||||||
<!-- 左侧图标 -->
|
<!-- 左侧图标 -->
|
||||||
<el-icon
|
<el-icon
|
||||||
@@ -43,6 +44,7 @@ interface Props {
|
|||||||
leftIcon?: any // 左侧图标组件
|
leftIcon?: any // 左侧图标组件
|
||||||
middleIcon?: any // 中间图标组件(如警告图标)
|
middleIcon?: any // 中间图标组件(如警告图标)
|
||||||
rightIcon?: any // 右侧图标组件(默认为 Right null 则不显示)
|
rightIcon?: any // 右侧图标组件(默认为 Right null 则不显示)
|
||||||
|
width?: string | number // 自定义宽度
|
||||||
}
|
}
|
||||||
|
|
||||||
const props = withDefaults(defineProps<Props>(), {
|
const props = withDefaults(defineProps<Props>(), {
|
||||||
@@ -50,7 +52,8 @@ const props = withDefaults(defineProps<Props>(), {
|
|||||||
size: 'default',
|
size: 'default',
|
||||||
leftIcon: undefined,
|
leftIcon: undefined,
|
||||||
middleIcon: undefined,
|
middleIcon: undefined,
|
||||||
rightIcon: undefined
|
rightIcon: undefined,
|
||||||
|
width: undefined
|
||||||
})
|
})
|
||||||
|
|
||||||
// 获取实际的右侧图标:未传值时使用默认图标,传 null 则不显示
|
// 获取实际的右侧图标:未传值时使用默认图标,传 null 则不显示
|
||||||
@@ -97,7 +100,6 @@ export default {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.middle-icon {
|
.middle-icon {
|
||||||
animation: pulse 1.5s ease-in-out infinite;
|
animation: pulse 1.5s ease-in-out infinite;
|
||||||
}
|
}
|
||||||
|
|||||||
162
src/components/DetailPopover/README.md
Normal file
162
src/components/DetailPopover/README.md
Normal file
@@ -0,0 +1,162 @@
|
|||||||
|
# DetailPopover 详情弹窗组件
|
||||||
|
|
||||||
|
一个通用的详情弹窗组件,用于展示结构化的详情信息。
|
||||||
|
|
||||||
|
## 功能特性
|
||||||
|
|
||||||
|
- ✅ 自定义标题和标题图标
|
||||||
|
- ✅ 支持多个详情项(label + content)
|
||||||
|
- ✅ 支持横向/纵向布局
|
||||||
|
- ✅ 支持自定义内容(插槽或组件)
|
||||||
|
- ✅ 支持标签图标
|
||||||
|
- ✅ 支持内容区域自定义样式类
|
||||||
|
|
||||||
|
## Props
|
||||||
|
|
||||||
|
| 参数 | 说明 | 类型 | 可选值 | 默认值 |
|
||||||
|
|-----|------|------|-------|--------|
|
||||||
|
| title | 标题 | string | - | '' |
|
||||||
|
| titleIcon | 标题图标组件 | Component | - | undefined |
|
||||||
|
| items | 详情项列表 | DetailItem[] | - | [] |
|
||||||
|
| placement | 弹出位置 | string | top/top-start/top-end/bottom/bottom-start/bottom-end/left/left-start/left-end/right/right-start/right-end | right |
|
||||||
|
| width | Popover 宽度 | string \| number | - | 300 |
|
||||||
|
| trigger | 触发方式 | string | click/focus/hover/contextmenu | click |
|
||||||
|
| popperClass | Popover 自定义类名 | string | - | '' |
|
||||||
|
|
||||||
|
## DetailItem 接口
|
||||||
|
|
||||||
|
```typescript
|
||||||
|
interface DetailItem {
|
||||||
|
label?: string // 标签文本
|
||||||
|
content?: string | number // 内容文本
|
||||||
|
labelIcon?: Component // 标签图标
|
||||||
|
layout?: 'horizontal' | 'vertical' // 布局方向,默认 vertical
|
||||||
|
contentClass?: string // 内容区域的自定义类名
|
||||||
|
component?: Component // 自定义组件
|
||||||
|
componentProps?: Record<string, any> // 自定义组件的 props
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
## Slots
|
||||||
|
|
||||||
|
| 插槽名 | 说明 | 参数 |
|
||||||
|
|--------|------|------|
|
||||||
|
| reference | 触发元素 | - |
|
||||||
|
| content-{index} | 自定义第 index 项的内容 | { item: DetailItem } |
|
||||||
|
| custom-content | 自定义内容(显示在所有详情项之后) | - |
|
||||||
|
|
||||||
|
## 使用示例
|
||||||
|
|
||||||
|
### 基础用法
|
||||||
|
|
||||||
|
```vue
|
||||||
|
<template>
|
||||||
|
<DetailPopover
|
||||||
|
title="专业变更详情"
|
||||||
|
:title-icon="InfoFilled"
|
||||||
|
:width="320"
|
||||||
|
:items="[
|
||||||
|
{ label: '旧专业', content: '计算机应用技术' },
|
||||||
|
{ label: '新专业', content: '软件技术', contentClass: 'new-major' }
|
||||||
|
]">
|
||||||
|
<template #reference>
|
||||||
|
<span class="link">查看详情</span>
|
||||||
|
</template>
|
||||||
|
</DetailPopover>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup>
|
||||||
|
import DetailPopover from '/@/components/DetailPopover/index.vue'
|
||||||
|
import { InfoFilled } from '@element-plus/icons-vue'
|
||||||
|
</script>
|
||||||
|
```
|
||||||
|
|
||||||
|
### 横向布局
|
||||||
|
|
||||||
|
```vue
|
||||||
|
<DetailPopover
|
||||||
|
title="异动审核详情"
|
||||||
|
:items="[
|
||||||
|
{
|
||||||
|
label: '审核状态',
|
||||||
|
layout: 'horizontal',
|
||||||
|
content: '待审核'
|
||||||
|
}
|
||||||
|
]">
|
||||||
|
<template #reference>
|
||||||
|
<el-button>查看</el-button>
|
||||||
|
</template>
|
||||||
|
</DetailPopover>
|
||||||
|
```
|
||||||
|
|
||||||
|
### 使用插槽自定义内容
|
||||||
|
|
||||||
|
```vue
|
||||||
|
<DetailPopover
|
||||||
|
title="异动审核详情"
|
||||||
|
:items="[
|
||||||
|
{ label: '审核状态', layout: 'horizontal' },
|
||||||
|
{ label: '备注信息', contentClass: 'reason-content' }
|
||||||
|
]">
|
||||||
|
<template #reference>
|
||||||
|
<ClickableTag>待审核</ClickableTag>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<!-- 自定义第一项内容 -->
|
||||||
|
<template #content-0>
|
||||||
|
<ClickableTag type="warning">待审核</ClickableTag>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<!-- 自定义第二项内容 -->
|
||||||
|
<template #content-1>
|
||||||
|
<div class="reason-content">
|
||||||
|
<el-icon><Warning /></el-icon>
|
||||||
|
<span>需要补充材料</span>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
</DetailPopover>
|
||||||
|
```
|
||||||
|
|
||||||
|
### 使用标签图标
|
||||||
|
|
||||||
|
```vue
|
||||||
|
<DetailPopover
|
||||||
|
title="详情"
|
||||||
|
:items="[
|
||||||
|
{
|
||||||
|
label: '状态',
|
||||||
|
labelIcon: CircleCheck,
|
||||||
|
content: '已完成'
|
||||||
|
}
|
||||||
|
]">
|
||||||
|
<template #reference>
|
||||||
|
<el-button>查看</el-button>
|
||||||
|
</template>
|
||||||
|
</DetailPopover>
|
||||||
|
```
|
||||||
|
|
||||||
|
## 样式自定义
|
||||||
|
|
||||||
|
可以通过 `contentClass` 为内容区域添加自定义样式类:
|
||||||
|
|
||||||
|
```vue
|
||||||
|
<DetailPopover
|
||||||
|
:items="[
|
||||||
|
{
|
||||||
|
label: '新专业',
|
||||||
|
content: '软件技术',
|
||||||
|
contentClass: 'new-major' // 添加自定义样式类
|
||||||
|
}
|
||||||
|
]">
|
||||||
|
<template #reference>
|
||||||
|
<span>查看</span>
|
||||||
|
</template>
|
||||||
|
</DetailPopover>
|
||||||
|
|
||||||
|
<style scoped>
|
||||||
|
.new-major {
|
||||||
|
color: var(--el-color-primary);
|
||||||
|
font-weight: 500;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
```
|
||||||
185
src/components/DetailPopover/index.vue
Normal file
185
src/components/DetailPopover/index.vue
Normal file
@@ -0,0 +1,185 @@
|
|||||||
|
<template>
|
||||||
|
<el-popover
|
||||||
|
:placement="placement"
|
||||||
|
:width="width"
|
||||||
|
:trigger="trigger"
|
||||||
|
:popper-class="popperClass">
|
||||||
|
<template #reference>
|
||||||
|
<slot name="reference"></slot>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<!-- 弹出内容 -->
|
||||||
|
<div class="detail-popover">
|
||||||
|
<!-- 标题 -->
|
||||||
|
<div v-if="title" class="detail-title">
|
||||||
|
<el-icon v-if="titleIcon" class="title-icon">
|
||||||
|
<component :is="titleIcon" />
|
||||||
|
</el-icon>
|
||||||
|
<span>{{ title }}</span>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- 详情项列表 -->
|
||||||
|
<div
|
||||||
|
v-for="(item, index) in items"
|
||||||
|
:key="index"
|
||||||
|
:class="['detail-section', { 'horizontal': item.layout === 'horizontal' }]">
|
||||||
|
<div v-if="item.label" class="section-label">
|
||||||
|
<el-icon v-if="item.labelIcon" class="label-icon">
|
||||||
|
<component :is="item.labelIcon" />
|
||||||
|
</el-icon>
|
||||||
|
<span>{{ item.label }}</span>
|
||||||
|
</div>
|
||||||
|
<div class="section-content" :class="item.contentClass">
|
||||||
|
<!-- 使用插槽自定义内容 -->
|
||||||
|
<slot
|
||||||
|
v-if="$slots[`content-${index}`]"
|
||||||
|
:name="`content-${index}`"
|
||||||
|
:item="item">
|
||||||
|
</slot>
|
||||||
|
<!-- 默认显示文本内容 -->
|
||||||
|
<template v-else>
|
||||||
|
<component
|
||||||
|
v-if="item.component"
|
||||||
|
:is="item.component"
|
||||||
|
v-bind="item.componentProps || {}">
|
||||||
|
</component>
|
||||||
|
<span v-else :class="item.contentClass">{{ item.content }}</span>
|
||||||
|
</template>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- 自定义内容插槽 -->
|
||||||
|
<slot name="custom-content"></slot>
|
||||||
|
</div>
|
||||||
|
</el-popover>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup lang="ts">
|
||||||
|
import type { Component } from 'vue'
|
||||||
|
|
||||||
|
export interface DetailItem {
|
||||||
|
label?: string // 标签文本
|
||||||
|
content?: string | number // 内容文本
|
||||||
|
labelIcon?: Component // 标签图标
|
||||||
|
layout?: 'horizontal' | 'vertical' // 布局方向,默认 vertical
|
||||||
|
contentClass?: string // 内容区域的自定义类名
|
||||||
|
component?: Component // 自定义组件
|
||||||
|
componentProps?: Record<string, any> // 自定义组件的 props
|
||||||
|
}
|
||||||
|
|
||||||
|
interface Props {
|
||||||
|
title?: string // 标题
|
||||||
|
titleIcon?: Component // 标题图标
|
||||||
|
items?: DetailItem[] // 详情项列表
|
||||||
|
placement?: 'top' | 'top-start' | 'top-end' | 'bottom' | 'bottom-start' | 'bottom-end' | 'left' | 'left-start' | 'left-end' | 'right' | 'right-start' | 'right-end'
|
||||||
|
width?: string | number // Popover 宽度
|
||||||
|
trigger?: 'click' | 'focus' | 'hover' | 'contextmenu' // 触发方式
|
||||||
|
popperClass?: string // Popover 自定义类名
|
||||||
|
}
|
||||||
|
|
||||||
|
withDefaults(defineProps<Props>(), {
|
||||||
|
title: '',
|
||||||
|
titleIcon: undefined,
|
||||||
|
items: () => [],
|
||||||
|
placement: 'right',
|
||||||
|
width: 300,
|
||||||
|
trigger: 'click',
|
||||||
|
popperClass: ''
|
||||||
|
})
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<script lang="ts">
|
||||||
|
export default {
|
||||||
|
name: 'DetailPopover'
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style scoped lang="scss">
|
||||||
|
.detail-popover {
|
||||||
|
padding: 0;
|
||||||
|
|
||||||
|
.detail-title {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
gap: 8px;
|
||||||
|
font-size: 15px;
|
||||||
|
font-weight: 600;
|
||||||
|
color: #303133;
|
||||||
|
margin-bottom: 20px;
|
||||||
|
padding-bottom: 16px;
|
||||||
|
border-bottom: 2px solid #EBEEF5;
|
||||||
|
|
||||||
|
.title-icon {
|
||||||
|
color: var(--el-color-primary);
|
||||||
|
font-size: 18px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.detail-section {
|
||||||
|
margin-bottom: 20px;
|
||||||
|
|
||||||
|
&:last-child {
|
||||||
|
margin-bottom: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 横向布局
|
||||||
|
&.horizontal {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
gap: 16px;
|
||||||
|
|
||||||
|
.section-label {
|
||||||
|
margin-bottom: 0;
|
||||||
|
white-space: nowrap;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
gap: 6px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.section-content {
|
||||||
|
flex: 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 纵向布局(默认)
|
||||||
|
&:not(.horizontal) {
|
||||||
|
.section-label {
|
||||||
|
margin-bottom: 10px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.section-label {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
gap: 6px;
|
||||||
|
font-size: 13px;
|
||||||
|
color: #909399;
|
||||||
|
font-weight: 500;
|
||||||
|
|
||||||
|
.label-icon {
|
||||||
|
font-size: 14px;
|
||||||
|
color: var(--el-color-primary);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.section-content {
|
||||||
|
font-size: 14px;
|
||||||
|
color: #303133;
|
||||||
|
line-height: 1.6;
|
||||||
|
word-break: break-all;
|
||||||
|
|
||||||
|
// 新专业样式(蓝色高亮)
|
||||||
|
&.new-major {
|
||||||
|
color: var(--el-color-primary);
|
||||||
|
font-weight: 500;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 支持嵌套的样式类
|
||||||
|
:deep(.new-major) {
|
||||||
|
color: var(--el-color-primary);
|
||||||
|
font-weight: 500;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
||||||
@@ -62,12 +62,6 @@ export const PUSHED_STATUS_LIST = [
|
|||||||
{ label: "已推送", value: "1" ,type: "success"},
|
{ label: "已推送", value: "1" ,type: "success"},
|
||||||
];
|
];
|
||||||
|
|
||||||
// 数据来源 (使用字典 recruit_data_source)
|
|
||||||
export const DATA_SOURCE_LIST = [
|
|
||||||
{ label: "学校", value: "0" },
|
|
||||||
{ label: "市平台", value: "1" }
|
|
||||||
];
|
|
||||||
|
|
||||||
// 录取通知书发放状态
|
// 录取通知书发放状态
|
||||||
export const NOTICE_SEND_STATUS_LIST = [
|
export const NOTICE_SEND_STATUS_LIST = [
|
||||||
{ label: "未发放", value: "0" },
|
{ label: "未发放", value: "0" },
|
||||||
@@ -123,6 +117,13 @@ export const NEW_CITY_MATERIAL_STATUS_LIST = [
|
|||||||
{ label: "已上传", value: "1" },
|
{ label: "已上传", value: "1" },
|
||||||
];
|
];
|
||||||
|
|
||||||
|
// 异动审核状态
|
||||||
|
export const TURNOVER_AUDIT_STATUS_LIST = [
|
||||||
|
{ label: "待审核", value: "1" ,type: "warning", icon: "Clock"},
|
||||||
|
{ label: "驳回", value: "2" ,type: "danger", icon: "CircleClose"},
|
||||||
|
{ label: "通过", value: "3" ,type: "success", icon: "CircleCheck"}
|
||||||
|
];
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 根据值从状态列表中获取配置项
|
* 根据值从状态列表中获取配置项
|
||||||
* @param statusList 状态列表
|
* @param statusList 状态列表
|
||||||
|
|||||||
@@ -350,6 +350,12 @@
|
|||||||
color: var(--el-text-color-regular);
|
color: var(--el-text-color-regular);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
&.detail-dialog .el-dialog__body {
|
||||||
|
min-height: 80vh !important;
|
||||||
|
max-height: 80vh !important;
|
||||||
|
height: 80vh !important;
|
||||||
|
}
|
||||||
|
|
||||||
.el-dialog__footer {
|
.el-dialog__footer {
|
||||||
padding: 12px 20px;
|
padding: 12px 20px;
|
||||||
|
|
||||||
|
|||||||
@@ -49,6 +49,7 @@ import { ref, reactive } from 'vue'
|
|||||||
import { useMessage } from '/@/hooks/message'
|
import { useMessage } from '/@/hooks/message'
|
||||||
import { useDict } from '/@/hooks/dict'
|
import { useDict } from '/@/hooks/dict'
|
||||||
import { putBackObj } from '/@/api/recruit/recruitstudentsignup'
|
import { putBackObj } from '/@/api/recruit/recruitstudentsignup'
|
||||||
|
import { getDicts } from '/@/api/admin/dict'
|
||||||
|
|
||||||
// 消息提示 hooks
|
// 消息提示 hooks
|
||||||
const message = useMessage()
|
const message = useMessage()
|
||||||
@@ -119,8 +120,8 @@ const init = async (formData: any, pageData: any) => {
|
|||||||
checkInStatusData.value = []
|
checkInStatusData.value = []
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const data = await getTypeValue('check_in_status')
|
const dictData = await getDicts('check_in_status')
|
||||||
checkInStatusData.value = data.data || []
|
checkInStatusData.value = dictData.data || []
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error('获取字典数据失败', error)
|
console.error('获取字典数据失败', error)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,32 +1,87 @@
|
|||||||
<!--
|
|
||||||
- Copyright (c) 2018-2025, cyweb All rights reserved.
|
|
||||||
-
|
|
||||||
- Redistribution and use in source and binary forms, with or without
|
|
||||||
- modification, are permitted provided that the following conditions are met:
|
|
||||||
-
|
|
||||||
- Redistributions of source code must retain the above copyright notice,
|
|
||||||
- this list of conditions and the following disclaimer.
|
|
||||||
- Redistributions in binary form must reproduce the above copyright
|
|
||||||
- notice, this list of conditions and the following disclaimer in the
|
|
||||||
- documentation and/or other materials provided with the distribution.
|
|
||||||
- Neither the name of the pig4cloud.com developer nor the names of its
|
|
||||||
- contributors may be used to endorse or promote products derived from
|
|
||||||
- this software without specific prior written permission.
|
|
||||||
-
|
|
||||||
-->
|
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<div class="layout-padding">
|
<div class="layout-padding">
|
||||||
<div class="layout-padding-auto layout-padding-view">
|
<div class="layout-padding-auto layout-padding-view">
|
||||||
<!-- 搜索表单 -->
|
<!-- 搜索表单 -->
|
||||||
<el-form :model="queryForm" inline>
|
<el-form :model="queryForm" inline ref="searchFormRef">
|
||||||
<el-form-item label="">
|
<el-form-item label="关键词">
|
||||||
<el-input
|
<el-input
|
||||||
v-model="queryForm.searchTotal"
|
v-model="queryForm.searchTotal"
|
||||||
clearable
|
clearable
|
||||||
placeholder="请输入姓名/身份证号/家庭联系人"
|
placeholder="请输入姓名/身份证号/家庭联系人"
|
||||||
/>
|
/>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
|
<el-form-item label="学院" prop="deptCode">
|
||||||
|
<el-select
|
||||||
|
v-model="queryForm.deptCode"
|
||||||
|
filterable
|
||||||
|
clearable
|
||||||
|
placeholder="请选择学院"
|
||||||
|
style="width: 200px">
|
||||||
|
<el-option
|
||||||
|
v-for="item in deptList"
|
||||||
|
:key="item.deptCode"
|
||||||
|
:label="item.deptName"
|
||||||
|
:value="item.deptCode"
|
||||||
|
/>
|
||||||
|
</el-select>
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="入学年份" prop="grade">
|
||||||
|
<el-select
|
||||||
|
v-model="queryForm.grade"
|
||||||
|
filterable
|
||||||
|
clearable
|
||||||
|
placeholder="请选择入学年份"
|
||||||
|
style="width: 150px">
|
||||||
|
<el-option
|
||||||
|
v-for="item in planList"
|
||||||
|
:key="item.id"
|
||||||
|
:label="item.year"
|
||||||
|
:value="item.year"
|
||||||
|
/>
|
||||||
|
</el-select>
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="班级" prop="classCode">
|
||||||
|
<el-select
|
||||||
|
v-model="queryForm.classCode"
|
||||||
|
filterable
|
||||||
|
clearable
|
||||||
|
placeholder="请选择班级"
|
||||||
|
style="width: 200px">
|
||||||
|
<el-option
|
||||||
|
v-for="item in classList"
|
||||||
|
:key="item.classCode"
|
||||||
|
:label="item.classNo"
|
||||||
|
:value="item.classCode"
|
||||||
|
/>
|
||||||
|
</el-select>
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="报到状态" prop="checkInStatus">
|
||||||
|
<el-select
|
||||||
|
v-model="queryForm.checkInStatus"
|
||||||
|
filterable
|
||||||
|
clearable
|
||||||
|
placeholder="请选择报到状态"
|
||||||
|
style="width: 150px">
|
||||||
|
<el-option
|
||||||
|
v-for="item in checkInStatusData"
|
||||||
|
:key="item.value"
|
||||||
|
:label="item.label"
|
||||||
|
:value="item.value"
|
||||||
|
/>
|
||||||
|
</el-select>
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="住宿申请" prop="isDormApply">
|
||||||
|
<el-select
|
||||||
|
v-model="queryForm.isDormApply"
|
||||||
|
filterable
|
||||||
|
clearable
|
||||||
|
placeholder="请选择住宿申请"
|
||||||
|
style="width: 150px">
|
||||||
|
<el-option label="未通过" value="0" />
|
||||||
|
<el-option label="申请通过" value="1" />
|
||||||
|
</el-select>
|
||||||
|
</el-form-item>
|
||||||
|
|
||||||
<el-form-item>
|
<el-form-item>
|
||||||
<el-button type="primary" icon="Search" @click="getDataList">查询</el-button>
|
<el-button type="primary" icon="Search" @click="getDataList">查询</el-button>
|
||||||
<el-button icon="Refresh" class="ml10" @click="resetQuery">重置</el-button>
|
<el-button icon="Refresh" class="ml10" @click="resetQuery">重置</el-button>
|
||||||
@@ -60,7 +115,7 @@
|
|||||||
<el-table-column type="index" label="序号" width="60" align="center" />
|
<el-table-column type="index" label="序号" width="60" align="center" />
|
||||||
<el-table-column prop="deptCode" label="学院" align="center" show-overflow-tooltip />
|
<el-table-column prop="deptCode" label="学院" align="center" show-overflow-tooltip />
|
||||||
<el-table-column prop="classCode" label="班级" align="center" width="80" show-overflow-tooltip />
|
<el-table-column prop="classCode" label="班级" align="center" width="80" show-overflow-tooltip />
|
||||||
<el-table-column label="姓名/学号" align="center" width="150" show-overflow-tooltip>
|
<el-table-column label="姓名/学号" align="center" min-width="150" show-overflow-tooltip>
|
||||||
<template #default="scope">
|
<template #default="scope">
|
||||||
<TeacherNameNo :name="scope.row.name" :no="scope.row.stuNo" />
|
<TeacherNameNo :name="scope.row.name" :no="scope.row.stuNo" />
|
||||||
</template>
|
</template>
|
||||||
@@ -78,32 +133,99 @@
|
|||||||
</el-tag>
|
</el-tag>
|
||||||
</template>
|
</template>
|
||||||
</el-table-column>
|
</el-table-column>
|
||||||
<el-table-column prop="isDormApply" label="住宿申请" align="center" width="100">
|
<el-table-column prop="isRoom" label="是否住宿" align="center" width="120">
|
||||||
<template #default="scope">
|
<template #default="scope">
|
||||||
<el-tag v-if="scope.row.isDormApply == '1'" type="success">通过</el-tag>
|
<template v-if="scope.row.isRoom == '1'">
|
||||||
<el-tag v-else-if="scope.row.isDormApply == '0'" type="info">未通过</el-tag>
|
<DetailPopover
|
||||||
|
title="住宿信息"
|
||||||
|
:title-icon="InfoFilled"
|
||||||
|
:width="320"
|
||||||
|
:items="[
|
||||||
|
{
|
||||||
|
label: '住宿申请',
|
||||||
|
layout: 'horizontal'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: '宿舍号',
|
||||||
|
layout: 'horizontal'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: '床位号',
|
||||||
|
layout: 'horizontal'
|
||||||
|
}
|
||||||
|
]">
|
||||||
|
<template #reference>
|
||||||
|
<el-tag type="success" class="dorm-tag">
|
||||||
|
{{ getStatusConfig(yes_no_type, scope.row.isRoom)?.label }}
|
||||||
|
<el-icon class="info-icon"><InfoFilled /></el-icon>
|
||||||
|
</el-tag>
|
||||||
|
</template>
|
||||||
|
<!-- 住宿申请状态 -->
|
||||||
|
<template #content-0>
|
||||||
|
<div class="dorm-apply-content">
|
||||||
|
<ClickableTag
|
||||||
|
v-if="scope.row.isDormApply == '1'"
|
||||||
|
type="success"
|
||||||
|
size="small"
|
||||||
|
:left-icon="CircleCheck"
|
||||||
|
:right-icon="null">
|
||||||
|
申请通过
|
||||||
|
</ClickableTag>
|
||||||
|
<ClickableTag
|
||||||
|
v-else-if="scope.row.isDormApply == '0'"
|
||||||
|
type="danger"
|
||||||
|
size="small"
|
||||||
|
:left-icon="CircleClose"
|
||||||
|
:right-icon="null">
|
||||||
|
未通过
|
||||||
|
</ClickableTag>
|
||||||
|
<span v-else class="empty-text">-</span>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
<!-- 宿舍号 -->
|
||||||
|
<template #content-1>
|
||||||
|
<div class="dorm-room-content">
|
||||||
|
<span :class="scope.row.roomNo ? 'room-text' : 'empty-text'">
|
||||||
|
{{ scope.row.roomNo || '-' }}
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
<!-- 床位号 -->
|
||||||
|
<template #content-2>
|
||||||
|
<el-tag v-if="scope.row.bedNo" size="small" type="sucess" effect="dark">
|
||||||
|
{{ scope.row.bedNo }}号
|
||||||
|
</el-tag>
|
||||||
|
</template>
|
||||||
|
</DetailPopover>
|
||||||
|
</template>
|
||||||
|
<span v-else>{{ getStatusConfig(yes_no_type, scope.row.isRoom)?.label }}</span>
|
||||||
</template>
|
</template>
|
||||||
</el-table-column>
|
</el-table-column>
|
||||||
<el-table-column prop="isRoom" label="是否住宿" align="center" width="100">
|
<el-table-column prop="degreeOfEducation" label="文化程度" align="center" show-overflow-tooltip >
|
||||||
<template #default="scope">
|
<template #default="scope">
|
||||||
<span>{{ scope.row.isRoom === '1' ? '是' : scope.row.isRoom === '0' ? '否' : '' }}</span>
|
<span>{{ getStatusConfig(eduList, scope.row.degreeOfEducation)?.label }}</span>
|
||||||
</template>
|
</template>
|
||||||
</el-table-column>
|
</el-table-column>
|
||||||
<el-table-column prop="roomNo" label="宿舍号" align="center" width="80" show-overflow-tooltip />
|
|
||||||
<el-table-column prop="bedNo" label="床位号" align="center" width="80" show-overflow-tooltip />
|
|
||||||
<el-table-column prop="degreeOfEducation" label="文化程度" align="center" show-overflow-tooltip />
|
|
||||||
<el-table-column prop="residenceDetail" label="居住地址" align="center" show-overflow-tooltip />
|
<el-table-column prop="residenceDetail" label="居住地址" align="center" show-overflow-tooltip />
|
||||||
<el-table-column prop="parentName" label="家庭联系人" width="100" align="center" show-overflow-tooltip />
|
<el-table-column prop="parentName" label="家庭联系人" width="100" align="center" show-overflow-tooltip />
|
||||||
<el-table-column prop="parentTelOne" label="家长电话1" align="center" show-overflow-tooltip />
|
<el-table-column label="家长电话" align="center" show-overflow-tooltip>
|
||||||
<el-table-column prop="parentTelTwo" label="家长电话2" align="center" show-overflow-tooltip />
|
<template #default="scope">
|
||||||
|
<div v-if="scope.row.parentTelOne || scope.row.parentTelTwo" class="parent-tel">
|
||||||
|
<span v-if="scope.row.parentTelOne" class="tel-item">{{ scope.row.parentTelOne }}</span>
|
||||||
|
<span v-if="scope.row.parentTelOne && scope.row.parentTelTwo" class="tel-separator">/</span>
|
||||||
|
<span v-if="scope.row.parentTelTwo" class="tel-item">{{ scope.row.parentTelTwo }}</span>
|
||||||
|
</div>
|
||||||
|
<span v-else class="empty-text">-</span>
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
<el-table-column prop="remarks" label="备注" align="center" show-overflow-tooltip />
|
<el-table-column prop="remarks" label="备注" align="center" show-overflow-tooltip />
|
||||||
<el-table-column label="操作" width="100" align="center" fixed="right">
|
<el-table-column label="操作" width="100" align="center" fixed="right">
|
||||||
<template #default="scope">
|
<template #default="scope">
|
||||||
<el-button
|
<el-button
|
||||||
v-if="permissions.recruit_newstucheckin_edit"
|
v-auth="'recruit_newstucheckin_edit'"
|
||||||
type="primary"
|
type="primary"
|
||||||
link
|
link
|
||||||
icon="CircleCheck"
|
icon="EditPen"
|
||||||
@click="handleCheckIn(scope.row)"
|
@click="handleCheckIn(scope.row)"
|
||||||
>
|
>
|
||||||
报到
|
报到
|
||||||
@@ -132,13 +254,23 @@ import { useUserInfo } from '/@/stores/userInfo'
|
|||||||
import { BasicTableProps, useTable } from '/@/hooks/table'
|
import { BasicTableProps, useTable } from '/@/hooks/table'
|
||||||
import { useMessage } from '/@/hooks/message'
|
import { useMessage } from '/@/hooks/message'
|
||||||
import { fetchList } from '/@/api/recruit/newstucheckin'
|
import { fetchList } from '/@/api/recruit/newstucheckin'
|
||||||
import { getTypeValue } from '/@/api/admin/dict'
|
import { getDictsByTypes } from '/@/api/admin/dict'
|
||||||
|
import { useDict } from '/@/hooks/dict'
|
||||||
import request from '/@/utils/request'
|
import request from '/@/utils/request'
|
||||||
|
import { getStatusConfig } from '/@/config/global'
|
||||||
|
import { getDeptList, getClassListByRole } from '/@/api/basic/basicclass'
|
||||||
|
import { getList } from '/@/api/recruit/recruitstudentplangroup'
|
||||||
|
import DetailPopover from '/@/components/DetailPopover/index.vue'
|
||||||
|
import ClickableTag from '/@/components/ClickableTag/index.vue'
|
||||||
|
import { InfoFilled, CircleCheck, CircleClose, HomeFilled, Grid } from '@element-plus/icons-vue'
|
||||||
|
|
||||||
const StuCheckIn = defineAsyncComponent(() => import('./stu-check-in.vue'))
|
const StuCheckIn = defineAsyncComponent(() => import('./stu-check-in.vue'))
|
||||||
const TeacherNameNo = defineAsyncComponent(() => import('/@/components/TeacherNameNo/index.vue'))
|
const TeacherNameNo = defineAsyncComponent(() => import('/@/components/TeacherNameNo/index.vue'))
|
||||||
const GenderTag = defineAsyncComponent(() => import('/@/components/GenderTag/index.vue'))
|
const GenderTag = defineAsyncComponent(() => import('/@/components/GenderTag/index.vue'))
|
||||||
|
|
||||||
|
// 是否住宿字典
|
||||||
|
const { yes_no_type } = useDict('yes_no_type')
|
||||||
|
|
||||||
// 使用 Pinia store
|
// 使用 Pinia store
|
||||||
const userInfoStore = useUserInfo()
|
const userInfoStore = useUserInfo()
|
||||||
const { userInfos } = storeToRefs(userInfoStore)
|
const { userInfos } = storeToRefs(userInfoStore)
|
||||||
@@ -155,15 +287,29 @@ const permissions = computed(() => {
|
|||||||
// 消息提示 hooks
|
// 消息提示 hooks
|
||||||
const message = useMessage()
|
const message = useMessage()
|
||||||
|
|
||||||
|
// 文化程度字典数据
|
||||||
|
const eduList = ref<any[]>([])
|
||||||
|
|
||||||
// 表格引用
|
// 表格引用
|
||||||
const tableRef = ref()
|
const tableRef = ref()
|
||||||
|
const searchFormRef = ref()
|
||||||
const stuCheckInRef = ref()
|
const stuCheckInRef = ref()
|
||||||
|
|
||||||
// 导出加载状态
|
// 导出加载状态
|
||||||
const exportLoading = ref(false)
|
const exportLoading = ref(false)
|
||||||
|
|
||||||
|
// 数据列表
|
||||||
|
const deptList = ref<any[]>([])
|
||||||
|
const planList = ref<any[]>([])
|
||||||
|
const classList = ref<any[]>([])
|
||||||
|
|
||||||
// 查询表单
|
// 查询表单
|
||||||
const queryForm = reactive({
|
const queryForm = reactive({
|
||||||
|
deptCode: '',
|
||||||
|
grade: '',
|
||||||
|
classCode: '',
|
||||||
|
checkInStatus: '',
|
||||||
|
isDormApply: '',
|
||||||
searchTotal: ''
|
searchTotal: ''
|
||||||
})
|
})
|
||||||
|
|
||||||
@@ -176,6 +322,11 @@ const state: BasicTableProps = reactive<BasicTableProps>({
|
|||||||
pageList: async (params: any) => {
|
pageList: async (params: any) => {
|
||||||
const response = await fetchList({
|
const response = await fetchList({
|
||||||
...params,
|
...params,
|
||||||
|
deptCode: queryForm.deptCode,
|
||||||
|
grade: queryForm.grade,
|
||||||
|
classCode: queryForm.classCode,
|
||||||
|
checkInStatus: queryForm.checkInStatus,
|
||||||
|
isDormApply: queryForm.isDormApply,
|
||||||
searchTotal: queryForm.searchTotal
|
searchTotal: queryForm.searchTotal
|
||||||
})
|
})
|
||||||
return {
|
return {
|
||||||
@@ -198,6 +349,12 @@ const getCheckInStatusLabel = (value: string) => {
|
|||||||
|
|
||||||
// 重置查询
|
// 重置查询
|
||||||
const resetQuery = () => {
|
const resetQuery = () => {
|
||||||
|
searchFormRef.value?.resetFields()
|
||||||
|
queryForm.deptCode = ''
|
||||||
|
queryForm.grade = ''
|
||||||
|
queryForm.classCode = ''
|
||||||
|
queryForm.checkInStatus = ''
|
||||||
|
queryForm.isDormApply = ''
|
||||||
queryForm.searchTotal = ''
|
queryForm.searchTotal = ''
|
||||||
getDataList()
|
getDataList()
|
||||||
}
|
}
|
||||||
@@ -256,20 +413,123 @@ const handleExportOut = async () => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// 查询报到状态字典
|
// 查询报到状态字典
|
||||||
const getCheckInStatusData = async () => {
|
const getDictsData = async () => {
|
||||||
try {
|
try {
|
||||||
const data = await getTypeValue('check_in_status')
|
const data = await getDictsByTypes(['check_in_status','finance_student_source'])
|
||||||
checkInStatusData.value = data.data || []
|
checkInStatusData.value = data.data.check_in_status || []
|
||||||
|
eduList.value = data.data.finance_student_source || []
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
// 获取报到状态字典失败
|
// 获取报到状态字典失败
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
onMounted(() => {
|
// 初始化数据
|
||||||
getCheckInStatusData()
|
const init = async () => {
|
||||||
|
try {
|
||||||
|
// 获取学院列表
|
||||||
|
const deptData = await getDeptList()
|
||||||
|
deptList.value = deptData.data || []
|
||||||
|
|
||||||
|
// 获取入学年份列表(招生计划)
|
||||||
|
const planData = await getList()
|
||||||
|
planList.value = planData.data || []
|
||||||
|
|
||||||
|
// 获取班级列表
|
||||||
|
const classData = await getClassListByRole()
|
||||||
|
classList.value = classData.data || []
|
||||||
|
|
||||||
|
// 获取字典数据
|
||||||
|
await getDictsData()
|
||||||
|
|
||||||
getDataList()
|
getDataList()
|
||||||
|
} catch (error) {
|
||||||
|
message.error('初始化失败')
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
onMounted(() => {
|
||||||
|
init()
|
||||||
})
|
})
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style lang="scss" scoped>
|
<style lang="scss" scoped>
|
||||||
|
.parent-tel {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
gap: 4px;
|
||||||
|
|
||||||
|
.tel-item {
|
||||||
|
color: #303133;
|
||||||
|
}
|
||||||
|
|
||||||
|
.tel-separator {
|
||||||
|
color: #909399;
|
||||||
|
margin: 0 2px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.empty-text {
|
||||||
|
color: #909399;
|
||||||
|
}
|
||||||
|
|
||||||
|
.dorm-tag {
|
||||||
|
display: inline-flex;
|
||||||
|
align-items: center;
|
||||||
|
gap: 4px;
|
||||||
|
cursor: pointer;
|
||||||
|
transition: all 0.2s ease;
|
||||||
|
|
||||||
|
&:hover {
|
||||||
|
transform: translateY(-1px);
|
||||||
|
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
|
||||||
|
}
|
||||||
|
|
||||||
|
.info-icon {
|
||||||
|
font-size: 12px;
|
||||||
|
opacity: 0.8;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 住宿申请状态内容
|
||||||
|
.dorm-apply-content {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 宿舍号内容
|
||||||
|
.dorm-room-content {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
gap: 6px;
|
||||||
|
|
||||||
|
.room-icon {
|
||||||
|
color: var(--el-color-primary);
|
||||||
|
font-size: 16px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.room-text {
|
||||||
|
color: var(--el-color-primary);
|
||||||
|
font-weight: 600;
|
||||||
|
font-size: 15px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 床位号内容
|
||||||
|
.dorm-bed-content {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
gap: 6px;
|
||||||
|
|
||||||
|
.bed-icon {
|
||||||
|
color: var(--el-color-primary);
|
||||||
|
font-size: 16px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.bed-text {
|
||||||
|
color: var(--el-color-primary);
|
||||||
|
font-weight: 600;
|
||||||
|
font-size: 15px;
|
||||||
|
}
|
||||||
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|||||||
@@ -1,30 +1,24 @@
|
|||||||
<template>
|
<template>
|
||||||
<div>
|
<div>
|
||||||
<el-dialog v-model="newStuCheckInDialog" width="40%">
|
<el-dialog v-model="newStuCheckInDialog" width="600" title="新生报到">
|
||||||
<el-form :model="form" :rules="rules" ref="formRef" label-width="120px"
|
<el-form :model="form" :rules="rules" ref="formRef" label-width="100px"
|
||||||
class="demo-ruleForm">
|
class="demo-ruleForm">
|
||||||
|
|
||||||
<el-form-item label="姓名" prop="realName">
|
<el-form-item label="姓名" prop="realName">
|
||||||
<el-input v-model="form.name" style=" width: 80%"></el-input>
|
<el-input v-model="form.name"></el-input>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
|
|
||||||
<el-form-item label="性别" prop="gender">
|
<el-form-item label="性别" prop="gender">
|
||||||
<el-select v-model="form.gender" placeholder="请选择性别" style=" width: 80%">
|
<el-radio-group v-model="form.gender">
|
||||||
<el-option
|
<el-radio v-for="item in genderData" :key="item.value" :label="item.value">{{ item.label }}</el-radio>
|
||||||
v-for="item in genderData"
|
</el-radio-group>
|
||||||
:key="item.value"
|
|
||||||
:label="item.label"
|
|
||||||
:value="item.value">
|
|
||||||
</el-option>
|
|
||||||
</el-select>
|
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
|
|
||||||
<el-form-item label="身份证号" prop="idCard">
|
<el-form-item label="身份证号" prop="idCard">
|
||||||
<el-input v-model="form.idNumber" style=" width: 80%"></el-input>
|
<el-input v-model="form.idNumber"></el-input>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
|
|
||||||
<el-form-item label="报到状态" prop="checkInStatus">
|
<el-form-item label="报到状态" prop="checkInStatus">
|
||||||
<el-select v-model="form.checkInStatus" filterable placeholder="请选择报到状态" style=" width: 80% ">
|
<el-select v-model="form.checkInStatus" filterable placeholder="请选择报到状态">
|
||||||
<el-option
|
<el-option
|
||||||
v-for="item in checkInStatusData"
|
v-for="item in checkInStatusData"
|
||||||
:key="item.value"
|
:key="item.value"
|
||||||
@@ -35,7 +29,7 @@
|
|||||||
</el-form-item>
|
</el-form-item>
|
||||||
|
|
||||||
<el-form-item label="是否住宿" prop="isRoom" v-if="isRoomTab">
|
<el-form-item label="是否住宿" prop="isRoom" v-if="isRoomTab">
|
||||||
<el-select v-model="form.isRoom" filterable placeholder="是否住宿" style=" width: 80% ">
|
<el-select v-model="form.isRoom" filterable placeholder="是否住宿">
|
||||||
<el-option
|
<el-option
|
||||||
v-for="item in yesOrNoData"
|
v-for="item in yesOrNoData"
|
||||||
:key="item.value"
|
:key="item.value"
|
||||||
@@ -54,7 +48,6 @@
|
|||||||
:remote-method="remoteMethod"
|
:remote-method="remoteMethod"
|
||||||
@change="handleRoomNoChange"
|
@change="handleRoomNoChange"
|
||||||
:loading="loading"
|
:loading="loading"
|
||||||
style=" width: 80% "
|
|
||||||
>
|
>
|
||||||
<el-option
|
<el-option
|
||||||
v-for="item in roomNoList"
|
v-for="item in roomNoList"
|
||||||
@@ -66,7 +59,7 @@
|
|||||||
</el-form-item>
|
</el-form-item>
|
||||||
|
|
||||||
<el-form-item label="床号" prop="bedNo" v-if="isRoomTab && form.isRoom=='1'">
|
<el-form-item label="床号" prop="bedNo" v-if="isRoomTab && form.isRoom=='1'">
|
||||||
<el-select v-model="form.bedNo" filterable placeholder="请选择床号" style=" width: 80% " :key="bedNoKey">
|
<el-select v-model="form.bedNo" filterable placeholder="请选择床号" :key="bedNoKey">
|
||||||
<el-option
|
<el-option
|
||||||
v-for="item in bedNoData"
|
v-for="item in bedNoData"
|
||||||
:key="item.bedNo"
|
:key="item.bedNo"
|
||||||
@@ -78,13 +71,13 @@
|
|||||||
</el-form-item>
|
</el-form-item>
|
||||||
|
|
||||||
<el-form-item label="备注" prop="remarks">
|
<el-form-item label="备注" prop="remarks">
|
||||||
<el-input v-model="form.remarks" :rows="2" style=" width: 80%"></el-input>
|
<el-input v-model="form.remarks" :rows="2"></el-input>
|
||||||
</el-form-item>
|
|
||||||
<el-form-item>
|
|
||||||
<el-button type="primary" @click="checkIn" v-loading="submitLoading">确定</el-button>
|
|
||||||
<el-button @click="newStuCheckInDialog = false">取消</el-button>
|
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
</el-form>
|
</el-form>
|
||||||
|
<template #footer>
|
||||||
|
<el-button @click="newStuCheckInDialog = false">取消</el-button>
|
||||||
|
<el-button type="primary" @click="checkIn" :loading="submitLoading">确定</el-button>
|
||||||
|
</template>
|
||||||
</el-dialog>
|
</el-dialog>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
@@ -92,10 +85,12 @@
|
|||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import { ref, reactive, watch } from 'vue'
|
import { ref, reactive, watch } from 'vue'
|
||||||
import { useMessage } from '/@/hooks/message'
|
import { useMessage } from '/@/hooks/message'
|
||||||
import { getDataByRoomNo } from "/@/api/stuwork/dormroom"
|
|
||||||
import { fearchRoomStuNum } from "/@/api/stuwork/dormroomstudent"
|
import { fearchRoomStuNum } from "/@/api/stuwork/dormroomstudent"
|
||||||
import { getDicts } from "/@/api/admin/dict"
|
import { putObj } from '/@/api/recruit/newstucheckin'
|
||||||
import { putObj } from '@/api/recruit/newstucheckin'
|
import { useDict } from '/@/hooks/dict'
|
||||||
|
import { getDicts } from '/@/api/admin/dict'
|
||||||
|
import { getDataByRoomNo } from '/@/api/stuwork/dormroom'
|
||||||
|
const { sexy:genderData ,yes_no_type:yesOrNoData} = useDict('sexy','yes_no_type')
|
||||||
|
|
||||||
// Emits
|
// Emits
|
||||||
const emit = defineEmits<{
|
const emit = defineEmits<{
|
||||||
@@ -118,15 +113,7 @@ const loading = ref(false)
|
|||||||
const isRoomTab = ref(false)
|
const isRoomTab = ref(false)
|
||||||
const bedNoKey = ref(0) // 用于强制更新床号选择器
|
const bedNoKey = ref(0) // 用于强制更新床号选择器
|
||||||
|
|
||||||
const yesOrNoData = [
|
|
||||||
{ label: '否', value: '0' },
|
|
||||||
{ label: '是', value: '1' }
|
|
||||||
]
|
|
||||||
|
|
||||||
const genderData = [
|
|
||||||
{ label: '女', value: '2' },
|
|
||||||
{ label: '男', value: '1' }
|
|
||||||
]
|
|
||||||
|
|
||||||
const submitLoading = ref(false)
|
const submitLoading = ref(false)
|
||||||
|
|
||||||
@@ -225,7 +212,6 @@ const init = (formData: any, pageData: any) => {
|
|||||||
getDicts('check_in_status').then(data => {
|
getDicts('check_in_status').then(data => {
|
||||||
checkInStatusData.value = data.data
|
checkInStatusData.value = data.data
|
||||||
})
|
})
|
||||||
console.log("OKKK")
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// 报到提交
|
// 报到提交
|
||||||
@@ -255,8 +241,6 @@ const remoteMethod = (query: string) => {
|
|||||||
loading.value = true
|
loading.value = true
|
||||||
getDataByRoomNo(data).then(data => {
|
getDataByRoomNo(data).then(data => {
|
||||||
roomNoList.value = data.data
|
roomNoList.value = data.data
|
||||||
console.log("this.roomNoList")
|
|
||||||
console.log(roomNoList.value)
|
|
||||||
loading.value = false
|
loading.value = false
|
||||||
}).catch(() => {
|
}).catch(() => {
|
||||||
loading.value = false
|
loading.value = false
|
||||||
@@ -266,8 +250,7 @@ const remoteMethod = (query: string) => {
|
|||||||
|
|
||||||
// 查询此房间为几人间
|
// 查询此房间为几人间
|
||||||
const fearchRoomStuNums = (roomNo: string) => {
|
const fearchRoomStuNums = (roomNo: string) => {
|
||||||
const data = { "roomNo": roomNo }
|
fearchRoomStuNum(roomNo).then(data => {
|
||||||
fearchRoomStuNum(data).then(data => {
|
|
||||||
bedNoData.value = data.data
|
bedNoData.value = data.data
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -299,7 +299,7 @@ import { getObj, addObjStu, putObj } from '/@/api/recruit/recruitprestudent'
|
|||||||
import { getList } from '/@/api/recruit/recruitstudentplangroup'
|
import { getList } from '/@/api/recruit/recruitstudentplangroup'
|
||||||
import { getDicts } from '/@/api/admin/dict'
|
import { getDicts } from '/@/api/admin/dict'
|
||||||
import { queryAllTeacherByRecruit } from '/@/api/professional/professionaluser/teacherbase'
|
import { queryAllTeacherByRecruit } from '/@/api/professional/professionaluser/teacherbase'
|
||||||
import { verifyIdCardAll, verifyPhone, verifyAdmissionNumber } from '/@/utils/toolsValidate'
|
import { verifyPhone, verifyAdmissionNumber } from '/@/utils/toolsValidate'
|
||||||
|
|
||||||
// Props
|
// Props
|
||||||
const props = defineProps<{
|
const props = defineProps<{
|
||||||
@@ -379,17 +379,7 @@ const dataRule = {
|
|||||||
}
|
}
|
||||||
],
|
],
|
||||||
idCard: [
|
idCard: [
|
||||||
{ required: true, message: '身份证不能为空', trigger: 'blur' },
|
{ required: true, message: '身份证不能为空', trigger: 'blur' }
|
||||||
{
|
|
||||||
validator: (rule: any, value: any, callback: any) => {
|
|
||||||
if (value && !verifyIdCardAll(value)) {
|
|
||||||
callback(new Error('请输入正确的身份证号码'))
|
|
||||||
} else {
|
|
||||||
callback()
|
|
||||||
}
|
|
||||||
},
|
|
||||||
trigger: 'blur'
|
|
||||||
}
|
|
||||||
],
|
],
|
||||||
admission: [
|
admission: [
|
||||||
{ required: true, message: '准考证不能为空', trigger: 'blur' },
|
{ required: true, message: '准考证不能为空', trigger: 'blur' },
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
@@ -294,14 +294,6 @@
|
|||||||
icon="Download"
|
icon="Download"
|
||||||
@click="handleExport()">名单导出
|
@click="handleExport()">名单导出
|
||||||
</el-button>
|
</el-button>
|
||||||
<!-- <el-button
|
|
||||||
class="ml10"
|
|
||||||
type="primary"
|
|
||||||
plain
|
|
||||||
icon="UploadFilled"
|
|
||||||
v-auth="'recruit_send_img'"
|
|
||||||
@click="handleSendImg()">图片同步
|
|
||||||
</el-button> -->
|
|
||||||
</div>
|
</div>
|
||||||
</el-row>
|
</el-row>
|
||||||
|
|
||||||
@@ -637,15 +629,9 @@
|
|||||||
<!-- 支付二维码弹窗 -->
|
<!-- 支付二维码弹窗 -->
|
||||||
<PayQrcodeDialog ref="payQrcodeDialogRef" @refresh="getDataList"></PayQrcodeDialog>
|
<PayQrcodeDialog ref="payQrcodeDialogRef" @refresh="getDataList"></PayQrcodeDialog>
|
||||||
|
|
||||||
<!-- 延迟缴费弹窗 -->
|
|
||||||
<DelayPayTimeDialog ref="delayPayTimeDialogRef" @refresh="getDataList"></DelayPayTimeDialog>
|
|
||||||
|
|
||||||
|
|
||||||
<!-- 录取通知书弹窗 -->
|
<!-- 录取通知书弹窗 -->
|
||||||
<AdmissionNoticeDialog ref="admissionNoticeDialogRef" @refresh="getDataList"></AdmissionNoticeDialog>
|
<AdmissionNoticeDialog ref="admissionNoticeDialogRef" @refresh="getDataList"></AdmissionNoticeDialog>
|
||||||
|
|
||||||
<DormFW ref="dormFWRef"></DormFW>
|
|
||||||
<ShowMap ref="baiduMapRef"></ShowMap>
|
|
||||||
<InterviewForm ref="interviewFormRef" @refresh="getDataList"></InterviewForm>
|
<InterviewForm ref="interviewFormRef" @refresh="getDataList"></InterviewForm>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@@ -653,7 +639,7 @@
|
|||||||
|
|
||||||
<script setup lang="ts" name="recruitstudentsignup">
|
<script setup lang="ts" name="recruitstudentsignup">
|
||||||
import { ref, reactive, onMounted, nextTick, defineAsyncComponent, watch } from 'vue'
|
import { ref, reactive, onMounted, nextTick, defineAsyncComponent, watch } from 'vue'
|
||||||
import { Edit, Check, DocumentChecked, Close, Switch, Tickets, Document, Upload, Warning, User, CircleCheck, CircleClose, Clock, WarningFilled } from '@element-plus/icons-vue'
|
import { Edit, Check, DocumentChecked, Close, Switch, Tickets, Document, Warning, User, CircleCheck } from '@element-plus/icons-vue'
|
||||||
import ClickableTag from '/@/components/ClickableTag/index.vue'
|
import ClickableTag from '/@/components/ClickableTag/index.vue'
|
||||||
import { useMessage, useMessageBox } from '/@/hooks/message'
|
import { useMessage, useMessageBox } from '/@/hooks/message'
|
||||||
import { BasicTableProps, useTable } from '/@/hooks/table'
|
import { BasicTableProps, useTable } from '/@/hooks/table'
|
||||||
@@ -661,27 +647,20 @@ import { auth } from '/@/utils/authFunction'
|
|||||||
import axios from 'axios'
|
import axios from 'axios'
|
||||||
import { getList } from '/@/api/recruit/recruitstudentplangroup'
|
import { getList } from '/@/api/recruit/recruitstudentplangroup'
|
||||||
import {
|
import {
|
||||||
delObj,
|
|
||||||
exportZip,
|
exportZip,
|
||||||
fetchList,
|
fetchList,
|
||||||
leaveSchool,
|
leaveSchool,
|
||||||
rePush as rePushApi,
|
rePush as rePushApi,
|
||||||
yjOut,
|
pushCity as pushCityApi,
|
||||||
oneClass,
|
resetSign as resetSignApi
|
||||||
oneStuNo,
|
|
||||||
tbStuWork,
|
|
||||||
sendImg,
|
|
||||||
pushCity as pushCityApi
|
|
||||||
} from '/@/api/recruit/recruitstudentsignup'
|
} from '/@/api/recruit/recruitstudentsignup'
|
||||||
import { getLabelValue, getLabelValueByProps, getMajorLabelWithYears } from '/@/utils/dictLabel'
|
import { getLabelValueByProps, getMajorLabelWithYears } from '/@/utils/dictLabel'
|
||||||
import { getDeptList } from "/@/api/basic/basicclass";
|
import { getDeptList } from "/@/api/basic/basicclass";
|
||||||
import { listPlanByCondition as planMajor } from "/@/api/recruit/recruitstudentplan";
|
import { listPlanByCondition as planMajor } from "/@/api/recruit/recruitstudentplan";
|
||||||
import { getDictsByTypes } from "/@/api/admin/dict";
|
import { getDictsByTypes } from "/@/api/admin/dict";
|
||||||
import { getUserListByRole } from "/@/api/admin/user";
|
|
||||||
import { queryTeacherBaseByNo } from "/@/api/professional/professionaluser/teacherbase";
|
import { queryTeacherBaseByNo } from "/@/api/professional/professionaluser/teacherbase";
|
||||||
import { useDict } from '/@/hooks/dict'
|
import { useDict } from '/@/hooks/dict'
|
||||||
import {
|
import {
|
||||||
ROLE_CODE,
|
|
||||||
PUSHED_STATUS_LIST,
|
PUSHED_STATUS_LIST,
|
||||||
NOTICE_SEND_STATUS_LIST,
|
NOTICE_SEND_STATUS_LIST,
|
||||||
RECRUIT_MATERIAL_STATUS_LIST,
|
RECRUIT_MATERIAL_STATUS_LIST,
|
||||||
@@ -697,11 +676,8 @@ import { showLoading, hideLoading } from '/@/api/asset/loading'
|
|||||||
const TableForm = defineAsyncComponent(() => import('./detaiform.vue'))
|
const TableForm = defineAsyncComponent(() => import('./detaiform.vue'))
|
||||||
const MajorChange = defineAsyncComponent(() => import('./majorChange.vue'))
|
const MajorChange = defineAsyncComponent(() => import('./majorChange.vue'))
|
||||||
const Update = defineAsyncComponent(() => import('./update.vue'))
|
const Update = defineAsyncComponent(() => import('./update.vue'))
|
||||||
const DormFW = defineAsyncComponent(() => import('./dormFW.vue'))
|
|
||||||
const ShowMap = defineAsyncComponent(() => import('./showMap.vue'))
|
|
||||||
const InterviewForm = defineAsyncComponent(() => import('/@/views/recruit/recruitstudentsignup/interviewForm.vue'))
|
const InterviewForm = defineAsyncComponent(() => import('/@/views/recruit/recruitstudentsignup/interviewForm.vue'))
|
||||||
const PayQrcodeDialog = defineAsyncComponent(() => import('./PayQrcodeDialog.vue'))
|
const PayQrcodeDialog = defineAsyncComponent(() => import('./PayQrcodeDialog.vue'))
|
||||||
const DelayPayTimeDialog = defineAsyncComponent(() => import('./DelayPayTimeDialog.vue'))
|
|
||||||
const AdmissionNoticeDialog = defineAsyncComponent(() => import('./AdmissionNoticeDialog.vue'))
|
const AdmissionNoticeDialog = defineAsyncComponent(() => import('./AdmissionNoticeDialog.vue'))
|
||||||
const ActionDropdown = defineAsyncComponent(() => import('/@/components/tools/action-dropdown.vue'))
|
const ActionDropdown = defineAsyncComponent(() => import('/@/components/tools/action-dropdown.vue'))
|
||||||
|
|
||||||
@@ -715,11 +691,8 @@ const searchFormRef = ref()
|
|||||||
const addOrUpdateRef = ref()
|
const addOrUpdateRef = ref()
|
||||||
const majorChangeRef = ref()
|
const majorChangeRef = ref()
|
||||||
const updateRef = ref()
|
const updateRef = ref()
|
||||||
const dormFWRef = ref()
|
|
||||||
const baiduMapRef = ref()
|
|
||||||
const interviewFormRef = ref()
|
const interviewFormRef = ref()
|
||||||
const payQrcodeDialogRef = ref()
|
const payQrcodeDialogRef = ref()
|
||||||
const delayPayTimeDialogRef = ref()
|
|
||||||
const admissionNoticeDialogRef = ref()
|
const admissionNoticeDialogRef = ref()
|
||||||
|
|
||||||
// 搜索表单显示状态
|
// 搜索表单显示状态
|
||||||
@@ -775,7 +748,6 @@ const { getDataList, currentChangeHandle, sizeChangeHandle, tableStyle } = useTa
|
|||||||
// 弹窗状态(已移除,组件内部通过 v-model="visible" 控制)
|
// 弹窗状态(已移除,组件内部通过 v-model="visible" 控制)
|
||||||
|
|
||||||
// 列表数据
|
// 列表数据
|
||||||
const auditorList = ref<any[]>([])
|
|
||||||
const planList = ref<any[]>([])
|
const planList = ref<any[]>([])
|
||||||
const eduList = ref<any[]>([])
|
const eduList = ref<any[]>([])
|
||||||
const planMajorList = ref<any[]>([])
|
const planMajorList = ref<any[]>([])
|
||||||
@@ -839,51 +811,6 @@ const remoteTeacherByQuery = (query: string) => {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// 发送图片
|
|
||||||
const handleSendImg = () => {
|
|
||||||
messageBox.confirm('是否确认同步招生图片到市平台?请谨慎操作').then(() => {
|
|
||||||
return sendImg()
|
|
||||||
}).then(() => {
|
|
||||||
message.success('同步图片请求已发起,请耐心等待')
|
|
||||||
}).catch(() => {
|
|
||||||
hideLoading()
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
// 同步学工
|
|
||||||
const handleTbStuWork = () => {
|
|
||||||
if (dataForm.groupId == '') {
|
|
||||||
message.warning('招生计划不能为空')
|
|
||||||
return
|
|
||||||
}
|
|
||||||
messageBox.confirm('是否确认同步学工?请谨慎操作').then(() => {
|
|
||||||
showLoading()
|
|
||||||
return tbStuWork(dataForm)
|
|
||||||
}).then(() => {
|
|
||||||
hideLoading()
|
|
||||||
message.success('同步完成')
|
|
||||||
}).catch(() => {
|
|
||||||
hideLoading()
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
// 一键分配班级和学号
|
|
||||||
const handleOneClassAndStuNo = () => {
|
|
||||||
if (dataForm.groupId == '') {
|
|
||||||
message.warning('招生计划不能为空')
|
|
||||||
return
|
|
||||||
}
|
|
||||||
messageBox.confirm('是否确认一键分配班级和学号?请谨慎操作').then(() => {
|
|
||||||
showLoading()
|
|
||||||
return Promise.all([oneClass(dataForm), oneStuNo(dataForm)])
|
|
||||||
}).then(() => {
|
|
||||||
hideLoading()
|
|
||||||
message.success('分配完成')
|
|
||||||
}).catch(() => {
|
|
||||||
hideLoading()
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
// 下载zip
|
// 下载zip
|
||||||
const downZip = () => {
|
const downZip = () => {
|
||||||
if (dataForm.groupId == '') {
|
if (dataForm.groupId == '') {
|
||||||
@@ -907,45 +834,6 @@ const downZip = () => {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
// 百度地图
|
|
||||||
const baiduMap = (row: any) => {
|
|
||||||
// 组件内部通过 v-model="visible" 控制显示
|
|
||||||
nextTick(() => {
|
|
||||||
baiduMapRef.value?.init(row)
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
// 设置宿舍
|
|
||||||
const setDormFW = () => {
|
|
||||||
// 组件内部通过 v-model="visible" 控制显示
|
|
||||||
nextTick(() => {
|
|
||||||
dormFWRef.value?.init()
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
// 一键判断是否超出住宿范围
|
|
||||||
const handleYjOut = () => {
|
|
||||||
if (dataForm.groupId == '') {
|
|
||||||
message.warning('招生计划不能为空')
|
|
||||||
return
|
|
||||||
}
|
|
||||||
messageBox.confirm('是否确认一键判断是否超出住宿范围?请谨慎操作').then(() => {
|
|
||||||
return yjOut({ groupId: dataForm.groupId })
|
|
||||||
}).then(() => {
|
|
||||||
message.success('操作成功')
|
|
||||||
getDataList()
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
// 导出审核
|
|
||||||
const handleExportAudit = (type: number) => {
|
|
||||||
if (dataForm.groupId == '') {
|
|
||||||
message.warning('招生计划不能为空')
|
|
||||||
return
|
|
||||||
}
|
|
||||||
downFile(type)
|
|
||||||
}
|
|
||||||
|
|
||||||
// 导出Excel
|
// 导出Excel
|
||||||
const exportExcel = (form: any, url: string) => {
|
const exportExcel = (form: any, url: string) => {
|
||||||
return axios({
|
return axios({
|
||||||
@@ -959,23 +847,6 @@ const exportExcel = (form: any, url: string) => {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
// 导出文件
|
|
||||||
const downFile = (type: number) => {
|
|
||||||
dataForm.type = String(type)
|
|
||||||
exportExcel(dataForm, '/recruit/recruitstudentsignup/exportExcel').then(res => {
|
|
||||||
const blob = new Blob([res.data])
|
|
||||||
const fileName = type == 1 ? '延迟缴费名单导出.xlsx' : '超时缴费名单导出.xlsx'
|
|
||||||
const elink = document.createElement('a')
|
|
||||||
elink.download = fileName
|
|
||||||
elink.style.display = 'none'
|
|
||||||
elink.href = URL.createObjectURL(blob)
|
|
||||||
document.body.appendChild(elink)
|
|
||||||
elink.click()
|
|
||||||
URL.revokeObjectURL(elink.href)
|
|
||||||
document.body.removeChild(elink)
|
|
||||||
}).catch(() => {})
|
|
||||||
}
|
|
||||||
|
|
||||||
// 导出
|
// 导出
|
||||||
const handleExport = () => {
|
const handleExport = () => {
|
||||||
if (dataForm.groupId == '') {
|
if (dataForm.groupId == '') {
|
||||||
@@ -994,11 +865,6 @@ const handleExport = () => {
|
|||||||
document.body.removeChild(elink)
|
document.body.removeChild(elink)
|
||||||
}).catch(() => {})
|
}).catch(() => {})
|
||||||
}
|
}
|
||||||
// 去重
|
|
||||||
const unique = (arr: any[]) => {
|
|
||||||
const rese = new Map()
|
|
||||||
return arr.filter((item) => !rese.has(item.username) && rese.set(item.username, 1))
|
|
||||||
}
|
|
||||||
|
|
||||||
// 切换专业
|
// 切换专业
|
||||||
const chanMajor = () => {
|
const chanMajor = () => {
|
||||||
@@ -1016,8 +882,8 @@ const handleFilter = () => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// 获取数据列表
|
// 获取数据列表
|
||||||
const handleAddData=()=>{
|
const handleAddData = ()=>{
|
||||||
addOrUpdateRef.value?.init(null, 1)
|
addOrUpdateRef.value?.init(null, 1, dataForm.groupId)
|
||||||
}
|
}
|
||||||
|
|
||||||
// 新增 / 修改
|
// 新增 / 修改
|
||||||
@@ -1052,12 +918,12 @@ const handleUpdate = (id: string, groupId: string, feeAgency: string) => {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
// 删除
|
// 复学
|
||||||
const deleteHandle = (id: string) => {
|
const reEntry = (id: string) => {
|
||||||
messageBox.confirm('是否确认删除本条数据?请谨慎操作').then(() => {
|
messageBox.confirm('是否确认复学操作?请谨慎操作').then(() => {
|
||||||
return delObj(id)
|
return resetSignApi({ id })
|
||||||
}).then(() => {
|
}).then(() => {
|
||||||
message.success('删除成功')
|
message.success('操作成功')
|
||||||
getDataList()
|
getDataList()
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
@@ -1093,18 +959,11 @@ const handlePushCity = (id: string) => {
|
|||||||
|
|
||||||
// 重新推送
|
// 重新推送
|
||||||
const handleRePush = (row: any) => {
|
const handleRePush = (row: any) => {
|
||||||
// messageBox.confirm('是否确认重新推送本条数据?请谨慎操作').then(() => {
|
messageBox.confirm('是否确认重新推送本条数据?请谨慎操作').then(() => {
|
||||||
// return rePushApi({ id: row.id })
|
return rePushApi({ id: row.id })
|
||||||
// }).then(() => {
|
}).then(() => {
|
||||||
// message.success('推送成功')
|
message.success('推送成功')
|
||||||
// getDataList()
|
getDataList()
|
||||||
// })
|
|
||||||
}
|
|
||||||
|
|
||||||
// 延迟缴费
|
|
||||||
const delayPayTimeSet = (row: any) => {
|
|
||||||
nextTick(() => {
|
|
||||||
delayPayTimeDialogRef.value?.init(row)
|
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1149,6 +1008,13 @@ const getActionMenuItems = (row: any) => {
|
|||||||
icon: Close,
|
icon: Close,
|
||||||
visible: () => auth('recruit_recruitstudentsignup_leaveSchool') && row.canQuit
|
visible: () => auth('recruit_recruitstudentsignup_leaveSchool') && row.canQuit
|
||||||
},
|
},
|
||||||
|
// 复学
|
||||||
|
{
|
||||||
|
command: 'reEntry',
|
||||||
|
label: '复学',
|
||||||
|
icon: Check,
|
||||||
|
visible: () => auth('recruit_resetsign') && row.canReset
|
||||||
|
},
|
||||||
{
|
{
|
||||||
command: 'majorChange',
|
command: 'majorChange',
|
||||||
label: '调整专业',
|
label: '调整专业',
|
||||||
@@ -1203,6 +1069,9 @@ const handleMoreCommand = (command: string, row: any) => {
|
|||||||
case 'leaveSchool':
|
case 'leaveSchool':
|
||||||
handleUpdate(row.id, row.groupId, row.feeAgency)
|
handleUpdate(row.id, row.groupId, row.feeAgency)
|
||||||
break
|
break
|
||||||
|
case 'reEntry':
|
||||||
|
reEntry(row.id)
|
||||||
|
break
|
||||||
case 'majorChange':
|
case 'majorChange':
|
||||||
majorChange(row.id)
|
majorChange(row.id)
|
||||||
break
|
break
|
||||||
@@ -1252,18 +1121,6 @@ const init = async () => {
|
|||||||
isOutList.value = res.data.recruit_data_source || []
|
isOutList.value = res.data.recruit_data_source || []
|
||||||
})
|
})
|
||||||
|
|
||||||
// 所有经办人
|
|
||||||
getUserListByRole(ROLE_CODE.ROLE_RECRUIT_SECOND).then((res: any) => {
|
|
||||||
auditorList.value = res.data || []
|
|
||||||
getUserListByRole(ROLE_CODE.ROLE_RECRUIT).then((re: any) => {
|
|
||||||
if (re.data) {
|
|
||||||
re.data.forEach((r: any) => {
|
|
||||||
auditorList.value.push(r)
|
|
||||||
})
|
|
||||||
}
|
|
||||||
auditorList.value = unique(auditorList.value)
|
|
||||||
})
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// 监听招生计划变化
|
// 监听招生计划变化
|
||||||
@@ -1293,14 +1150,6 @@ onMounted(() => {
|
|||||||
|
|
||||||
.major-icon {
|
.major-icon {
|
||||||
color: var(--el-color-primary);
|
color: var(--el-color-primary);
|
||||||
font-size: 14px;
|
|
||||||
flex-shrink: 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
.major-text {
|
|
||||||
color: #303133;
|
|
||||||
font-weight: 500;
|
|
||||||
font-size: 13px;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1309,14 +1158,6 @@ onMounted(() => {
|
|||||||
font-size: 13px;
|
font-size: 13px;
|
||||||
}
|
}
|
||||||
|
|
||||||
// 面试结果样式
|
|
||||||
.interview-cell {
|
|
||||||
display: flex;
|
|
||||||
flex-direction: column;
|
|
||||||
align-items: center;
|
|
||||||
gap: 6px;
|
|
||||||
}
|
|
||||||
|
|
||||||
// 面试详情弹窗样式
|
// 面试详情弹窗样式
|
||||||
.interview-detail-popover {
|
.interview-detail-popover {
|
||||||
.detail-title {
|
.detail-title {
|
||||||
@@ -1543,89 +1384,4 @@ onMounted(() => {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// 旧样式保留(如果其他地方还在使用)
|
|
||||||
.material-check-cell {
|
|
||||||
display: flex;
|
|
||||||
flex-direction: column;
|
|
||||||
gap: 8px;
|
|
||||||
padding: 4px 0;
|
|
||||||
|
|
||||||
.check-item {
|
|
||||||
display: flex;
|
|
||||||
align-items: flex-start;
|
|
||||||
gap: 6px;
|
|
||||||
line-height: 1.5;
|
|
||||||
|
|
||||||
.check-label {
|
|
||||||
color: #606266;
|
|
||||||
font-size: 12px;
|
|
||||||
font-weight: 500;
|
|
||||||
white-space: nowrap;
|
|
||||||
flex-shrink: 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
:deep(.el-tag) {
|
|
||||||
display: inline-flex;
|
|
||||||
align-items: center;
|
|
||||||
vertical-align: middle;
|
|
||||||
gap: 4px;
|
|
||||||
line-height: 1;
|
|
||||||
|
|
||||||
.tag-icon {
|
|
||||||
font-size: 12px;
|
|
||||||
vertical-align: middle;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.material-status {
|
|
||||||
display: flex;
|
|
||||||
flex-direction: row;
|
|
||||||
flex-wrap: nowrap;
|
|
||||||
gap: 6px;
|
|
||||||
align-items: center;
|
|
||||||
|
|
||||||
.material-tag {
|
|
||||||
margin: 0;
|
|
||||||
flex-shrink: 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
.no-upload-text {
|
|
||||||
color: #67c23a;
|
|
||||||
font-size: 12px;
|
|
||||||
white-space: nowrap;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.check-remark {
|
|
||||||
margin-top: 4px;
|
|
||||||
|
|
||||||
.remark-content {
|
|
||||||
display: flex;
|
|
||||||
align-items: flex-start;
|
|
||||||
gap: 4px;
|
|
||||||
flex: 1;
|
|
||||||
|
|
||||||
.remark-icon {
|
|
||||||
color: #f56c6c;
|
|
||||||
font-size: 14px;
|
|
||||||
flex-shrink: 0;
|
|
||||||
margin-top: 2px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.remark-text {
|
|
||||||
color: #f56c6c;
|
|
||||||
font-size: 12px;
|
|
||||||
line-height: 1.5;
|
|
||||||
display: inline-block;
|
|
||||||
max-width: 200px;
|
|
||||||
overflow: hidden;
|
|
||||||
text-overflow: ellipsis;
|
|
||||||
white-space: nowrap;
|
|
||||||
vertical-align: top;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
</style>
|
</style>
|
||||||
|
|||||||
@@ -311,7 +311,7 @@
|
|||||||
header-align="center"
|
header-align="center"
|
||||||
align="center"
|
align="center"
|
||||||
width="100"
|
width="100"
|
||||||
label="是否同步">
|
label="是否已同步">
|
||||||
<template #default="scope">
|
<template #default="scope">
|
||||||
<el-tag :type="getYesNoType(scope.row.isTb)?.type">
|
<el-tag :type="getYesNoType(scope.row.isTb)?.type">
|
||||||
{{ getYesNoType(scope.row.isTb)?.label }}
|
{{ getYesNoType(scope.row.isTb)?.label }}
|
||||||
@@ -376,7 +376,7 @@
|
|||||||
</el-form>
|
</el-form>
|
||||||
<template #footer>
|
<template #footer>
|
||||||
<div class="dialog-footer">
|
<div class="dialog-footer">
|
||||||
<el-button @click="changeClassVisible=false">关 闭</el-button>
|
<el-button @click="changeClassVisible=false">取消</el-button>
|
||||||
<el-button @click="changeClassInfoHandle" type="primary">保存</el-button>
|
<el-button @click="changeClassInfoHandle" type="primary">保存</el-button>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
@@ -387,8 +387,6 @@
|
|||||||
|
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import { ref, reactive, nextTick, onMounted, defineAsyncComponent } from 'vue'
|
import { ref, reactive, nextTick, onMounted, defineAsyncComponent } from 'vue'
|
||||||
import { Search, ZoomIn, Edit } from '@element-plus/icons-vue'
|
|
||||||
import { ElNotification } from 'element-plus'
|
|
||||||
import { useMessage } from '/@/hooks/message'
|
import { useMessage } from '/@/hooks/message'
|
||||||
import { useMessageBox } from '/@/hooks/message'
|
import { useMessageBox } from '/@/hooks/message'
|
||||||
import { BasicTableProps, useTable } from '/@/hooks/table'
|
import { BasicTableProps, useTable } from '/@/hooks/table'
|
||||||
@@ -400,14 +398,14 @@ import {
|
|||||||
oneClass,
|
oneClass,
|
||||||
oneStuNo,
|
oneStuNo,
|
||||||
changeClassInfo,
|
changeClassInfo,
|
||||||
getMajorClass
|
getMajorClass,
|
||||||
|
queryAllRecruitUser
|
||||||
} from '/@/api/recruit/recruitstudentsignup'
|
} from '/@/api/recruit/recruitstudentsignup'
|
||||||
import { getLabelValueByProps } from '/@/utils/dictLabel'
|
import { getLabelValueByProps } from '/@/utils/dictLabel'
|
||||||
import { getClassListByRole, getDeptList } from "/@/api/basic/basicclass"
|
import { getClassListByRole, getDeptList } from "/@/api/basic/basicclass"
|
||||||
import {listPlanByCondition as planMajor} from "/@/api/recruit/recruitstudentplan"
|
import {listPlanByCondition as planMajor} from "/@/api/recruit/recruitstudentplan"
|
||||||
import { getDictsByTypes } from "/@/api/admin/dict"
|
import { getDictsByTypes } from "/@/api/admin/dict"
|
||||||
import { getUserListByRole } from "/@/api/admin/user"
|
import { PUSHED_STATUS_LIST, PAY_STATUS_LIST, getStatusConfig } from "/@/config/global"
|
||||||
import { ROLE_CODE, PUSHED_STATUS_LIST, PAY_STATUS_LIST, getStatusConfig } from "/@/config/global"
|
|
||||||
import { showLoading, hideLoading } from '/@/api/asset/loading'
|
import { showLoading, hideLoading } from '/@/api/asset/loading'
|
||||||
import { useDict } from '/@/hooks/dict'
|
import { useDict } from '/@/hooks/dict'
|
||||||
|
|
||||||
@@ -642,20 +640,9 @@ const init = () => {
|
|||||||
})
|
})
|
||||||
|
|
||||||
// 所有经办人
|
// 所有经办人
|
||||||
getUserListByRole(ROLE_CODE.ROLE_RECRUIT_SECOND).then((res: any) => {
|
queryAllRecruitUser().then((res: any) => {
|
||||||
auditorList.value = res.data
|
auditorList.value = res.data || []
|
||||||
getUserListByRole(ROLE_CODE.ROLE_RECRUIT).then((re: any) => {
|
|
||||||
re.data.forEach((r: any) => {
|
|
||||||
auditorList.value.push(r)
|
|
||||||
})
|
})
|
||||||
auditorList.value = unique(auditorList.value)
|
|
||||||
})
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
const unique = (arr: any[]) => {
|
|
||||||
const rese = new Map()
|
|
||||||
return arr.filter((item) => !rese.has(item.username) && rese.set(item.username, 1))
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const chanMajor = () => {
|
const chanMajor = () => {
|
||||||
|
|||||||
@@ -1,30 +1,38 @@
|
|||||||
<template>
|
<template>
|
||||||
<el-dialog v-model="visible" width="60%" :title="`面试审核(${row.name})`">
|
<el-dialog v-model="visible" width="600" :title="`面试审核(${row.name})`">
|
||||||
<el-row>
|
<el-form ref="dataFormRef" :model="dataForm" :rules="dataRule" label-width="120px">
|
||||||
<el-radio v-model="status" label="1">通过</el-radio>
|
<el-form-item label="面试结果" prop="interview">
|
||||||
<el-radio v-model="status" label="-1">未通过</el-radio>
|
<el-radio-group v-model="dataForm.interview" @change="handleInterviewChange">
|
||||||
</el-row>
|
<el-radio :label="item.value" v-for="item in interviewDicList" :key="item.value">{{ item.label }}</el-radio>
|
||||||
<el-row v-if="status == '-1'">
|
</el-radio-group>
|
||||||
<br />
|
</el-form-item>
|
||||||
<el-input type="textarea" v-model="reason" placeholder="请输入未通过的原因"></el-input>
|
<el-form-item label="未通过原因" prop="interviewReason" v-if="dataForm.interview == '-1'">
|
||||||
</el-row>
|
<el-input
|
||||||
|
type="textarea"
|
||||||
|
v-model="dataForm.interviewReason"
|
||||||
|
placeholder="请输入未通过的原因"
|
||||||
|
:rows="4">
|
||||||
|
</el-input>
|
||||||
|
</el-form-item>
|
||||||
|
</el-form>
|
||||||
|
|
||||||
<template #footer>
|
<template #footer>
|
||||||
<div class="dialog-footer">
|
<div class="dialog-footer">
|
||||||
<el-button type="primary" @click="confirm"><span>确认</span></el-button>
|
|
||||||
<el-button @click="visible = false">取消</el-button>
|
<el-button @click="visible = false">取消</el-button>
|
||||||
|
<el-button type="primary" @click="confirm">确认</el-button>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
</el-dialog>
|
</el-dialog>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import { ref, reactive } from 'vue'
|
import { ref, reactive, nextTick } from 'vue'
|
||||||
import { useMessage } from '/@/hooks/message'
|
import { useMessage } from '/@/hooks/message'
|
||||||
// @ts-ignore
|
import { interview } from "/@/api/recruit/recruitstudentsignup"
|
||||||
import global from "@/components/tools/commondict.vue"
|
import { INTERVIEW_DIC_LIST } from '/@/config/global'
|
||||||
import { interview } from "@/api/recruit/recruitstudentsignup"
|
import type { FormInstance } from 'element-plus'
|
||||||
|
|
||||||
|
const interviewDicList = INTERVIEW_DIC_LIST.filter((item) => item.value != '0')
|
||||||
// 消息提示 hooks
|
// 消息提示 hooks
|
||||||
const message = useMessage()
|
const message = useMessage()
|
||||||
|
|
||||||
@@ -36,31 +44,60 @@ const emit = defineEmits<{
|
|||||||
// 响应式数据
|
// 响应式数据
|
||||||
const visible = ref(false)
|
const visible = ref(false)
|
||||||
const row = reactive<any>({})
|
const row = reactive<any>({})
|
||||||
const status = ref('1')
|
const dataFormRef = ref<FormInstance>()
|
||||||
const reason = ref('')
|
const dataForm = reactive({
|
||||||
|
interview: '1',
|
||||||
|
interviewReason: ''
|
||||||
|
})
|
||||||
|
|
||||||
|
// 表单验证规则
|
||||||
|
const dataRule = reactive({
|
||||||
|
interview: [
|
||||||
|
{ required: true, message: '请选择面试结果', trigger: 'change' }
|
||||||
|
],
|
||||||
|
interviewReason: [] as any[]
|
||||||
|
})
|
||||||
|
|
||||||
// 初始化
|
// 初始化
|
||||||
const init = (rowData: any) => {
|
const init = (rowData: any) => {
|
||||||
visible.value = true
|
visible.value = true
|
||||||
Object.assign(row, rowData)
|
Object.assign(row, rowData)
|
||||||
status.value = rowData.interview || '1'
|
dataForm.interview = rowData.interview || '1'
|
||||||
reason.value = rowData.interviewReason || ''
|
dataForm.interviewReason = rowData.interviewReason || ''
|
||||||
|
// 重置表单验证状态
|
||||||
|
nextTick(() => {
|
||||||
|
dataFormRef.value?.clearValidate()
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
// 面试结果改变
|
||||||
|
const handleInterviewChange = () => {
|
||||||
|
dataForm.interviewReason = ''
|
||||||
|
if(dataForm.interview == '-1'){
|
||||||
|
dataRule.interviewReason = [
|
||||||
|
{ required: true, message: '请输入未通过的原因', trigger: 'blur' }
|
||||||
|
]
|
||||||
|
} else {
|
||||||
|
dataRule.interviewReason = []
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// 确认
|
// 确认
|
||||||
const confirm = () => {
|
const confirm = () => {
|
||||||
if (!status.value || (status.value == '-1' && !reason.value)) {
|
dataFormRef.value?.validate((valid: boolean) => {
|
||||||
message.warning('请选择通过还是未通过,未通过请输入原因')
|
if (!valid) {
|
||||||
return
|
return
|
||||||
} else {
|
}
|
||||||
interview({ "id": row.id, "interview": status.value, "interviewReason": reason.value }).then(() => {
|
interview({
|
||||||
|
"id": row.id,
|
||||||
|
"interview": dataForm.interview,
|
||||||
|
"interviewReason": dataForm.interviewReason
|
||||||
|
}).then(() => {
|
||||||
message.success('操作成功')
|
message.success('操作成功')
|
||||||
visible.value = false
|
visible.value = false
|
||||||
emit('refresh')
|
emit('refresh')
|
||||||
}).catch(() => {
|
|
||||||
message.error('操作失败')
|
|
||||||
})
|
})
|
||||||
}
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
// 暴露方法给父组件
|
// 暴露方法给父组件
|
||||||
@@ -70,7 +107,5 @@ defineExpose({
|
|||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style scoped>
|
<style scoped>
|
||||||
.dialog-footer {
|
|
||||||
text-align: right;
|
|
||||||
}
|
|
||||||
</style>
|
</style>
|
||||||
|
|||||||
@@ -25,14 +25,14 @@
|
|||||||
<el-row>
|
<el-row>
|
||||||
<el-col :span="24">
|
<el-col :span="24">
|
||||||
<el-form-item label="姓名" prop="name">
|
<el-form-item label="姓名" prop="name">
|
||||||
<el-input type="text" v-model="dataForm.name" :disabled="type != 1"></el-input>
|
<el-input type="text" v-model="dataForm.name" disabled></el-input>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
</el-col>
|
</el-col>
|
||||||
</el-row>
|
</el-row>
|
||||||
<el-row>
|
<el-row>
|
||||||
<el-col :span="24">
|
<el-col :span="24">
|
||||||
<el-form-item label="身份证号" prop="idNumber">
|
<el-form-item label="身份证号" prop="idNumber">
|
||||||
<el-input type="text" v-model="dataForm.idNumber" :disabled="type != 2"></el-input>
|
<el-input type="text" v-model="dataForm.idNumber" disabled></el-input>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
</el-col>
|
</el-col>
|
||||||
</el-row>
|
</el-row>
|
||||||
@@ -46,7 +46,7 @@
|
|||||||
<el-row>
|
<el-row>
|
||||||
<el-col :span="24">
|
<el-col :span="24">
|
||||||
<el-form-item label="原录取专业" prop="confirmedMajor">
|
<el-form-item label="原录取专业" prop="confirmedMajor">
|
||||||
<el-select v-model="dataForm.confirmedMajor" filterable clearable placeholder="" :disabled="type != 1" @change="changeM(dataForm.confirmedMajor)">
|
<el-select v-model="dataForm.confirmedMajor" filterable clearable placeholder="" disabled>
|
||||||
<el-option
|
<el-option
|
||||||
v-for="item in planMajorList"
|
v-for="item in planMajorList"
|
||||||
:key="item.majorCode"
|
:key="item.majorCode"
|
||||||
@@ -75,26 +75,26 @@
|
|||||||
<el-row>
|
<el-row>
|
||||||
<el-col :span="12">
|
<el-col :span="12">
|
||||||
<el-form-item label="学费" prop="feeTuition">
|
<el-form-item label="学费" prop="feeTuition">
|
||||||
<el-input-number v-model="dataForm.feeTuition" controls-position="right" :min="0" :max="999999" :step-strictly="true" :disabled="type == 2"></el-input-number>
|
<el-input-number v-model="dataForm.feeTuition" controls-position="right" :min="0" :max="999999" :step-strictly="true" disabled></el-input-number>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
</el-col>
|
</el-col>
|
||||||
<el-col :span="12">
|
<el-col :span="12">
|
||||||
<el-form-item label="代办费" prop="feeAgency">
|
<el-form-item label="代办费" prop="feeAgency">
|
||||||
<el-input-number v-model="dataForm.feeAgency" controls-position="right" :min="0" :max="999999" :step-strictly="true" :disabled="type == 2"></el-input-number>
|
<el-input-number v-model="dataForm.feeAgency" controls-position="right" :min="0" :max="999999" :step-strictly="true" disabled></el-input-number>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
</el-col>
|
</el-col>
|
||||||
</el-row>
|
</el-row>
|
||||||
<el-row>
|
<el-row>
|
||||||
<el-col :span="24">
|
<el-col :span="24">
|
||||||
<el-form-item label="总费用" prop="allMoney">
|
<el-form-item label="总费用" prop="allMoney">
|
||||||
<span style="color: red">{{ dataForm.feeTuition + dataForm.feeAgency }}</span>
|
<span style="color: red">{{ Number(dataForm.feeTuition) + Number(dataForm.feeAgency) }}</span>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
</el-col>
|
</el-col>
|
||||||
</el-row>
|
</el-row>
|
||||||
<el-row>
|
<el-row>
|
||||||
<el-col :span="24">
|
<el-col :span="24">
|
||||||
<el-form-item label="审核备注" prop="auditRemarks">
|
<el-form-item label="备注" prop="auditRemarks">
|
||||||
<el-input type="textarea" v-model="dataForm.auditRemarks" placeholder="审核备注" :rows="2"></el-input>
|
<el-input type="textarea" v-model="dataForm.auditRemarks" placeholder="备注" :rows="2"></el-input>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
</el-col>
|
</el-col>
|
||||||
</el-row>
|
</el-row>
|
||||||
@@ -110,17 +110,18 @@
|
|||||||
|
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import { ref, reactive, nextTick } from 'vue'
|
import { ref, reactive, nextTick } from 'vue'
|
||||||
import { ElNotification } from 'element-plus'
|
import { useMessageBox, useMessage } from '/@/hooks/message'
|
||||||
import { useMessageBox } from '/@/hooks/message'
|
|
||||||
import { getObj, changeMajor } from '/@/api/recruit/recruitstudentsignup'
|
import { getObj, changeMajor } from '/@/api/recruit/recruitstudentsignup'
|
||||||
import { getList } from "/@/api/recruit/recruitstudentplangroup"
|
import { getList } from "/@/api/recruit/recruitstudentplangroup"
|
||||||
import { listByEdu } from "/@/api/recruit/recruitstudentplan"
|
import { listByEdu } from "/@/api/recruit/recruitstudentplan"
|
||||||
import { getDicts } from "/@/api/admin/dict"
|
import { getDicts } from "/@/api/admin/dict"
|
||||||
import { list as scoreList } from "/@/api/recruit/recruitstudentplancorrectscoreconfig"
|
import { list as scoreList } from "/@/api/recruit/recruitstudentplancorrectscoreconfig"
|
||||||
|
import { getStatusConfig, AUDIT_STATUS_LIST } from '/@/config/global'
|
||||||
|
|
||||||
|
const auditStatusList = AUDIT_STATUS_LIST
|
||||||
// 消息提示 hooks
|
// 消息提示 hooks
|
||||||
const messageBox = useMessageBox()
|
const messageBox = useMessageBox()
|
||||||
|
const message = useMessage()
|
||||||
// Emits
|
// Emits
|
||||||
const emit = defineEmits<{
|
const emit = defineEmits<{
|
||||||
(e: 'refreshDataList'): void
|
(e: 'refreshDataList'): void
|
||||||
@@ -133,11 +134,9 @@ const dataFormRef = ref()
|
|||||||
const visible = ref(false)
|
const visible = ref(false)
|
||||||
const canSubmit = ref(false)
|
const canSubmit = ref(false)
|
||||||
const title = ref("")
|
const title = ref("")
|
||||||
const type = ref<number | null>(null)
|
|
||||||
const planList = ref<any[]>([])
|
const planList = ref<any[]>([])
|
||||||
const planMajorList = ref<any[]>([])
|
const planMajorList = ref<any[]>([])
|
||||||
const agencyFeeList = ref<any[]>([])
|
const agencyFeeList = ref<any[]>([])
|
||||||
const tuitionFeeList = ref<any[]>([])
|
|
||||||
const schoolCodeList = ref<any[]>([])
|
const schoolCodeList = ref<any[]>([])
|
||||||
|
|
||||||
const dataForm = reactive({
|
const dataForm = reactive({
|
||||||
@@ -210,7 +209,7 @@ const dataForm = reactive({
|
|||||||
feeAgency: 0
|
feeAgency: 0
|
||||||
})
|
})
|
||||||
|
|
||||||
const dataRule = {
|
const dataRule = reactive({
|
||||||
groupId: [
|
groupId: [
|
||||||
{ required: true, message: '招生计划不能为空', trigger: 'change' }
|
{ required: true, message: '招生计划不能为空', trigger: 'change' }
|
||||||
],
|
],
|
||||||
@@ -229,7 +228,7 @@ const dataRule = {
|
|||||||
newConfirmedMajor: [
|
newConfirmedMajor: [
|
||||||
{ required: true, message: '新录取专业不能为空', trigger: 'change' }
|
{ required: true, message: '新录取专业不能为空', trigger: 'change' }
|
||||||
]
|
]
|
||||||
}
|
})
|
||||||
|
|
||||||
// 初始化数据
|
// 初始化数据
|
||||||
const initData = () => {
|
const initData = () => {
|
||||||
@@ -238,56 +237,45 @@ const initData = () => {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
// 改变新专业
|
// 根据新专业和文化程度更新学费
|
||||||
const changeCM = (id: string) => {
|
const updateTuitionByNewMajorAndEducation = () => {
|
||||||
if (id) {
|
if (!dataForm.newConfirmedMajor || !dataForm.degreeOfEducation) {
|
||||||
let flag = false
|
return
|
||||||
planMajorList.value.forEach((e: any) => {
|
|
||||||
if (dataForm.newConfirmedMajor == e.majorCode && e.isZd == "1" && String(dataForm.degreeOfEducation) == "1") {
|
|
||||||
flag = true
|
|
||||||
}
|
}
|
||||||
})
|
|
||||||
if (String(dataForm.degreeOfEducation) == "1") {
|
// 查找选中的新专业
|
||||||
dataForm.feeTuition = 0
|
const selectedMajor = planMajorList.value.find((major: any) => major.majorCode === dataForm.newConfirmedMajor)
|
||||||
tuitionFeeList.value.forEach((e: any) => {
|
if (!selectedMajor) {
|
||||||
if (e.label == "0" && flag) {
|
return
|
||||||
dataForm.feeTuition = e.value
|
|
||||||
}
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 根据文化程度选择对应的学费字段
|
||||||
|
// '1' = 初中 -> czFee
|
||||||
|
// '2' = 高中 -> gzFee
|
||||||
|
// '3' = 技职校 -> jzxFee
|
||||||
|
if (dataForm.degreeOfEducation === '1' && selectedMajor.czFee !== undefined && selectedMajor.czFee !== null) {
|
||||||
|
dataForm.feeTuition = selectedMajor.czFee
|
||||||
|
} else if (dataForm.degreeOfEducation === '2' && selectedMajor.gzFee !== undefined && selectedMajor.gzFee !== null) {
|
||||||
|
dataForm.feeTuition = selectedMajor.gzFee
|
||||||
|
} else if (dataForm.degreeOfEducation === '3' && selectedMajor.jzxFee !== undefined && selectedMajor.jzxFee !== null) {
|
||||||
|
dataForm.feeTuition = selectedMajor.jzxFee
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// 改变原专业
|
// 改变新专业
|
||||||
const changeM = (id: string) => {
|
const changeCM = (id: string) => {
|
||||||
if (id) {
|
if (id) {
|
||||||
dataForm.confirmedMajor = id
|
// 从新专业中获取学费
|
||||||
// 是初中生并且是中德班
|
updateTuitionByNewMajorAndEducation()
|
||||||
let flag = false
|
|
||||||
planMajorList.value.forEach((e: any) => {
|
|
||||||
if (dataForm.confirmedMajor == e.majorCode && e.isZd == "1" && String(dataForm.degreeOfEducation) == "1") {
|
|
||||||
flag = true
|
|
||||||
}
|
|
||||||
})
|
|
||||||
if (String(dataForm.degreeOfEducation) == "1") {
|
|
||||||
dataForm.feeTuition = 0
|
|
||||||
tuitionFeeList.value.forEach((e: any) => {
|
|
||||||
if (e.label == "0" && flag) {
|
|
||||||
dataForm.feeTuition = e.value
|
|
||||||
}
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// 表单提交
|
// 表单提交
|
||||||
const dataFormSubmit = async () => {
|
const dataFormSubmit = async () => {
|
||||||
const titleText = "确认调整录取专业么?"
|
const titleText = "确认调整录取专业么?"
|
||||||
if (dataForm.confirmedMajor == dataForm.newConfirmedMajor) {
|
if (dataForm.confirmedMajor == dataForm.newConfirmedMajor) {
|
||||||
ElNotification.error({
|
message.error('新专业不能和原专业相同')
|
||||||
title: '错误',
|
|
||||||
message: '新专业不能和原专业相同'
|
|
||||||
})
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
try {
|
try {
|
||||||
@@ -297,10 +285,7 @@ const dataFormSubmit = async () => {
|
|||||||
canSubmit.value = false
|
canSubmit.value = false
|
||||||
if (dataForm.id) {
|
if (dataForm.id) {
|
||||||
changeMajor(dataForm).then(() => {
|
changeMajor(dataForm).then(() => {
|
||||||
ElNotification.success({
|
message.success('操作成功')
|
||||||
title: '成功',
|
|
||||||
message: '操作成功'
|
|
||||||
})
|
|
||||||
visible.value = false
|
visible.value = false
|
||||||
emit('refreshDataList')
|
emit('refreshDataList')
|
||||||
}).catch(() => {
|
}).catch(() => {
|
||||||
@@ -316,7 +301,7 @@ const dataFormSubmit = async () => {
|
|||||||
|
|
||||||
// 初始化方法
|
// 初始化方法
|
||||||
const init = (id: string | null) => {
|
const init = (id: string | null) => {
|
||||||
dataForm.id = id || null
|
dataForm.id = id || ""
|
||||||
visible.value = true
|
visible.value = true
|
||||||
canSubmit.value = true
|
canSubmit.value = true
|
||||||
initData()
|
initData()
|
||||||
@@ -326,9 +311,6 @@ const init = (id: string | null) => {
|
|||||||
// 获取数据字典代办费
|
// 获取数据字典代办费
|
||||||
getDicts('agency_fee').then((res: any) => {
|
getDicts('agency_fee').then((res: any) => {
|
||||||
agencyFeeList.value = res.data
|
agencyFeeList.value = res.data
|
||||||
// 获取数据字典学费
|
|
||||||
getDicts('tuition_fee').then((res: any) => {
|
|
||||||
tuitionFeeList.value = res.data
|
|
||||||
getObj(dataForm.id).then((response: any) => {
|
getObj(dataForm.id).then((response: any) => {
|
||||||
Object.assign(dataForm, response.data)
|
Object.assign(dataForm, response.data)
|
||||||
title.value = dataForm.serialNumber
|
title.value = dataForm.serialNumber
|
||||||
@@ -340,34 +322,32 @@ const init = (id: string | null) => {
|
|||||||
dataForm.feeAgency = e.value
|
dataForm.feeAgency = e.value
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
tuitionFeeList.value.forEach((e: any) => {
|
|
||||||
if (String(dataForm.degreeOfEducation) == String(e.label) && (String(dataForm.degreeOfEducation) != "1")) {
|
|
||||||
dataForm.feeTuition = e.value
|
|
||||||
}
|
|
||||||
})
|
|
||||||
listByEdu({ groupId: dataForm.groupId, degreeOfEducation: dataForm.degreeOfEducation }).then((e: any) => {
|
listByEdu({ groupId: dataForm.groupId, degreeOfEducation: dataForm.degreeOfEducation }).then((e: any) => {
|
||||||
planMajorList.value = e.data
|
planMajorList.value = e.data
|
||||||
})
|
// 加载专业列表后,如果已有新专业,更新学费
|
||||||
|
if (dataForm.newConfirmedMajor) {
|
||||||
|
updateTuitionByNewMajorAndEducation()
|
||||||
|
}
|
||||||
// 获取招生计划下的学校和分数线
|
// 获取招生计划下的学校和分数线
|
||||||
scoreList({ groupId: dataForm.groupId }).then((data: any) => {
|
scoreList({ groupId: dataForm.groupId }).then((data: any) => {
|
||||||
schoolCodeList.value = data.data
|
schoolCodeList.value = data.data
|
||||||
})
|
})
|
||||||
|
|
||||||
if ("1" == dataForm.degreeOfEducation) {
|
const educationPrefixMap: Record<string, string> = {
|
||||||
title.value = "C" + title.value
|
'1': 'C', // 初中
|
||||||
} else if ("2" == dataForm.degreeOfEducation) {
|
'2': 'G', // 高中
|
||||||
title.value = "G" + title.value
|
'3': 'J' // 技职校
|
||||||
} else if ("3" == dataForm.degreeOfEducation) {
|
}
|
||||||
title.value = "J" + title.value
|
const prefix = educationPrefixMap[String(dataForm.degreeOfEducation)]
|
||||||
|
if (prefix) {
|
||||||
|
title.value = prefix + title.value
|
||||||
|
}
|
||||||
|
// 从字典数据获取录取状态标签
|
||||||
|
const auditStatusConfig = getStatusConfig(auditStatusList, dataForm.auditStatus)
|
||||||
|
if (auditStatusConfig && auditStatusConfig.label) {
|
||||||
|
title.value = auditStatusConfig.label + " " + title.value
|
||||||
}
|
}
|
||||||
|
|
||||||
if ("-20" == dataForm.auditStatus) {
|
|
||||||
title.value = "未录取 " + title.value
|
|
||||||
} else if ("0" == dataForm.auditStatus) {
|
|
||||||
title.value = "待审核 " + title.value
|
|
||||||
} else if ("20" == dataForm.auditStatus) {
|
|
||||||
title.value = "已录取 " + title.value
|
|
||||||
}
|
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|||||||
@@ -4,11 +4,11 @@
|
|||||||
:close-on-click-modal="false"
|
:close-on-click-modal="false"
|
||||||
v-model="visible"
|
v-model="visible"
|
||||||
append-to-body
|
append-to-body
|
||||||
width="900px">
|
width="70%">
|
||||||
<el-form :model="dataForm" :rules="dataRule" ref="dataFormRef" @keyup.enter="dataFormSubmit"
|
<el-form :model="dataForm" :rules="dataRule" ref="dataFormRef" @keyup.enter="() => dataFormSubmit('1')"
|
||||||
label-width="100px">
|
label-width="100px">
|
||||||
<el-row>
|
<el-row>
|
||||||
<el-col :span="24">
|
<el-col :span="8">
|
||||||
<el-form-item label="招生计划" prop="groupId">
|
<el-form-item label="招生计划" prop="groupId">
|
||||||
<el-select v-model="dataForm.groupId" filterable :disabled="!!dataForm.id"
|
<el-select v-model="dataForm.groupId" filterable :disabled="!!dataForm.id"
|
||||||
placeholder="请选择招生计划">
|
placeholder="请选择招生计划">
|
||||||
@@ -21,14 +21,12 @@
|
|||||||
</el-select>
|
</el-select>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
</el-col>
|
</el-col>
|
||||||
</el-row>
|
<el-col :span="8">
|
||||||
<el-row>
|
|
||||||
<el-col :span="12">
|
|
||||||
<el-form-item label="姓名" prop="name">
|
<el-form-item label="姓名" prop="name">
|
||||||
<el-input type="text" v-model="dataForm.name" :disabled="type != 1"></el-input>
|
<el-input type="text" v-model="dataForm.name" :disabled="type != 1"></el-input>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
</el-col>
|
</el-col>
|
||||||
<el-col :span="12">
|
<el-col :span="8">
|
||||||
<el-form-item label="联系人" prop="contactName">
|
<el-form-item label="联系人" prop="contactName">
|
||||||
<el-select v-model="dataForm.contactName" filterable clearable placeholder="" :disabled="!(permissions.recruit_recruitprestudent_dj_sure || dataForm.auditStatus != '20')">
|
<el-select v-model="dataForm.contactName" filterable clearable placeholder="" :disabled="!(permissions.recruit_recruitprestudent_dj_sure || dataForm.auditStatus != '20')">
|
||||||
<el-option
|
<el-option
|
||||||
@@ -42,89 +40,91 @@
|
|||||||
</el-col>
|
</el-col>
|
||||||
</el-row>
|
</el-row>
|
||||||
|
|
||||||
|
|
||||||
<el-row>
|
<el-row>
|
||||||
<el-col :span="8">
|
<el-col :span="6">
|
||||||
<el-form-item label="成绩单" prop="scorePhoto">
|
<el-form-item label="成绩单" prop="scorePhoto">
|
||||||
<el-upload
|
<el-upload
|
||||||
action="/recruit/file/uploadAttachment"
|
:action="uploadUrl"
|
||||||
list-type="picture-card"
|
class="avatar-uploader"
|
||||||
name="file"
|
name="file"
|
||||||
:headers="headers"
|
:headers="headers"
|
||||||
:limit="1"
|
|
||||||
:data="uploadData"
|
:data="uploadData"
|
||||||
:file-list="fileList"
|
:show-file-list="false"
|
||||||
:before-upload="beforeUpload"
|
:before-upload="beforeUpload"
|
||||||
:on-preview="handlePictureCardPreview"
|
|
||||||
:on-remove="removeHandler"
|
|
||||||
:http-request="httpRequest"
|
:http-request="httpRequest"
|
||||||
:on-success="uploadSuccess">
|
:on-success="uploadSuccess">
|
||||||
<el-icon class="avatar-uploader-icon"><Plus /></el-icon>
|
<div v-if="dataForm.scorePhoto" class="avatar-wrapper">
|
||||||
|
<img :src="baseUrl + dataForm.scorePhoto" class="avatar"/>
|
||||||
|
</div>
|
||||||
|
<el-icon v-else class="avatar-uploader-icon"><Plus /></el-icon>
|
||||||
</el-upload>
|
</el-upload>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
</el-col>
|
</el-col>
|
||||||
<el-col :span="8">
|
<el-col :span="6">
|
||||||
<el-form-item label="毕业证" prop="graPic">
|
<el-form-item label="毕业证" prop="graPic">
|
||||||
<el-upload
|
<el-upload
|
||||||
action="/recruit/file/uploadAttachment"
|
:action="uploadUrl"
|
||||||
list-type="picture-card"
|
class="avatar-uploader"
|
||||||
name="file"
|
name="file"
|
||||||
:headers="headers"
|
:headers="headers"
|
||||||
:limit="1"
|
|
||||||
:data="uploadData"
|
:data="uploadData"
|
||||||
:file-list="graPicList"
|
:show-file-list="false"
|
||||||
:before-upload="beforeUpload"
|
:before-upload="beforeUpload"
|
||||||
:on-preview="handlePictureCardPreview"
|
|
||||||
:on-remove="remove2Handler"
|
|
||||||
:http-request="httpRequest"
|
:http-request="httpRequest"
|
||||||
:on-success="upload2Success">
|
:on-success="upload2Success">
|
||||||
<el-icon class="avatar-uploader-icon"><Plus /></el-icon>
|
<div v-if="dataForm.graPic" class="avatar-wrapper">
|
||||||
|
<img :src="baseUrl + dataForm.graPic" class="avatar"/>
|
||||||
|
</div>
|
||||||
|
<el-icon v-else class="avatar-uploader-icon"><Plus /></el-icon>
|
||||||
</el-upload>
|
</el-upload>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
</el-col>
|
</el-col>
|
||||||
<el-col :span="8">
|
<el-col :span="6">
|
||||||
<el-form-item label="在常营业执照" prop="yyPic">
|
<el-form-item label="在常营业执照" prop="yyPic">
|
||||||
<el-upload
|
<el-upload
|
||||||
action="/recruit/file/uploadAttachment"
|
:action="uploadUrl"
|
||||||
list-type="picture-card"
|
class="avatar-uploader"
|
||||||
name="file"
|
name="file"
|
||||||
:headers="headers"
|
:headers="headers"
|
||||||
:limit="1"
|
|
||||||
:data="uploadData"
|
:data="uploadData"
|
||||||
:file-list="yyPicList"
|
:show-file-list="false"
|
||||||
:before-upload="beforeUpload"
|
:before-upload="beforeUpload"
|
||||||
:on-preview="handlePictureCardPreview"
|
|
||||||
:on-remove="remove3Handler"
|
|
||||||
:http-request="httpRequest"
|
:http-request="httpRequest"
|
||||||
:on-success="upload3Success">
|
:on-success="upload3Success">
|
||||||
<el-icon class="avatar-uploader-icon"><Plus /></el-icon>
|
<div v-if="dataForm.yyPic" class="avatar-wrapper">
|
||||||
|
<img :src="baseUrl + dataForm.yyPic" class="avatar"/>
|
||||||
|
</div>
|
||||||
|
<el-icon v-else class="avatar-uploader-icon"><Plus /></el-icon>
|
||||||
|
</el-upload>
|
||||||
|
</el-form-item>
|
||||||
|
</el-col>
|
||||||
|
<el-col :span="6">
|
||||||
|
<el-form-item label="在常社保证明" prop="sbPic">
|
||||||
|
<el-upload
|
||||||
|
:action="uploadUrl"
|
||||||
|
class="avatar-uploader"
|
||||||
|
name="file"
|
||||||
|
:headers="headers"
|
||||||
|
:data="uploadData"
|
||||||
|
:show-file-list="false"
|
||||||
|
:before-upload="beforeUpload"
|
||||||
|
:http-request="httpRequest"
|
||||||
|
:on-success="upload5Success">
|
||||||
|
<div v-if="dataForm.sbPic" class="avatar-wrapper">
|
||||||
|
<img :src="baseUrl + dataForm.sbPic" class="avatar"/>
|
||||||
|
</div>
|
||||||
|
<el-icon v-else class="avatar-uploader-icon"><Plus /></el-icon>
|
||||||
</el-upload>
|
</el-upload>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
</el-col>
|
</el-col>
|
||||||
</el-row>
|
</el-row>
|
||||||
<el-row>
|
<el-row>
|
||||||
<el-col :span="8">
|
|
||||||
<el-form-item label="在常就业社保证明" prop="sbPic">
|
<el-col >
|
||||||
<el-upload
|
|
||||||
action="/recruit/file/uploadAttachment"
|
|
||||||
list-type="picture-card"
|
|
||||||
name="file"
|
|
||||||
:headers="headers"
|
|
||||||
:limit="1"
|
|
||||||
:data="uploadData"
|
|
||||||
:file-list="sbPicList"
|
|
||||||
:before-upload="beforeUpload"
|
|
||||||
:on-preview="handlePictureCardPreview"
|
|
||||||
:on-remove="remove5Handler"
|
|
||||||
:http-request="httpRequest"
|
|
||||||
:on-success="upload5Success">
|
|
||||||
<el-icon class="avatar-uploader-icon"><Plus /></el-icon>
|
|
||||||
</el-upload>
|
|
||||||
</el-form-item>
|
|
||||||
</el-col>
|
|
||||||
<el-col :span="8">
|
|
||||||
<el-form-item label="在常租赁合同/房产证明" prop="housePic">
|
<el-form-item label="在常租赁合同/房产证明" prop="housePic">
|
||||||
<el-upload
|
<el-upload
|
||||||
action="/recruit/file/uploadAttachment"
|
:action="uploadUrl"
|
||||||
list-type="picture-card"
|
list-type="picture-card"
|
||||||
name="file"
|
name="file"
|
||||||
:headers="headers"
|
:headers="headers"
|
||||||
@@ -137,14 +137,17 @@
|
|||||||
:http-request="httpRequest"
|
:http-request="httpRequest"
|
||||||
:on-success="upload4Success">
|
:on-success="upload4Success">
|
||||||
<el-icon class="avatar-uploader-icon"><Plus /></el-icon>
|
<el-icon class="avatar-uploader-icon"><Plus /></el-icon>
|
||||||
|
<template #tip>
|
||||||
|
<div>最多上传5张</div>
|
||||||
|
</template>
|
||||||
</el-upload>
|
</el-upload>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
</el-col>
|
</el-col>
|
||||||
|
|
||||||
<el-col :span="8">
|
<el-col>
|
||||||
<el-form-item label="户口本" prop="householdPic">
|
<el-form-item label="户口本" prop="householdPic">
|
||||||
<el-upload
|
<el-upload
|
||||||
action="/recruit/file/uploadAttachment"
|
:action="uploadUrl"
|
||||||
list-type="picture-card"
|
list-type="picture-card"
|
||||||
name="file"
|
name="file"
|
||||||
:headers="headers"
|
:headers="headers"
|
||||||
@@ -157,6 +160,9 @@
|
|||||||
:http-request="httpRequest"
|
:http-request="httpRequest"
|
||||||
:on-success="upload6Success">
|
:on-success="upload6Success">
|
||||||
<el-icon class="avatar-uploader-icon"><Plus /></el-icon>
|
<el-icon class="avatar-uploader-icon"><Plus /></el-icon>
|
||||||
|
<template #tip>
|
||||||
|
<div>最多上传5张</div>
|
||||||
|
</template>
|
||||||
</el-upload>
|
</el-upload>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
</el-col>
|
</el-col>
|
||||||
@@ -173,8 +179,8 @@
|
|||||||
<div class="dialog-footer">
|
<div class="dialog-footer">
|
||||||
<el-button @click="visible = false">取消</el-button>
|
<el-button @click="visible = false">取消</el-button>
|
||||||
<el-button type="primary" @click="dataFormSubmit('1')" v-auth="'recruit_recruitstudentsignup_edit'" v-if="canSubmit">保存</el-button>
|
<el-button type="primary" @click="dataFormSubmit('1')" v-auth="'recruit_recruitstudentsignup_edit'" v-if="canSubmit">保存</el-button>
|
||||||
<el-button type="success" plain @click="dataFormSubmit('2')" v-auth="'signup_material_exam'" v-if="canSubmit">通过</el-button>
|
<el-button type="success" icon="CircleCheck" @click="dataFormSubmit('2')" v-auth="'signup_material_exam'" v-if="canSubmit">通过</el-button>
|
||||||
<el-button type="danger" plain @click="dataFormSubmit('3')" v-auth="'signup_material_exam'" v-if="canSubmit">驳回</el-button>
|
<el-button type="danger" icon="CircleClose" @click="dataFormSubmit('3')" v-auth="'signup_material_exam'" v-if="canSubmit">驳回</el-button>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
@@ -187,18 +193,25 @@
|
|||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import { ref, reactive, nextTick, computed, onMounted } from 'vue'
|
import { ref, reactive, nextTick, computed, onMounted } from 'vue'
|
||||||
import { Plus } from '@element-plus/icons-vue'
|
import { Plus } from '@element-plus/icons-vue'
|
||||||
import { ElNotification } from 'element-plus'
|
|
||||||
import { storeToRefs } from 'pinia'
|
import { storeToRefs } from 'pinia'
|
||||||
import { useUserInfo } from '/@/stores/userInfo'
|
import { useUserInfo } from '/@/stores/userInfo'
|
||||||
|
import { useMessage } from '/@/hooks/message'
|
||||||
import { Session } from '/@/utils/storage'
|
import { Session } from '/@/utils/storage'
|
||||||
import axios from 'axios'
|
import axios from 'axios'
|
||||||
import { getObj, materialExam } from '/@/api/recruit/recruitstudentsignup'
|
import { getObj, materialExam } from '/@/api/recruit/recruitstudentsignup'
|
||||||
import { getList } from '/@/api/recruit/recruitstudentplangroup'
|
import { getList } from '/@/api/recruit/recruitstudentplangroup'
|
||||||
import { queryAllTeacher } from '/@/api/professional/professionaluser/teacherbase'
|
import { queryAllTeacher } from '/@/api/professional/professionaluser/teacherbase'
|
||||||
|
import { AUDIT_STATUS_LIST, getStatusConfig } from '/@/config/global'
|
||||||
|
|
||||||
|
const auditStatusList = AUDIT_STATUS_LIST
|
||||||
|
// 消息提示 hooks
|
||||||
|
const message = useMessage()
|
||||||
|
|
||||||
// 使用 Pinia store
|
// 使用 Pinia store
|
||||||
const userInfoStore = useUserInfo()
|
const userInfoStore = useUserInfo()
|
||||||
const { userInfos } = storeToRefs(userInfoStore)
|
const { userInfos } = storeToRefs(userInfoStore)
|
||||||
|
const baseUrl = import.meta.env.VITE_API_URL
|
||||||
|
const uploadUrl = baseUrl + '/recruit/file/uploadAttachment'
|
||||||
|
|
||||||
// 创建权限对象
|
// 创建权限对象
|
||||||
const permissions = computed(() => {
|
const permissions = computed(() => {
|
||||||
@@ -234,20 +247,7 @@ const type = ref<number | null>(null)
|
|||||||
const contactNameList = ref<any[]>([])
|
const contactNameList = ref<any[]>([])
|
||||||
const planList = ref<any[]>([])
|
const planList = ref<any[]>([])
|
||||||
|
|
||||||
const form = reactive({
|
|
||||||
attachment: '',
|
|
||||||
graPic: "",
|
|
||||||
yyPic: "",
|
|
||||||
housePic: "",
|
|
||||||
sbPic: "",
|
|
||||||
hkPic: ""
|
|
||||||
})
|
|
||||||
|
|
||||||
const fileList = ref<any[]>([])
|
|
||||||
const graPicList = ref<any[]>([])
|
|
||||||
const yyPicList = ref<any[]>([])
|
|
||||||
const houseList = ref<any[]>([])
|
const houseList = ref<any[]>([])
|
||||||
const sbPicList = ref<any[]>([])
|
|
||||||
const hkPicList = ref<any[]>([])
|
const hkPicList = ref<any[]>([])
|
||||||
|
|
||||||
const fileReader = ref<FileReader | null>(null)
|
const fileReader = ref<FileReader | null>(null)
|
||||||
@@ -259,69 +259,18 @@ const dataForm = reactive({
|
|||||||
zlshRemark: "",
|
zlshRemark: "",
|
||||||
groupId: "",
|
groupId: "",
|
||||||
name: "",
|
name: "",
|
||||||
oldName: "",
|
contactName: "",
|
||||||
gender: "",
|
|
||||||
nationality: "",
|
|
||||||
degreeOfEducation: "",
|
|
||||||
isLeagueMember: "",
|
|
||||||
schoolOfGraduation: "",
|
|
||||||
isAccommodation: "",
|
|
||||||
examRegistrationNumbers: "",
|
|
||||||
isMinimumLivingSecurity: "",
|
|
||||||
score: "",
|
|
||||||
postcode: "",
|
|
||||||
residenceType: "",
|
|
||||||
correctedScore: "",
|
|
||||||
placeScore: "",
|
|
||||||
schoolFrom: "",
|
|
||||||
idNumber: "",
|
|
||||||
residenceProvince: "",
|
|
||||||
residenceCity: "",
|
|
||||||
residenceArea: "",
|
|
||||||
residenceDetail: "",
|
|
||||||
homeAddressProvince: "",
|
|
||||||
homeAddressCity: "",
|
|
||||||
homeAddressArea: "",
|
|
||||||
homeAddressDetail: "",
|
|
||||||
parentName: "",
|
|
||||||
parentTelOne: "",
|
|
||||||
parentTelTwo: "",
|
|
||||||
selfTel: "",
|
|
||||||
wishMajorOne: "",
|
|
||||||
wishMajorTwo: "",
|
|
||||||
wishMajorThree: "",
|
|
||||||
confirmedMajor: "",
|
|
||||||
sevenMajor: "",
|
|
||||||
sixMajor: "",
|
|
||||||
fiveMajor: "",
|
|
||||||
fourMajor: "",
|
|
||||||
threeMajor: "",
|
|
||||||
twoMajor: "",
|
|
||||||
feeContribute: 0,
|
|
||||||
scorePhoto: "",
|
scorePhoto: "",
|
||||||
graPic: "",
|
graPic: "",
|
||||||
yyPic: "",
|
yyPic: "",
|
||||||
housePic: "",
|
housePic: "",
|
||||||
sbPic: "",
|
sbPic: "",
|
||||||
contactName: "",
|
|
||||||
oldSerialNumber: "",
|
|
||||||
colorDiscrimination: "",
|
|
||||||
nutrition: "",
|
|
||||||
height: "",
|
|
||||||
weight: "",
|
|
||||||
pastMedicalHistory: "",
|
|
||||||
eyesightLeft: "",
|
|
||||||
eyesightRight: "",
|
|
||||||
correctEyesightLeft: "",
|
|
||||||
correctEyesightRight: "",
|
|
||||||
remarks: "",
|
|
||||||
auditRemarks: "",
|
|
||||||
serialNumber: "",
|
|
||||||
auditStatus: "",
|
|
||||||
schoolCode: "",
|
|
||||||
newConfirmedMajor: "",
|
|
||||||
householdPic: "",
|
householdPic: "",
|
||||||
zlsh: ""
|
zlsh: "",
|
||||||
|
// 以下字段从后端获取,用于显示和判断
|
||||||
|
serialNumber: "",
|
||||||
|
degreeOfEducation: "",
|
||||||
|
auditStatus: ""
|
||||||
})
|
})
|
||||||
|
|
||||||
const dataRule = {
|
const dataRule = {
|
||||||
@@ -348,7 +297,7 @@ const dataRule = {
|
|||||||
// 初始化 FileReader
|
// 初始化 FileReader
|
||||||
onMounted(() => {
|
onMounted(() => {
|
||||||
if (!window.FileReader) {
|
if (!window.FileReader) {
|
||||||
console.error('Your browser does not support FileReader API!')
|
message.error('您的浏览器不支持 FileReader API!')
|
||||||
} else {
|
} else {
|
||||||
fileReader.value = new FileReader()
|
fileReader.value = new FileReader()
|
||||||
}
|
}
|
||||||
@@ -358,10 +307,7 @@ onMounted(() => {
|
|||||||
const beforeUpload = (file: File) => {
|
const beforeUpload = (file: File) => {
|
||||||
const isLt5M = file.size < 10 * 1024 * 1024
|
const isLt5M = file.size < 10 * 1024 * 1024
|
||||||
if (!isLt5M) {
|
if (!isLt5M) {
|
||||||
ElNotification.error({
|
message.error('文件大小不能超过10M')
|
||||||
title: '错误',
|
|
||||||
message: '文件大小不能超过10M'
|
|
||||||
})
|
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
return true
|
return true
|
||||||
@@ -373,68 +319,28 @@ const handlePictureCardPreview = (file: any) => {
|
|||||||
dialogUploadVisible.value = true
|
dialogUploadVisible.value = true
|
||||||
}
|
}
|
||||||
|
|
||||||
// 移除文件处理
|
|
||||||
const removeHandler = (file: any) => {
|
|
||||||
const index = fileList.value.findIndex((item: any) => item.url === file.url)
|
|
||||||
if (index > -1) {
|
|
||||||
fileList.value.splice(index, 1)
|
|
||||||
}
|
|
||||||
form.attachment = ""
|
|
||||||
dataForm.scorePhoto = ""
|
|
||||||
}
|
|
||||||
|
|
||||||
const remove2Handler = (file: any) => {
|
// 通用移除文件处理(多文件)
|
||||||
const index = graPicList.value.findIndex((item: any) => item.url === file.url)
|
const handleRemoveMultiple = (fileList: any[], dataFormField: string) => {
|
||||||
if (index > -1) {
|
return (file: any) => {
|
||||||
graPicList.value.splice(index, 1)
|
|
||||||
}
|
|
||||||
form.graPic = ""
|
|
||||||
dataForm.graPic = ""
|
|
||||||
}
|
|
||||||
|
|
||||||
const remove3Handler = (file: any) => {
|
|
||||||
const index = yyPicList.value.findIndex((item: any) => item.url === file.url)
|
|
||||||
if (index > -1) {
|
|
||||||
yyPicList.value.splice(index, 1)
|
|
||||||
}
|
|
||||||
form.yyPic = ""
|
|
||||||
dataForm.yyPic = ""
|
|
||||||
}
|
|
||||||
|
|
||||||
const remove4Handler = (file: any) => {
|
|
||||||
const arr: any[] = []
|
const arr: any[] = []
|
||||||
const strArr: string[] = []
|
const strArr: string[] = []
|
||||||
houseList.value.forEach((e: any) => {
|
const dataFormObj = dataForm as any
|
||||||
|
fileList.forEach((e: any) => {
|
||||||
if (e.url != file.url) {
|
if (e.url != file.url) {
|
||||||
arr.push(e)
|
arr.push(e)
|
||||||
strArr.push(e.url)
|
// 保存时使用原始路径
|
||||||
|
strArr.push(e.originalUrl || (e.url.startsWith(baseUrl) ? e.url.substring(baseUrl.length) : e.url))
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
houseList.value = arr
|
fileList.splice(0, fileList.length, ...arr)
|
||||||
dataForm.housePic = strArr.join(",")
|
dataFormObj[dataFormField] = strArr.join(",")
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const remove5Handler = (file: any) => {
|
// 移除文件处理(多图上传)
|
||||||
const index = sbPicList.value.findIndex((item: any) => item.url === file.url)
|
const remove4Handler = handleRemoveMultiple(houseList.value, 'housePic')
|
||||||
if (index > -1) {
|
const remove6Handler = handleRemoveMultiple(hkPicList.value, 'householdPic')
|
||||||
sbPicList.value.splice(index, 1)
|
|
||||||
}
|
|
||||||
form.sbPic = ""
|
|
||||||
dataForm.sbPic = ""
|
|
||||||
}
|
|
||||||
|
|
||||||
const remove6Handler = (file: any) => {
|
|
||||||
const arr: any[] = []
|
|
||||||
const strArr: string[] = []
|
|
||||||
hkPicList.value.forEach((e: any) => {
|
|
||||||
if (e.url != file.url) {
|
|
||||||
arr.push(e)
|
|
||||||
strArr.push(e.url)
|
|
||||||
}
|
|
||||||
})
|
|
||||||
hkPicList.value = arr
|
|
||||||
dataForm.householdPic = strArr.join(",")
|
|
||||||
}
|
|
||||||
|
|
||||||
// 自定义上传请求
|
// 自定义上传请求
|
||||||
const httpRequest = (options: any) => {
|
const httpRequest = (options: any) => {
|
||||||
@@ -444,8 +350,9 @@ const httpRequest = (options: any) => {
|
|||||||
fileReader.value.onload = () => {
|
fileReader.value.onload = () => {
|
||||||
const base64Str = fileReader.value?.result as string
|
const base64Str = fileReader.value?.result as string
|
||||||
const config = {
|
const config = {
|
||||||
url: '/recruit/file/uploadAttachment',
|
url: uploadUrl,
|
||||||
method: 'post',
|
method: 'post',
|
||||||
|
headers: headers.value,
|
||||||
data: {
|
data: {
|
||||||
base64Str: base64Str.split(',')[1]
|
base64Str: base64Str.split(',')[1]
|
||||||
},
|
},
|
||||||
@@ -466,66 +373,39 @@ const httpRequest = (options: any) => {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 通用上传成功回调(单文件 - avatar模式)
|
||||||
|
const handleUploadSuccess = (dataFormField: string) => {
|
||||||
|
return (res: any) => {
|
||||||
|
const fileUrl = res.data.fileUrl
|
||||||
|
const dataFormObj = dataForm as any
|
||||||
|
dataFormObj[dataFormField] = fileUrl
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 通用上传成功回调(多文件)
|
||||||
|
const handleUploadSuccessMultiple = (fileList: any[], dataFormField: string) => {
|
||||||
|
return (res: any) => {
|
||||||
|
const fileUrl = res.data.fileUrl // 后端返回的原始路径
|
||||||
|
const dataFormObj = dataForm as any
|
||||||
|
// 添加到文件列表,显示时添加 baseUrl 前缀,同时保存原始路径用于提交
|
||||||
|
fileList.push({ url: baseUrl + fileUrl, name: '', originalUrl: fileUrl })
|
||||||
|
// 保存时使用原始路径
|
||||||
|
const arr: string[] = []
|
||||||
|
fileList.forEach((e: any) => {
|
||||||
|
// 优先使用保存的原始路径,如果没有则从 url 中提取
|
||||||
|
arr.push(e.originalUrl || (e.url.startsWith(baseUrl) ? e.url.substring(baseUrl.length) : e.url))
|
||||||
|
})
|
||||||
|
dataFormObj[dataFormField] = arr.join(",")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// 上传成功回调
|
// 上传成功回调
|
||||||
const uploadSuccess = (res: any, file: any) => {
|
const uploadSuccess = handleUploadSuccess('scorePhoto')
|
||||||
form.attachment = res.data.fileUrl
|
const upload2Success = handleUploadSuccess('graPic')
|
||||||
if (fileList.value.length > 0) {
|
const upload3Success = handleUploadSuccess('yyPic')
|
||||||
fileList.value[0] = { url: form.attachment, name: "" }
|
const upload4Success = handleUploadSuccessMultiple(houseList.value, 'housePic')
|
||||||
} else {
|
const upload5Success = handleUploadSuccess('sbPic')
|
||||||
fileList.value.push({ url: form.attachment, name: "" })
|
const upload6Success = handleUploadSuccessMultiple(hkPicList.value, 'householdPic')
|
||||||
}
|
|
||||||
dataForm.scorePhoto = form.attachment
|
|
||||||
}
|
|
||||||
|
|
||||||
const upload2Success = (res: any, file: any) => {
|
|
||||||
form.graPic = res.data.fileUrl
|
|
||||||
if (graPicList.value.length > 0) {
|
|
||||||
graPicList.value[0] = { url: form.graPic, name: "" }
|
|
||||||
} else {
|
|
||||||
graPicList.value.push({ url: form.graPic, name: "" })
|
|
||||||
}
|
|
||||||
dataForm.graPic = form.graPic
|
|
||||||
}
|
|
||||||
|
|
||||||
const upload3Success = (res: any, file: any) => {
|
|
||||||
form.yyPic = res.data.fileUrl
|
|
||||||
if (yyPicList.value.length > 0) {
|
|
||||||
yyPicList.value[0] = { url: form.yyPic, name: "" }
|
|
||||||
} else {
|
|
||||||
yyPicList.value.push({ url: form.yyPic, name: "" })
|
|
||||||
}
|
|
||||||
dataForm.yyPic = form.yyPic
|
|
||||||
}
|
|
||||||
|
|
||||||
const upload4Success = (res: any, file: any) => {
|
|
||||||
form.housePic = res.data.fileUrl
|
|
||||||
houseList.value.push({ url: form.housePic })
|
|
||||||
const arr: string[] = []
|
|
||||||
houseList.value.forEach((e: any) => {
|
|
||||||
arr.push(e.url)
|
|
||||||
})
|
|
||||||
dataForm.housePic = arr.join(",")
|
|
||||||
}
|
|
||||||
|
|
||||||
const upload5Success = (res: any, file: any) => {
|
|
||||||
form.sbPic = res.data.fileUrl
|
|
||||||
if (sbPicList.value.length > 0) {
|
|
||||||
sbPicList.value[0] = { url: form.sbPic, name: "" }
|
|
||||||
} else {
|
|
||||||
sbPicList.value.push({ url: form.sbPic, name: "" })
|
|
||||||
}
|
|
||||||
dataForm.sbPic = form.sbPic
|
|
||||||
}
|
|
||||||
|
|
||||||
const upload6Success = (res: any, file: any) => {
|
|
||||||
form.hkPic = res.data.fileUrl
|
|
||||||
hkPicList.value.push({ url: form.hkPic })
|
|
||||||
const arr: string[] = []
|
|
||||||
hkPicList.value.forEach((e: any) => {
|
|
||||||
arr.push(e.url)
|
|
||||||
})
|
|
||||||
dataForm.householdPic = arr.join(",")
|
|
||||||
}
|
|
||||||
|
|
||||||
// 初始化数据
|
// 初始化数据
|
||||||
const initData = () => {
|
const initData = () => {
|
||||||
@@ -540,20 +420,14 @@ const initData = () => {
|
|||||||
|
|
||||||
// 表单提交
|
// 表单提交
|
||||||
const dataFormSubmit = (submitType: string) => {
|
const dataFormSubmit = (submitType: string) => {
|
||||||
if (dataForm.zlshRemark == '' && submitType == '3') {
|
if ((dataForm.zlshRemark == '' || !dataForm.zlshRemark) && submitType == '3') {
|
||||||
ElNotification.error({
|
message.error('请填写驳回理由')
|
||||||
title: '错误',
|
|
||||||
message: '请填写驳回理由'
|
|
||||||
})
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
dataForm.zlsh = submitType
|
dataForm.zlsh = submitType
|
||||||
canSubmit.value = false
|
canSubmit.value = false
|
||||||
materialExam(dataForm).then(() => {
|
materialExam(dataForm).then(() => {
|
||||||
ElNotification.success({
|
message.success('操作成功')
|
||||||
title: '成功',
|
|
||||||
message: '操作成功'
|
|
||||||
})
|
|
||||||
visible.value = false
|
visible.value = false
|
||||||
emit('refreshDataList')
|
emit('refreshDataList')
|
||||||
}).catch(() => {
|
}).catch(() => {
|
||||||
@@ -563,7 +437,7 @@ const dataFormSubmit = (submitType: string) => {
|
|||||||
|
|
||||||
// 初始化方法
|
// 初始化方法
|
||||||
const init = (id: string | null) => {
|
const init = (id: string | null) => {
|
||||||
dataForm.id = id || null
|
dataForm.id = id || ""
|
||||||
visible.value = true
|
visible.value = true
|
||||||
canSubmit.value = true
|
canSubmit.value = true
|
||||||
initData()
|
initData()
|
||||||
@@ -571,55 +445,45 @@ const init = (id: string | null) => {
|
|||||||
dataFormRef.value?.resetFields()
|
dataFormRef.value?.resetFields()
|
||||||
if (dataForm.id) {
|
if (dataForm.id) {
|
||||||
getObj(dataForm.id).then((response: any) => {
|
getObj(dataForm.id).then((response: any) => {
|
||||||
fileList.value = []
|
// 清空多图上传的列表
|
||||||
graPicList.value = []
|
|
||||||
yyPicList.value = []
|
|
||||||
houseList.value = []
|
houseList.value = []
|
||||||
sbPicList.value = []
|
|
||||||
hkPicList.value = []
|
hkPicList.value = []
|
||||||
Object.assign(dataForm, response.data)
|
Object.assign(dataForm, response.data)
|
||||||
title.value = dataForm.serialNumber
|
title.value = dataForm.serialNumber
|
||||||
if (dataForm.scorePhoto != '') {
|
// avatar 模式直接使用 dataForm 中的字段,不需要 fileList
|
||||||
fileList.value.push({ url: dataForm.scorePhoto, name: "" })
|
// 多图上传需要初始化列表
|
||||||
}
|
if (dataForm.housePic && dataForm.housePic != '') {
|
||||||
if (dataForm.graPic != '') {
|
const arr = dataForm.housePic.split(",").filter((item: string) => item && item.trim())
|
||||||
graPicList.value.push({ url: dataForm.graPic, name: "" })
|
|
||||||
}
|
|
||||||
if (dataForm.yyPic != '') {
|
|
||||||
yyPicList.value.push({ url: dataForm.yyPic, name: "" })
|
|
||||||
}
|
|
||||||
if (dataForm.housePic != '') {
|
|
||||||
const arr = dataForm.housePic.split(",")
|
|
||||||
arr.forEach((e: string) => {
|
arr.forEach((e: string) => {
|
||||||
houseList.value.push({ url: e })
|
// 保存原始路径,显示时添加 baseUrl 前缀
|
||||||
|
houseList.value.push({ url: baseUrl + e, name: '', originalUrl: e })
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
if (dataForm.sbPic != '') {
|
if (dataForm.householdPic && dataForm.householdPic != '') {
|
||||||
sbPicList.value.push({ url: dataForm.sbPic, name: "" })
|
const arr2 = dataForm.householdPic.split(",").filter((item: string) => item && item.trim())
|
||||||
}
|
|
||||||
if (dataForm.householdPic != '') {
|
|
||||||
const arr2 = dataForm.householdPic.split(",")
|
|
||||||
arr2.forEach((e: string) => {
|
arr2.forEach((e: string) => {
|
||||||
hkPicList.value.push({ url: e })
|
// 保存原始路径,显示时添加 baseUrl 前缀
|
||||||
|
hkPicList.value.push({ url: baseUrl + e, name: '', originalUrl: e })
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
if ("1" == String(dataForm.degreeOfEducation)) {
|
const educationPrefixMap: Record<string, string> = {
|
||||||
title.value = "C" + title.value
|
'1': 'C', // 初中
|
||||||
} else if ("2" == String(dataForm.degreeOfEducation)) {
|
'2': 'G', // 高中
|
||||||
title.value = "G" + title.value
|
'3': 'J' // 技职校
|
||||||
} else if ("3" == String(dataForm.degreeOfEducation)) {
|
}
|
||||||
title.value = "J" + title.value
|
const prefix = educationPrefixMap[String(dataForm.degreeOfEducation)]
|
||||||
|
if (prefix) {
|
||||||
|
title.value = prefix + title.value
|
||||||
}
|
}
|
||||||
contactNameflag.value = false
|
contactNameflag.value = false
|
||||||
if ("-20" == String(dataForm.auditStatus)) {
|
const auditStatusConfig = getStatusConfig(auditStatusList, dataForm.auditStatus)
|
||||||
title.value = "未录取 " + title.value
|
if (auditStatusConfig) {
|
||||||
} else if ("0" == String(dataForm.auditStatus)) {
|
title.value = auditStatusConfig.label + " " + title.value
|
||||||
title.value = "待审核 " + title.value
|
if (auditStatusConfig.value == '20') {
|
||||||
} else if ("20" == String(dataForm.auditStatus)) {
|
|
||||||
title.value = "已录取 " + title.value
|
|
||||||
contactNameflag.value = true
|
contactNameflag.value = true
|
||||||
}
|
}
|
||||||
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
@@ -637,16 +501,42 @@ defineExpose({
|
|||||||
margin-bottom:18px!important;
|
margin-bottom:18px!important;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
.avatar-uploader-icon {
|
|
||||||
|
|
||||||
|
.avatar-uploader {
|
||||||
|
:deep(.el-upload) {
|
||||||
|
border: 1px dashed var(--el-border-color);
|
||||||
|
border-radius: 6px;
|
||||||
|
cursor: pointer;
|
||||||
|
position: relative;
|
||||||
|
overflow: hidden;
|
||||||
|
transition: var(--el-transition-duration-fast);
|
||||||
|
width: 148px;
|
||||||
|
height: 148px;
|
||||||
|
&:hover {
|
||||||
|
border-color: var(--el-color-primary);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.avatar-uploader-icon {
|
||||||
font-size: 28px;
|
font-size: 28px;
|
||||||
color: #8c939d;
|
color: #8c939d;
|
||||||
width: 100px;
|
width: 148px;
|
||||||
height: 100px;
|
height: 148px;
|
||||||
line-height: 100px;
|
line-height: 148px;
|
||||||
text-align: center;
|
text-align: center;
|
||||||
}
|
}
|
||||||
|
|
||||||
.dialog-footer {
|
.avatar-wrapper {
|
||||||
text-align: right;
|
width: 148px;
|
||||||
}
|
height: 148px;
|
||||||
|
.avatar {
|
||||||
|
width: 148px;
|
||||||
|
height: 148px;
|
||||||
|
display: block;
|
||||||
|
object-fit: cover;
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|||||||
@@ -1,20 +1,3 @@
|
|||||||
<!--
|
|
||||||
- Copyright (c) 2018-2025, cyweb All rights reserved.
|
|
||||||
-
|
|
||||||
- Redistribution and use in source and binary forms, with or without
|
|
||||||
- modification, are permitted provided that the following conditions are met:
|
|
||||||
-
|
|
||||||
- Redistributions of source code must retain the above copyright notice,
|
|
||||||
- this list of conditions and the following disclaimer.
|
|
||||||
- Redistributions in binary form must reproduce the above copyright
|
|
||||||
- notice, this list of conditions and the following disclaimer in the
|
|
||||||
- documentation and/or other materials provided with the distribution.
|
|
||||||
- Neither the name of the pig4cloud.com developer nor the names of its
|
|
||||||
- contributors may be used to endorse or promote products derived from
|
|
||||||
- this software without specific prior written permission.
|
|
||||||
-
|
|
||||||
-->
|
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<div class="layout-padding">
|
<div class="layout-padding">
|
||||||
<div class="layout-padding-auto layout-padding-view">
|
<div class="layout-padding-auto layout-padding-view">
|
||||||
@@ -60,37 +43,120 @@
|
|||||||
:header-cell-style="tableStyle.headerCellStyle"
|
:header-cell-style="tableStyle.headerCellStyle"
|
||||||
>
|
>
|
||||||
<el-table-column type="index" label="序号" width="60" align="center" />
|
<el-table-column type="index" label="序号" width="60" align="center" />
|
||||||
<el-table-column prop="type" label="异动类型" align="center" show-overflow-tooltip>
|
<el-table-column prop="type" label="异动类型" width="100" align="center" show-overflow-tooltip>
|
||||||
<template #default="scope">
|
<template #default="scope">
|
||||||
{{ getTypeLabel(scope.row.type) }}
|
{{ getTypeLabel(scope.row.type) }}
|
||||||
</template>
|
</template>
|
||||||
</el-table-column>
|
</el-table-column>
|
||||||
<el-table-column prop="name" label="姓名[唯一号]" width="140" align="center" show-overflow-tooltip />
|
<el-table-column prop="name" label="姓名[唯一号]" min-width="160" align="center" show-overflow-tooltip />
|
||||||
<el-table-column prop="majorChangeInfo" label="专业变更情况" align="center" show-overflow-tooltip />
|
<el-table-column prop="majorChangeInfo" label="专业变更情况" min-width="180" align="center" show-overflow-tooltip>
|
||||||
<el-table-column label="学费变更情况" align="center">
|
|
||||||
<el-table-column prop="dbName" label="费用类型" align="center" show-overflow-tooltip />
|
|
||||||
<el-table-column prop="dbOldValue" label="原费用" align="center" show-overflow-tooltip />
|
|
||||||
<el-table-column prop="dbNewValue" label="新费用" align="center" show-overflow-tooltip />
|
|
||||||
<el-table-column prop="dbType" label="变更类型" align="center" show-overflow-tooltip />
|
|
||||||
<el-table-column prop="dbChangeValue" label="变更金额" align="center" show-overflow-tooltip />
|
|
||||||
</el-table-column>
|
|
||||||
<el-table-column label="分数变更情况" align="center">
|
|
||||||
<el-table-column prop="scoreName" label="分数类型" align="center" show-overflow-tooltip />
|
|
||||||
<el-table-column prop="scoreOldValue" label="原分值" align="center" show-overflow-tooltip />
|
|
||||||
<el-table-column prop="scoreNewValue" label="新分值" align="center" show-overflow-tooltip />
|
|
||||||
</el-table-column>
|
|
||||||
<el-table-column prop="createBy" label="异动发起人" align="center" show-overflow-tooltip />
|
|
||||||
<el-table-column prop="createDate" label="异动时间" align="center" show-overflow-tooltip />
|
|
||||||
<el-table-column prop="remarks" label="备注信息" align="center" show-overflow-tooltip />
|
|
||||||
<el-table-column prop="isMajorChange" label="异动审核" width="110" align="center" show-overflow-tooltip>
|
|
||||||
<template #default="scope">
|
<template #default="scope">
|
||||||
<AuditState :state="scope.row.isMajorChange" :options="auditStateOptions" />
|
<DetailPopover
|
||||||
|
v-if="scope.row.newMajorInfo || scope.row.oldMajorInfo"
|
||||||
|
title="专业变更详情"
|
||||||
|
:title-icon="InfoFilled"
|
||||||
|
:width="320"
|
||||||
|
:items="(() => {
|
||||||
|
const items = []
|
||||||
|
if (scope.row.oldMajorInfo) {
|
||||||
|
items.push({ label: '旧专业', content: scope.row.oldMajorInfo })
|
||||||
|
}
|
||||||
|
if (scope.row.newMajorInfo) {
|
||||||
|
items.push({ label: '新专业', content: scope.row.newMajorInfo, contentClass: 'new-major' })
|
||||||
|
}
|
||||||
|
return items
|
||||||
|
})()">
|
||||||
|
<template #reference>
|
||||||
|
<span class="major-change-link">
|
||||||
|
{{ scope.row.newMajorInfo || '查看详情' }}
|
||||||
|
<el-icon class="title-icon"><InfoFilled /></el-icon>
|
||||||
|
</span>
|
||||||
|
</template>
|
||||||
|
</DetailPopover>
|
||||||
|
<span v-else class="empty-text">-</span>
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
<el-table-column label="代办费变更情况" min-width="130" align="center" show-overflow-tooltip>
|
||||||
|
<template #default="scope">
|
||||||
|
<span class="new-fee">{{ scope.row.newAgencyFee }}</span> / <span class="old-fee">{{ scope.row.oldAgencyFee }}</span>
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
<el-table-column label="学费变更情况" min-width="140" align="center" show-overflow-tooltip>
|
||||||
|
<template #default="scope">
|
||||||
|
<span class="new-fee">{{ scope.row.newFeeTuition }}</span> / <span class="old-fee">{{ scope.row.oldFeeTuition }}</span>
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
<el-table-column label="分数变更情况" min-width="130" align="center">
|
||||||
|
<template #default="scope">
|
||||||
|
<span class="new-fee">{{ scope.row.newCorrectedScore }}</span> / <span class="old-fee">{{ scope.row.oldCorrectedScore }}</span>
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
<el-table-column prop="createBy" label="异动发起人" min-width="120" align="center" show-overflow-tooltip />
|
||||||
|
<el-table-column prop="createTime" label="异动时间" min-width="180" align="center" show-overflow-tooltip />
|
||||||
|
<el-table-column prop="isMajorChange" label="异动审核" min-width="110" align="center" show-overflow-tooltip>
|
||||||
|
<template #default="scope">
|
||||||
|
<template v-if="getStatusConfig(auditStateOptions, scope.row.isMajorChange)">
|
||||||
|
<!-- 有备注信息时,使用 popover 包裹 ClickableTag -->
|
||||||
|
<DetailPopover
|
||||||
|
v-if="scope.row.remarks"
|
||||||
|
title="异动审核详情"
|
||||||
|
:width="300"
|
||||||
|
:items="[
|
||||||
|
{
|
||||||
|
label: '审核状态',
|
||||||
|
layout: 'horizontal',
|
||||||
|
content: getStatusConfig(auditStateOptions, scope.row.isMajorChange)?.label
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: '备注信息',
|
||||||
|
content: scope.row.remarks,
|
||||||
|
contentClass: 'reason-content'
|
||||||
|
}
|
||||||
|
]">
|
||||||
|
<template #reference>
|
||||||
|
<ClickableTag
|
||||||
|
width="80"
|
||||||
|
:type="getStatusConfig(auditStateOptions, scope.row.isMajorChange)?.type || 'info'"
|
||||||
|
:left-icon="getStatusConfig(auditStateOptions, scope.row.isMajorChange)?.icon">
|
||||||
|
{{ getStatusConfig(auditStateOptions, scope.row.isMajorChange)?.label }}
|
||||||
|
</ClickableTag>
|
||||||
|
</template>
|
||||||
|
<template #content-0>
|
||||||
|
<ClickableTag
|
||||||
|
:type="getStatusConfig(auditStateOptions, scope.row.isMajorChange)?.type || 'info'"
|
||||||
|
:left-icon="getStatusConfig(auditStateOptions, scope.row.isMajorChange)?.icon"
|
||||||
|
:right-icon="null">
|
||||||
|
{{ getStatusConfig(auditStateOptions, scope.row.isMajorChange)?.label }}
|
||||||
|
</ClickableTag>
|
||||||
|
</template>
|
||||||
|
<template #content-1>
|
||||||
|
<div class="reason-content">
|
||||||
|
<el-icon class="reason-icon"><Warning /></el-icon>
|
||||||
|
<span>{{ scope.row.remarks }}</span>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
</DetailPopover>
|
||||||
|
|
||||||
|
<!-- 没有备注信息时,直接显示 ClickableTag -->
|
||||||
|
<ClickableTag
|
||||||
|
v-else
|
||||||
|
width="80"
|
||||||
|
:type="getStatusConfig(auditStateOptions, scope.row.isMajorChange)?.type || 'info'"
|
||||||
|
:left-icon="getStatusConfig(auditStateOptions, scope.row.isMajorChange)?.icon"
|
||||||
|
:right-icon="null">
|
||||||
|
{{ getStatusConfig(auditStateOptions, scope.row.isMajorChange)?.label }}
|
||||||
|
</ClickableTag>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<!-- 无状态 -->
|
||||||
|
<span v-else class="empty-text">-</span>
|
||||||
</template>
|
</template>
|
||||||
</el-table-column>
|
</el-table-column>
|
||||||
<el-table-column label="操作" width="100" align="center" fixed="right">
|
<el-table-column label="操作" width="100" align="center" fixed="right">
|
||||||
<template #default="scope">
|
<template #default="scope">
|
||||||
<el-button
|
<el-button
|
||||||
v-if="permissions.recruit_recruitstudentsignupturnover_edit && scope.row.isMajorChange == '1'"
|
v-auth="'recruit_recruitstudentsignupturnover_edit'"
|
||||||
|
v-if="scope.row.isMajorChange == '1'"
|
||||||
type="primary"
|
type="primary"
|
||||||
link
|
link
|
||||||
icon="EditPen"
|
icon="EditPen"
|
||||||
@@ -111,9 +177,9 @@
|
|||||||
|
|
||||||
<!-- 异动审核弹窗 -->
|
<!-- 异动审核弹窗 -->
|
||||||
<el-dialog v-model="majorChangeVisible" title="异动审核" width="600px">
|
<el-dialog v-model="majorChangeVisible" title="异动审核" width="600px">
|
||||||
<el-form :model="exarmForm" ref="exarmFormRef" label-width="80px" :rules="dataRule">
|
<el-form :model="exarmForm" ref="exarmFormRef" label-width="100px" :rules="dataRule">
|
||||||
<el-form-item label="审核结果" prop="isMajorChange">
|
<el-form-item label="审核结果" prop="isMajorChange">
|
||||||
<el-select v-model="exarmForm.isMajorChange" filterable clearable placeholder="请选择审核结果" style="width: 100%">
|
<el-select v-model="exarmForm.isMajorChange" filterable clearable placeholder="请选择审核结果">
|
||||||
<el-option
|
<el-option
|
||||||
v-for="item in isMajorChangeList"
|
v-for="item in isMajorChangeList"
|
||||||
:key="item.value"
|
:key="item.value"
|
||||||
@@ -125,7 +191,7 @@
|
|||||||
<el-form-item label="审核意见" prop="remarks">
|
<el-form-item label="审核意见" prop="remarks">
|
||||||
<el-input
|
<el-input
|
||||||
type="textarea"
|
type="textarea"
|
||||||
placeholder="请输入审核内容"
|
placeholder="请输入审核意见"
|
||||||
:autosize="{ minRows: 2, maxRows: 4 }"
|
:autosize="{ minRows: 2, maxRows: 4 }"
|
||||||
style="width: 100%"
|
style="width: 100%"
|
||||||
v-model="exarmForm.remarks"
|
v-model="exarmForm.remarks"
|
||||||
@@ -145,29 +211,16 @@
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup lang="ts" name="recruitstudentsignupturnover">
|
<script setup lang="ts" name="recruitstudentsignupturnover">
|
||||||
import { ref, reactive, computed, onMounted, defineAsyncComponent } from 'vue'
|
import { ref, reactive, computed, onMounted } from 'vue'
|
||||||
import { storeToRefs } from 'pinia'
|
|
||||||
import { useUserInfo } from '/@/stores/userInfo'
|
|
||||||
import { BasicTableProps, useTable } from '/@/hooks/table'
|
import { BasicTableProps, useTable } from '/@/hooks/table'
|
||||||
import { useMessage } from '/@/hooks/message'
|
import { useMessage } from '/@/hooks/message'
|
||||||
import { fetchList, putObj } from '/@/api/recruit/recruitstudentsignupturnover'
|
import { fetchList, putObj } from '/@/api/recruit/recruitstudentsignupturnover'
|
||||||
import { getList } from '/@/api/recruit/recruitstudentplangroup'
|
import { getList } from '/@/api/recruit/recruitstudentplangroup'
|
||||||
import type { StateOption } from '/@/components/AuditState/index.vue'
|
import ClickableTag from '/@/components/ClickableTag/index.vue'
|
||||||
|
import DetailPopover from '/@/components/DetailPopover/index.vue'
|
||||||
const AuditState = defineAsyncComponent(() => import('/@/components/AuditState/index.vue'))
|
import { Warning, InfoFilled } from '@element-plus/icons-vue'
|
||||||
|
import { TURNOVER_AUDIT_STATUS_LIST, getStatusConfig } from '/@/config/global'
|
||||||
// 使用 Pinia store
|
import { getDicts } from '/@/api/admin/dict'
|
||||||
const userInfoStore = useUserInfo()
|
|
||||||
const { userInfos } = storeToRefs(userInfoStore)
|
|
||||||
|
|
||||||
// 创建权限对象
|
|
||||||
const permissions = computed(() => {
|
|
||||||
const perms: Record<string, boolean> = {}
|
|
||||||
userInfos.value.authBtnList.forEach((perm: string) => {
|
|
||||||
perms[perm] = true
|
|
||||||
})
|
|
||||||
return perms
|
|
||||||
})
|
|
||||||
|
|
||||||
// 消息提示 hooks
|
// 消息提示 hooks
|
||||||
const message = useMessage()
|
const message = useMessage()
|
||||||
@@ -182,14 +235,11 @@ const majorChangeVisible = ref(false)
|
|||||||
|
|
||||||
// 数据
|
// 数据
|
||||||
const planList = ref<any[]>([])
|
const planList = ref<any[]>([])
|
||||||
const typeList = ref([{ label: '专业变更', value: '1' }, { label: '退学', value: '2' }])
|
// 使用字典 recruit_change_type
|
||||||
|
const typeList = ref<any[]>([])
|
||||||
|
|
||||||
// 审核状态选项配置(用于 AuditState 组件和检索条件)
|
// 审核状态选项配置(用于 ClickableTag 组件和检索条件)
|
||||||
const auditStateOptions = ref<StateOption[]>([
|
const auditStateOptions = ref<any[]>(TURNOVER_AUDIT_STATUS_LIST)
|
||||||
{ value: '1', label: '待审核', type: 'warning', icon: 'fa-regular fa-clock', effect: 'light' },
|
|
||||||
{ value: '2', label: '驳回', type: 'danger', icon: 'fa-solid fa-circle-xmark', effect: 'dark' },
|
|
||||||
{ value: '3', label: '通过', type: 'success', icon: 'fa-solid fa-circle-check', effect: 'dark' }
|
|
||||||
])
|
|
||||||
|
|
||||||
// 从 auditStateOptions 派生检索条件列表(只包含 label 和 value)
|
// 从 auditStateOptions 派生检索条件列表(只包含 label 和 value)
|
||||||
const majorChangeList = computed(() => {
|
const majorChangeList = computed(() => {
|
||||||
@@ -202,7 +252,7 @@ const majorChangeList = computed(() => {
|
|||||||
// 审核弹窗中的选项(只包含通过和驳回)
|
// 审核弹窗中的选项(只包含通过和驳回)
|
||||||
const isMajorChangeList = computed(() => {
|
const isMajorChangeList = computed(() => {
|
||||||
return auditStateOptions.value
|
return auditStateOptions.value
|
||||||
.filter(item => item.value === '2' || item.value === '3')
|
.filter(item => item.value !== '1')
|
||||||
.map(item => ({
|
.map(item => ({
|
||||||
label: item.label,
|
label: item.label,
|
||||||
value: item.value
|
value: item.value
|
||||||
@@ -234,7 +284,7 @@ const dataRule = {
|
|||||||
|
|
||||||
// 获取异动类型标签
|
// 获取异动类型标签
|
||||||
const getTypeLabel = (type: string) => {
|
const getTypeLabel = (type: string) => {
|
||||||
const item = typeList.value.find(item => item.value === type)
|
const item = typeList.value.find((it: any) => String(it.value) === String(type))
|
||||||
return item ? item.label : ''
|
return item ? item.label : ''
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -265,9 +315,12 @@ const init = async () => {
|
|||||||
if (planList.value.length > 0) {
|
if (planList.value.length > 0) {
|
||||||
queryForm.groupId = planList.value[0].id
|
queryForm.groupId = planList.value[0].id
|
||||||
}
|
}
|
||||||
|
const typeData = await getDicts('recruit_change_type')
|
||||||
|
typeList.value = typeData.data || []
|
||||||
getDataList()
|
getDataList()
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
message.error('初始化失败')
|
// eslint-disable-next-line no-console
|
||||||
|
console.log('初始化失败', error)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -295,8 +348,9 @@ const update = async () => {
|
|||||||
message.success('审核成功')
|
message.success('审核成功')
|
||||||
majorChangeVisible.value = false
|
majorChangeVisible.value = false
|
||||||
getDataList()
|
getDataList()
|
||||||
} catch (error: any) {
|
} catch (error) {
|
||||||
message.error(error.msg || '审核失败')
|
// eslint-disable-next-line no-console
|
||||||
|
console.log(error)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -318,4 +372,69 @@ onMounted(() => {
|
|||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style lang="scss" scoped>
|
<style lang="scss" scoped>
|
||||||
|
.new-fee {
|
||||||
|
color: var(--el-color-primary);
|
||||||
|
font-weight: 600;
|
||||||
|
font-size: 14px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.old-fee {
|
||||||
|
text-decoration: line-through;
|
||||||
|
color: #606266;
|
||||||
|
font-size: 13px;
|
||||||
|
margin-left: 4px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.empty-text {
|
||||||
|
color: #909399;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 备注内容样式(用于 DetailPopover 的插槽内容)
|
||||||
|
.reason-content {
|
||||||
|
display: flex;
|
||||||
|
align-items: flex-start;
|
||||||
|
gap: 8px;
|
||||||
|
padding: 12px;
|
||||||
|
background-color: #fef0f0;
|
||||||
|
border-radius: 4px;
|
||||||
|
border-left: 3px solid #f56c6c;
|
||||||
|
|
||||||
|
.reason-icon {
|
||||||
|
color: #f56c6c;
|
||||||
|
font-size: 16px;
|
||||||
|
flex-shrink: 0;
|
||||||
|
margin-top: 1px;
|
||||||
|
}
|
||||||
|
|
||||||
|
span {
|
||||||
|
color: #f56c6c;
|
||||||
|
line-height: 1.6;
|
||||||
|
word-break: break-all;
|
||||||
|
flex: 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 专业变更链接样式
|
||||||
|
.major-change-link {
|
||||||
|
display: inline-flex;
|
||||||
|
align-items: center;
|
||||||
|
gap: 4px;
|
||||||
|
color: var(--el-color-primary);
|
||||||
|
text-decoration: underline;
|
||||||
|
cursor: pointer;
|
||||||
|
font-weight: 500;
|
||||||
|
|
||||||
|
&:hover {
|
||||||
|
color: var(--el-color-primary-light-3);
|
||||||
|
}
|
||||||
|
.title-icon {
|
||||||
|
color: var(--el-color-primary);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 新专业样式(用于 DetailPopover 的内容类)
|
||||||
|
.new-major {
|
||||||
|
color: var(--el-color-primary);
|
||||||
|
font-weight: 500;
|
||||||
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|||||||
Reference in New Issue
Block a user