题库列表渲染,添加功能
This commit is contained in:
parent
27766bf8a5
commit
5e42046c5c
|
@ -0,0 +1,11 @@
|
||||||
|
import requset from '@/utils/request'
|
||||||
|
|
||||||
|
export const useGetTypeList = (encoding) =>
|
||||||
|
requset.get('question/get_typeList', {
|
||||||
|
params: {
|
||||||
|
encoding: encoding
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
export const useAddTypeName = (typeName, encoding, userId) =>
|
||||||
|
requset.post('question/add_typeName', { typeName, encoding, userId })
|
|
@ -1,8 +1,15 @@
|
||||||
import request from "@/utils/request.js"
|
import request from '@/utils/request.js'
|
||||||
|
|
||||||
export const adminLogin=({phone,encoding,password})=>request.post("admin/login",{
|
|
||||||
|
|
||||||
|
export const adminLogin = ({ phone, encoding, password }) =>
|
||||||
|
request.post('admin/login', {
|
||||||
phone,
|
phone,
|
||||||
encoding,
|
encoding,
|
||||||
password
|
password
|
||||||
})
|
})
|
||||||
|
|
||||||
|
export const useGetUserInfo = (token) =>
|
||||||
|
request.get('admin/get_userInfo', {
|
||||||
|
params: {
|
||||||
|
token: token
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
Binary file not shown.
After Width: | Height: | Size: 2.9 KiB |
|
@ -0,0 +1,20 @@
|
||||||
|
body {
|
||||||
|
margin: 0;
|
||||||
|
background-color: #f5f5f5;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* fade-slide */
|
||||||
|
.fade-slide-leave-active,
|
||||||
|
.fade-slide-enter-active {
|
||||||
|
transition: all 0.3s;
|
||||||
|
}
|
||||||
|
|
||||||
|
.fade-slide-enter-from {
|
||||||
|
transform: translateX(-30px);
|
||||||
|
opacity: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.fade-slide-leave-to {
|
||||||
|
transform: translateX(30px);
|
||||||
|
opacity: 0;
|
||||||
|
}
|
|
@ -0,0 +1,34 @@
|
||||||
|
<script setup>
|
||||||
|
defineProps({
|
||||||
|
title: {
|
||||||
|
required: true,
|
||||||
|
type: String
|
||||||
|
}
|
||||||
|
})
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<el-card class="page-container">
|
||||||
|
<template #header>
|
||||||
|
<div class="header">
|
||||||
|
<span>{{ title }}</span>
|
||||||
|
<div class="extra">
|
||||||
|
<slot name="extra"></slot>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
<slot></slot>
|
||||||
|
</el-card>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<style lang="scss" scoped>
|
||||||
|
.page-container {
|
||||||
|
min-height: 100%;
|
||||||
|
box-sizing: border-box;
|
||||||
|
.header {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: space-between;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
|
@ -1,10 +1,9 @@
|
||||||
|
|
||||||
import { createApp } from 'vue'
|
import { createApp } from 'vue'
|
||||||
import pinia from "@/stores";
|
import pinia from '@/stores'
|
||||||
|
|
||||||
import App from './App.vue'
|
import App from './App.vue'
|
||||||
import router from './router'
|
import router from './router'
|
||||||
|
import './assets/main.scss'
|
||||||
const app = createApp(App)
|
const app = createApp(App)
|
||||||
|
|
||||||
app.use(pinia)
|
app.use(pinia)
|
||||||
|
|
|
@ -1,11 +1,25 @@
|
||||||
import { createRouter, createWebHistory } from 'vue-router'
|
import { createRouter, createWebHistory } from 'vue-router'
|
||||||
import { useUserStore } from "@/stores";
|
import { useUserStore } from '@/stores'
|
||||||
|
|
||||||
const router = createRouter({
|
const router = createRouter({
|
||||||
history: createWebHistory(import.meta.env.BASE_URL),
|
history: createWebHistory(import.meta.env.BASE_URL),
|
||||||
routes: [
|
routes: [
|
||||||
{ path: '/login', component: () => import('@/views/login/LoginPage.vue') },
|
{ path: '/login', component: () => import('@/views/login/LoginPage.vue') },
|
||||||
{ path: '/', component: () => import('@/views/layout/LayoutContainer.vue') }
|
{
|
||||||
|
path: '/',
|
||||||
|
component: () => import('@/views/layout/LayoutContainer.vue'),
|
||||||
|
|
||||||
|
children: [
|
||||||
|
{
|
||||||
|
path: '/question/type',
|
||||||
|
component: () => import('@/views/question/QuestionTypePage.vue')
|
||||||
|
},
|
||||||
|
{
|
||||||
|
path: '/question/manager',
|
||||||
|
component: () => import('@/views/question/QuestionManager.vue')
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
]
|
]
|
||||||
})
|
})
|
||||||
router.beforeEach((to) => {
|
router.beforeEach((to) => {
|
||||||
|
|
|
@ -6,5 +6,5 @@ pinia.use(persist)
|
||||||
|
|
||||||
export default pinia
|
export default pinia
|
||||||
|
|
||||||
|
export * from '@/stores/modules/userStore.js'
|
||||||
export * from "@/stores/modules/userStore.js"
|
export * from '@/stores/modules/companyStore.js'
|
||||||
|
|
|
@ -0,0 +1,28 @@
|
||||||
|
import { defineStore } from 'pinia'
|
||||||
|
import { ref } from 'vue'
|
||||||
|
|
||||||
|
export const useCompanyStore = defineStore(
|
||||||
|
'interviewer-company',
|
||||||
|
() => {
|
||||||
|
const encoding = ref('')
|
||||||
|
|
||||||
|
const setEncoding = (newEncoding) => {
|
||||||
|
encoding.value = newEncoding
|
||||||
|
}
|
||||||
|
|
||||||
|
const removeEncoding = () => {
|
||||||
|
encoding.value = ''
|
||||||
|
}
|
||||||
|
|
||||||
|
return {
|
||||||
|
encoding,
|
||||||
|
setEncoding,
|
||||||
|
removeEncoding
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
persist: {
|
||||||
|
paths: ['encoding']
|
||||||
|
}
|
||||||
|
}
|
||||||
|
)
|
|
@ -1,10 +1,9 @@
|
||||||
import { defineStore } from "pinia"
|
import { defineStore } from 'pinia'
|
||||||
import { ref } from "vue";
|
import { ref } from 'vue'
|
||||||
|
|
||||||
|
|
||||||
export const useUserStore=defineStore('interviewer-user',()=>{
|
|
||||||
|
|
||||||
|
|
||||||
|
export const useUserStore = defineStore(
|
||||||
|
'interviewer-user',
|
||||||
|
() => {
|
||||||
const token = ref('')
|
const token = ref('')
|
||||||
|
|
||||||
const setToken = (newToken) => {
|
const setToken = (newToken) => {
|
||||||
|
@ -15,16 +14,26 @@ export const useUserStore=defineStore('interviewer-user',()=>{
|
||||||
token.value = ''
|
token.value = ''
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const userInfo = ref({})
|
||||||
|
|
||||||
|
const setUserInfo = (newUserInfo) => {
|
||||||
|
userInfo.value = newUserInfo
|
||||||
|
}
|
||||||
|
const removeUserInfo = () => {
|
||||||
|
userInfo.value = {}
|
||||||
|
}
|
||||||
return {
|
return {
|
||||||
|
|
||||||
token,
|
token,
|
||||||
setToken,
|
setToken,
|
||||||
removeToken
|
removeToken,
|
||||||
|
userInfo,
|
||||||
|
setUserInfo,
|
||||||
|
removeUserInfo
|
||||||
}
|
}
|
||||||
},{
|
},
|
||||||
|
{
|
||||||
persist: {
|
persist: {
|
||||||
paths: ['token']
|
paths: ['token', 'userInfo']
|
||||||
}
|
}
|
||||||
})
|
}
|
||||||
|
)
|
||||||
|
|
|
@ -1,15 +1,25 @@
|
||||||
<script setup>
|
<script setup>
|
||||||
import {
|
import {
|
||||||
Management,
|
Management,
|
||||||
Promotion,
|
Files,
|
||||||
UserFilled,
|
|
||||||
User,
|
User,
|
||||||
Crop,
|
Crop,
|
||||||
|
DocumentCopy,
|
||||||
EditPen,
|
EditPen,
|
||||||
SwitchButton,
|
SwitchButton,
|
||||||
CaretBottom
|
CaretBottom
|
||||||
} from '@element-plus/icons-vue'
|
} from '@element-plus/icons-vue'
|
||||||
import avatar from '@/assets/default.png'
|
import avatar from '@/assets/default.png'
|
||||||
|
import { useUserStore } from '@/stores'
|
||||||
|
import { useGetUserInfo } from '../../api/user'
|
||||||
|
const userStore = useUserStore()
|
||||||
|
|
||||||
|
const getUserInfo = async () => {
|
||||||
|
const res = await useGetUserInfo(userStore.token)
|
||||||
|
console.log(res)
|
||||||
|
userStore.setUserInfo(res.data.data)
|
||||||
|
}
|
||||||
|
getUserInfo()
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
|
@ -25,35 +35,48 @@ import avatar from '@/assets/default.png'
|
||||||
>
|
>
|
||||||
<el-menu-item index="/article/channel">
|
<el-menu-item index="/article/channel">
|
||||||
<el-icon><Management /></el-icon>
|
<el-icon><Management /></el-icon>
|
||||||
<span>文章分类</span>
|
<span>员工管理</span>
|
||||||
</el-menu-item>
|
</el-menu-item>
|
||||||
<el-menu-item index="/article/manage">
|
<el-sub-menu index="/interview">
|
||||||
<el-icon><Promotion /></el-icon>
|
|
||||||
<span>文章管理</span>
|
|
||||||
</el-menu-item>
|
|
||||||
<el-sub-menu index="/user">
|
|
||||||
<template #title>
|
<template #title>
|
||||||
<el-icon><UserFilled /></el-icon>
|
<el-icon><Files /></el-icon>
|
||||||
<span>个人中心</span>
|
<span>个性化面试</span>
|
||||||
</template>
|
</template>
|
||||||
<el-menu-item index="/user/profile">
|
<el-menu-item index="">
|
||||||
<el-icon><User /></el-icon>
|
<el-icon><DocumentCopy /></el-icon>
|
||||||
<span>基本资料</span>
|
<span>形象管理</span>
|
||||||
</el-menu-item>
|
</el-menu-item>
|
||||||
<el-menu-item index="/user/avatar">
|
<el-menu-item index="">
|
||||||
<el-icon><Crop /></el-icon>
|
|
||||||
<span>更换头像</span>
|
|
||||||
</el-menu-item>
|
|
||||||
<el-menu-item index="/user/password">
|
|
||||||
<el-icon><EditPen /></el-icon>
|
<el-icon><EditPen /></el-icon>
|
||||||
<span>重置密码</span>
|
<span>背景管理</span>
|
||||||
|
</el-menu-item>
|
||||||
|
<el-menu-item index="">
|
||||||
|
<el-icon><EditPen /></el-icon>
|
||||||
|
<span>Logo管理</span>
|
||||||
|
</el-menu-item>
|
||||||
|
</el-sub-menu>
|
||||||
|
|
||||||
|
<el-sub-menu index="/question">
|
||||||
|
<template #title>
|
||||||
|
<el-icon><Files /></el-icon>
|
||||||
|
<span>个性化题库</span>
|
||||||
|
</template>
|
||||||
|
<el-menu-item index="/question/type">
|
||||||
|
<el-icon><DocumentCopy /></el-icon>
|
||||||
|
<span>题库类型</span>
|
||||||
|
</el-menu-item>
|
||||||
|
<el-menu-item index="/question/manager">
|
||||||
|
<el-icon><EditPen /></el-icon>
|
||||||
|
<span>题目管理</span>
|
||||||
</el-menu-item>
|
</el-menu-item>
|
||||||
</el-sub-menu>
|
</el-sub-menu>
|
||||||
</el-menu>
|
</el-menu>
|
||||||
</el-aside>
|
</el-aside>
|
||||||
<el-container>
|
<el-container>
|
||||||
<el-header>
|
<el-header>
|
||||||
<div>黑马程序员:<strong>小帅鹏</strong></div>
|
<div>
|
||||||
|
欢迎您:<strong>{{ userStore.userInfo.username }}</strong>
|
||||||
|
</div>
|
||||||
<el-dropdown placement="bottom-end">
|
<el-dropdown placement="bottom-end">
|
||||||
<span class="el-dropdown__box">
|
<span class="el-dropdown__box">
|
||||||
<el-avatar :src="avatar" />
|
<el-avatar :src="avatar" />
|
||||||
|
@ -80,7 +103,7 @@ import avatar from '@/assets/default.png'
|
||||||
<el-main>
|
<el-main>
|
||||||
<router-view></router-view>
|
<router-view></router-view>
|
||||||
</el-main>
|
</el-main>
|
||||||
<el-footer>大事件 ©2023 Created by 黑马程序员</el-footer>
|
<el-footer>Ai-面试 ©2023 Created by 扬州大学开发团队</el-footer>
|
||||||
</el-container>
|
</el-container>
|
||||||
</el-container>
|
</el-container>
|
||||||
</template>
|
</template>
|
||||||
|
@ -92,7 +115,7 @@ import avatar from '@/assets/default.png'
|
||||||
background-color: #232323;
|
background-color: #232323;
|
||||||
&__logo {
|
&__logo {
|
||||||
height: 120px;
|
height: 120px;
|
||||||
background: url('@/assets/logo.png') no-repeat center / 120px auto;
|
background: url('@/assets/login_title.png') no-repeat center / 120px auto;
|
||||||
}
|
}
|
||||||
.el-menu {
|
.el-menu {
|
||||||
border-right: none;
|
border-right: none;
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
import { Lock, User } from '@element-plus/icons-vue'
|
import { Lock, User } from '@element-plus/icons-vue'
|
||||||
import { ref } from 'vue'
|
import { ref } from 'vue'
|
||||||
import { adminLogin } from '@/api/user.js'
|
import { adminLogin } from '@/api/user.js'
|
||||||
import { useUserStore } from '@/stores'
|
import { useUserStore, useCompanyStore } from '@/stores'
|
||||||
import { useRouter } from 'vue-router'
|
import { useRouter } from 'vue-router'
|
||||||
|
|
||||||
const form = ref()
|
const form = ref()
|
||||||
|
@ -37,11 +37,13 @@ const rules = {
|
||||||
|
|
||||||
const userStore = useUserStore()
|
const userStore = useUserStore()
|
||||||
const router = useRouter()
|
const router = useRouter()
|
||||||
|
const companyStore = useCompanyStore()
|
||||||
const goLogin = async () => {
|
const goLogin = async () => {
|
||||||
await form.value.validate()
|
await form.value.validate()
|
||||||
const res = await adminLogin(formModel.value)
|
const res = await adminLogin(formModel.value)
|
||||||
console.log(res)
|
console.log(res)
|
||||||
userStore.setToken(res.data.data.token)
|
userStore.setToken(res.data.data.token)
|
||||||
|
companyStore.setEncoding(res.data.data.encoding)
|
||||||
ElMessage.success('登录成功')
|
ElMessage.success('登录成功')
|
||||||
router.push('/')
|
router.push('/')
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,43 @@
|
||||||
|
<script setup>
|
||||||
|
import { Edit, Delete } from '@element-plus/icons-vue'
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<page-container title="题目管理">
|
||||||
|
<template #extra>
|
||||||
|
<el-button type="primary" @click="onAddEdit">添加题目 </el-button>
|
||||||
|
</template>
|
||||||
|
<el-table
|
||||||
|
v-loading="loading"
|
||||||
|
:data="channelList"
|
||||||
|
stripe
|
||||||
|
style="width: 100%"
|
||||||
|
>
|
||||||
|
<el-table-column type="index" label="序号" width="100" />
|
||||||
|
<el-table-column prop="cate_name" label="分类名称" />
|
||||||
|
<el-table-column prop="cate_alias" label="分类别名" />
|
||||||
|
<el-table-column label="操作" width="150">
|
||||||
|
<template #default="{ row }">
|
||||||
|
<el-button
|
||||||
|
type="primary"
|
||||||
|
:icon="Edit"
|
||||||
|
@click="handleEdit(row)"
|
||||||
|
circle
|
||||||
|
plain
|
||||||
|
></el-button>
|
||||||
|
<el-button
|
||||||
|
type="danger"
|
||||||
|
:icon="Delete"
|
||||||
|
@click="handleDelete(row)"
|
||||||
|
circle
|
||||||
|
plain
|
||||||
|
></el-button>
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
<template #empty>
|
||||||
|
<el-empty description="没有数据" />
|
||||||
|
</template>
|
||||||
|
</el-table>
|
||||||
|
<ChannelEdit ref="dialog"></ChannelEdit>
|
||||||
|
</page-container>
|
||||||
|
</template>
|
|
@ -0,0 +1,77 @@
|
||||||
|
<script setup>
|
||||||
|
import { Edit, Delete } from '@element-plus/icons-vue'
|
||||||
|
import { useGetTypeList } from '@/api/question'
|
||||||
|
|
||||||
|
import { useCompanyStore } from '@/stores'
|
||||||
|
import { ref } from 'vue'
|
||||||
|
import QuestionTypeEdit from './components/QuestionTypeEdit.vue'
|
||||||
|
|
||||||
|
const questionTypeList = ref([])
|
||||||
|
const loading = ref(false)
|
||||||
|
const companyStore = useCompanyStore()
|
||||||
|
const getQuestionTypeList = async () => {
|
||||||
|
loading.value = true
|
||||||
|
const res = await useGetTypeList(companyStore.encoding)
|
||||||
|
questionTypeList.value = res.data.data
|
||||||
|
console.log(res.data.data)
|
||||||
|
loading.value = false
|
||||||
|
}
|
||||||
|
getQuestionTypeList()
|
||||||
|
const dialog = ref()
|
||||||
|
const handleEdit = (row) => {
|
||||||
|
dialog.value.open(row)
|
||||||
|
}
|
||||||
|
|
||||||
|
const handleDelete = (row) => {
|
||||||
|
console.log(row)
|
||||||
|
}
|
||||||
|
|
||||||
|
const onAddEdit = () => {
|
||||||
|
dialog.value.open({})
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<page-container title="题库管理">
|
||||||
|
<template #extra>
|
||||||
|
<el-button type="primary" @click="onAddEdit">添加类型 </el-button>
|
||||||
|
</template>
|
||||||
|
<el-table
|
||||||
|
v-loading="loading"
|
||||||
|
:data="questionTypeList"
|
||||||
|
stripe
|
||||||
|
height="650"
|
||||||
|
style="width: 100%"
|
||||||
|
>
|
||||||
|
<el-table-column type="index" label="序号" width="100" />
|
||||||
|
<el-table-column prop="name" label="题库类型" />
|
||||||
|
<el-table-column prop="createTime" label="创建时间" />
|
||||||
|
<el-table-column prop="updateTime" label="更新时间" />
|
||||||
|
<el-table-column label="操作" width="150">
|
||||||
|
<template #default="{ row }">
|
||||||
|
<el-button
|
||||||
|
type="primary"
|
||||||
|
:icon="Edit"
|
||||||
|
@click="handleEdit(row)"
|
||||||
|
circle
|
||||||
|
plain
|
||||||
|
></el-button>
|
||||||
|
<el-button
|
||||||
|
type="danger"
|
||||||
|
:icon="Delete"
|
||||||
|
@click="handleDelete(row)"
|
||||||
|
circle
|
||||||
|
plain
|
||||||
|
></el-button>
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
<template #empty>
|
||||||
|
<el-empty description="没有数据" />
|
||||||
|
</template>
|
||||||
|
</el-table>
|
||||||
|
<QuestionTypeEdit
|
||||||
|
@getQuestionTypeList="getQuestionTypeList"
|
||||||
|
ref="dialog"
|
||||||
|
></QuestionTypeEdit>
|
||||||
|
</page-container>
|
||||||
|
</template>
|
|
@ -0,0 +1,67 @@
|
||||||
|
<script setup>
|
||||||
|
import { ElMessage } from 'element-plus'
|
||||||
|
import { ref } from 'vue'
|
||||||
|
import { useAddTypeName } from '@/api/question'
|
||||||
|
import { useUserStore, useCompanyStore } from '@/stores'
|
||||||
|
|
||||||
|
const dialogVisible = ref(false)
|
||||||
|
|
||||||
|
const FormModel = ref({
|
||||||
|
typeName: ''
|
||||||
|
})
|
||||||
|
|
||||||
|
const open = (row) => {
|
||||||
|
console.log(row)
|
||||||
|
dialogVisible.value = true
|
||||||
|
}
|
||||||
|
|
||||||
|
const rules = {
|
||||||
|
typeName: [{ required: true, message: '请输入题库名称', trigger: 'blur' }]
|
||||||
|
}
|
||||||
|
|
||||||
|
const companyStore = useCompanyStore()
|
||||||
|
const userStore = useUserStore()
|
||||||
|
const emit = defineEmits(['getQuestionTypeList'])
|
||||||
|
const onADD = async () => {
|
||||||
|
if (FormModel.value.typeName === '') {
|
||||||
|
ElMessage.error('请输入内容')
|
||||||
|
return
|
||||||
|
}
|
||||||
|
await useAddTypeName(
|
||||||
|
FormModel.value.typeName,
|
||||||
|
companyStore.encoding,
|
||||||
|
userStore.userInfo.id
|
||||||
|
)
|
||||||
|
emit('getQuestionTypeList')
|
||||||
|
FormModel.value.typeName = ''
|
||||||
|
dialogVisible.value = false
|
||||||
|
}
|
||||||
|
|
||||||
|
defineExpose({
|
||||||
|
open
|
||||||
|
})
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<el-dialog v-model="dialogVisible" title="添加弹层" width="30%">
|
||||||
|
<el-form
|
||||||
|
label-width="100px"
|
||||||
|
style="padding-right: 30px"
|
||||||
|
:model="FormModel"
|
||||||
|
:rules="rules"
|
||||||
|
>
|
||||||
|
<el-form-item label="题库类型名" prop="typeName">
|
||||||
|
<el-input
|
||||||
|
v-model="FormModel.typeName"
|
||||||
|
placeholder="请输入题库类型名称"
|
||||||
|
></el-input>
|
||||||
|
</el-form-item>
|
||||||
|
</el-form>
|
||||||
|
<template #footer>
|
||||||
|
<span class="dialog-footer">
|
||||||
|
<el-button @click="dialogVisible = false">取消</el-button>
|
||||||
|
<el-button type="primary" @click="onADD"> 确认 </el-button>
|
||||||
|
</span>
|
||||||
|
</template>
|
||||||
|
</el-dialog>
|
||||||
|
</template>
|
Loading…
Reference in New Issue