专家库查询界面
This commit is contained in:
parent
3cd25e051e
commit
a9efc7c762
|
@ -0,0 +1,29 @@
|
|||
import request from '@/utils/request'
|
||||
|
||||
export function getExpertList(query) {
|
||||
return request({
|
||||
url: '/expert/expert/',
|
||||
method: 'get',
|
||||
params: query
|
||||
})
|
||||
}
|
||||
export function createExpert(data) {
|
||||
return request({
|
||||
url: '/expert/expert/',
|
||||
method: 'post',
|
||||
data
|
||||
})
|
||||
}
|
||||
export function updateExpert(id, data) {
|
||||
return request({
|
||||
url: `/expert/expert/${id}/`,
|
||||
method: 'put',
|
||||
data
|
||||
})
|
||||
}
|
||||
export function deleteExpert(id) {
|
||||
return request({
|
||||
url: `/expert/expert/${id}/`,
|
||||
method: 'delete'
|
||||
})
|
||||
}
|
|
@ -35,7 +35,7 @@ export default {
|
|||
pageSizes: {
|
||||
type: Array,
|
||||
default() {
|
||||
return [10, 20, 30, 50]
|
||||
return [12, 24, 36, 48]
|
||||
}
|
||||
},
|
||||
layout: {
|
||||
|
|
|
@ -52,7 +52,8 @@ export default {
|
|||
computed: {
|
||||
...mapGetters([
|
||||
'sidebar',
|
||||
'avatar'
|
||||
'avatar',
|
||||
'name'
|
||||
])
|
||||
},
|
||||
methods: {
|
||||
|
|
|
@ -24,7 +24,7 @@ export default {
|
|||
},
|
||||
data() {
|
||||
return {
|
||||
title: 'Django Vue Admin',
|
||||
title: '总院专家库',
|
||||
logo: 'https://wpimg.wallstcn.com/69a1c46c-eb1c-4b46-8bd4-e9e686ef5251.png'
|
||||
}
|
||||
}
|
||||
|
|
|
@ -78,6 +78,17 @@ export const constantRoutes = [
|
|||
* the routes that need to be dynamically loaded based on user perms
|
||||
*/
|
||||
export const asyncRoutes = [
|
||||
{
|
||||
path: '/search',
|
||||
component: Layout,
|
||||
redirect: '/search',
|
||||
children: [{
|
||||
path: 'search',
|
||||
name: 'Search',
|
||||
component: () => import('@/views/search/index'),
|
||||
meta: { title: '专家检索', icon: 'search' }
|
||||
}]
|
||||
},
|
||||
{
|
||||
path: '/system',
|
||||
component: Layout,
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
module.exports = {
|
||||
|
||||
title: '管理系统',
|
||||
title: '总院专家库',
|
||||
|
||||
/**
|
||||
* @type {boolean} true | false
|
||||
|
|
|
@ -10,6 +10,7 @@ body {
|
|||
-webkit-font-smoothing: antialiased;
|
||||
text-rendering: optimizeLegibility;
|
||||
font-family: Helvetica Neue, Helvetica, PingFang SC, Hiragino Sans GB, Microsoft YaHei, Arial, sans-serif;
|
||||
background-color: #f0f2f5;
|
||||
}
|
||||
|
||||
label {
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
import defaultSettings from '@/settings'
|
||||
|
||||
const title = defaultSettings.title || '认证系统'
|
||||
const title = defaultSettings.title || '总院专家库'
|
||||
|
||||
export default function getPageTitle(pageTitle) {
|
||||
if (pageTitle) {
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
<el-form ref="loginForm" :model="loginForm" :rules="loginRules" class="login-form" auto-complete="on" label-position="left">
|
||||
|
||||
<div class="title-container">
|
||||
<h3 class="title">系统登陆</h3>
|
||||
<h3 class="title">总院专家库</h3>
|
||||
</div>
|
||||
|
||||
<el-form-item prop="username">
|
||||
|
|
|
@ -0,0 +1,294 @@
|
|||
<template>
|
||||
<div class="app-container">
|
||||
<el-card>
|
||||
<div slot="header" class="clearfix">
|
||||
<span>专家库检索</span>
|
||||
</div>
|
||||
<el-row type="flex">
|
||||
<el-col :sm="18">
|
||||
<el-row :gutter="8">
|
||||
<el-col :xs="16" :sm="20">
|
||||
<el-input
|
||||
v-model="listQuery.search"
|
||||
placeholder="请输入关键字"
|
||||
@keyup.enter.native="handleFilter"
|
||||
></el-input>
|
||||
</el-col>
|
||||
<el-col :xs="8" :sm="4">
|
||||
<el-button
|
||||
type="primary"
|
||||
style="width: 100%"
|
||||
@click="handleFilter"
|
||||
>搜索一下</el-button
|
||||
>
|
||||
</el-col>
|
||||
</el-row>
|
||||
</el-col>
|
||||
</el-row>
|
||||
<el-row style="margin-top:6px">
|
||||
<el-col :xs="12" :sm="12" :lg="6" :xl="6">
|
||||
<el-select
|
||||
v-model="listQuery.hdegree"
|
||||
placeholder="最高学历"
|
||||
clearable
|
||||
@change="handleFilter"
|
||||
style="width:100%"
|
||||
>
|
||||
<el-option
|
||||
v-for="item in degreeOptions"
|
||||
:key="item.key"
|
||||
:label="item.label"
|
||||
:value="item.key"
|
||||
/>
|
||||
</el-select>
|
||||
</el-col>
|
||||
</el-row>
|
||||
</el-card>
|
||||
<el-card style="margin-top: 6px">
|
||||
<div slot="header" class="clearfix">
|
||||
<span>专家库</span>
|
||||
</div>
|
||||
<p
|
||||
style="text-align: center; font-weight: bold; color: gray"
|
||||
v-if="tableData.count == 0"
|
||||
>
|
||||
暂无数据
|
||||
</p>
|
||||
<el-row :gutter="10" v-else v-loading="listLoading">
|
||||
<el-col
|
||||
:xs="12"
|
||||
:sm="6"
|
||||
:lg="6"
|
||||
:xl="4"
|
||||
v-for="item in tableData.results"
|
||||
v-bind:key="item.id"
|
||||
>
|
||||
<el-card>
|
||||
<div slot="header" class="clearfix">
|
||||
<span>{{ item.name }}</span>
|
||||
<el-button style="float: right; padding: 3px 0" type="text"
|
||||
>更多信息</el-button
|
||||
>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<el-row :gutter="8">
|
||||
<el-col :xs="9" :sm="10" :lg="8" :xl="8">
|
||||
<el-image
|
||||
style="width: 100%"
|
||||
:src="item.photo"
|
||||
:preview-src-list="[item.photo]"
|
||||
>
|
||||
<div slot="error" class="image-slot">
|
||||
<i class="el-icon-picture-outline"></i>
|
||||
</div>
|
||||
</el-image>
|
||||
</el-col>
|
||||
<el-col :xs="15" :sm="14" :lg="16" :xl="16">
|
||||
<div style="text-align: center">
|
||||
<div
|
||||
style="
|
||||
font-weight: bold;
|
||||
font-size: 18px;
|
||||
margin-top: 4px;
|
||||
"
|
||||
>
|
||||
<i
|
||||
class="el-icon-male"
|
||||
style="color: blue; font-weight: bold"
|
||||
v-if="item.gender == '男'"
|
||||
></i>
|
||||
<i
|
||||
class="el-icon-female"
|
||||
style="color: blue; font-weight: red"
|
||||
v-else
|
||||
></i>
|
||||
{{ item.name }}
|
||||
</div>
|
||||
<div style="margin-top: 4px">{{ item.hdegree }}</div>
|
||||
<div style="margin-top: 4px">{{ item.idnumber }}</div>
|
||||
</div>
|
||||
</el-col>
|
||||
</el-row>
|
||||
|
||||
<el-row :gutter="2" style="font-size: 14px" v-if="item.project_.length">
|
||||
<el-col
|
||||
:xs="24"
|
||||
:sm="24"
|
||||
:lg="6"
|
||||
:xl="4"
|
||||
style="color: gray; font-weight: bold; margin-top: 2px"
|
||||
|
||||
>项目经历</el-col
|
||||
>
|
||||
<el-col
|
||||
:xs="24"
|
||||
:sm="24"
|
||||
:lg="18"
|
||||
:xl="20"
|
||||
style="margin-top: 2px"
|
||||
>
|
||||
<div v-for="x in item.project_" v-bind:key="x.id" v-html="x.name_">
|
||||
</div>
|
||||
</el-col>
|
||||
</el-row>
|
||||
<el-row :gutter="2" style="font-size: 14px" v-if="item.paper_.length">
|
||||
<el-col
|
||||
:xs="24"
|
||||
:sm="24"
|
||||
:lg="6"
|
||||
:xl="4"
|
||||
style="color: gray; font-weight: bold; margin-top: 2px"
|
||||
v-if="item.paper_.length"
|
||||
>论文/著作</el-col
|
||||
>
|
||||
<el-col
|
||||
:xs="24"
|
||||
:sm="24"
|
||||
:lg="18"
|
||||
:xl="20"
|
||||
style="margin-top: 2px"
|
||||
>
|
||||
<div v-for="x in item.paper_" v-bind:key="x.id" class="tip" v-html="x.name_">
|
||||
</div>
|
||||
</el-col>
|
||||
</el-row>
|
||||
<el-row :gutter="2" style="font-size: 14px" v-if="item.award_.length">
|
||||
<el-col
|
||||
:xs="24"
|
||||
:sm="24"
|
||||
:lg="6"
|
||||
:xl="4"
|
||||
style="color: gray; font-weight: bold; margin-top: 2px"
|
||||
v-if="item.award_.length"
|
||||
>所获奖项</el-col
|
||||
>
|
||||
<el-col
|
||||
:xs="24"
|
||||
:sm="24"
|
||||
:lg="18"
|
||||
:xl="20"
|
||||
style="margin-top: 2px"
|
||||
>
|
||||
<div v-for="x in item.award_" v-bind:key="x.id" class="tip" v-html="x.name_">
|
||||
</div>
|
||||
</el-col>
|
||||
</el-row>
|
||||
</div>
|
||||
</el-card>
|
||||
</el-col>
|
||||
</el-row>
|
||||
|
||||
<pagination
|
||||
style="margin-top: 6px"
|
||||
v-show="tableData.count > 0"
|
||||
:total="tableData.count"
|
||||
:page.sync="listQuery.page"
|
||||
:limit.sync="listQuery.page_size"
|
||||
@pagination="getList"
|
||||
/>
|
||||
</el-card>
|
||||
</div>
|
||||
</template>
|
||||
<script>
|
||||
import { getExpertList } from "@/api/expert";
|
||||
import checkPermission from "@/utils/permission";
|
||||
import Pagination from "@/components/Pagination"; // secondary package based on el-pagination
|
||||
export default {
|
||||
components: { Pagination },
|
||||
data() {
|
||||
return {
|
||||
search: null,
|
||||
listQuery: {
|
||||
page: 1,
|
||||
page_size: 12,
|
||||
search: "",
|
||||
},
|
||||
listLoading: false,
|
||||
tableData: {
|
||||
count: 0,
|
||||
results: [],
|
||||
},
|
||||
degreeOptions:[
|
||||
{ key: "博士研究生", value: "博士研究生" },
|
||||
{ key: "硕士研究生", value: "硕士研究生" },
|
||||
{ key: "本科", value: "本科" },
|
||||
{ key: "大专", value: "大专" },
|
||||
]
|
||||
};
|
||||
},
|
||||
created() {
|
||||
this.getList();
|
||||
},
|
||||
methods: {
|
||||
checkPermission,
|
||||
getList() {
|
||||
this.listLoading = true;
|
||||
getExpertList(this.listQuery)
|
||||
.then((res) => {
|
||||
this.listLoading = false;
|
||||
this.tableData = res.data;
|
||||
//高亮显示
|
||||
this.showLight();
|
||||
})
|
||||
.catch((e) => {
|
||||
this.listLoading = false;
|
||||
});
|
||||
},
|
||||
handleFilter() {
|
||||
this.page = 1;
|
||||
this.getList();
|
||||
},
|
||||
lessStr(data, arg) {
|
||||
for (var i = 0; i < data.length; i++) {
|
||||
let len1 = data[i][arg].length;
|
||||
if (len1 > 2) {
|
||||
data[i][arg] = data[i][arg].slice(0, 2);
|
||||
}
|
||||
for (var x = 0; x < data[i][arg].length; x++) {
|
||||
data[i][arg][x].name_ = data[i][arg][x].name.substr(0, 14) + "...";
|
||||
}
|
||||
}
|
||||
},
|
||||
lessStr2(data, arg, searchList) {
|
||||
for (var i = 0; i < data.length; i++) {
|
||||
//项目经历
|
||||
var ll = [];
|
||||
for (var x = 0; x < data[i][arg].length; x++) {
|
||||
for (var m = 0; m < searchList.length; m++) {
|
||||
if (data[i][arg][x].name.indexOf(searchList[m]) != -1) {
|
||||
let sm = data[i][arg][x]
|
||||
sm.name_ = data[i][arg][x].name.replace(
|
||||
searchList[m],
|
||||
'<span style="color:red;">' + searchList[m] + "</span>"
|
||||
);
|
||||
ll.push(sm);
|
||||
}
|
||||
}
|
||||
}
|
||||
data[i][arg]=ll
|
||||
}
|
||||
|
||||
},
|
||||
showLight() {
|
||||
var data = this.tableData.results
|
||||
if (this.listQuery.search == "") {
|
||||
|
||||
//项目经历
|
||||
this.lessStr(data, "project_");
|
||||
//论文
|
||||
this.lessStr(data, "paper_");
|
||||
//获奖
|
||||
this.lessStr(data, "award_");
|
||||
} else {
|
||||
let searchList = this.listQuery.search.split(" ");
|
||||
this.lessStr2(data, 'project_', searchList)
|
||||
this.lessStr2(data, 'paper_', searchList)
|
||||
this.lessStr2(data, 'award_', searchList)
|
||||
}
|
||||
},
|
||||
},
|
||||
};
|
||||
</script>
|
||||
<style lang="scss" scoped>
|
||||
</style>
|
|
@ -0,0 +1,21 @@
|
|||
# Generated by Django 3.1.8 on 2021-07-08 02:43
|
||||
|
||||
from django.db import migrations
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('expert', '0003_historicalexpert'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AlterModelOptions(
|
||||
name='expert',
|
||||
options={'verbose_name': '专家信息', 'verbose_name_plural': '专家信息'},
|
||||
),
|
||||
migrations.AlterModelOptions(
|
||||
name='historicalexpert',
|
||||
options={'get_latest_by': 'history_date', 'ordering': ('-history_date', '-history_id'), 'verbose_name': 'historical 专家信息'},
|
||||
),
|
||||
]
|
|
@ -0,0 +1,16 @@
|
|||
# Generated by Django 3.1.8 on 2021-07-08 02:44
|
||||
|
||||
from django.db import migrations
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('expert', '0004_auto_20210708_1043'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.DeleteModel(
|
||||
name='HistoricalExpert',
|
||||
),
|
||||
]
|
|
@ -0,0 +1,18 @@
|
|||
# Generated by Django 3.1.8 on 2021-07-08 08:25
|
||||
|
||||
from django.db import migrations, models
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('expert', '0005_delete_historicalexpert'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AddField(
|
||||
model_name='expert',
|
||||
name='Hdegree',
|
||||
field=models.CharField(choices=[('男', '男'), ('女', '女')], default='本科', max_length=10, verbose_name='最高学历'),
|
||||
),
|
||||
]
|
|
@ -0,0 +1,18 @@
|
|||
# Generated by Django 3.1.8 on 2021-07-08 08:27
|
||||
|
||||
from django.db import migrations
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('expert', '0006_expert_hdegree'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.RenameField(
|
||||
model_name='expert',
|
||||
old_name='Hdegree',
|
||||
new_name='hdegree',
|
||||
),
|
||||
]
|
|
@ -10,6 +10,12 @@ class Expert(CommonBModel):
|
|||
('男', '男'),
|
||||
('女', '女'),
|
||||
)
|
||||
degree_choices = (
|
||||
('大专', '大专'),
|
||||
('本科', '本科'),
|
||||
('硕士研究生', '硕士研究生'),
|
||||
('博士研究生', '博士研究生'),
|
||||
)
|
||||
|
||||
user = models.OneToOneField(User, on_delete=models.CASCADE, null=True, blank=True, verbose_name="关联账户", related_name="expert_user")
|
||||
name = models.CharField(verbose_name="姓名", max_length=100)
|
||||
|
@ -17,7 +23,7 @@ class Expert(CommonBModel):
|
|||
idnumber = models.CharField(verbose_name="身份证号", max_length=40)
|
||||
paddress = models.TextField(verbose_name="通讯地址")
|
||||
photo = models.CharField(verbose_name="证件照", max_length=100, null=True, blank=True)
|
||||
history = HistoricalRecords()
|
||||
hdegree = models.CharField(verbose_name="最高学历",choices=gender_choices, default='本科', max_length=10)
|
||||
|
||||
class Meta:
|
||||
verbose_name = '专家信息'
|
||||
|
|
|
@ -0,0 +1,37 @@
|
|||
from rest_framework.serializers import ModelSerializer
|
||||
from .models import Award, Expert, Paper, Project, WorkExperience
|
||||
|
||||
class WorkExperienceSimpleSerializer(ModelSerializer):
|
||||
class Meta:
|
||||
model = WorkExperience
|
||||
fields = ['id', 'name']
|
||||
|
||||
class ProjectSimpleSerializer(ModelSerializer):
|
||||
class Meta:
|
||||
model = Project
|
||||
fields = ['id', 'name']
|
||||
|
||||
class PaperSimpleSerializer(ModelSerializer):
|
||||
class Meta:
|
||||
model = Paper
|
||||
fields = ['id', 'name']
|
||||
|
||||
class AwardSimpleSerializer(ModelSerializer):
|
||||
class Meta:
|
||||
model = Award
|
||||
fields = ['id', 'name']
|
||||
|
||||
class ExpertListSerializer(ModelSerializer):
|
||||
workexperience_ = WorkExperienceSimpleSerializer(source='workexperience_expert', many=True, read_only=True)
|
||||
project_ = ProjectSimpleSerializer(source='project_expert', many=True, read_only=True)
|
||||
paper_ = PaperSimpleSerializer(source='paper_expert', many=True, read_only=True)
|
||||
award_ = AwardSimpleSerializer(source='award_expert', many=True, read_only=True)
|
||||
class Meta:
|
||||
model = Expert
|
||||
fields = '__all__'
|
||||
|
||||
@staticmethod
|
||||
def setup_eager_loading(queryset):
|
||||
""" Perform necessary eager loading of data. """
|
||||
queryset = queryset.prefetch_related('workexperience_expert','project_expert', 'paper_expert', 'award_expert')
|
||||
return queryset
|
|
@ -0,0 +1,10 @@
|
|||
from django.urls import path, include
|
||||
from .views import ExpertViewSet
|
||||
from rest_framework import routers
|
||||
|
||||
router = routers.DefaultRouter()
|
||||
router.register('expert', ExpertViewSet, basename="expert")
|
||||
|
||||
urlpatterns = [
|
||||
path('', include(router.urls)),
|
||||
]
|
|
@ -1,3 +1,14 @@
|
|||
from django.shortcuts import render
|
||||
|
||||
from rest_framework.viewsets import ModelViewSet
|
||||
from .models import Expert
|
||||
from .serializers import ExpertListSerializer
|
||||
from apps.system.mixins import OptimizationMixin
|
||||
# Create your views here.
|
||||
|
||||
class ExpertViewSet(OptimizationMixin, ModelViewSet):
|
||||
perms_map={'get':'expert_view'}
|
||||
queryset = Expert.objects.all()
|
||||
search_fields = ['name', 'workexperience_expert__name', 'project_expert__name', 'paper_expert__name', 'award_expert__name']
|
||||
filterset_fields = ['hdegree']
|
||||
serializer_class = ExpertListSerializer
|
||||
ordering = ['-create_time']
|
Binary file not shown.
After Width: | Height: | Size: 30 KiB |
|
@ -49,6 +49,7 @@ urlpatterns = [
|
|||
path('token/black/', LogoutView.as_view(), name='token_black'),
|
||||
path('system/', include('apps.system.urls')),
|
||||
path('monitor/', include('apps.monitor.urls')),
|
||||
path('expert/', include('apps.expert.urls')),
|
||||
|
||||
# api文档
|
||||
path('docs/', include_docs_urls(title="接口文档", authentication_classes=[], permission_classes=[])),
|
||||
|
|
Loading…
Reference in New Issue