初步设计完毕

This commit is contained in:
caoqianming 2021-07-12 15:36:08 +08:00
parent a9efc7c762
commit d6506924f4
6 changed files with 346 additions and 80 deletions

Binary file not shown.

After

Width:  |  Height:  |  Size: 509 KiB

View File

@ -82,11 +82,18 @@ export const asyncRoutes = [
path: '/search', path: '/search',
component: Layout, component: Layout,
redirect: '/search', redirect: '/search',
meta: { title: '专家检索', icon: 'search' },
children: [{ children: [{
path: 'search', path: 'search',
name: 'Search', name: 'Search',
component: () => import('@/views/search/index'), component: () => import('@/views/search/index'),
meta: { title: '专家检索', icon: 'search' } meta: { title: '专家检索(卡片)', icon: 'search' }
},
{
path: 'search2',
name: 'Search2',
component: () => import('@/views/search/index2'),
meta: { title: '专家检索(列表)', icon: 'search' }
}] }]
}, },
{ {

View File

@ -1,11 +1,19 @@
<template> <template>
<div class="login-container"> <div class="login-container">
<el-form ref="loginForm" :model="loginForm" :rules="loginRules" class="login-form" auto-complete="on" label-position="left"> <el-form
ref="loginForm"
:model="loginForm"
:rules="loginRules"
class="login-form"
auto-complete="on"
label-position="left"
>
<div style="text-align:center;margin-bottom:8px">
<!-- <img class="logo" src="../../assets/logo.png" /> -->
</div>
<div class="title-container"> <div class="title-container">
<h3 class="title">总院专家库</h3> <h3 class="title">总院专家库</h3>
</div> </div>
<el-form-item prop="username"> <el-form-item prop="username">
<span class="svg-container"> <span class="svg-container">
<svg-icon icon-class="user" /> <svg-icon icon-class="user" />
@ -37,17 +45,24 @@
@keyup.enter.native="handleLogin" @keyup.enter.native="handleLogin"
/> />
<span class="show-pwd" @click="showPwd"> <span class="show-pwd" @click="showPwd">
<svg-icon :icon-class="passwordType === 'password' ? 'eye' : 'eye-open'" /> <svg-icon
:icon-class="passwordType === 'password' ? 'eye' : 'eye-open'"
/>
</span> </span>
</el-form-item> </el-form-item>
<el-button :loading="loading" type="primary" style="width:100%;margin-bottom:30px;" @click.native.prevent="handleLogin">登陆</el-button> <el-button
:loading="loading"
type="primary"
style="width: 100%; margin-bottom: 30px"
@click.native.prevent="handleLogin"
>登陆</el-button
>
<!-- <div class="tips"> <!-- <div class="tips">
<span style="margin-right:20px;">username: admin</span> <span style="margin-right:20px;">username: admin</span>
<span> password: any</span> <span> password: any</span>
</div> --> </div> -->
</el-form> </el-form>
</div> </div>
</template> </template>
@ -56,7 +71,7 @@
// import { validUsername } from '@/utils/validate' // import { validUsername } from '@/utils/validate'
export default { export default {
name: 'Login', name: "Login",
data() { data() {
// const validateUsername = (rule, value, callback) => { // const validateUsername = (rule, value, callback) => {
// if (!validUsername(value)) { // if (!validUsername(value)) {
@ -67,78 +82,82 @@ export default {
// } // }
const validatePassword = (rule, value, callback) => { const validatePassword = (rule, value, callback) => {
if (value.length < 4) { if (value.length < 4) {
callback(new Error('密码长度小于4位!')) callback(new Error("密码长度小于4位!"));
} else { } else {
callback() callback();
} }
} };
return { return {
loginForm: { loginForm: {
username: '', username: "",
password: '' password: "",
}, },
loginRules: { loginRules: {
username: [{ required: true, trigger: 'blur', message: '请输入账户' }], username: [{ required: true, trigger: "blur", message: "请输入账户" }],
password: [{ required: true, trigger: 'blur', validator: validatePassword, message: '请输入密码' }] password: [
{
required: true,
trigger: "blur",
validator: validatePassword,
message: "请输入密码",
},
],
}, },
loading: false, loading: false,
passwordType: 'password', passwordType: "password",
redirect: undefined redirect: undefined,
} };
}, },
watch: { watch: {
$route: { $route: {
handler: function(route) { handler: function (route) {
this.redirect = route.query && route.query.redirect this.redirect = route.query && route.query.redirect;
}, },
immediate: true immediate: true,
} },
}, },
methods: { methods: {
showPwd() { showPwd() {
if (this.passwordType === 'password') { if (this.passwordType === "password") {
this.passwordType = '' this.passwordType = "";
} else { } else {
this.passwordType = 'password' this.passwordType = "password";
} }
this.$nextTick(() => { this.$nextTick(() => {
this.$refs.password.focus() this.$refs.password.focus();
}) });
}, },
handleLogin() { handleLogin() {
this.$refs.loginForm.validate(valid => { this.$refs.loginForm.validate((valid) => {
if (valid) { if (valid) {
this.loading = true this.loading = true;
this.$store.dispatch('user/login', this.loginForm).then(() => { this.$store
this.$router.push({ path: this.redirect || '/' }) .dispatch("user/login", this.loginForm)
this.loading = false .then(() => {
}).catch(() => { this.$router.push({ path: this.redirect || "/crm/consumer" });
this.loading = false this.loading = false;
}) })
.catch(() => {
this.loading = false;
});
} else { } else {
console.log('error submit!!') console.log("error submit!!");
return false return false;
} }
}) });
} },
} },
} };
</script> </script>
<style lang="scss"> <style lang="scss">
/* 修复input 背景不协调 和光标变色 */ /* 修复input 背景不协调 和光标变色 */
/* Detail see https://github.com/PanJiaChen/vue-element-admin/pull/927 */ /* Detail see https://github.com/PanJiaChen/vue-element-admin/pull/927 */
$bg:#283443; $bg: #283443;
$light_gray:#fff; $light_gray: #fff;
$cursor: #fff; $cursor: #fff;
@supports (-webkit-mask: none) and (not (cater-color: $cursor)) {
.login-container .el-input input {
color: $cursor;
}
}
/* reset element-ui css */ /* reset element-ui css */
.login-container { .login-container {
.el-input { .el-input {
@ -152,20 +171,18 @@ $cursor: #fff;
-webkit-appearance: none; -webkit-appearance: none;
border-radius: 0px; border-radius: 0px;
padding: 12px 5px 12px 15px; padding: 12px 5px 12px 15px;
color: $light_gray; // color: $light_gray;
height: 47px; height: 47px;
caret-color: $cursor; // caret-color: $cursor;
&:-webkit-autofill { // &:-webkit-autofill {
box-shadow: 0 0 0px 1000px $bg inset !important; // box-shadow: 0 0 0px 1000px inset !important;
-webkit-text-fill-color: $cursor !important; // }
}
} }
} }
.el-form-item { .el-form-item {
border: 1px solid rgba(255, 255, 255, 0.1); border: 1px solid;
background: rgba(0, 0, 0, 0.1);
border-radius: 5px; border-radius: 5px;
color: #454545; color: #454545;
} }
@ -173,23 +190,26 @@ $cursor: #fff;
</style> </style>
<style lang="scss" scoped> <style lang="scss" scoped>
$bg:#2d3a4b; $bg: #2d3a4b;
$dark_gray:#889aa4; $dark_gray: #889aa4;
$light_gray:#eee; $light_gray: #eee;
.login-container { .login-container {
min-height: 100%; display: flex;
width: 100%; justify-content: center;
background-color: $bg; align-items: center;
overflow: hidden; height: 100%;
background-image: url("../../assets/background.jpg");
background-size: cover;
.login-form { .login-form {
position: relative; border-radius: 6px;
width: 520px; background: #ffffff;
max-width: 100%; padding: 25px 25px 5px 25px;
padding: 160px 35px 0; width: 400px;
margin: 0 auto; .logo {
overflow: hidden; width: 350px;
height: 140px;
}
} }
.tips { .tips {
@ -206,7 +226,7 @@ $light_gray:#eee;
.svg-container { .svg-container {
padding: 6px 5px 6px 15px; padding: 6px 5px 6px 15px;
color: $dark_gray; // color: $dark_gray;
vertical-align: middle; vertical-align: middle;
width: 30px; width: 30px;
display: inline-block; display: inline-block;
@ -217,8 +237,8 @@ $light_gray:#eee;
.title { .title {
font-size: 26px; font-size: 26px;
color: $light_gray; color: #0174d7;
margin: 0px auto 40px auto; margin: 0px auto 20px auto;
text-align: center; text-align: center;
font-weight: bold; font-weight: bold;
} }
@ -229,7 +249,7 @@ $light_gray:#eee;
right: 10px; right: 10px;
top: 7px; top: 7px;
font-size: 16px; font-size: 16px;
color: $dark_gray; // color: $dark_gray;
cursor: pointer; cursor: pointer;
user-select: none; user-select: none;
} }

View File

@ -75,7 +75,7 @@
<el-row :gutter="8"> <el-row :gutter="8">
<el-col :xs="9" :sm="10" :lg="8" :xl="8"> <el-col :xs="9" :sm="10" :lg="8" :xl="8">
<el-image <el-image
style="width: 100%" style="width: 80px"
:src="item.photo" :src="item.photo"
:preview-src-list="[item.photo]" :preview-src-list="[item.photo]"
> >
@ -85,7 +85,7 @@
</el-image> </el-image>
</el-col> </el-col>
<el-col :xs="15" :sm="14" :lg="16" :xl="16"> <el-col :xs="15" :sm="14" :lg="16" :xl="16">
<div style="text-align: center"> <div >
<div <div
style=" style="
font-weight: bold; font-weight: bold;
@ -93,6 +93,8 @@
margin-top: 4px; margin-top: 4px;
" "
> >
{{ item.name }}
<i <i
class="el-icon-male" class="el-icon-male"
style="color: blue; font-weight: bold" style="color: blue; font-weight: bold"
@ -103,7 +105,6 @@
style="color: blue; font-weight: red" style="color: blue; font-weight: red"
v-else v-else
></i> ></i>
{{ item.name }}
</div> </div>
<div style="margin-top: 4px">{{ item.hdegree }}</div> <div style="margin-top: 4px">{{ item.hdegree }}</div>
<div style="margin-top: 4px">{{ item.idnumber }}</div> <div style="margin-top: 4px">{{ item.idnumber }}</div>
@ -260,7 +261,7 @@ export default {
let sm = data[i][arg][x] let sm = data[i][arg][x]
sm.name_ = data[i][arg][x].name.replace( sm.name_ = data[i][arg][x].name.replace(
searchList[m], searchList[m],
'<span style="color:red;">' + searchList[m] + "</span>" '<span style="color:red;font-weight:bold">' + searchList[m] + "</span>"
); );
ll.push(sm); ll.push(sm);
} }

View File

@ -0,0 +1,238 @@
<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>
<el-table
v-loading="listLoading"
:data="tableData.results"
highlight-current-row
row-key="id"
height="100"
stripe
v-el-height-adaptive-table="{bottomOffset: 50}"
>
<el-table-column type="index" width="50" />
<el-table-column align="center" label="证件照" width="80px">
<template slot-scope="scope" >
<el-image
style="width: 100%"
:src="scope.row.photo"
:preview-src-list="[scope.row.photo]"
>
<div slot="error" class="image-slot">
<i class="el-icon-picture-outline"></i>
</div>
</el-image>
</template>
</el-table-column>
<el-table-column label="基本信息">
<template slot-scope="scope">
<div
style="
font-weight: bold;
font-size: 18px;
margin-top: 4px;
"
>
{{ scope.row.name }}
<i
class="el-icon-male"
style="color: blue; font-weight: bold"
v-if="scope.row.gender == ''"
></i>
<i
class="el-icon-female"
style="color: blue; font-weight: red"
v-else
></i>
</div>
<div style="margin-top: 4px">{{ scope.row.hdegree }}</div>
<div style="margin-top: 4px">{{ scope.row.idnumber }}</div>
</template>
</el-table-column>
<el-table-column align="header-center" label="项目经历">
<template slot-scope="scope"><div v-for="x in scope.row.project_" v-bind:key="x.id" class="tip" v-html="x.name_">
</div></template>
</el-table-column>
<el-table-column align="header-center" label="论文著作">
<template slot-scope="scope">
<div v-for="x in scope.row.paper_" v-bind:key="x.id" class="tip" v-html="x.name_">
</div></template>
</el-table-column>
<el-table-column label="所获奖项">
<template slot-scope="scope">
<div v-for="x in scope.row.award_" v-bind:key="x.id" class="tip" v-html="x.name_">
</div>
</template>
</el-table-column>
<el-table-column align="center" label="操作">
<template slot-scope="scope">
<el-button
type="primary"
size="small"
@click="handleEdit(scope)"
>更多信息</el-button>
</template>
</el-table-column>
</el-table>
<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;
}
}
},
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;font-weight:bold">' + 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>

View File

@ -23,7 +23,7 @@ class Expert(CommonBModel):
idnumber = models.CharField(verbose_name="身份证号", max_length=40) idnumber = models.CharField(verbose_name="身份证号", max_length=40)
paddress = models.TextField(verbose_name="通讯地址") paddress = models.TextField(verbose_name="通讯地址")
photo = models.CharField(verbose_name="证件照", max_length=100, null=True, blank=True) photo = models.CharField(verbose_name="证件照", max_length=100, null=True, blank=True)
hdegree = models.CharField(verbose_name="最高学历",choices=gender_choices, default='本科', max_length=10) hdegree = models.CharField(verbose_name="最高学历",choices=degree_choices, default='本科', max_length=10)
class Meta: class Meta:
verbose_name = '专家信息' verbose_name = '专家信息'