create admin

This commit is contained in:
caoqianming 2020-08-10 11:59:11 +08:00
parent 7949661044
commit 3924c85d25
19 changed files with 299 additions and 121 deletions

View File

@ -64,4 +64,12 @@ export function deleteUser(id, data) {
}) })
} }
export function changePassword(data) {
return request({
url: '/rbac/user/password/',
method: 'put',
data
})
}

View File

@ -16,6 +16,11 @@
首页 首页
</el-dropdown-item> </el-dropdown-item>
</router-link> </router-link>
<router-link to="/system/user/password">
<el-dropdown-item divided>
修改密码
</el-dropdown-item>
</router-link>
<!-- <a target="_blank" href="https://github.com/PanJiaChen/vue-admin-template/"> <!-- <a target="_blank" href="https://github.com/PanJiaChen/vue-admin-template/">
<el-dropdown-item>Github</el-dropdown-item> <el-dropdown-item>Github</el-dropdown-item>
</a> </a>

View File

@ -41,19 +41,7 @@ export const constantRoutes = [
path: '/404', path: '/404',
component: () => import('@/views/404'), component: () => import('@/views/404'),
hidden: true hidden: true
}, }
{
path: '/',
component: Layout,
redirect: '/dashboard',
children: [{
path: 'dashboard',
name: 'Dashboard',
component: () => import('@/views/dashboard/index'),
meta: { title: '首页', icon: 'dashboard' }
}]
},
] ]
@ -63,10 +51,21 @@ export const constantRoutes = [
* the routes that need to be dynamically loaded based on user perms * the routes that need to be dynamically loaded based on user perms
*/ */
export const asyncRoutes = [ export const asyncRoutes = [
{
path: '/',
component: Layout,
redirect: '/dashboard',
children: [{
path: 'dashboard',
name: 'Dashboard',
component: () => import('@/views/dashboard/index'),
meta: { title: '首页', icon: 'dashboard', perms:['admin'] }
}]
},
{ {
path: '/cms', path: '/cms',
component: Layout, component: Layout,
redirect: '/cms/', redirect: '/cms/materials',
name: 'CMS', name: 'CMS',
meta: { title: '资料文章', icon: 'documentation', perms: ['news_view'] }, meta: { title: '资料文章', icon: 'documentation', perms: ['news_view'] },
children: [ children: [
@ -101,9 +100,9 @@ export const asyncRoutes = [
{ {
path: '/crm', path: '/crm',
component: Layout, component: Layout,
redirect: '/crm/', redirect: '/crm/consumer',
name: 'Crm', name: 'Crm',
meta: { title: '客户管理', icon: 'peoples', perms: ['custom_manage'] }, meta: { title: '客户管理', icon: 'peoples', perms: ['consumer_view'] },
children: [ children: [
{ {
path: 'company', path: 'company',
@ -115,7 +114,7 @@ export const asyncRoutes = [
path: 'consumer', path: 'consumer',
name: 'Consumer', name: 'Consumer',
component: () => import('@/views/crm/consumer.vue'), component: () => import('@/views/crm/consumer.vue'),
meta: { title: '学员列表', icon: '', perms: ['consumer_list'] } meta: { title: '学员列表', icon: '', perms: ['consumer_view'] }
}, },
{ {
path: 'consumerrule', path: 'consumerrule',
@ -129,9 +128,9 @@ export const asyncRoutes = [
{ {
path: '/Qmanage', path: '/Qmanage',
component: Layout, component: Layout,
redirect: '/Qmanage/', redirect: '/Qmanage/question',
name: 'Qmanage', name: 'Qmanage',
meta: { title: '题库管理', icon: 'table'}, meta: { title: '题库管理', icon: 'table', perms: []},
children: [ children: [
{ {
path: 'subject', path: 'subject',
@ -170,9 +169,9 @@ export const asyncRoutes = [
{ {
path: '/sjmanage', path: '/sjmanage',
component: Layout, component: Layout,
redirect: '/sjmanage/', redirect: '/sjmanage/workscope',
name: 'Sjmanage', name: 'Sjmanage',
meta: { title: '出卷管理', icon: 'component'}, meta: { title: '出卷管理', icon: 'component', perms: []},
children: [ children: [
{ {
path: 'testrule', path: 'testrule',
@ -239,15 +238,15 @@ export const asyncRoutes = [
{ {
path: '/analyse', path: '/analyse',
component: Layout, component: Layout,
redirect: '/analyse/', redirect: '/analyse/examtest',
name: 'Analyse', name: 'Analyse',
meta: { title: '统计分析', icon: 'chart'}, meta: { title: '统计分析', icon: 'chart', perms: ['examtest_view']},
children: [ children: [
{ {
path: 'examtest', path: 'examtest',
name: 'ExamTest', name: 'ExamTest',
component: () => import('@/views/analyse/examtest.vue'), component: () => import('@/views/analyse/examtest.vue'),
meta: { title: '答卷列表', icon: '', perms: ['examtest_list'] } meta: { title: '答卷列表', icon: '', perms: ['examtest_view'] }
}, },
{ {
path: 'chart', path: 'chart',
@ -261,9 +260,9 @@ export const asyncRoutes = [
{ {
path: '/system', path: '/system',
component: Layout, component: Layout,
redirect: '/system/user', redirect: '/system/admin',
name: 'System', name: 'System',
meta: { title: '系统管理', icon: 'tree', perms: ['system_manage'] }, meta: { title: '系统管理', icon: 'tree', perms: [] },
children: [ children: [
{ {
path: 'banner', path: 'banner',
@ -277,6 +276,19 @@ export const asyncRoutes = [
component: () => import('@/views/system/admin.vue'), component: () => import('@/views/system/admin.vue'),
meta: { title: '管理员', icon: '', perms: ['admin_manage'] } meta: { title: '管理员', icon: '', perms: ['admin_manage'] }
}, },
{
path: 'role',
name: 'Role',
component: () => import('@/views/system/role'),
meta: { title: '管理员角色', icon: '', perms: ['role_manage'] }
},
{
path: 'user/password',
name: 'ChangePassword',
component: () => import('@/views/system/changepassword'),
meta: { title: '修改密码', noCache: true, icon: ''},
hidden: true
},
] ]
}, },
// 404 page must be placed at the end !!! // 404 page must be placed at the end !!!

View File

@ -45,29 +45,41 @@ service.interceptors.response.use(
const res = response.data const res = response.data
// 50008: Illegal token; 50012: Other clients logged in; 50014: Token expired; // 50008: Illegal token; 50012: Other clients logged in; 50014: Token expired;
if (res.code === 401) { if (res.code === 401) {
MessageBox.confirm('您已退出,您可以停留在本页或者重新登陆.', '确认退出', { if(res.msg.indexOf('No active account')!=-1){
confirmButtonText: '重新登陆', Message({
cancelButtonText: '取消', message: '用户名或密码错误',
type: 'warning' type: 'error',
}).then(() => { duration: 3 * 1000
store.dispatch('user/resetToken').then(() => {
location.reload()
}) })
}) }else{
} MessageBox.confirm('认证失败,请重新登陆.', '确认退出', {
confirmButtonText: '重新登陆',
// if the custom code is not 20000, it is judged as an error. cancelButtonText: '取消',
type: 'warning'
else if ( res.code == 400 || res.code > 401) { }).then(() => {
Message({ store.dispatch('user/resetToken').then(() => {
message: res.msg || '请求出错', location.reload()
type: 'error', })
duration: 5 * 1000 })
}) }
} else if (res.code >= 400) {
var data = JSON.stringify(res.msg)
if(data.indexOf('无法使用提供的认证信息登录')!=-1){
Message({
message: '用户名或密码错误',
type: 'error',
duration: 3 * 1000
})
}else{
Message({
message: res.msg || '请求出错',
type: 'error',
duration: 3 * 1000
})
return Promise.reject(new Error(res.msg || '请求出错'))
}
// return Promise.reject(new Error(res.error || '请求出错'))
} else { } else {
return res return res
} }

View File

@ -15,6 +15,7 @@
<div class="bullshit__headline">{{ message }}</div> <div class="bullshit__headline">{{ message }}</div>
<div class="bullshit__info">请检查访问地址,或者点击按钮返回首页.</div> <div class="bullshit__info">请检查访问地址,或者点击按钮返回首页.</div>
<a href="" class="bullshit__return-home">首页</a> <a href="" class="bullshit__return-home">首页</a>
<a class="bullshit__return-home" style="margin-left:2px" @click="goConsumer">学员列表页</a>
</div> </div>
</div> </div>
</div> </div>
@ -28,6 +29,11 @@ export default {
message() { message() {
return '您好像没有该页面的访问权限...' return '您好像没有该页面的访问权限...'
} }
},
methods:{
goConsumer(){
this.$router.push('/crm/consumer')
}
} }
} }
</script> </script>

View File

@ -110,7 +110,7 @@ export default {
if (valid) { if (valid) {
this.loading = true this.loading = true
this.$store.dispatch('user/login', this.loginForm).then(() => { this.$store.dispatch('user/login', this.loginForm).then(() => {
this.$router.push({ path: this.redirect || '/' }) this.$router.push({ path: this.redirect || '/crm/consumer' })
this.loading = false this.loading = false
}).catch(() => { }).catch(() => {
this.loading = false this.loading = false

View File

@ -14,6 +14,9 @@
<el-table-column align="header-center" label="账户"> <el-table-column align="header-center" label="账户">
<template slot-scope="scope">{{ scope.row.username }}</template> <template slot-scope="scope">{{ scope.row.username }}</template>
</el-table-column> </el-table-column>
<el-table-column align="header-center" label="姓名">
<template slot-scope="scope">{{ scope.row.name }}</template>
</el-table-column>
<el-table-column label="创建日期"> <el-table-column label="创建日期">
<template slot-scope="scope"> <template slot-scope="scope">
<span>{{ scope.row.date_joined }}</span> <span>{{ scope.row.date_joined }}</span>
@ -21,12 +24,21 @@
</el-table-column> </el-table-column>
<el-table-column align="center" label="操作"> <el-table-column align="center" label="操作">
<template slot-scope="scope"> <template slot-scope="scope">
<el-button
type="primary"
size="small"
@click="handleUpdate(scope)"
icon="el-icon-edit"
:disabled="!checkPermission(['user_update'])"
v-if="!scope.row.is_superuser"
></el-button>
<el-button <el-button
type="danger" type="danger"
size="small" size="small"
@click="handleDelete(scope)" @click="handleDelete(scope)"
icon="el-icon-delete" icon="el-icon-delete"
:disabled="!checkPermission(['user_delete'])" :disabled="!checkPermission(['user_delete'])"
v-if="!scope.row.is_superuser"
></el-button> ></el-button>
</template> </template>
</el-table-column> </el-table-column>
@ -40,7 +52,7 @@
@pagination="getList" @pagination="getList"
/> />
<el-dialog :visible.sync="dialogVisible" title="新增管理员"> <el-dialog :visible.sync="dialogVisible" :title="dialogType==='update'?'编辑管理员':'新增管理员'">
<el-form <el-form
:model="user" :model="user"
label-width="80px" label-width="80px"
@ -51,8 +63,18 @@
<el-form-item label="账户" prop="username"> <el-form-item label="账户" prop="username">
<el-input v-model="user.username" placeholder="账户" /> <el-input v-model="user.username" placeholder="账户" />
</el-form-item> </el-form-item>
<el-form-item label="密码" prop="password"> <el-form-item label="姓名" prop="name">
<el-input v-model="user.password" placeholder="密码" /> <el-input v-model="user.name" placeholder="姓名" />
</el-form-item>
<el-form-item label="角色" prop="roles">
<el-select v-model="user.roles" multiple placeholder="请选择" style="width:100%">
<el-option
v-for="item in roles"
:key="item.id"
:label="item.name"
:value="item.id"
/>
</el-select>
</el-form-item> </el-form-item>
</el-form> </el-form>
<div style="text-align:right;"> <div style="text-align:right;">
@ -63,7 +85,8 @@
</div> </div>
</template> </template>
<script> <script>
import { getUserList, createUser, deleteUser} from "@/api/user"; import { getUserList, createUser, deleteUser, updateUser} from "@/api/user";
import { getRoles } from "@/api/role"
import checkPermission from "@/utils/permission"; import checkPermission from "@/utils/permission";
import Pagination from "@/components/Pagination"; // secondary package based on el-pagination import Pagination from "@/components/Pagination"; // secondary package based on el-pagination
@ -71,13 +94,14 @@ const defaultUser = {
id: "", id: "",
username: "", username: "",
password: "", password: "",
is_superuser:true is_superuser:false
}; };
export default { export default {
components: { Pagination }, components: { Pagination },
data() { data() {
return { return {
user: defaultUser, user: defaultUser,
roles:[],
userList: [], userList: [],
total: 0, total: 0,
listLoading: true, listLoading: true,
@ -88,21 +112,26 @@ export default {
dialogVisible: false, dialogVisible: false,
rule1: { rule1: {
username: [{ required: true, message: "请输入账号", trigger: "change" }], username: [{ required: true, message: "请输入账号", trigger: "change" }],
password: [
{ required: true, message: "请输入密码", trigger: "change" }
],
}, },
filterOrgText: "", filterOrgText: "",
treeLoding: false, treeLoding: false,
orgData: [] orgData: [],
dialogType:'create',
dialogVisible:false
}; };
}, },
computed: {}, computed: {},
created() { created() {
this.getList(); this.getList();
this.getRoles()
}, },
methods: { methods: {
checkPermission, checkPermission,
getRoles() {
getRoles().then(response => {
this.roles = response.data
});
},
getList() { getList() {
this.listLoading = true; this.listLoading = true;
getUserList(this.listQuery).then(response => { getUserList(this.listQuery).then(response => {
@ -114,10 +143,17 @@ export default {
handleAddUser() { handleAddUser() {
this.user = Object.assign({}, defaultUser); this.user = Object.assign({}, defaultUser);
this.dialogVisible = true; this.dialogVisible = true;
this.dialogType = 'create'
this.$nextTick(() => { this.$nextTick(() => {
this.$refs["userForm"].clearValidate(); this.$refs["userForm"].clearValidate();
}); });
}, },
handleUpdate(scope){
this.user = Object.assign({}, scope.row);
this.dialogVisible = true;
this.dialogType = 'update'
} ,
handleDelete(scope) { handleDelete(scope) {
this.$confirm("确认删除?", "警告", { this.$confirm("确认删除?", "警告", {
confirmButtonText: "确认", confirmButtonText: "确认",
@ -139,18 +175,26 @@ export default {
async confirmUser(form) { async confirmUser(form) {
this.$refs[form].validate(valid => { this.$refs[form].validate(valid => {
if (valid) { if (valid) {
createUser(this.user).then(res => { const isEdit = this.dialogType === "update";
// this.user = res.data if (isEdit) {
// this.userList.unshift(this.user) updateUser(this.user.id, this.user).then(res => {
this.getList(); this.getList();
this.dialogVisible = false; this.dialogVisible = false;
this.$notify({ this.$message({
title: "成功", message: "编辑成功",
message: "新增成功", type: "success",
type: "success", });
duration: 2000
});
}); });
} else {
createUser(this.user).then(res => {
this.getList();
this.dialogVisible = false;
this.$message({
message: "新增成功",
type: "success"
});
});
}
} else { } else {
return false; return false;
} }

View File

@ -0,0 +1,78 @@
<template>
<div class="app-container">
<el-form ref="elForm" :model="formData" :rules="rules" size="medium" label-width="100px">
<el-form-item label="旧密码" prop="old_password">
<el-input v-model="formData.old_password" placeholder="请输入旧密码" clearable show-password
:style="{width: '100%'}"></el-input>
</el-form-item>
<el-form-item label="新密码" prop="new_password1">
<el-input v-model="formData.new_password1" placeholder="请输入新密码" clearable show-password
:style="{width: '100%'}"></el-input>
</el-form-item>
<el-form-item label="新密码" prop="new_password2">
<el-input v-model="formData.new_password2" placeholder="请再次输入新密码" clearable show-password
:style="{width: '100%'}"></el-input>
</el-form-item>
<el-form-item size="large">
<el-button type="primary" @click="submitForm">提交</el-button>
<el-button @click="resetForm">重置</el-button>
</el-form-item>
</el-form>
</div>
</template>
<script>
import { changePassword } from "@/api/user"
export default {
components: {},
props: [],
data() {
return {
formData: {
old_password: undefined,
new_password1: undefined,
new_password2: undefined,
},
rules: {
old_password: [{
required: true,
message: '请输入旧密码',
trigger: 'blur'
}],
new_password1: [{
required: true,
message: '请输入新密码',
trigger: 'blur'
}],
new_password2: [{
required: true,
message: '请再次输入新密码',
trigger: 'blur'
}],
},
}
},
computed: {},
watch: {},
created() {},
mounted() {},
methods: {
submitForm() {
this.$refs['elForm'].validate(valid => {
if (!valid) return
// TODO
changePassword(this.formData).then(async(res)=>{
this.$message({
message: '密码修改成功,请重新登陆',
type: 'success'
})
await this.$store.dispatch('user/logout')
this.$router.push(`/login`)
})
})
},
resetForm() {
this.$refs['elForm'].resetFields()
},
}
}
</script>

View File

@ -169,15 +169,7 @@ export default {
const { desc, name } = this.role const { desc, name } = this.role
this.dialogVisible = false this.dialogVisible = false
this.$notify({ this.$message.success('成功')
title: 'Success',
dangerouslyUseHTMLString: true,
message: `
<div>角色名: ${name}</div>
<div>角色描述: ${desc}</div>
`,
type: 'success'
})
}, },
} }
} }

View File

@ -271,7 +271,7 @@ export default {
computed: {}, computed: {},
created() { created() {
this.getList(); this.getList();
this.getOrgList(); // this.getOrgList();
this.getRoles(); this.getRoles();
}, },
methods: { methods: {
@ -307,13 +307,13 @@ export default {
this.listLoading = false; this.listLoading = false;
}); });
}, },
getOrgList() { // getOrgList() {
this.treeLoding = true; // this.treeLoding = true;
getOrgList().then(response => { // getOrgList().then(response => {
this.orgData = genTree(response.data); // this.orgData = genTree(response.data);
this.treeLoding = false; // this.treeLoding = false;
}); // });
}, // },
getRoles() { getRoles() {
getRoles().then(response => { getRoles().then(response => {
this.roles = genTree(response.data); this.roles = genTree(response.data);

View File

@ -18,8 +18,10 @@ Page({
duration: 1500, duration: 1500,
nowWork:null, nowWork:null,
msgList: [ msgList: [
{ title: "欢迎使用中科辐射学堂!" }, { title: "欢迎使用辐射学堂!" },
{ title: "如有疑问,请致电课程顾问" },] { title: "QQ交流群:1072443859" },
{ title: "如有疑问,请致电课程顾问" },
]
}, },
imgH: function (e) { imgH: function (e) {
let winWid = wx.getSystemInfoSync().windowWidth; //获取当前屏幕的宽度 let winWid = wx.getSystemInfoSync().windowWidth; //获取当前屏幕的宽度

View File

@ -11,7 +11,7 @@
</block> </block>
</swiper> </swiper>
</view> </view>
<swiper class="swiper_container1" vertical="true" autoplay="true" circular="true" interval="3000"> <swiper class="swiper_container1" vertical="true" autoplay="true" circular="true" interval="6000">
<block wx:for="{{msgList}}" wx:key="title"> <block wx:for="{{msgList}}" wx:key="title">
<swiper-item> <swiper-item>
<view class="swiper_item1">{{item.title}}</view> <view class="swiper_item1">{{item.title}}</view>
@ -23,7 +23,7 @@
<view class="weui-cell__hd"> <view class="weui-cell__hd">
<image src="/images/quota.svg" style="margin-right: 16px;vertical-align: middle;width:20px; height: 20px;"></image> <image src="/images/quota.svg" style="margin-right: 16px;vertical-align: middle;width:20px; height: 20px;"></image>
</view> </view>
<view class="weui-cell__bd">考名额监控</view> <view class="weui-cell__bd">考名额监控</view>
<view class="weui-cell__ft weui-cell__ft_in-access" style="color:red"> <view class="weui-cell__ft weui-cell__ft_in-access" style="color:red">
<!-- <span wx:if="{{to_read}}">{{to_read}}条未读</span> --> <!-- <span wx:if="{{to_read}}">{{to_read}}条未读</span> -->
</view> </view>
@ -32,7 +32,7 @@
<view class="weui-cell__hd"> <view class="weui-cell__hd">
<image src="/images/candidate.svg" style="margin-right: 16px;vertical-align: middle;width:20px; height: 20px;"></image> <image src="/images/candidate.svg" style="margin-right: 16px;vertical-align: middle;width:20px; height: 20px;"></image>
</view> </view>
<view class="weui-cell__bd">证书查询</view> <view class="weui-cell__bd">成绩报告单查询</view>
<view class="weui-cell__ft weui-cell__ft_in-access" style="color:red"> <view class="weui-cell__ft weui-cell__ft_in-access" style="color:red">
<!-- <span wx:if="{{to_read}}">{{to_read}}条未读</span> --> <!-- <span wx:if="{{to_read}}">{{to_read}}条未读</span> -->
</view> </view>

View File

@ -18,15 +18,15 @@
"checkInvalidKey": true, "checkInvalidKey": true,
"checkSiteMap": true, "checkSiteMap": true,
"uploadWithSourceMap": true, "uploadWithSourceMap": true,
"compileHotReLoad": false,
"babelSetting": { "babelSetting": {
"ignore": [], "ignore": [],
"disablePlugins": [], "disablePlugins": [],
"outputPath": "" "outputPath": ""
}, },
"useIsolateContext": true, "useCompilerModule": false,
"useCompilerModule": true, "userConfirmedUseCompilerModuleSwitch": false,
"userConfirmedUseCompilerModuleSwitch": false "compileHotReLoad": false,
"useIsolateContext": true
}, },
"compileType": "miniprogram", "compileType": "miniprogram",
"libVersion": "2.10.3", "libVersion": "2.10.3",

View File

@ -0,0 +1,21 @@
# Generated by Django 3.0.4 on 2020-08-10 03:51
from django.conf import settings
from django.db import migrations, models
import django.db.models.deletion
class Migration(migrations.Migration):
dependencies = [
migrations.swappable_dependency(settings.AUTH_USER_MODEL),
('crm', '0019_auto_20200802_0931'),
]
operations = [
migrations.AddField(
model_name='consumer',
name='create_admin',
field=models.ForeignKey(default=1, on_delete=django.db.models.deletion.DO_NOTHING, to=settings.AUTH_USER_MODEL),
),
]

View File

@ -1,6 +1,6 @@
from django.db import models from django.db import models
import django.utils.timezone as timezone import django.utils.timezone as timezone
from rbac.models import SoftCommonModel, CommonModel from rbac.models import SoftCommonModel, CommonModel, UserProfile
from question.models import Questioncat, Question from question.models import Questioncat, Question
from examtest.models_paper import WorkScope from examtest.models_paper import WorkScope
from django.contrib.postgres.fields import JSONField from django.contrib.postgres.fields import JSONField
@ -71,6 +71,8 @@ class Consumer(CommonModel):
ID_number = models.CharField('身份证号', max_length=100, null=True, blank=True) ID_number = models.CharField('身份证号', max_length=100, null=True, blank=True)
realname = models.CharField('真实姓名', max_length=100, null=True, blank=True) realname = models.CharField('真实姓名', max_length=100, null=True, blank=True)
create_admin = models.ForeignKey(UserProfile, default=1, on_delete=models.DO_NOTHING)
class Meta: class Meta:
verbose_name = '客户' verbose_name = '客户'

View File

@ -123,7 +123,9 @@ class ConsumerViewSet(ModelViewSet):
def get_queryset(self): def get_queryset(self):
queryset = self.queryset queryset = self.queryset
queryset = self.get_serializer_class().setup_eager_loading(queryset) queryset = self.get_serializer_class().setup_eager_loading(queryset)
if not self.request.user.is_superuser:
queryset = queryset.filter(create_admin = self.request.user)
return queryset return queryset
def create(self, request, *args, **kwargs): def create(self, request, *args, **kwargs):

View File

@ -219,7 +219,7 @@ class ExamTestViewSet(ModelViewSet):
""" """
考试记录列表和详情 考试记录列表和详情
""" """
perms_map = [{'get': 'examtest_list'},{'post': '*'}] perms_map = [{'get': 'examtest_view'},{'post': '*'}]
pagination_class = CommonPagination pagination_class = CommonPagination
queryset = ExamTest.objects.filter(is_delete=0).all() queryset = ExamTest.objects.filter(is_delete=0).all()
serializer_class = ExamTestListSerializer serializer_class = ExamTestListSerializer
@ -244,6 +244,8 @@ class ExamTestViewSet(ModelViewSet):
queryset = queryset.filter(start_time__gte=self.request.query_params['start'] ) queryset = queryset.filter(start_time__gte=self.request.query_params['start'] )
if self.request.query_params.get('end'): if self.request.query_params.get('end'):
queryset = queryset.filter(start_time__lte=self.request.query_params['end']) queryset = queryset.filter(start_time__lte=self.request.query_params['end'])
if not self.request.user.is_superuser:
queryset = queryset.filter(consumer__create_admin = self.request.user)
return queryset return queryset
@action(methods=['get'], detail=False,url_path='self', url_name='selftest', perms_map = [{'*':'my_examtest'}]) @action(methods=['get'], detail=False,url_path='self', url_name='selftest', perms_map = [{'*':'my_examtest'}])
def selftest(self, request, pk=None): def selftest(self, request, pk=None):

View File

@ -65,13 +65,13 @@ class UserViewSet(ModelViewSet):
""" """
perms_map = ({'get': 'user_list'}, {'post': 'user_create'}, {'put': 'user_update'}, perms_map = ({'get': 'user_list'}, {'post': 'user_create'}, {'put': 'user_update'},
{'delete': 'user_delete'}) {'delete': 'user_delete'})
queryset = UserProfile.objects.filter(is_delete=0).all().order_by('-id') queryset = UserProfile.objects.filter(is_delete=0).all()
serializer_class = UserListSerializer serializer_class = UserListSerializer
pagination_class = CommonPagination pagination_class = CommonPagination
# filter_backends = (DjangoFilterBackend, SearchFilter, OrderingFilter) # filter_backends = (DjangoFilterBackend, SearchFilter, OrderingFilter)
filter_fields = ('is_active',) filter_fields = ('is_active',)
# search_fields = ('username', 'name', 'mobile', 'email') # search_fields = ('username', 'name', 'mobile', 'email')
ordering_fields = ('-id',) ordering_fields = ('id',)
# authentication_classes = (JSONWebTokenAuthentication,) # authentication_classes = (JSONWebTokenAuthentication,)
# permission_classes = (RbacPermission,IsAuthenticated) # permission_classes = (RbacPermission,IsAuthenticated)
@ -107,38 +107,30 @@ class UserViewSet(ModelViewSet):
if password: if password:
request.data['password'] = make_password(password) request.data['password'] = make_password(password)
else: else:
request.data['password'] = make_password('0000') request.data['password'] = make_password('fs0000')
serializer = self.get_serializer(data=request.data) serializer = self.get_serializer(data=request.data)
serializer.is_valid(raise_exception=True) serializer.is_valid(raise_exception=True)
self.perform_create(serializer) self.perform_create(serializer)
headers = self.get_success_headers(serializer.data) headers = self.get_success_headers(serializer.data)
return Response(serializer.data, headers=headers) return Response(serializer.data, headers=headers)
@action(methods=['post'], detail=True, permission_classes=[IsAuthenticated], @action(methods=['put'], detail=False, permission_classes=[IsAuthenticated], # perms_map={'put':'change_password'}
url_path='change_passwd', url_name='change_passwd') url_name='change_password')
def set_password(self, request, pk=None): def password(self, request, pk=None):
perms = UserInfoView.get_permission_from_role(request) """
user = UserProfile.objects.get(id=pk) 修改密码
if 'admin' in perms or 'user_all' in perms or request.user.is_superuser: """
user = request.user
old_password = request.data['old_password']
if check_password(old_password, user.password):
new_password1 = request.data['new_password1'] new_password1 = request.data['new_password1']
new_password2 = request.data['new_password2'] new_password2 = request.data['new_password2']
if new_password1 == new_password2: if new_password1 == new_password2:
user.set_password(new_password2) user.set_password(new_password2)
user.save() user.save()
return Response({"detail": '密码修改成功!'}) return Response('密码修改成功!')
else: else:
return Response({"error": '新密码两次输入不一致!'}) return Response({'error': '新密码两次输入不一致!'})
else: else:
old_password = request.data['old_password'] return Response({'error':'旧密码错误!'})
if check_password(old_password, user.password):
new_password1 = request.data['new_password1']
new_password2 = request.data['new_password2']
if new_password1 == new_password2:
user.set_password(new_password2)
user.save()
return Response({"error": '密码修改成功!'})
else:
return Response({"error": '新密码两次输入不一致!'})
else:
return Response({"error": '旧密码错误!'})

View File

@ -45,7 +45,7 @@ class FitJSONRenderer(JSONRenderer):
response = renderer_context.get("response") response = renderer_context.get("response")
response_body.code = response.status_code response_body.code = response.status_code
if response_body.code >= 400: # drf异常 if response_body.code >= 400: # drf异常
response_body.msg = response.data response_body.msg = data['detail'] if 'detail' in data else data
elif data and 'error' in data and data['error']:# 自传异常,key为error elif data and 'error' in data and data['error']:# 自传异常,key为error
response_body.code = data.get("code",400) response_body.code = data.get("code",400)
response_body.msg = data.get("error", "") response_body.msg = data.get("error", "")