This commit is contained in:
parent
b4cdf86580
commit
327564d769
|
@ -13,6 +13,7 @@
|
|||
"dependencies": {
|
||||
"@arco-design/web-vue": "^2.53.0",
|
||||
"@element-plus/icons-vue": "^2.1.0",
|
||||
"@tinymce/tinymce-vue": "^4.0.1",
|
||||
"ant-design-vue": "4.x",
|
||||
"axios": "^1.5.1",
|
||||
"echarts": "^5.4.3",
|
||||
|
@ -20,6 +21,7 @@
|
|||
"element-plus": "^2.4.0",
|
||||
"less": "^4.2.0",
|
||||
"pinia": "^2.1.6",
|
||||
"tinymce": "^5.6.2",
|
||||
"uuid": "^9.0.1",
|
||||
"uuidv1": "^1.6.14",
|
||||
"vue": "^3.3.4",
|
||||
|
|
|
@ -11,6 +11,9 @@ dependencies:
|
|||
'@element-plus/icons-vue':
|
||||
specifier: ^2.1.0
|
||||
version: registry.npmmirror.com/@element-plus/icons-vue@2.1.0(vue@3.3.4)
|
||||
'@tinymce/tinymce-vue':
|
||||
specifier: ^4.0.1
|
||||
version: registry.npmmirror.com/@tinymce/tinymce-vue@4.0.7(vue@3.3.4)
|
||||
ant-design-vue:
|
||||
specifier: 4.x
|
||||
version: registry.npmmirror.com/ant-design-vue@4.0.7(vue@3.3.4)
|
||||
|
@ -32,6 +35,9 @@ dependencies:
|
|||
pinia:
|
||||
specifier: ^2.1.6
|
||||
version: registry.npmmirror.com/pinia@2.1.7(vue@3.3.4)
|
||||
tinymce:
|
||||
specifier: ^5.6.2
|
||||
version: registry.npmmirror.com/tinymce@5.10.9
|
||||
uuid:
|
||||
specifier: ^9.0.1
|
||||
version: registry.npmmirror.com/uuid@9.0.1
|
||||
|
@ -651,6 +657,18 @@ packages:
|
|||
version: 2.11.7
|
||||
dev: false
|
||||
|
||||
registry.npmmirror.com/@tinymce/tinymce-vue@4.0.7(vue@3.3.4):
|
||||
resolution: {integrity: sha512-1esB8wGWrjPCY+rK8vy3QB1cxwXo7HLJWuNrcyPl6LOVR+QJjub0OiV/C+TUEsLN6OpCtRv+QnIqMC5vXz783Q==, registry: http://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/@tinymce/tinymce-vue/-/tinymce-vue-4.0.7.tgz}
|
||||
id: registry.npmmirror.com/@tinymce/tinymce-vue/4.0.7
|
||||
name: '@tinymce/tinymce-vue'
|
||||
version: 4.0.7
|
||||
peerDependencies:
|
||||
vue: ^3.0.0
|
||||
dependencies:
|
||||
tinymce: registry.npmmirror.com/tinymce@5.10.9
|
||||
vue: registry.npmmirror.com/vue@3.3.4
|
||||
dev: false
|
||||
|
||||
registry.npmmirror.com/@types/estree@1.0.2:
|
||||
resolution: {integrity: sha512-VeiPZ9MMwXjO32/Xu7+OwflfmeoRwkE/qzndw42gGtgJwZopBnzy2gD//NN1+go1mADzkDcqf/KnFRSjTJ8xJA==, registry: http://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/@types/estree/-/estree-1.0.2.tgz}
|
||||
name: '@types/estree'
|
||||
|
@ -3135,6 +3153,12 @@ packages:
|
|||
engines: {node: '>=12.22'}
|
||||
dev: false
|
||||
|
||||
registry.npmmirror.com/tinymce@5.10.9:
|
||||
resolution: {integrity: sha512-5bkrors87X9LhYX2xq8GgPHrIgJYHl87YNs+kBcjQ5I3CiUgzo/vFcGvT3MZQ9QHsEeYMhYO6a5CLGGffR8hMg==, registry: http://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/tinymce/-/tinymce-5.10.9.tgz}
|
||||
name: tinymce
|
||||
version: 5.10.9
|
||||
dev: false
|
||||
|
||||
registry.npmmirror.com/titleize@3.0.0:
|
||||
resolution: {integrity: sha512-KxVu8EYHDPBdUYdKZdKtU2aj2XfEx9AfjXxE/Aj0vT06w2icA09Vus1rh6eSu1y01akYg6BjIK/hxyLJINoMLQ==, registry: http://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/titleize/-/titleize-3.0.0.tgz}
|
||||
name: titleize
|
||||
|
|
|
@ -0,0 +1,7 @@
|
|||
import request from '@/utils/request'
|
||||
|
||||
export const useGetCarouselChart = () =>
|
||||
request.get('vx_interview/getCarouselChart')
|
||||
|
||||
export const useUpdateCarouselChart = ({ submitImages }) =>
|
||||
request.post('vx_interview/updateCarouselChart', { submitImages })
|
|
@ -0,0 +1,9 @@
|
|||
import request from '@/utils/request'
|
||||
|
||||
export const useGetApplicationCount = (days, encoding) =>
|
||||
request.get('company/getApplicationCount', {
|
||||
params: {
|
||||
days: days,
|
||||
encoding: encoding
|
||||
}
|
||||
})
|
|
@ -86,3 +86,19 @@ export const useUploadUserInfo = ({
|
|||
|
||||
export const useAdminEditPassword = ({ userId, updateUserId, password }) =>
|
||||
request.post('admin/adminEditPassword', { userId, updateUserId, password })
|
||||
|
||||
//获取反馈列表
|
||||
export const useGetFeedBackList = (status) =>
|
||||
request.get('vxUser/getAllFeedBack', {
|
||||
params: {
|
||||
status: status
|
||||
}
|
||||
})
|
||||
//修改反馈的状态
|
||||
export const useChangeFeedBackStatus = (id, userId) =>
|
||||
request.get('vxUser/changeFeedBackStatus', {
|
||||
params: {
|
||||
id: id,
|
||||
userId: userId
|
||||
}
|
||||
})
|
||||
|
|
|
@ -35,6 +35,23 @@ const router = createRouter({
|
|||
path: '/manager',
|
||||
component: () => import('@/views/manager/ManagerPage.vue')
|
||||
},
|
||||
{
|
||||
path: '/adminManager',
|
||||
component: () => import('@/views/manager/AdminMangePage.vue')
|
||||
},
|
||||
{
|
||||
path: '/companyManager',
|
||||
component: () => import('@/views/manager/CompanyManagePage.vue')
|
||||
},
|
||||
{
|
||||
path: '/carouselChart',
|
||||
component: () => import('@/views/carouselChart/CarouselChartPage.vue')
|
||||
},
|
||||
{
|
||||
path: '/feedbackmanage',
|
||||
component: () =>
|
||||
import('@/views/feedbackmanage/FeedbackManagePage.vue')
|
||||
},
|
||||
{
|
||||
path: '/interview/imageManagement',
|
||||
component: () => import('@/views/interview/ImageManagement.vue')
|
||||
|
|
|
@ -2,7 +2,7 @@ import { useUserStore } from '@/stores'
|
|||
import axios from 'axios'
|
||||
import router from '@/router'
|
||||
|
||||
const baseURL = 'http://localhost:5380'
|
||||
const baseURL = 'http://localhost:8080'
|
||||
|
||||
const instance = axios.create({
|
||||
baseURL,
|
||||
|
|
|
@ -0,0 +1,141 @@
|
|||
<script setup>
|
||||
import {
|
||||
useGetCarouselChart,
|
||||
useUpdateCarouselChart
|
||||
} from '@/api/carouselChart'
|
||||
import { ref } from 'vue'
|
||||
import { useUploadPic, useDeletePic } from '@/api/upload'
|
||||
import { Plus } from '@element-plus/icons-vue'
|
||||
|
||||
const submitForm = ref({
|
||||
images: [],
|
||||
submitImages: ''
|
||||
})
|
||||
|
||||
const getCarouselChart = async () => {
|
||||
const res = await useGetCarouselChart()
|
||||
if (res.data.data) {
|
||||
submitForm.value.images = [...JSON.parse(res.data.data)]
|
||||
submitForm.value.submitImages = res.data.data
|
||||
} else {
|
||||
submitForm.value.images = []
|
||||
}
|
||||
console.log(res)
|
||||
console.log(submitForm.value)
|
||||
}
|
||||
getCarouselChart()
|
||||
|
||||
//移除图片功能
|
||||
const handleRemove = async (file, fileList) => {
|
||||
console.log('删除')
|
||||
await useDeletePic(file.name)
|
||||
submitForm.value.images = fileList
|
||||
handleEndit()
|
||||
}
|
||||
//预览图片功能
|
||||
const dialogImageUrl = ref('')
|
||||
const dialogVisible = ref(false)
|
||||
const handlePictureCardPreview = (file) => {
|
||||
dialogVisible.value = true
|
||||
dialogImageUrl.value = file.url
|
||||
}
|
||||
|
||||
const handleExceed = (files, fileList) => {
|
||||
ElMessage.warning(
|
||||
`当前限制选择 5 个文件,本次选择了 ${files.length} 个文件,共选择了 ${
|
||||
files.length + fileList.length
|
||||
} 个文件`
|
||||
)
|
||||
}
|
||||
const limit = ref(5)
|
||||
|
||||
const hideUpload = ref(false)
|
||||
const OnChange = async (file, fileList) => {
|
||||
console.log('改变')
|
||||
console.log(fileList)
|
||||
const isType = file.type === 'image/jpeg' || 'image/png'
|
||||
const isLt5M = file.size / 1024 / 1024 < 5
|
||||
|
||||
if (!isType) {
|
||||
ElMessage.error('上传头像图片只能是 JPG 格式!')
|
||||
fileList.pop()
|
||||
}
|
||||
if (!isLt5M) {
|
||||
ElMessage.error('上传头像图片大小不能超过 5MB!')
|
||||
fileList.pop()
|
||||
}
|
||||
console.log(submitForm.value.images)
|
||||
|
||||
hideUpload.value = submitForm.value.images.length >= limit.value
|
||||
let fd = new FormData()
|
||||
|
||||
fd.append('file', file.raw) //传给后台接收的名字 file
|
||||
|
||||
const res = await useUploadPic(fd)
|
||||
|
||||
var newImageObject = {
|
||||
name: res.data.data.filename,
|
||||
url: res.data.data.image
|
||||
}
|
||||
file.name = res.data.data.filename
|
||||
file.url = res.data.data.image
|
||||
|
||||
submitForm.value.images.push(newImageObject)
|
||||
}
|
||||
const handleEndit = async () => {
|
||||
console.log('修改')
|
||||
submitForm.value.submitImages = JSON.stringify(
|
||||
submitForm.value.images.map((item) => {
|
||||
return {
|
||||
name: item.name,
|
||||
url: item.url
|
||||
}
|
||||
})
|
||||
)
|
||||
const res = await useUpdateCarouselChart(submitForm.value)
|
||||
|
||||
ElMessage.success(res.data.data)
|
||||
getCarouselChart()
|
||||
}
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<el-form
|
||||
ref="form"
|
||||
label-width="150px"
|
||||
style="padding-right: 30px; padding-top: 5%"
|
||||
:class="hideUpload ? 'hide' : 'display'"
|
||||
>
|
||||
<el-form-item label="轮播图图片">
|
||||
<el-upload
|
||||
ref="upload"
|
||||
action="#"
|
||||
multiple
|
||||
:limit="limit"
|
||||
:file-list="submitForm.images"
|
||||
list-type="picture-card"
|
||||
:on-preview="handlePictureCardPreview"
|
||||
:on-change="OnChange"
|
||||
:on-remove="handleRemove"
|
||||
:on-exceed="handleExceed"
|
||||
accept="image/jpeg,image/png"
|
||||
:auto-upload="false"
|
||||
>
|
||||
<i class="el-icon-plus">
|
||||
<el-icon><Plus /></el-icon
|
||||
></i>
|
||||
<template #tip>
|
||||
<div class="el-upload__tip">
|
||||
只能上传jpg/png文件,最多上传5张且单张图片不超过5M
|
||||
</div>
|
||||
</template>
|
||||
</el-upload>
|
||||
<el-dialog v-model="dialogVisible" style="line-height: 0">
|
||||
<img style="width: 100%; height: 100%" :src="dialogImageUrl" alt="" />
|
||||
</el-dialog>
|
||||
</el-form-item>
|
||||
<div style="text-align: center; padding-top: 20%">
|
||||
<el-button type="primary" @click="handleEndit">保存修改</el-button>
|
||||
</div>
|
||||
</el-form>
|
||||
</template>
|
|
@ -0,0 +1,97 @@
|
|||
<script setup>
|
||||
import { ref } from 'vue'
|
||||
import { useGetFeedBackList, useChangeFeedBackStatus } from '@/api/user'
|
||||
import { Check } from '@element-plus/icons-vue'
|
||||
import { useUserStore } from '@/stores'
|
||||
import ViewImagesDialog from './components/ViewImagesDialog.vue'
|
||||
const feedbackLoading = ref(false)
|
||||
const feedBackList = ref([])
|
||||
const status = ref('1')
|
||||
|
||||
const getfeedBackList = async () => {
|
||||
feedbackLoading.value = true
|
||||
const res = await useGetFeedBackList(parseInt(status.value))
|
||||
feedBackList.value = res.data.data
|
||||
feedbackLoading.value = false
|
||||
console.log(res.data.data)
|
||||
}
|
||||
getfeedBackList()
|
||||
const handleChangeStatus = async () => {
|
||||
feedbackLoading.value = true
|
||||
const res = await useGetFeedBackList(parseInt(status.value))
|
||||
feedBackList.value = res.data.data
|
||||
feedbackLoading.value = false
|
||||
}
|
||||
const userStore = useUserStore()
|
||||
const handleEdit = async (row) => {
|
||||
const res = await useChangeFeedBackStatus(row.id, userStore.userInfo.id)
|
||||
|
||||
ElMessage.success(res.data.data)
|
||||
getfeedBackList()
|
||||
}
|
||||
const viewImagesDialog = ref()
|
||||
const handleView = (row) => {
|
||||
viewImagesDialog.value.open(row)
|
||||
}
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<page-container title="反馈管理" v-loading="feedbackLoading">
|
||||
<template #filter>
|
||||
<el-select
|
||||
v-model="status"
|
||||
placeholder="筛选"
|
||||
style="width: 115px"
|
||||
@change="handleChangeStatus"
|
||||
>
|
||||
<el-option label="待处理" value="1" />
|
||||
<el-option label="已处理" value="2" />
|
||||
</el-select>
|
||||
</template>
|
||||
<el-table :data="feedBackList" stripe style="width: 100%">
|
||||
<el-table-column type="index" label="序号" width="100" />
|
||||
<el-table-column prop="content" label="描述" />
|
||||
<el-table-column label="反馈图片">
|
||||
<template #default="{ row }">
|
||||
<el-tooltip
|
||||
class="box-item"
|
||||
effect="dark"
|
||||
content="查看图片"
|
||||
placement="top-start"
|
||||
>
|
||||
<el-button type="warning" @click="handleView(row)" plain
|
||||
>查看图片</el-button
|
||||
>
|
||||
</el-tooltip>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column prop="phone" label="联系电话" />
|
||||
<el-table-column prop="createTime" label="反馈时间" />
|
||||
<el-table-column prop="status" label="状态">
|
||||
<template #default="{ row }"
|
||||
>{{ row.status === 1 ? '待处理' : '已处理' }}
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="操作" width="150">
|
||||
<template #default="{ row }">
|
||||
<el-tooltip
|
||||
class="box-item"
|
||||
effect="dark"
|
||||
content="确认"
|
||||
placement="top-start"
|
||||
v-if="row.status === 1"
|
||||
>
|
||||
<el-button
|
||||
type="primary"
|
||||
:icon="Check"
|
||||
@click="handleEdit(row)"
|
||||
circle
|
||||
plain
|
||||
></el-button>
|
||||
</el-tooltip>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
<ViewImagesDialog ref="viewImagesDialog"></ViewImagesDialog>
|
||||
</page-container>
|
||||
</template>
|
|
@ -0,0 +1,53 @@
|
|||
<script setup>
|
||||
import { ref } from 'vue'
|
||||
const viewImagesDialogVisible = ref(false)
|
||||
const imgUrls = ref([])
|
||||
|
||||
const open = (row) => {
|
||||
viewImagesDialogVisible.value = true
|
||||
imgUrls.value = JSON.parse(row.imgUrl)
|
||||
}
|
||||
defineExpose({
|
||||
open
|
||||
})
|
||||
</script>
|
||||
<template>
|
||||
<el-dialog
|
||||
v-model="viewImagesDialogVisible"
|
||||
title="反馈图片"
|
||||
width="50%"
|
||||
align-center
|
||||
>
|
||||
<el-carousel :interval="4000" type="card" height="200px">
|
||||
<el-carousel-item v-for="item in imgUrls" :key="item">
|
||||
<el-image
|
||||
style="width: 100px; height: 100px"
|
||||
:src="item"
|
||||
:fit="contain"
|
||||
/>
|
||||
</el-carousel-item>
|
||||
</el-carousel>
|
||||
<template #footer>
|
||||
<span class="dialog-footer">
|
||||
<el-button @click="centerDialogVisible = false">关闭</el-button>
|
||||
</span>
|
||||
</template>
|
||||
</el-dialog>
|
||||
</template>
|
||||
<style scoped>
|
||||
.el-carousel__item h3 {
|
||||
color: #475669;
|
||||
opacity: 0.75;
|
||||
line-height: 200px;
|
||||
margin: 0;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.el-carousel__item:nth-child(2n) {
|
||||
background-color: #99a9bf;
|
||||
}
|
||||
|
||||
.el-carousel__item:nth-child(2n + 1) {
|
||||
background-color: #d3dce6;
|
||||
}
|
||||
</style>
|
|
@ -5,7 +5,7 @@ import { BarChart } from 'echarts/charts'
|
|||
import { CanvasRenderer } from 'echarts/renderers'
|
||||
|
||||
import VChart, { THEME_KEY } from 'vue-echarts'
|
||||
import { ref, provide } from 'vue'
|
||||
import { ref, provide, onBeforeMount } from 'vue'
|
||||
import { useCompanyStore, useUserStore } from '@/stores'
|
||||
import {
|
||||
Search,
|
||||
|
@ -14,6 +14,7 @@ import {
|
|||
ChatDotSquare,
|
||||
Tickets
|
||||
} from '@element-plus/icons-vue'
|
||||
import { useRouter } from 'vue-router'
|
||||
import {
|
||||
useGetJobList,
|
||||
getApplicationList,
|
||||
|
@ -24,12 +25,21 @@ import {
|
|||
getInterviewRecordList,
|
||||
agreeUsersPassInterview
|
||||
} from '@/api/interview'
|
||||
import { useGetApplicationCount } from '@/api/company'
|
||||
import { ElMessage } from 'element-plus'
|
||||
import DisagreeDialog from './components/DisagreeDialog.vue'
|
||||
import InviteDialog from './components/InviteDialog.vue'
|
||||
import ViewResume from './components/ViewResume.vue'
|
||||
import ViewInterviewRecord from './components/ViewInterviewRecord.vue'
|
||||
|
||||
use([TooltipComponent, GridComponent, BarChart, CanvasRenderer])
|
||||
onBeforeMount(() => {
|
||||
const router = useRouter()
|
||||
const userStore = useUserStore()
|
||||
if (userStore.userInfo.role === '1') {
|
||||
router.replace('/adminManager')
|
||||
}
|
||||
})
|
||||
|
||||
const companyStore = useCompanyStore()
|
||||
const jobList = ref([])
|
||||
|
@ -62,63 +72,26 @@ getJobList()
|
|||
provide(THEME_KEY, 'white')
|
||||
// prettier-ignore
|
||||
const date = ref(Number)
|
||||
const data7 = ref([])
|
||||
|
||||
const setDate = (day) => {
|
||||
const dataValues7 = ref([])
|
||||
|
||||
const setDate = async (day) => {
|
||||
date.value = day
|
||||
|
||||
const resSeven = await useGetApplicationCount(day, companyStore.encoding)
|
||||
resSeven.data.data.map((item) => {
|
||||
data7.value.push(item.createTime)
|
||||
})
|
||||
console.log(data7.value)
|
||||
resSeven.data.data.map((item) => {
|
||||
dataValues7.value.push(item.count)
|
||||
})
|
||||
console.log(dataValues7.value)
|
||||
}
|
||||
setDate(7)
|
||||
|
||||
const date30 = [
|
||||
'2023-10-01',
|
||||
'2023-10-02',
|
||||
'2023-10-03',
|
||||
'2023-10-04',
|
||||
'2023-10-05',
|
||||
'2023-10-06',
|
||||
'2023-10-07',
|
||||
'2023-10-08',
|
||||
'2023-10-09',
|
||||
'2023-10-10',
|
||||
'2023-10-11',
|
||||
'2023-10-12',
|
||||
'2023-10-13',
|
||||
'2023-10-14',
|
||||
'2023-10-15',
|
||||
'2023-10-16',
|
||||
'2023-10-17',
|
||||
'2023-10-18',
|
||||
'2023-10-19',
|
||||
'2023-10-20',
|
||||
'2023-10-21',
|
||||
'2023-10-22',
|
||||
'2023-10-23',
|
||||
'2023-10-24',
|
||||
'2023-10-25',
|
||||
'2023-10-26',
|
||||
'2023-10-27',
|
||||
'2023-10-28',
|
||||
'2023-10-29',
|
||||
'2023-10-30'
|
||||
]
|
||||
|
||||
const data7 = [
|
||||
'2023-10-24',
|
||||
'2023-10-25',
|
||||
'2023-10-26',
|
||||
'2023-10-27',
|
||||
'2023-10-28',
|
||||
'2023-10-29',
|
||||
'2023-10-30'
|
||||
]
|
||||
|
||||
const dataValues7 = [10, 52, 200, 334, 390, 330, 220]
|
||||
const dataValue30 = [
|
||||
10, 52, 200, 334, 390, 330, 220, 10, 52, 200, 334, 390, 330, 220, 10, 52, 200,
|
||||
334, 390, 330, 220, 10, 52, 200, 334, 390, 330, 220, 10, 52, 200, 334, 390,
|
||||
330, 220, 10, 52, 200, 334, 390, 330, 220, 10, 52, 200, 334, 390, 330, 220,
|
||||
400, 500
|
||||
]
|
||||
const option1 = ref({
|
||||
const option = ref({
|
||||
tooltip: {
|
||||
trigger: 'axis',
|
||||
axisPointer: {
|
||||
|
@ -134,7 +107,7 @@ const option1 = ref({
|
|||
xAxis: [
|
||||
{
|
||||
type: 'category',
|
||||
data: data7,
|
||||
data: data7.value,
|
||||
axisTick: {
|
||||
alignWithLabel: true
|
||||
}
|
||||
|
@ -150,43 +123,7 @@ const option1 = ref({
|
|||
name: '投递人数',
|
||||
type: 'bar',
|
||||
barWidth: '50%',
|
||||
data: dataValues7
|
||||
}
|
||||
]
|
||||
})
|
||||
const option2 = ref({
|
||||
tooltip: {
|
||||
trigger: 'axis',
|
||||
axisPointer: {
|
||||
type: 'shadow'
|
||||
}
|
||||
},
|
||||
grid: {
|
||||
left: '3%',
|
||||
right: '4%',
|
||||
bottom: '3%',
|
||||
containLabel: true
|
||||
},
|
||||
xAxis: [
|
||||
{
|
||||
type: 'category',
|
||||
data: date30,
|
||||
axisTick: {
|
||||
alignWithLabel: true
|
||||
}
|
||||
}
|
||||
],
|
||||
yAxis: [
|
||||
{
|
||||
type: 'value'
|
||||
}
|
||||
],
|
||||
series: [
|
||||
{
|
||||
name: '投递人数',
|
||||
type: 'bar',
|
||||
barWidth: '50%',
|
||||
data: dataValue30
|
||||
data: dataValues7.value
|
||||
}
|
||||
]
|
||||
})
|
||||
|
@ -291,7 +228,7 @@ const handleSelectionChange = (val) => {
|
|||
}
|
||||
console.log(selectAgreeUsers.value)
|
||||
}
|
||||
const userStore = useUserStore()
|
||||
|
||||
const PassInterview = async () => {
|
||||
if (filterRecored.value === '2') {
|
||||
ElMessage.error('所勾选的列表已经通过面试啦,请不要重复操作')
|
||||
|
@ -376,37 +313,18 @@ const handleDisagreeApplication = (row) => {
|
|||
console.log(row)
|
||||
}
|
||||
|
||||
const viewInterviewRecord = ref()
|
||||
const handleViewRecordDetail = (row) => {
|
||||
console.log(row)
|
||||
viewInterviewRecord.value.open(row)
|
||||
}
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<el-dropdown>
|
||||
<el-button type="warning" bg>
|
||||
{{ date === 7 ? '近7天' : '近30天'
|
||||
}}<el-icon class="el-icon--right"><arrow-down /></el-icon>
|
||||
</el-button>
|
||||
<template #dropdown>
|
||||
<el-dropdown-menu>
|
||||
<el-dropdown-item @click="setDate(7)">近7天</el-dropdown-item>
|
||||
<el-dropdown-item @click="setDate(30)">近30天</el-dropdown-item>
|
||||
</el-dropdown-menu>
|
||||
</template>
|
||||
</el-dropdown>
|
||||
<h1 style="text-align: center">
|
||||
{{ date === 7 ? '近7天' : '近30天' }}投递简历人数
|
||||
</h1>
|
||||
<h1 style="text-align: center">{{ '近7天' }}投递简历人数</h1>
|
||||
<v-chart
|
||||
class="chart"
|
||||
v-if="date === 7"
|
||||
:option="option1"
|
||||
style="width: 90%; height: 80%"
|
||||
/>
|
||||
<v-chart
|
||||
class="chart"
|
||||
v-else
|
||||
:option="option2"
|
||||
:option="option"
|
||||
style="width: 90%; height: 80%"
|
||||
/>
|
||||
<!-- 第一个页面 -->
|
||||
|
@ -683,6 +601,7 @@ const handleViewRecordDetail = (row) => {
|
|||
></DisagreeDialog>
|
||||
<InviteDialog ref="inviteDialog" @getJobList="getJobList"></InviteDialog>
|
||||
<ViewResume ref="viewResume"></ViewResume>
|
||||
<ViewInterviewRecord ref="viewInterviewRecord"></ViewInterviewRecord>
|
||||
</template>
|
||||
|
||||
<style scoped></style>
|
||||
|
|
|
@ -0,0 +1,49 @@
|
|||
<script setup>
|
||||
import { ref } from 'vue'
|
||||
|
||||
const InterviewRecordDialog = ref(false)
|
||||
|
||||
const interviewInfo = ref({})
|
||||
|
||||
const open = (row) => {
|
||||
interviewInfo.value = row
|
||||
InterviewRecordDialog.value = true
|
||||
console.log(interviewInfo.value)
|
||||
}
|
||||
|
||||
defineExpose({
|
||||
open
|
||||
})
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<el-drawer
|
||||
v-model="InterviewRecordDialog"
|
||||
:title="'面试详情'"
|
||||
direction="rtl"
|
||||
size="50%"
|
||||
>
|
||||
<el-form ref="form" label-width="150px">
|
||||
<el-form-item label="面试详情">
|
||||
<el-input
|
||||
v-model="interviewInfo.detail"
|
||||
:autosize="{ minRows: 2, maxRows: 6 }"
|
||||
type="textarea"
|
||||
placeholder="请输入面试详情"
|
||||
id="detail"
|
||||
disabled="false"
|
||||
/>
|
||||
</el-form-item>
|
||||
<el-form-item label="面试评语">
|
||||
<el-input
|
||||
v-model="interviewInfo.comments"
|
||||
:autosize="{ minRows: 2, maxRows: 4 }"
|
||||
type="textarea"
|
||||
placeholder="请输入面试评语"
|
||||
id="comments"
|
||||
disabled="false"
|
||||
/>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
</el-drawer>
|
||||
</template>
|
|
@ -24,6 +24,7 @@ import { useAdminLogout } from '../../api/user'
|
|||
import { useRouter } from 'vue-router'
|
||||
import ChangeAvatarDialog from './components/ChangeAvatarDialog.vue'
|
||||
import RestPasswordDialog from './components/ResetPasswordDialog.vue'
|
||||
|
||||
import { ref } from 'vue'
|
||||
import UserInfoDialog from './components/UserInfoDialog.vue'
|
||||
|
||||
|
@ -66,16 +67,58 @@ const RestPassword = () => {
|
|||
text-color="#fff"
|
||||
router
|
||||
>
|
||||
<el-menu-item index="/home">
|
||||
<el-menu-item
|
||||
index="/home"
|
||||
v-if="
|
||||
userStore.userInfo.role === '2' || userStore.userInfo.role === '3'
|
||||
"
|
||||
>
|
||||
<el-icon><House /></el-icon>
|
||||
<span>首页</span>
|
||||
</el-menu-item>
|
||||
<el-menu-item index="/manager">
|
||||
<el-menu-item
|
||||
index="/manager"
|
||||
v-if="
|
||||
userStore.userInfo.role === '2' || userStore.userInfo.role === '3'
|
||||
"
|
||||
>
|
||||
<el-icon><User /></el-icon>
|
||||
<span>人员管理</span>
|
||||
</el-menu-item>
|
||||
<el-menu-item
|
||||
index="/adminManager"
|
||||
v-if="userStore.userInfo.role === '1'"
|
||||
>
|
||||
<el-icon><User /></el-icon>
|
||||
<span>管理员管理</span>
|
||||
</el-menu-item>
|
||||
|
||||
<el-sub-menu index="/interview/imageManagement">
|
||||
<el-menu-item
|
||||
index="/companyManager"
|
||||
v-if="userStore.userInfo.role === '1'"
|
||||
>
|
||||
<el-icon><User /></el-icon>
|
||||
<span>公司管理</span>
|
||||
</el-menu-item>
|
||||
<el-menu-item
|
||||
index="/carouselChart"
|
||||
v-if="userStore.userInfo.role === '1'"
|
||||
>
|
||||
<el-icon><User /></el-icon>
|
||||
<span>轮播图管理</span>
|
||||
</el-menu-item>
|
||||
<el-menu-item
|
||||
index="/feedbackmanage"
|
||||
v-if="userStore.userInfo.role === '1'"
|
||||
>
|
||||
<el-icon><User /></el-icon>
|
||||
<span>反馈管理</span>
|
||||
</el-menu-item>
|
||||
<el-sub-menu
|
||||
index="/interview/imageManagement"
|
||||
v-if="
|
||||
userStore.userInfo.role === '2' || userStore.userInfo.role === '3'
|
||||
"
|
||||
>
|
||||
<template #title>
|
||||
<el-icon><VideoCamera /></el-icon>
|
||||
<span>个性化面试</span>
|
||||
|
@ -95,7 +138,12 @@ const RestPassword = () => {
|
|||
</el-menu-item>
|
||||
</el-sub-menu>
|
||||
|
||||
<el-sub-menu index="/question/type">
|
||||
<el-sub-menu
|
||||
index="/question/type"
|
||||
v-if="
|
||||
userStore.userInfo.role === '2' || userStore.userInfo.role === '3'
|
||||
"
|
||||
>
|
||||
<template #title>
|
||||
<el-icon><Files /></el-icon>
|
||||
<span>题库设置</span>
|
||||
|
@ -113,7 +161,12 @@ const RestPassword = () => {
|
|||
<span>题目广场</span>
|
||||
</el-menu-item>
|
||||
</el-sub-menu>
|
||||
<el-sub-menu index="/recruitment/publicManagement">
|
||||
<el-sub-menu
|
||||
index="/recruitment/publicManagement"
|
||||
v-if="
|
||||
userStore.userInfo.role === '2' || userStore.userInfo.role === '3'
|
||||
"
|
||||
>
|
||||
<template #title>
|
||||
<el-icon><Phone /></el-icon>
|
||||
<span>招聘</span>
|
||||
|
|
|
@ -22,11 +22,11 @@ const open = () => {
|
|||
submitForm.value = userStore.userInfo
|
||||
userRole.value =
|
||||
userStore.userInfo.role === '1'
|
||||
? '超级管理员'
|
||||
? '系统管理员'
|
||||
: userStore.userInfo.role === '2'
|
||||
? 'HR'
|
||||
? '公司管理员'
|
||||
: userStore.userInfo.role === '3'
|
||||
? '员工'
|
||||
? 'HR'
|
||||
: '面试者'
|
||||
|
||||
submitForm.value.userId = submitForm.value.id
|
||||
|
@ -38,7 +38,8 @@ const rules = ref({
|
|||
role: [{ required: true, message: '请输入权限', trigger: 'blur' }],
|
||||
username: [{ required: true, message: '请输入姓名', trigger: 'blur' }],
|
||||
age: [{ required: true, message: '请输入年龄', trigger: 'blur' }],
|
||||
email: [{ required: true, message: '请输入电子邮箱', trigger: 'blur' }]
|
||||
email: [{ required: true, message: '请输入电子邮箱', trigger: 'blur' }],
|
||||
sex: [{ required: true, message: '请输入选择性别', trigger: 'blur' }]
|
||||
})
|
||||
|
||||
//上传图片的方法
|
||||
|
@ -146,7 +147,7 @@ defineExpose({
|
|||
v-model="submitForm.email"
|
||||
></el-input>
|
||||
</el-form-item>
|
||||
<el-form-item label="性别">
|
||||
<el-form-item label="性别" prop="sex">
|
||||
<el-radio-group v-model="submitForm.sex">
|
||||
<el-radio label="男">男</el-radio>
|
||||
<el-radio label="女">女</el-radio>
|
||||
|
|
|
@ -0,0 +1,105 @@
|
|||
<script setup>
|
||||
import { Search, Edit, Delete } from '@element-plus/icons-vue'
|
||||
import { useCompanyStore } from '@/stores'
|
||||
import { useGetAdminList } from '@/api/user'
|
||||
import { ref } from 'vue'
|
||||
import AdminDelEndit from './components/AdminDelEndit.vue'
|
||||
import ResetPasswordDialog from './components/ResetPasswordDialog.vue'
|
||||
import AdminProAddDialog from './components/AdminProAddDialog.vue'
|
||||
|
||||
const searchName = ref('')
|
||||
const loading = ref(false)
|
||||
const adminList = ref([])
|
||||
const searchUserName = () => {}
|
||||
const companyStore = useCompanyStore()
|
||||
const getAdminList = async () => {
|
||||
const res = await useGetAdminList(companyStore.encoding)
|
||||
|
||||
adminList.value = res.data.data
|
||||
}
|
||||
getAdminList()
|
||||
const adminDelEndit = ref()
|
||||
const handleDelete = (row) => {
|
||||
adminDelEndit.value.open(row)
|
||||
}
|
||||
const resetPasswordDialog = ref()
|
||||
const handleEdit = (row) => {
|
||||
resetPasswordDialog.value.open(row)
|
||||
}
|
||||
const adminProAddDialog = ref()
|
||||
|
||||
const onAddEdit = () => {
|
||||
adminProAddDialog.value.open()
|
||||
}
|
||||
</script>
|
||||
<template>
|
||||
<page-container title="管理员管理">
|
||||
<template #filter>
|
||||
<div class="mt-4">
|
||||
<el-input
|
||||
v-model="searchName"
|
||||
placeholder="请输入姓名"
|
||||
class="input-with-select"
|
||||
>
|
||||
<template #prepend>
|
||||
<el-button :icon="Search" @click="searchUserName" />
|
||||
</template>
|
||||
<template #append>
|
||||
<el-button @click="getAdminList">重置</el-button>
|
||||
</template>
|
||||
</el-input>
|
||||
</div>
|
||||
</template>
|
||||
<template #extra>
|
||||
<el-button type="primary" @click="onAddEdit">添加管理员 </el-button>
|
||||
</template>
|
||||
<el-table v-loading="loading" :data="adminList" stripe style="width: 100%">
|
||||
<el-table-column type="index" label="序号" width="100" />
|
||||
<el-table-column prop="username" label="姓名" />
|
||||
<el-table-column prop="phone" label="账号" />
|
||||
<el-table-column prop="email" label="电子邮箱" />
|
||||
<el-table-column label="操作" width="200">
|
||||
<template #default="{ row }">
|
||||
<el-tooltip
|
||||
class="box-item"
|
||||
effect="dark"
|
||||
content="修改密码"
|
||||
placement="top-start"
|
||||
>
|
||||
<el-button
|
||||
type="primary"
|
||||
:icon="Edit"
|
||||
@click="handleEdit(row)"
|
||||
circle
|
||||
plain
|
||||
></el-button>
|
||||
</el-tooltip>
|
||||
<el-tooltip
|
||||
class="box-item"
|
||||
effect="dark"
|
||||
content="删除"
|
||||
placement="top-start"
|
||||
>
|
||||
<el-button
|
||||
type="danger"
|
||||
:icon="Delete"
|
||||
@click="handleDelete(row)"
|
||||
circle
|
||||
plain
|
||||
></el-button>
|
||||
</el-tooltip>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<template #empty>
|
||||
<el-empty description="没有数据" />
|
||||
</template>
|
||||
</el-table>
|
||||
<AdminDelEndit ref="adminDelEndit" @getAdminList="getAdminList">
|
||||
</AdminDelEndit>
|
||||
<ResetPasswordDialog ref="resetPasswordDialog"></ResetPasswordDialog>
|
||||
<AdminProAddDialog
|
||||
ref="adminProAddDialog"
|
||||
@getAdminList="getAdminList"
|
||||
></AdminProAddDialog>
|
||||
</page-container>
|
||||
</template>
|
|
@ -0,0 +1,38 @@
|
|||
<script setup>
|
||||
import { Search } from '@element-plus/icons-vue'
|
||||
import { ref } from 'vue'
|
||||
|
||||
const getCompanyList = () => {}
|
||||
const searchName = ref('')
|
||||
const searchCompanyName = () => {}
|
||||
|
||||
const onAddEdit = () => {}
|
||||
</script>
|
||||
<template>
|
||||
<page-container title="公司管理">
|
||||
<template #filter>
|
||||
<div class="mt-4">
|
||||
<el-input
|
||||
v-model="searchName"
|
||||
placeholder="请输入姓名"
|
||||
class="input-with-select"
|
||||
>
|
||||
<template #prepend>
|
||||
<el-button :icon="Search" @click="searchCompanyName" />
|
||||
</template>
|
||||
<template #append>
|
||||
<el-button @click="getCompanyList">重置</el-button>
|
||||
</template>
|
||||
</el-input>
|
||||
</div>
|
||||
</template>
|
||||
<template #extra>
|
||||
<el-button type="primary" @click="onAddEdit">公司注册 </el-button>
|
||||
</template>
|
||||
<el-table :data="tableData" stripe style="width: 100%">
|
||||
<el-table-column prop="date" label="Date" width="180" />
|
||||
<el-table-column prop="name" label="Name" width="180" />
|
||||
<el-table-column prop="address" label="Address" />
|
||||
</el-table>
|
||||
</page-container>
|
||||
</template>
|
|
@ -45,7 +45,7 @@ const handleEdit = (row) => {
|
|||
</script>
|
||||
|
||||
<template>
|
||||
<page-container title="管理员管理">
|
||||
<page-container title="人员管理">
|
||||
<template #filter>
|
||||
<div class="mt-4">
|
||||
<el-input
|
||||
|
|
|
@ -0,0 +1,94 @@
|
|||
<script setup>
|
||||
import { ref } from 'vue'
|
||||
import { useAddAdmin } from '@/api/user'
|
||||
import { useUserStore, useCompanyStore } from '@/stores'
|
||||
|
||||
const userStore = useUserStore()
|
||||
const companyStore = useCompanyStore()
|
||||
|
||||
const addEnditDialog = ref(false)
|
||||
|
||||
const form = ref()
|
||||
const FormModel = ref({
|
||||
username: '',
|
||||
phone: '',
|
||||
role: '1'
|
||||
})
|
||||
|
||||
const open = () => {
|
||||
addEnditDialog.value = true
|
||||
}
|
||||
const rules = {
|
||||
username: [{ required: true, message: '请输入姓名!', trigger: 'blur' }],
|
||||
phone: [
|
||||
{ required: true, message: '请输入手机号码!', trigger: 'blur' },
|
||||
{
|
||||
pattern: /(^((\+86)|(86))?(1[3-9])\d{9}$)|(^(0\d{2,3})-?(\d{7,8})$)/,
|
||||
message: '输入的手机号码格式不正确,请重新输入',
|
||||
trigger: 'blur'
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
const emit = defineEmits(['getAdminList'])
|
||||
const submitForm = async () => {
|
||||
await form.value.validate()
|
||||
|
||||
await useAddAdmin(
|
||||
companyStore.encoding,
|
||||
userStore.userInfo.id,
|
||||
FormModel.value.username,
|
||||
FormModel.value.phone,
|
||||
FormModel.value.role
|
||||
)
|
||||
ElMessage.success('添加成功!')
|
||||
FormModel.value = {
|
||||
username: '',
|
||||
phone: '',
|
||||
role: '1'
|
||||
}
|
||||
|
||||
addEnditDialog.value = false
|
||||
|
||||
emit('getAdminList')
|
||||
}
|
||||
defineExpose({
|
||||
open
|
||||
})
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<el-dialog v-model="addEnditDialog" title="添加管理员" width="30%">
|
||||
<el-form
|
||||
ref="form"
|
||||
label-width="150px"
|
||||
style="padding-right: 30px"
|
||||
:model="FormModel"
|
||||
:rules="rules"
|
||||
>
|
||||
<el-form-item label="姓名" prop="username">
|
||||
<el-input
|
||||
v-model="FormModel.username"
|
||||
placeholder="请输入管理员姓名"
|
||||
></el-input>
|
||||
</el-form-item>
|
||||
<el-form-item label="账号/手机号码" prop="phone">
|
||||
<el-input v-model="FormModel.phone" placeholder="请输入账号/手机号码" />
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
<div><span class="fontstyle">注:初始化密码就是账号的后六位</span></div>
|
||||
<template #footer>
|
||||
<span class="dialog-footer">
|
||||
<el-button @click="dialogVisible = false">取消</el-button>
|
||||
<el-button type="primary" @click="submitForm"> 确认 </el-button>
|
||||
</span>
|
||||
</template>
|
||||
</el-dialog>
|
||||
</template>
|
||||
|
||||
<style scoped>
|
||||
.fontstyle {
|
||||
font-weight: bold;
|
||||
color: red;
|
||||
}
|
||||
</style>
|
|
@ -124,7 +124,7 @@ defineExpose({
|
|||
<el-table-column property="title" label="标题" width="200" />
|
||||
<el-table-column property="typeName" label="题库名称" />
|
||||
<el-table-column property="details" label="内容" show-overflow-tooltip />
|
||||
<el-table-column property="promote" label="promote" />
|
||||
<el-table-column property="answer" label="题目预设答案" />
|
||||
<el-table-column property="createUserName" label="创建人" />
|
||||
<el-table-column property="updateTime" label="更新时间" />
|
||||
</el-table>
|
||||
|
|
|
@ -19,7 +19,9 @@ const open = (SharedBankIds) => {
|
|||
submitForm.value.userId = userStore.userInfo.id
|
||||
}
|
||||
const addEndit = async () => {
|
||||
console.log(submitForm.value)
|
||||
const res = await useAddQuestionTypeFromShare(submitForm.value)
|
||||
|
||||
ElMessage.success(res.data.data)
|
||||
submitForm.value = {
|
||||
SharedBankIds: [],
|
||||
|
|
|
@ -31,7 +31,7 @@ const rules = {
|
|||
title: [{ required: true, message: '请输入标题', trigger: 'blur' }],
|
||||
typeName: [{ required: true, message: '请选择题库类型', trigger: 'blur' }],
|
||||
details: [{ required: true, message: '请输入题目详情', trigger: 'blur' }],
|
||||
promote: [{ required: true, message: '请输入题目的promote', trigger: 'blur' }]
|
||||
answer: [{ required: true, message: '请输入题目的预设答案', trigger: 'blur' }]
|
||||
}
|
||||
const form = ref()
|
||||
const update = async () => {
|
||||
|
@ -91,9 +91,9 @@ defineExpose({
|
|||
placeholder="请输入题目详情"
|
||||
/>
|
||||
</el-form-item>
|
||||
<el-form-item label="题目promote" prop="promote">
|
||||
<el-form-item label="题目预设答案" prop="answer">
|
||||
<el-input
|
||||
v-model="updateForm.promote"
|
||||
v-model="updateForm.answer"
|
||||
:autosize="{ minRows: 2, maxRows: 4 }"
|
||||
type="textarea"
|
||||
placeholder="请输入题目的promote"
|
||||
|
|
|
@ -68,13 +68,6 @@ const getCompanyDetail = async () => {
|
|||
|
||||
submitForm.value.userId = userStore.userInfo.id
|
||||
|
||||
// submitForm.value.address = submitForm.value.address.slice(1, -1).split(', ')
|
||||
|
||||
// submitForm.value.treatment = submitForm.value.treatment
|
||||
// .slice(1, -1)
|
||||
// .split(', ')
|
||||
|
||||
// submitForm.value.images = submitForm.value.images.slice(1, -1).split(', ')
|
||||
|
||||
if (res.data.data.images === '') {
|
||||
submitForm.value.images = []
|
||||
|
@ -140,10 +133,7 @@ const UploadImage = async (file) => {
|
|||
}
|
||||
//移除图片功能
|
||||
const handleRemove = async (file) => {
|
||||
console.log('删除')
|
||||
console.log(file.name)
|
||||
await useDeletePic(file.name)
|
||||
|
||||
handleEndit()
|
||||
}
|
||||
//预览图片功能
|
||||
|
@ -204,7 +194,6 @@ const handleEndit = async () => {
|
|||
}
|
||||
})
|
||||
)
|
||||
console.log(submitForm.value.companyLogo)
|
||||
submitForm.value.subLogo = JSON.stringify(
|
||||
submitForm.value.companyLogo.map((item) => {
|
||||
return {
|
||||
|
@ -214,7 +203,6 @@ const handleEndit = async () => {
|
|||
})
|
||||
)
|
||||
submitForm.value.treatment = JSON.stringify(submitForm.value.treatment)
|
||||
console.log(submitForm.value)
|
||||
const res = await useUploadCompanyDetail(submitForm.value)
|
||||
ElMessage.success(res.data.data)
|
||||
|
||||
|
|
|
@ -26,7 +26,7 @@ export default defineConfig({
|
|||
|
||||
//代理设置
|
||||
server: {
|
||||
port: 5173,
|
||||
port: 5174,
|
||||
host: '0.0.0.0',
|
||||
base: './',
|
||||
cors: true, // 默认启用并允许任何源
|
||||
|
|
Loading…
Reference in New Issue