server banner
|
@ -0,0 +1,28 @@
|
|||
import request from '@/utils/request'
|
||||
|
||||
export function getBannerAll() {
|
||||
return request({
|
||||
url: '/examtest/banner/',
|
||||
method: 'get',
|
||||
})
|
||||
}
|
||||
export function createBanner(data) {
|
||||
return request({
|
||||
url: '/examtest/banner/',
|
||||
method: 'post',
|
||||
data
|
||||
})
|
||||
}
|
||||
export function updateBanner(id, data) {
|
||||
return request({
|
||||
url: `/examtest/banner/${id}/`,
|
||||
method: 'put',
|
||||
data
|
||||
})
|
||||
}
|
||||
export function deleteBanner(id) {
|
||||
return request({
|
||||
url: `/examtest/banner/${id}/`,
|
||||
method: 'delete',
|
||||
})
|
||||
}
|
|
@ -195,6 +195,12 @@ export const asyncRoutes = [
|
|||
name: 'System',
|
||||
meta: { title: '系统管理', icon: 'tree', perms: ['system_manage'] },
|
||||
children: [
|
||||
{
|
||||
path: 'banner',
|
||||
name: 'Banner',
|
||||
component: () => import('@/views/system/banner.vue'),
|
||||
meta: { title: '轮播图', icon: '', perms: ['banner_manage'] }
|
||||
},
|
||||
{
|
||||
path: 'user',
|
||||
name: 'User',
|
||||
|
|
|
@ -0,0 +1,230 @@
|
|||
<template>
|
||||
<div class="app-container">
|
||||
<el-button type="primary" @click="handleAdd" icon="el-icon-plus">新增</el-button>
|
||||
<el-table
|
||||
:data="tableData"
|
||||
style="width: 100%;margin-top:10px;"
|
||||
border
|
||||
fit
|
||||
v-loading="listLoading"
|
||||
highlight-current-row
|
||||
max-height="600"
|
||||
row-key="id"
|
||||
default-expand-all
|
||||
:tree-props="{children: 'children', hasChildren: 'hasChildren'}"
|
||||
|
||||
>
|
||||
<el-table-column type="index" width="50"></el-table-column>
|
||||
<el-table-column label="图片名称">
|
||||
<template slot-scope="scope">{{ scope.row.name }}</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="图片">
|
||||
<template scope="scope">
|
||||
<img :src="scope.row.path" width="160" height="90" />
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="链接">
|
||||
<template slot-scope="scope">
|
||||
<span>{{ scope.row.url }}</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="排序数">
|
||||
<template slot-scope="scope">
|
||||
<span>{{ scope.row.sort }}</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column align="center" label="操作">
|
||||
<template slot-scope="scope">
|
||||
<el-button
|
||||
type="primary"
|
||||
size="small"
|
||||
@click="handleEdit(scope)"
|
||||
icon="el-icon-edit"
|
||||
:disabled="!checkPermission(['banner_update'])"
|
||||
></el-button>
|
||||
<el-button
|
||||
type="danger"
|
||||
size="small"
|
||||
@click="handleDelete(scope)"
|
||||
icon="el-icon-delete"
|
||||
:disabled="!checkPermission(['banner_delete'])"
|
||||
></el-button>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
|
||||
<el-dialog :visible.sync="dialogVisible" :title="dialogType==='edit'?'编辑':'新增'" >
|
||||
<el-form :model="banner" label-width="80px" label-position="right" :rules="rule1" ref="Form">
|
||||
<el-form-item label="名称" prop="name">
|
||||
<el-input v-model="banner.name" placeholder="名称" />
|
||||
</el-form-item>
|
||||
<el-form-item label="链接" prop="url">
|
||||
<el-input v-model="banner.url" placeholder="链接" />
|
||||
</el-form-item>
|
||||
<el-form-item label="排序" prop="sort">
|
||||
<el-input-number v-model="banner.sort" :min="1" :max="4"></el-input-number>
|
||||
</el-form-item>
|
||||
<el-form-item label="图片" prop="path" >
|
||||
<el-upload
|
||||
class="avatar-uploader"
|
||||
:headers="myHeaders"
|
||||
:action="uploadUrl"
|
||||
accept="image/jpeg, image/gif, image/png, image/bmp"
|
||||
:show-file-list="false"
|
||||
:on-success="handleImgSuccess"
|
||||
:before-upload="beforeImgUpload"
|
||||
>
|
||||
<img v-if="banner.path" :src="banner.path" style="width: 80%;height: auto;display: block;"/>
|
||||
<el-button size="small" type="primary" v-else>点击上传</el-button>
|
||||
</el-upload>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
<div style="text-align:right;">
|
||||
<el-button type="danger" @click="dialogVisible=false">取消</el-button>
|
||||
<el-button type="primary" @click="confirmBanner('Form')">确认</el-button>
|
||||
</div>
|
||||
</el-dialog>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { getBannerAll, createBanner, deleteBanner, updateBanner } from "@/api/banner";
|
||||
import { deepClone } from "@/utils";
|
||||
import checkPermission from "@/utils/permission";
|
||||
import { uploadUrl } from "@/api/file";
|
||||
import { getToken } from "@/utils/auth";
|
||||
|
||||
|
||||
|
||||
const defaultBanner = {
|
||||
id: "",
|
||||
name: "",
|
||||
url:"",
|
||||
sort:0,
|
||||
path:""
|
||||
};
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
myHeaders: { Authorization: "JWT " + getToken() },
|
||||
uploadUrl: uploadUrl(),
|
||||
banner: {
|
||||
id: "",
|
||||
name: "",
|
||||
url:"",
|
||||
sort:0,
|
||||
path:""
|
||||
},
|
||||
search:'',
|
||||
tableData: [],
|
||||
bannerData:[],
|
||||
listLoading: true,
|
||||
dialogVisible: false,
|
||||
dialogType: "new",
|
||||
rule1: {
|
||||
name: [{ required: true, message: "请输入名称", trigger: "blur" }],
|
||||
path: [{ required: true, message: "请上传文件", trigger: "blur" }],
|
||||
},
|
||||
fileList:[],
|
||||
};
|
||||
},
|
||||
computed: {},
|
||||
created() {
|
||||
this.getList();
|
||||
},
|
||||
methods: {
|
||||
checkPermission,
|
||||
handleImgSuccess(res, file) {
|
||||
this.banner.path = res.data.path
|
||||
},
|
||||
beforeImgUpload(file) {
|
||||
const isLt2M = file.size / 1024 / 1024 < 0.5;
|
||||
if (!isLt2M) {
|
||||
this.$message.error("上传图片大小不能超过 500KB!");
|
||||
}
|
||||
return isLt2M;
|
||||
},
|
||||
getList() {
|
||||
this.listLoading = true
|
||||
getBannerAll().then(response => {
|
||||
this.tableData = response.data;
|
||||
this.listLoading = false
|
||||
});
|
||||
},
|
||||
resetFilter() {
|
||||
this.getList();
|
||||
},
|
||||
// handleFilter() {
|
||||
// let newData = this.bannerData.filter(data => !this.search || data.name.toLowerCase().includes(this.search.toLowerCase()))
|
||||
// },
|
||||
handleAdd() {
|
||||
this.banner = Object.assign({}, defaultBanner);
|
||||
this.dialogType = "new";
|
||||
this.dialogVisible = true;
|
||||
this.$nextTick(() => {
|
||||
this.$refs["Form"].clearValidate();
|
||||
});
|
||||
},
|
||||
handleEdit(scope) {
|
||||
this.banner = Object.assign({}, scope.row); // copy obj
|
||||
this.dialogType = "edit";
|
||||
this.dialogVisible = true;
|
||||
this.$nextTick(() => {
|
||||
this.$refs["Form"].clearValidate();
|
||||
});
|
||||
},
|
||||
handleDelete(scope) {
|
||||
this.$confirm("确认删除?", "警告", {
|
||||
confirmButtonText: "确认",
|
||||
cancelButtonText: "取消",
|
||||
type: "error"
|
||||
})
|
||||
.then(async () => {
|
||||
await deleteBanner(scope.row.id);
|
||||
this.getList()
|
||||
this.$message({
|
||||
type: "success",
|
||||
message: "成功删除!"
|
||||
});
|
||||
})
|
||||
.catch(err => {
|
||||
// console.error(err);
|
||||
});
|
||||
},
|
||||
async confirmBanner(form) {
|
||||
this.$refs[form].validate(valid => {
|
||||
if (valid) {
|
||||
const isEdit = this.dialogType === "edit";
|
||||
if (isEdit) {
|
||||
updateBanner(this.banner.id, this.banner).then(() => {
|
||||
this.getList();
|
||||
this.dialogVisible = false;
|
||||
this.$notify({
|
||||
title: "成功",
|
||||
message: "编辑成功",
|
||||
type: "success",
|
||||
duration: 2000
|
||||
});
|
||||
});
|
||||
} else {
|
||||
createBanner(this.banner).then(res => {
|
||||
// this.banner = res.data
|
||||
// this.tableData.unshift(this.banner)
|
||||
this.getList();
|
||||
this.dialogVisible = false;
|
||||
this.$notify({
|
||||
title: "成功",
|
||||
message: "新增成功",
|
||||
type: "success",
|
||||
duration: 2000
|
||||
});
|
||||
});
|
||||
}
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
};
|
||||
</script>
|
|
@ -0,0 +1,30 @@
|
|||
# Generated by Django 3.0.4 on 2020-03-29 13:35
|
||||
|
||||
from django.db import migrations, models
|
||||
import django.utils.timezone
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('examtest', '0016_auto_20200325_1610'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.CreateModel(
|
||||
name='Banner',
|
||||
fields=[
|
||||
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
||||
('create_time', models.DateTimeField(default=django.utils.timezone.now, help_text='创建时间', verbose_name='创建时间')),
|
||||
('update_time', models.DateTimeField(auto_now=True, help_text='修改时间', verbose_name='修改时间')),
|
||||
('is_delete', models.BooleanField(default=False, help_text='删除标记', verbose_name='删除标记')),
|
||||
('name', models.CharField(max_length=200, verbose_name='名称')),
|
||||
('path', models.CharField(blank=True, max_length=1000, null=True, verbose_name='图片地址')),
|
||||
('url', models.CharField(blank=True, max_length=1000, null=True, verbose_name='链接地址')),
|
||||
('sort', models.IntegerField(default=1, verbose_name='排序数字')),
|
||||
],
|
||||
options={
|
||||
'abstract': False,
|
||||
},
|
||||
),
|
||||
]
|
|
@ -40,4 +40,11 @@ class AnswerDetail(SoftCommonModel):
|
|||
is_right = models.BooleanField(default=False, verbose_name='是否正确')
|
||||
class Meta:
|
||||
verbose_name = '答题记录'
|
||||
verbose_name_plural = verbose_name
|
||||
verbose_name_plural = verbose_name
|
||||
|
||||
|
||||
class Banner(CommonModel):
|
||||
name = models.CharField(max_length=200, verbose_name='名称')
|
||||
path = models.CharField(max_length=1000, null=True, blank=True, verbose_name='图片地址')
|
||||
url = models.CharField(max_length=1000, null=True, blank=True, verbose_name='链接地址')
|
||||
sort = models.IntegerField(default=1, verbose_name='排序数字')
|
||||
|
|
|
@ -1,11 +1,17 @@
|
|||
from rest_framework import serializers
|
||||
from question.models import Questioncat
|
||||
from crm.models import Consumer
|
||||
from .models import ExamTest, AnswerDetail
|
||||
from .models import ExamTest, AnswerDetail, Banner
|
||||
from .models_paper import TestRule, WorkScope
|
||||
|
||||
|
||||
|
||||
class BannerSerializer(serializers.ModelSerializer):
|
||||
"""
|
||||
轮播图序列化
|
||||
"""
|
||||
class Meta:
|
||||
model = Banner
|
||||
fields = ('id','name','path', 'url', 'sort')
|
||||
class TestRuleSerializer(serializers.ModelSerializer):
|
||||
"""
|
||||
规则序列化
|
||||
|
|
|
@ -1,11 +1,12 @@
|
|||
from django.urls import path,include
|
||||
from .views import TestRuleViewSet, MoniTestView, MyExamTestView, AnswerDetailView, MyExamTestFxView, WorkScopeViewSet
|
||||
from .views import TestRuleViewSet, MoniTestView, MyExamTestView, AnswerDetailView, MyExamTestFxView, WorkScopeViewSet, BannerViewSet
|
||||
from rest_framework import routers
|
||||
|
||||
|
||||
router = routers.DefaultRouter()
|
||||
router.register('testrule', TestRuleViewSet, basename="testrule")
|
||||
router.register('workscope', WorkScopeViewSet, basename="workscope")
|
||||
router.register('banner', BannerViewSet, basename='banner')
|
||||
|
||||
urlpatterns = [
|
||||
path('monitest/',MoniTestView.as_view()),
|
||||
|
|
|
@ -16,9 +16,9 @@ from utils.custom import CommonPagination
|
|||
from rbac.permission import RbacPermission
|
||||
from question.models import Question
|
||||
from question.serializers import QuestionSerializer
|
||||
from .models import ExamTest, AnswerDetail
|
||||
from .models import ExamTest, AnswerDetail, Banner
|
||||
from .models_paper import TestRule, WorkScope
|
||||
from .serializers import TestRuleSerializer, MoniTestSerializer, AnswerDetailSerializer, ExamTestListSerializer, AnswerDetailCreateSerializer, WorkScopeSerializer
|
||||
from .serializers import TestRuleSerializer, MoniTestSerializer, AnswerDetailSerializer, ExamTestListSerializer, AnswerDetailCreateSerializer, WorkScopeSerializer, BannerSerializer
|
||||
from server import settings
|
||||
from crm.authentication import ConsumerTokenAuthentication
|
||||
from utils.custom import CommonPagination
|
||||
|
@ -163,6 +163,35 @@ class WorkScopeViewSet(ModelViewSet):
|
|||
return Response(ret)
|
||||
|
||||
|
||||
class BannerViewSet(ModelViewSet):
|
||||
"""
|
||||
轮播图:增删改查
|
||||
"""
|
||||
perms_map = (
|
||||
{'*': 'admin'}, {'*': 'Banner_all'}, {'get': 'Banner_list'}, {'post': 'Banner_create'},
|
||||
{'put': 'Banner_update'}, {'delete': 'Banner_delete'})
|
||||
pagination_class = None
|
||||
queryset = Banner.objects.filter(is_delete=0).all().order_by("sort")
|
||||
serializer_class = BannerSerializer
|
||||
ordering_fields = ('id', 'sort')
|
||||
ordering = ['sort']
|
||||
|
||||
def get_authenticators(self):
|
||||
"""
|
||||
GET请求不做登陆验证
|
||||
"""
|
||||
if self.request.method == 'GET':
|
||||
self.authentication_classes = []
|
||||
return [auth() for auth in self.authentication_classes]
|
||||
|
||||
def get_permissions(self):
|
||||
"""
|
||||
GET请求不做权限验证
|
||||
"""
|
||||
if self.request.method == 'GET':
|
||||
self.permission_classes = []
|
||||
return [permission() for permission in self.permission_classes]
|
||||
|
||||
class TestRuleViewSet(ModelViewSet):
|
||||
"""
|
||||
模考规则:增删改查
|
||||
|
|
After Width: | Height: | Size: 161 KiB |
After Width: | Height: | Size: 161 KiB |
After Width: | Height: | Size: 161 KiB |
After Width: | Height: | Size: 20 KiB |
After Width: | Height: | Size: 161 KiB |
After Width: | Height: | Size: 3.6 KiB |
After Width: | Height: | Size: 161 KiB |
After Width: | Height: | Size: 3.6 KiB |
After Width: | Height: | Size: 3.6 KiB |
After Width: | Height: | Size: 161 KiB |
After Width: | Height: | Size: 3.6 KiB |
After Width: | Height: | Size: 3.6 KiB |
After Width: | Height: | Size: 161 KiB |
After Width: | Height: | Size: 161 KiB |
After Width: | Height: | Size: 20 KiB |