题库列表渲染,添加功能

This commit is contained in:
Unique-Jerry 2023-10-20 13:15:45 +08:00
parent 27766bf8a5
commit 5e42046c5c
15 changed files with 394 additions and 60 deletions

11
src/api/question.js Normal file
View File

@ -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 })

View File

@ -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
}
})

BIN
src/assets/login_title.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.9 KiB

20
src/assets/main.scss Normal file
View File

@ -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;
}

View File

@ -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>

View File

@ -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)

View File

@ -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) => {

View File

@ -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'

View File

@ -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']
}
}
)

View File

@ -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']
}
})
)

View File

@ -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;

View File

@ -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('/')
}

View File

@ -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>

View File

@ -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>

View File

@ -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>