题库列表渲染,添加功能
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,
|
||||
encoding,
|
||||
password
|
||||
})
|
||||
|
||||
phone,
|
||||
encoding,
|
||||
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 pinia from "@/stores";
|
||||
import pinia from '@/stores'
|
||||
|
||||
import App from './App.vue'
|
||||
import router from './router'
|
||||
|
||||
import './assets/main.scss'
|
||||
const app = createApp(App)
|
||||
|
||||
app.use(pinia)
|
||||
|
|
|
@ -1,11 +1,25 @@
|
|||
import { createRouter, createWebHistory } from 'vue-router'
|
||||
import { useUserStore } from "@/stores";
|
||||
import { useUserStore } from '@/stores'
|
||||
|
||||
const router = createRouter({
|
||||
history: createWebHistory(import.meta.env.BASE_URL),
|
||||
routes: [
|
||||
{ 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) => {
|
||||
|
|
|
@ -6,5 +6,5 @@ pinia.use(persist)
|
|||
|
||||
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,30 +1,39 @@
|
|||
import { defineStore } from "pinia"
|
||||
import { ref } from "vue";
|
||||
import { defineStore } from 'pinia'
|
||||
import { ref } from 'vue'
|
||||
|
||||
export const useUserStore = defineStore(
|
||||
'interviewer-user',
|
||||
() => {
|
||||
const token = ref('')
|
||||
|
||||
export const useUserStore=defineStore('interviewer-user',()=>{
|
||||
const setToken = (newToken) => {
|
||||
token.value = newToken
|
||||
}
|
||||
|
||||
const removeToken = () => {
|
||||
token.value = ''
|
||||
}
|
||||
|
||||
const token = ref('')
|
||||
const userInfo = ref({})
|
||||
|
||||
const setToken = (newToken) => {
|
||||
token.value = newToken
|
||||
const setUserInfo = (newUserInfo) => {
|
||||
userInfo.value = newUserInfo
|
||||
}
|
||||
const removeUserInfo = () => {
|
||||
userInfo.value = {}
|
||||
}
|
||||
return {
|
||||
token,
|
||||
setToken,
|
||||
removeToken,
|
||||
userInfo,
|
||||
setUserInfo,
|
||||
removeUserInfo
|
||||
}
|
||||
},
|
||||
{
|
||||
persist: {
|
||||
paths: ['token', 'userInfo']
|
||||
}
|
||||
}
|
||||
|
||||
const removeToken = () => {
|
||||
token.value = ''
|
||||
}
|
||||
|
||||
|
||||
return {
|
||||
|
||||
token,
|
||||
setToken,
|
||||
removeToken
|
||||
|
||||
}
|
||||
},{
|
||||
persist: {
|
||||
paths: ['token']
|
||||
}
|
||||
})
|
||||
)
|
||||
|
|
|
@ -1,15 +1,25 @@
|
|||
<script setup>
|
||||
import {
|
||||
Management,
|
||||
Promotion,
|
||||
UserFilled,
|
||||
Files,
|
||||
User,
|
||||
Crop,
|
||||
DocumentCopy,
|
||||
EditPen,
|
||||
SwitchButton,
|
||||
CaretBottom
|
||||
} from '@element-plus/icons-vue'
|
||||
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>
|
||||
|
||||
<template>
|
||||
|
@ -25,35 +35,48 @@ import avatar from '@/assets/default.png'
|
|||
>
|
||||
<el-menu-item index="/article/channel">
|
||||
<el-icon><Management /></el-icon>
|
||||
<span>文章分类</span>
|
||||
<span>员工管理</span>
|
||||
</el-menu-item>
|
||||
<el-menu-item index="/article/manage">
|
||||
<el-icon><Promotion /></el-icon>
|
||||
<span>文章管理</span>
|
||||
</el-menu-item>
|
||||
<el-sub-menu index="/user">
|
||||
<el-sub-menu index="/interview">
|
||||
<template #title>
|
||||
<el-icon><UserFilled /></el-icon>
|
||||
<span>个人中心</span>
|
||||
<el-icon><Files /></el-icon>
|
||||
<span>个性化面试</span>
|
||||
</template>
|
||||
<el-menu-item index="/user/profile">
|
||||
<el-icon><User /></el-icon>
|
||||
<span>基本资料</span>
|
||||
<el-menu-item index="">
|
||||
<el-icon><DocumentCopy /></el-icon>
|
||||
<span>形象管理</span>
|
||||
</el-menu-item>
|
||||
<el-menu-item index="/user/avatar">
|
||||
<el-icon><Crop /></el-icon>
|
||||
<span>更换头像</span>
|
||||
</el-menu-item>
|
||||
<el-menu-item index="/user/password">
|
||||
<el-menu-item index="">
|
||||
<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-sub-menu>
|
||||
</el-menu>
|
||||
</el-aside>
|
||||
<el-container>
|
||||
<el-header>
|
||||
<div>黑马程序员:<strong>小帅鹏</strong></div>
|
||||
<div>
|
||||
欢迎您:<strong>{{ userStore.userInfo.username }}</strong>
|
||||
</div>
|
||||
<el-dropdown placement="bottom-end">
|
||||
<span class="el-dropdown__box">
|
||||
<el-avatar :src="avatar" />
|
||||
|
@ -80,7 +103,7 @@ import avatar from '@/assets/default.png'
|
|||
<el-main>
|
||||
<router-view></router-view>
|
||||
</el-main>
|
||||
<el-footer>大事件 ©2023 Created by 黑马程序员</el-footer>
|
||||
<el-footer>Ai-面试 ©2023 Created by 扬州大学开发团队</el-footer>
|
||||
</el-container>
|
||||
</el-container>
|
||||
</template>
|
||||
|
@ -92,7 +115,7 @@ import avatar from '@/assets/default.png'
|
|||
background-color: #232323;
|
||||
&__logo {
|
||||
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 {
|
||||
border-right: none;
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
import { Lock, User } from '@element-plus/icons-vue'
|
||||
import { ref } from 'vue'
|
||||
import { adminLogin } from '@/api/user.js'
|
||||
import { useUserStore } from '@/stores'
|
||||
import { useUserStore, useCompanyStore } from '@/stores'
|
||||
import { useRouter } from 'vue-router'
|
||||
|
||||
const form = ref()
|
||||
|
@ -37,11 +37,13 @@ const rules = {
|
|||
|
||||
const userStore = useUserStore()
|
||||
const router = useRouter()
|
||||
const companyStore = useCompanyStore()
|
||||
const goLogin = async () => {
|
||||
await form.value.validate()
|
||||
const res = await adminLogin(formModel.value)
|
||||
console.log(res)
|
||||
userStore.setToken(res.data.data.token)
|
||||
companyStore.setEncoding(res.data.data.encoding)
|
||||
ElMessage.success('登录成功')
|
||||
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