冲突修改
|
|
@ -2,7 +2,6 @@
|
|||
.vscode/
|
||||
.vs/
|
||||
venv/
|
||||
media/
|
||||
__pycache__/
|
||||
*.pyc
|
||||
|
||||
|
|
|
|||
|
After Width: | Height: | Size: 226 KiB |
|
|
@ -2,13 +2,7 @@
|
|||
ENV = 'development'
|
||||
|
||||
# base api
|
||||
VUE_APP_BASE_API = 'http://localhost:8000'
|
||||
|
||||
# vue-cli uses the VUE_CLI_BABEL_TRANSPILE_MODULES environment variable,
|
||||
# to control whether the babel-plugin-dynamic-import-node plugin is enabled.
|
||||
# It only does one thing by converting all import() to require().
|
||||
# This configuration can significantly increase the speed of hot updates,
|
||||
# when you have a large number of pages.
|
||||
# Detail: https://github.com/vuejs/vue-cli/blob/dev/packages/@vue/babel-preset-app/index.js
|
||||
#VUE_APP_BASE_API = 'http://localhost:8000'
|
||||
VUE_APP_BASE_API = 'https://qw.ctc-zc.com/api'
|
||||
|
||||
VUE_CLI_BABEL_TRANSPILE_MODULES = true
|
||||
|
|
|
|||
|
|
@ -3,4 +3,4 @@ ENV = 'production'
|
|||
|
||||
# base api
|
||||
# VUE_APP_BASE_API = '/prod-api'
|
||||
VUE_APP_BASE_API = 'https://apitest.ahctc.cn'
|
||||
VUE_APP_BASE_API = 'https://qw.ctc-zc.com/api'
|
||||
|
|
|
|||
|
|
@ -5,8 +5,8 @@
|
|||
"author": "Pan <panfree23@gmail.com>",
|
||||
"license": "MIT",
|
||||
"scripts": {
|
||||
"dev": "vue-cli-service serve",
|
||||
"build:prod": "vue-cli-service build",
|
||||
"dev": "set NODE_OPTIONS=--openssl-legacy-provider && vue-cli-service serve",
|
||||
"build:prod": "set NODE_OPTIONS=--openssl-legacy-provider && vue-cli-service build",
|
||||
"build:stage": "vue-cli-service build --mode staging",
|
||||
"preview": "node build/index.js --preview",
|
||||
"lint": "eslint --ext .js,.vue src",
|
||||
|
|
@ -49,9 +49,9 @@
|
|||
"eslint-plugin-vue": "5.2.2",
|
||||
"html-webpack-plugin": "3.2.0",
|
||||
"mockjs": "1.0.1-beta3",
|
||||
"node-sass": "^4.14.1",
|
||||
"sass": "^1.26.5",
|
||||
"runjs": "^4.3.2",
|
||||
"sass-loader": "^7.1.0",
|
||||
"sass-loader": "^8.0",
|
||||
"script-ext-html-webpack-plugin": "2.1.3",
|
||||
"script-loader": "0.7.2",
|
||||
"serve-static": "^1.13.2",
|
||||
|
|
|
|||
|
|
@ -0,0 +1,21 @@
|
|||
const DEFAULT_CONFIG = {
|
||||
//接口地址
|
||||
API_URL: get_api_url(),
|
||||
//name
|
||||
APP_TUTLE:'气味分析',
|
||||
//请求超时
|
||||
TIMEOUT: 30000,
|
||||
}
|
||||
function get_api_url(){
|
||||
if(process.env.ENV === 'development' || (process.env.ENV === 'production' && window.location.host.indexOf('localhost') > -1)){
|
||||
return process.env.VUE_APP_BASE_API
|
||||
}
|
||||
return 'https://' + window.location.host + '/api'
|
||||
}
|
||||
// // 如果生产模式,就合并动态的APP_CONFIG
|
||||
// // public/config.js
|
||||
// if (process.env.NODE_ENV === 'production') {
|
||||
// Object.assign(DEFAULT_CONFIG, APP_CONFIG)
|
||||
// }
|
||||
|
||||
module.exports = DEFAULT_CONFIG
|
||||
|
|
@ -24,7 +24,7 @@ export default {
|
|||
},
|
||||
data() {
|
||||
return {
|
||||
title: '辐射学堂后台管理',
|
||||
title: '小程序后台管理',
|
||||
logo: 'https://wpimg.wallstcn.com/69a1c46c-eb1c-4b46-8bd4-e9e686ef5251.png'
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -311,21 +311,21 @@ export const asyncRoutes = [
|
|||
]
|
||||
},
|
||||
|
||||
{
|
||||
path: '/qtest',
|
||||
component: Layout,
|
||||
redirect: '/qtest/consult',
|
||||
name: 'Qtest',
|
||||
meta: { title: '铅当量检测', icon: '', perms: ['qtest_view']},
|
||||
children: [
|
||||
{
|
||||
path: 'consult',
|
||||
name: 'Consult',
|
||||
component: () => import('@/views/qtest/consult.vue'),
|
||||
meta: { title: '铅当量检测', icon: 'eye-open', perms: ['qtest_view'] }
|
||||
},
|
||||
]
|
||||
},
|
||||
// {
|
||||
// path: '/qtest',
|
||||
// component: Layout,
|
||||
// redirect: '/qtest/consult',
|
||||
// name: 'Qtest',
|
||||
// meta: { title: '铅当量检测', icon: '', perms: ['qtest_view']},
|
||||
// children: [
|
||||
// {
|
||||
// path: 'consult',
|
||||
// name: 'Consult',
|
||||
// component: () => import('@/views/qtest/consult.vue'),
|
||||
// meta: { title: '铅当量检测', icon: 'eye-open', perms: ['qtest_view'] }
|
||||
// },
|
||||
// ]
|
||||
// },
|
||||
{
|
||||
path: '/system',
|
||||
component: Layout,
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
module.exports = {
|
||||
|
||||
title: '中科辐射',
|
||||
title: '小程序',
|
||||
|
||||
/**
|
||||
* @type {boolean} true | false
|
||||
|
|
|
|||
|
|
@ -1,11 +1,12 @@
|
|||
import axios from 'axios'
|
||||
import { MessageBox, Message } from 'element-ui'
|
||||
import store from '@/store'
|
||||
import sysConfig from "@/config";
|
||||
import { getToken } from '@/utils/auth'
|
||||
|
||||
// create an axios instance
|
||||
const service = axios.create({
|
||||
baseURL: process.env.VUE_APP_BASE_API, // url = base url + request url
|
||||
baseURL: sysConfig.API_URL, // url = base url + request url
|
||||
// withCredentials: true, // send cookies when cross-domain requests
|
||||
timeout: 30000, // request timeout
|
||||
})
|
||||
|
|
|
|||
|
|
@ -74,7 +74,10 @@
|
|||
<template slot-scope="scope">{{ scope.row.type }}</template>
|
||||
</el-table-column>
|
||||
<el-table-column align="left" label="用户">
|
||||
<template slot-scope="scope">{{ scope.row.consumer_name }}</template>
|
||||
<template slot-scope="scope">
|
||||
<span v-if="scope.row.consumer_name==''">{{ scope.row.consumer_username }}</span>
|
||||
<span v-else>{{ scope.row.consumer_name }}</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column align="left" label="单位">
|
||||
<template slot-scope="scope">{{ scope.row.consumer_company_name }}</template>
|
||||
|
|
|
|||
|
|
@ -209,8 +209,12 @@
|
|||
<el-table-column label="单位" sortable="custom" prop="company">
|
||||
<template
|
||||
slot-scope="scope"
|
||||
v-if="scope.row.company_name != null"
|
||||
>{{ scope.row.company_name }}</template>
|
||||
>
|
||||
<span v-if="scope.row.company_name">{{ scope.row.company_name }}</span>
|
||||
<span v-else>
|
||||
<span v-if="scope.row.companyname">{{ scope.row.companyname }}</span>
|
||||
</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="工作类别" sortable="custom" prop="workscope">
|
||||
<template slot-scope="scope">
|
||||
|
|
@ -297,6 +301,9 @@
|
|||
<el-button slot="append" icon="el-icon-search" @click="choose()"></el-button>
|
||||
</el-input>
|
||||
</el-form-item>
|
||||
<el-form-item label="单位(自填)" prop="companyname">
|
||||
<el-input v-model="consumer.companyname" placeholder="单位" />
|
||||
</el-form-item>
|
||||
<el-form-item label="缴费学科" prop="subjects">
|
||||
<el-select v-model="consumer.subjects" placeholder="缴费学科" style="width:100%" multiple>
|
||||
<el-option
|
||||
|
|
|
|||
|
|
@ -126,7 +126,16 @@
|
|||
<el-form-item label="监考人联系方式" prop="proctor_phone" label-width="120px">
|
||||
<el-input v-model="exam.proctor_phone" placeholder="监考人联系方式" />
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item label="选定试卷" prop="paper" >
|
||||
<el-select v-model="exam.paper" placeholder="可指定试卷" style="width:100%" clearable>
|
||||
<el-option
|
||||
v-for="item in paperOptions"
|
||||
:key="item.id"
|
||||
:label="item.name"
|
||||
:value="item.id"
|
||||
></el-option>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item label="培训名称" prop="train_name">
|
||||
<el-input v-model="exam.train_name" placeholder="培训名称" />
|
||||
</el-form-item>
|
||||
|
|
@ -159,7 +168,7 @@
|
|||
|
||||
<script>
|
||||
import { getexamlist, createexam, deleteexam, updateexam} from "@/api/exam";
|
||||
import { getWorkScopeAll } from "@/api/examtest"
|
||||
import { getWorkScopeAll, getPaperList } from "@/api/examtest"
|
||||
import { deepClone } from "@/utils";
|
||||
import checkPermission from "@/utils/permission";
|
||||
import Pagination from "@/components/Pagination"
|
||||
|
|
@ -194,6 +203,7 @@ export default {
|
|||
dialogVisible: false,
|
||||
dialogType: "new",
|
||||
workscopeOptions:[],
|
||||
paperOptions:[],
|
||||
rule1: {
|
||||
name: [{ required: true, message: "请输入", trigger: "blur" }],
|
||||
place: [{ required: true, message: "请输入", trigger: "change" }],
|
||||
|
|
@ -210,6 +220,7 @@ export default {
|
|||
created() {
|
||||
this.getList();
|
||||
this.getworkscopeOptions();
|
||||
this.getPaperOptions();
|
||||
},
|
||||
methods: {
|
||||
checkPermission,
|
||||
|
|
@ -218,6 +229,11 @@ export default {
|
|||
this.workscopeOptions = res.data
|
||||
})
|
||||
},
|
||||
getPaperOptions(){
|
||||
getPaperList({pageoff:true}).then(res=>{
|
||||
this.paperOptions = res.data
|
||||
})
|
||||
},
|
||||
getList() {
|
||||
this.listLoading = true
|
||||
getexamlist(this.listQuery).then(response => {
|
||||
|
|
|
|||
|
|
@ -12,7 +12,7 @@
|
|||
<!-- <img class="logo" src="../../assets/logo.png" /> -->
|
||||
</div>
|
||||
<div class="title-container">
|
||||
<h3 class="title">辐射学堂后台管理</h3>
|
||||
<h3 class="title">小程序后台管理</h3>
|
||||
</div>
|
||||
<el-form-item prop="username">
|
||||
<span class="svg-container">
|
||||
|
|
|
|||
|
|
@ -43,15 +43,16 @@
|
|||
<span v-else>{{ scope.row.name }}</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="类型">
|
||||
<el-table-column label="资源类型">
|
||||
<template slot-scope="scope">{{ scope.row.type }}</template>
|
||||
</el-table-column>
|
||||
<el-table-column align="header-center" label="排序码">
|
||||
<template slot-scope="scope">{{ scope.row.sort }}</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="上传时间">
|
||||
<template slot-scope="scope">{{ scope.row.create_time }}</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="分类" prop="cate"></el-table-column>
|
||||
<el-table-column align="header-center" label="排序码">
|
||||
<template slot-scope="scope">{{ scope.row.sort }}</template>
|
||||
</el-table-column>
|
||||
<el-table-column align="header-center" label="下载量/播放量">
|
||||
<template slot-scope="scope">{{ scope.row.down_count }}</template>
|
||||
</el-table-column>
|
||||
|
|
@ -99,6 +100,22 @@
|
|||
<el-form-item label="描述" prop="description">
|
||||
<el-input v-model="material.description" placeholder="描述" />
|
||||
</el-form-item>
|
||||
<el-form-item label="分类" prop="cate">
|
||||
<el-select
|
||||
v-model="material.cate"
|
||||
placeholder="所属分类"
|
||||
clearable
|
||||
style="width: 200px"
|
||||
class="filter-item"
|
||||
>
|
||||
<el-option
|
||||
v-for="item in cateData"
|
||||
:key="item"
|
||||
:label="item"
|
||||
:value="item"
|
||||
/>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item label="排序" prop="description">
|
||||
<el-input-number v-model="material.sort" :min="1"></el-input-number>
|
||||
</el-form-item>
|
||||
|
|
@ -210,6 +227,7 @@ const defaultmaterial = {
|
|||
path: null,
|
||||
poster: null,
|
||||
type: "文档",
|
||||
cate:null,
|
||||
};
|
||||
export default {
|
||||
components: { Pagination },
|
||||
|
|
@ -224,11 +242,13 @@ export default {
|
|||
page: 1,
|
||||
limit: 20,
|
||||
},
|
||||
cateData:['标准文件','文献','指南'],
|
||||
dialogVisible: false,
|
||||
dialogType: "create",
|
||||
rule1: {
|
||||
name: [{ required: true, message: "请输入姓名", trigger: "blur" }],
|
||||
path: [{ required: true, message: "请上传文件", trigger: "blur" }],
|
||||
cate: [{ required: true, message: "请选择文件分类", trigger: "blur" }],
|
||||
},
|
||||
fileList: [],
|
||||
videoFlag:false,
|
||||
|
|
|
|||
|
|
@ -32,11 +32,17 @@ module.exports = {
|
|||
devServer: {
|
||||
port: port,
|
||||
open: true,
|
||||
overlay: {
|
||||
warnings: false,
|
||||
errors: true
|
||||
},
|
||||
before: require('./mock/mock-server.js')
|
||||
proxy: {
|
||||
'/api': {
|
||||
target: process.env.VUE_APP_BASE_API,
|
||||
ws: true,
|
||||
changeOrigin:true,
|
||||
pathRewrite: {
|
||||
'^/api': '/'
|
||||
}
|
||||
}
|
||||
},
|
||||
// before: require('./mock/mock-server.js')
|
||||
},
|
||||
configureWebpack: {
|
||||
// provide the app's title in webpack's name field, so that
|
||||
|
|
|
|||
|
|
@ -71,9 +71,9 @@ App({
|
|||
globalData: {
|
||||
userInfo: {},
|
||||
userinfo: {}, // 服务器传回的消费者信息
|
||||
host: 'https://apitest.ahctc.cn',
|
||||
// host: 'https://apitest.ahctc.cn',
|
||||
mediahost: 'https://apitest.ahctc.cn',
|
||||
// host: 'http://127.0.0.1:8000',
|
||||
host: 'http://127.0.0.1:8000',
|
||||
//mediahost: 'http://127.0.0.1:8000',
|
||||
token : '',
|
||||
rlogin:true
|
||||
|
|
|
|||
|
|
@ -0,0 +1,10 @@
|
|||
.vscode/
|
||||
.vs/
|
||||
venv/
|
||||
!media/default/*
|
||||
!media/muban/*
|
||||
__pycache__/
|
||||
*.pyc
|
||||
server/conf*.py
|
||||
dist/*
|
||||
log/*
|
||||
|
|
@ -23,18 +23,22 @@ class BasicCount(APIView):
|
|||
ret={}
|
||||
q1 = Consumer.objects.filter(is_delete=False)
|
||||
q1 = q1.filter(create_time__gte = request.query_params.get('datestart')) if request.query_params.get('datestart', None) else q1
|
||||
q1 = q1.filter(create_time__lte = request.query_params.get('dateend')) if request.query_params.get('dateend', None) else q1
|
||||
ret['consumer1_count'] = q1.count()
|
||||
|
||||
q2 = Consumer.objects.filter(is_delete=False).exclude(create_admin=None)
|
||||
q2 = q2.filter(create_time__gte = request.query_params.get('datestart')) if request.query_params.get('datestart', None) else q2
|
||||
q2 = q2.filter(create_time__lte = request.query_params.get('dateend')) if request.query_params.get('dateend', None) else q2
|
||||
ret['consumer2_count'] = q2.count()
|
||||
|
||||
q3 = ExamTest.objects.filter(is_delete=False)
|
||||
q3 = q3.filter(create_time__gte = request.query_params.get('datestart')) if request.query_params.get('datestart', None) else q3
|
||||
q3 = q3.filter(create_time__lte = request.query_params.get('dateend')) if request.query_params.get('dateend', None) else q3
|
||||
ret['test_count'] = q3.count()
|
||||
|
||||
q4 = Question.objects.filter(is_delete=False)
|
||||
q4 = q4.filter(create_time__gte = request.query_params.get('datestart')) if request.query_params.get('datestart', None) else q4
|
||||
# q4 = q4.filter(create_time__gte = request.query_params.get('datestart')) if request.query_params.get('datestart', None) else q4
|
||||
# q4 = q4.filter(create_time__lte = request.query_params.get('dateend')) if request.query_params.get('dateend', None) else q4
|
||||
ret['question_count'] = q4.count()
|
||||
return Response(ret)
|
||||
|
||||
|
|
|
|||
|
|
@ -0,0 +1,18 @@
|
|||
# Generated by Django 3.0.4 on 2023-05-05 02:53
|
||||
|
||||
from django.db import migrations, models
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('cms', '0008_material_sort'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AddField(
|
||||
model_name='material',
|
||||
name='cate',
|
||||
field=models.CharField(default='未分类', max_length=50, verbose_name='分类'),
|
||||
),
|
||||
]
|
||||
|
|
@ -35,6 +35,7 @@ class Material(CommonModel):
|
|||
description = models.TextField('描述', null=True, blank=True)
|
||||
path = models.CharField(max_length=1000, verbose_name='文件地址')
|
||||
poster = models.CharField(max_length=10000, verbose_name='封面地址', null=True, blank=True)
|
||||
cate = models.CharField('分类', max_length=50, default='未分类')
|
||||
type = models.CharField('格式', default='文档', max_length=50)
|
||||
down_count = models.IntegerField('阅读量', default=0)
|
||||
sort = models.IntegerField('排序码', default=1)
|
||||
|
|
|
|||
|
|
@ -69,7 +69,7 @@ class MaterialViewSet(ModelViewSet):
|
|||
search_fields = ['name','description']
|
||||
ordering_fields = ['update_time', 'down_count']
|
||||
ordering = ['sort', '-down_count']
|
||||
filterset_fields = ['type', 'name']
|
||||
filterset_fields = ['type', 'name', 'cate']
|
||||
|
||||
@action(methods=['get'], detail=True, url_name='down_material', perms_map=[{'*':'down_material'}])
|
||||
def down(self, request, *args, **kwargs):
|
||||
|
|
|
|||
|
|
@ -14,11 +14,11 @@ def export_consumer(users):
|
|||
wb = Workbook()
|
||||
ws1 = wb.active
|
||||
ws1.title = '用户表'
|
||||
ws1.append(['姓名','手机号', '单位', '身份证号', '微信昵称', '工作类别', '用户角色', '创建日期', '所属账户'])
|
||||
ws1.append(['姓名','手机号', '单位', '单位自填', '身份证号', '微信昵称', '工作类别', '用户角色', '创建日期', '所属账户'])
|
||||
row = ws1.row_dimensions[1]
|
||||
row.font = Font(bold=True)
|
||||
for i in users:
|
||||
ws1.append([i['name'], i['username'], i['company_name'], i['ID_number1'], i['nickname'], i['workscope_name'], i['role_name'], i['create_time'], i['create_admin_name']])
|
||||
ws1.append([i['name'], i['username'], i['company_name'], i['companyname'], i['ID_number1'], i['nickname'], i['workscope_name'], i['role_name'], i['create_time'], i['create_admin_name']])
|
||||
filename = 'users' + datetime.now().strftime("%Y%m%d%H%M%S") +'.xlsx'
|
||||
path = '/media/export/' + filename
|
||||
wb.save((BASE_DIR + path).replace('\\', '/'))
|
||||
|
|
|
|||
|
|
@ -0,0 +1,25 @@
|
|||
# Generated by Django 3.0.4 on 2023-03-30 06:02
|
||||
|
||||
from django.db import migrations, models
|
||||
import django.db.models.deletion
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('examtest', '0037_exam_paper'),
|
||||
('crm', '0044_auto_20220528_2332'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AlterField(
|
||||
model_name='candidate',
|
||||
name='examtest',
|
||||
field=models.OneToOneField(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, to='examtest.ExamTest', verbose_name='关联考试'),
|
||||
),
|
||||
migrations.AlterField(
|
||||
model_name='candidate',
|
||||
name='workscope',
|
||||
field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='candidate_workscope', to='examtest.WorkScope'),
|
||||
),
|
||||
]
|
||||
|
|
@ -0,0 +1,23 @@
|
|||
# Generated by Django 3.0.4 on 2023-04-07 02:12
|
||||
|
||||
from django.db import migrations, models
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('crm', '0045_auto_20230330_1402'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AddField(
|
||||
model_name='consumer',
|
||||
name='companyname',
|
||||
field=models.CharField(blank=True, max_length=60, null=True, verbose_name='单位'),
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name='consumer',
|
||||
name='title',
|
||||
field=models.CharField(blank=True, max_length=100, null=True, verbose_name='职称/职务'),
|
||||
),
|
||||
]
|
||||
|
|
@ -73,6 +73,8 @@ class Consumer(CommonModel):
|
|||
realname = models.CharField('查询真实姓名', max_length=100, null=True, blank=True)
|
||||
|
||||
ID_number1 = models.CharField('身份证号', max_length=100, null=True, blank=True)
|
||||
title = models.CharField('职称/职务', max_length=100, null=True, blank=True)
|
||||
companyname = models.CharField('单位', max_length=60, null=True, blank=True)
|
||||
create_admin = models.ForeignKey(UserProfile, on_delete=models.SET_NULL, null=True, blank=True, related_name='consumer_create_admin')
|
||||
deptname = models.CharField('所在部门', max_length=100, null=True, blank=True)
|
||||
exceed_date = models.DateField('账号过期', null=True, blank=True)
|
||||
|
|
@ -106,8 +108,8 @@ class SendCode(CommonModel):
|
|||
|
||||
class Candidate(CommonModel):
|
||||
consumer = models.ForeignKey(Consumer, on_delete=models.SET_NULL, related_name='candidate_consumer', null=True, blank=True)
|
||||
workscope = models.ForeignKey(WorkScope, on_delete=models.DO_NOTHING, related_name='candidate_workscope', null=True, blank=True)
|
||||
examtest = models.OneToOneField(to='examtest.examtest', verbose_name='关联考试', null=True, blank=True, on_delete=models.DO_NOTHING)
|
||||
workscope = models.ForeignKey(WorkScope, on_delete=models.SET_NULL, related_name='candidate_workscope', null=True, blank=True)
|
||||
examtest = models.OneToOneField(to='examtest.examtest', verbose_name='关联考试', null=True, blank=True, on_delete=models.SET_NULL)
|
||||
is_manual = models.BooleanField('是否手动创建', default=False)
|
||||
|
||||
# 下面是证书信息
|
||||
|
|
|
|||
|
|
@ -29,17 +29,17 @@ def get_consumerperm_list(consumer):
|
|||
if consumer.workscope.can_exam: # 如果是三类考试工作类别不做过期检测
|
||||
pass
|
||||
elif consumer.exceed_date and (consumer.exceed_date < datetime.date(timezone.now())):
|
||||
if consumer.name and consumer.ID_number1:
|
||||
candidates = getZs(consumer.name, consumer.ID_number1)
|
||||
if candidates:
|
||||
perms.append('account_exceed')
|
||||
else:
|
||||
# 未通过考试增加30天期限
|
||||
newdate = datetime.date(timezone.now() + timedelta(days=30))
|
||||
consumer.exceed_date = newdate
|
||||
consumer.save()
|
||||
else:
|
||||
perms.append('account_exceed')
|
||||
# if consumer.name and consumer.ID_number1:
|
||||
# candidates = getZs(consumer.name, consumer.ID_number1)
|
||||
# if candidates:
|
||||
# perms.append('account_exceed')
|
||||
# else:
|
||||
# # 未通过考试增加30天期限
|
||||
# newdate = datetime.date(timezone.now() + timedelta(days=30))
|
||||
# consumer.exceed_date = newdate
|
||||
# consumer.save()
|
||||
# else:
|
||||
perms.append('account_exceed')
|
||||
cache.set('cperms_'+str(consumer.id), perms, 60*60)
|
||||
return perms
|
||||
|
||||
|
|
@ -67,7 +67,7 @@ class MyPermission(RbacPermission):
|
|||
if request.user.exceed_date and (request.user.exceed_date >= datetime.date(timezone.now())):
|
||||
pass
|
||||
else:
|
||||
perms = ['questioncat_view','my_examtest','down_material']
|
||||
perms = ['questioncat_view','my_examtest','down_material', 'account_exceed']
|
||||
if not hasattr(view, 'perms_map'):
|
||||
return True
|
||||
else:
|
||||
|
|
|
|||
|
|
@ -52,6 +52,11 @@ class ConsumerSerializer(serializers.ModelSerializer):
|
|||
queryset = queryset.prefetch_related('subjects',)
|
||||
return queryset
|
||||
|
||||
class ConsumerImproveSerializer(serializers.ModelSerializer):
|
||||
class Meta:
|
||||
model = Consumer
|
||||
fields = ['name', 'ID_number1', 'companyname', 'title']
|
||||
|
||||
class ConsumerDetailSerializer(serializers.ModelSerializer):
|
||||
"""
|
||||
客户详情序列化
|
||||
|
|
|
|||
|
|
@ -29,13 +29,13 @@ from utils.custom import CommonPagination
|
|||
from .filters import ConsumerFilter
|
||||
from .exports import export_consumer
|
||||
from .models import Candidate, Company, Consumer, PaySubject, SendCode, ConsumerPerm, ConsumerRole
|
||||
from .serializers import CandidateCreateSerializer, CandidateSerializer, CompanySerializer, ConsumerSerializer, ConsumerPermSerializer, ConsumerRoleSerializer, ConsumerDetailSerializer, MsgSerializer
|
||||
from .serializers import CandidateCreateSerializer, CandidateSerializer, CompanySerializer, ConsumerSerializer, ConsumerPermSerializer, ConsumerRoleSerializer, ConsumerDetailSerializer, MsgSerializer, ConsumerImproveSerializer
|
||||
from lxml import etree
|
||||
from rbac.models import UserProfile
|
||||
from django.http import Http404
|
||||
from .spider import getZs
|
||||
import time
|
||||
from server.config import *
|
||||
from server.conf import *
|
||||
from .hwmsg import sendMsg
|
||||
|
||||
def my_payload_handler(user, dtype="admin"):
|
||||
|
|
@ -393,6 +393,16 @@ class ConsumerViewSet(ModelViewSet):
|
|||
request.user.save()
|
||||
return Response(status=status.HTTP_200_OK)
|
||||
|
||||
@action(methods=['post'], detail=False, perms_map=[{'*':'*'}], serializer_class=ConsumerImproveSerializer)
|
||||
def improve(self, request):
|
||||
'''
|
||||
完善个人信息
|
||||
'''
|
||||
if isinstance(request.user, Consumer):
|
||||
sr = ConsumerImproveSerializer(instance=request.user, data=request.data)
|
||||
sr.is_valid(raise_exception=True)
|
||||
sr.save()
|
||||
return Response(status=status.HTTP_200_OK)
|
||||
|
||||
@action(methods=['get'], detail=False,
|
||||
url_path='candidate', url_name='consumer_candidate', perms_map=[{'*':'*'}])
|
||||
|
|
@ -612,10 +622,10 @@ class ConsumerRegister(APIView):
|
|||
consumer.nickname = nickname
|
||||
if consumer.role and consumer.role.name == '游客':
|
||||
consumer.role = ConsumerRole.objects.get(name='注册用户')
|
||||
# 默认工作类别是非医学Ⅲ类
|
||||
# 默认一个工作类别
|
||||
if not consumer.workscope:
|
||||
try:
|
||||
consumer.workscope = WorkScope.objects.get(name='非医学Ⅲ类')
|
||||
consumer.workscope = WorkScope.objects.filter(sortnum=0).order_by('id').first()
|
||||
except:
|
||||
pass
|
||||
consumer.save()
|
||||
|
|
@ -628,10 +638,10 @@ class ConsumerRegister(APIView):
|
|||
consumer.nickname = nickname
|
||||
if consumer.role and consumer.role.name == '游客':
|
||||
consumer.role = ConsumerRole.objects.get(name='注册用户')
|
||||
# 默认工作类别是非医学Ⅲ类
|
||||
# 默认一个工作类别
|
||||
if not consumer.workscope:
|
||||
try:
|
||||
consumer.workscope = WorkScope.objects.get(name='非医学Ⅲ类')
|
||||
consumer.workscope = WorkScope.objects.filter(sortnum=0).order_by('id').first()
|
||||
except:
|
||||
pass
|
||||
consumer.save()
|
||||
|
|
@ -661,12 +671,13 @@ class WxphoneRegister(APIView):
|
|||
consumer.save()
|
||||
else:
|
||||
request.user.username = phoneNumber
|
||||
request.user.name = data.get('name', '未知')
|
||||
if request.user.role.name =='游客':
|
||||
request.user.role = ConsumerRole.objects.get(name='注册用户')
|
||||
if not request.user.workscope:
|
||||
request.user.workscope = WorkScope.objects.get(name='非医学Ⅲ类')
|
||||
# if not request.user.workscope:
|
||||
# request.user.workscope = WorkScope.objects.filter(sortnum=1).order_by('id').first()
|
||||
request.user.save()
|
||||
return Response(status=status.HTTP_200_OK)
|
||||
return Response(status=status.HTTP_200_OK, data=ConsumerDetailSerializer(instance=request.user).data)
|
||||
|
||||
class change_remain_count(APIView):
|
||||
perms_map=[{'*':'change_remain_count'}]
|
||||
|
|
@ -721,8 +732,8 @@ class CandidateViewSet(RetrieveModelMixin, ListModelMixin, CreateModelMixin, Upd
|
|||
serializer_class = CandidateSerializer
|
||||
pagination_class = CommonPagination
|
||||
filter_backends = [DjangoFilterBackend,SearchFilter, OrderingFilter]
|
||||
filterset_fields = ['consumer']
|
||||
search_fields = ('number', 'consumer_name', 'workscope_name', 'company_name')
|
||||
filterset_fields = ['consumer', 'create_admin']
|
||||
search_fields = ('number', 'consumer_name', 'workscope_name', 'company_name', 'create_admin__username', 'ID_number')
|
||||
ordering_fields = ('-id', 'update_time')
|
||||
ordering = ['-update_time']
|
||||
|
||||
|
|
@ -749,6 +760,8 @@ class CandidateViewSet(RetrieveModelMixin, ListModelMixin, CreateModelMixin, Upd
|
|||
|
||||
def get_queryset(self):
|
||||
queryset = self.queryset
|
||||
if isinstance(self.request.user, Consumer) and self.request.method == 'GET':
|
||||
return queryset
|
||||
if self.request.user.is_superuser:
|
||||
return queryset
|
||||
roles = self.request.user.roles.values_list('name', flat=True)
|
||||
|
|
|
|||
|
|
@ -0,0 +1,19 @@
|
|||
# Generated by Django 3.0.4 on 2023-03-30 06:02
|
||||
|
||||
from django.db import migrations, models
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('vod', '0002_auto_20220326_2305'),
|
||||
('examtest', '0037_exam_paper'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AlterField(
|
||||
model_name='workscope',
|
||||
name='courses',
|
||||
field=models.ManyToManyField(blank=True, to='vod.Course', verbose_name='所选课程'),
|
||||
),
|
||||
]
|
||||
|
|
@ -37,7 +37,7 @@ class WorkScope(CommonModel):
|
|||
sortnum = models.IntegerField('排序码', default=1)
|
||||
is_public = models.BooleanField('是否公开', default=True)
|
||||
# can_choose = models.BooleanField('客户是否可选择', default=False)
|
||||
courses = models.ManyToManyField(Course, verbose_name='所选课程')
|
||||
courses = models.ManyToManyField(Course, verbose_name='所选课程', blank=True)
|
||||
issue_year = models.PositiveSmallIntegerField('证书有效期', default=5)
|
||||
# can_examself = models.BooleanField('是否可自主考核', default=False)
|
||||
|
||||
|
|
@ -67,6 +67,8 @@ class Paper(SoftCommonModel):
|
|||
|
||||
def __str__(self):
|
||||
return self.name
|
||||
|
||||
|
||||
class PaperQuestions(CommonModel):
|
||||
paper = models.ForeignKey(Paper, on_delete=models.CASCADE, verbose_name='试卷')
|
||||
question = models.ForeignKey(Question, on_delete=models.CASCADE, verbose_name='试题')
|
||||
|
|
|
|||
|
|
@ -260,7 +260,7 @@ class WorkScopeViewSet(ModelViewSet):
|
|||
ret['panduan_score'] = workscope.rule.panduan_score
|
||||
question_queryset = Question.objects.none()
|
||||
questioncats = workscope.questioncat.exclude(name='辐射小知识更新中').order_by('type', 'create_time')
|
||||
if questioncats.count() == 3:
|
||||
if questioncats.count() == 3 and questioncats.filter(name='电离辐射法律法规').exists():
|
||||
import random
|
||||
b2 = random.randint(1,8)
|
||||
b3 = random.randint(1,9-b2)
|
||||
|
|
@ -525,7 +525,7 @@ class ExamTestViewSet(PageOrNot, ModelViewSet):
|
|||
'''
|
||||
个人考试记录
|
||||
'''
|
||||
queryset = ExamTest.objects.filter(consumer=request.user).order_by('-create_time')
|
||||
queryset = self.filter_queryset(ExamTest.objects.filter(consumer=request.user)).order_by('-create_time')
|
||||
pg = CommonPagination()
|
||||
p = pg.paginate_queryset(queryset=queryset,request=request,view=self)
|
||||
serializer = ExamTestListSerializer(instance=p,many=True)
|
||||
|
|
|
|||
|
Before Width: | Height: | Size: 530 KiB |
|
Before Width: | Height: | Size: 468 KiB |
|
Before Width: | Height: | Size: 181 KiB |
|
Before Width: | Height: | Size: 153 KiB |
|
Before Width: | Height: | Size: 181 KiB |
|
Before Width: | Height: | Size: 153 KiB |
|
Before Width: | Height: | Size: 181 KiB |
|
Before Width: | Height: | Size: 940 KiB |
|
Before Width: | Height: | Size: 940 KiB |
|
Before Width: | Height: | Size: 940 KiB |
|
Before Width: | Height: | Size: 940 KiB |
|
Before Width: | Height: | Size: 940 KiB |
|
Before Width: | Height: | Size: 940 KiB |
|
Before Width: | Height: | Size: 940 KiB |
|
Before Width: | Height: | Size: 940 KiB |
|
Before Width: | Height: | Size: 940 KiB |
|
Before Width: | Height: | Size: 940 KiB |
|
Before Width: | Height: | Size: 940 KiB |
|
Before Width: | Height: | Size: 940 KiB |
|
Before Width: | Height: | Size: 940 KiB |
|
Before Width: | Height: | Size: 940 KiB |
|
Before Width: | Height: | Size: 940 KiB |
|
Before Width: | Height: | Size: 1.5 MiB |
|
|
@ -27,7 +27,7 @@ from ..serializers.user_serializer import (UserCreateSerializer,
|
|||
UserInfoListSerializer,
|
||||
UserListSerializer,
|
||||
UserModifySerializer)
|
||||
from server.config import *
|
||||
from server.conf import *
|
||||
from rest_framework_jwt.serializers import jwt_encode_handler
|
||||
from crm.views import my_payload_handler
|
||||
|
||||
|
|
|
|||
|
|
@ -1,5 +0,0 @@
|
|||
appid = 'wxf1e9471c93f05ad6'
|
||||
secret = '4bf7f9bd6c52634586bbe792a1f0a834'
|
||||
sms_appid = '100172'
|
||||
sms_appsecret = '00b8681c-0ce6-41c8-a867-904c1891c78a'
|
||||
sms_url = 'https://sms.zhenzikj.com'
|
||||
|
|
@ -13,7 +13,7 @@ https://docs.djangoproject.com/en/3.0/ref/settings/
|
|||
import os
|
||||
import datetime
|
||||
import sys
|
||||
|
||||
from . import conf
|
||||
# Build paths inside the project like this: os.path.join(BASE_DIR, ...)
|
||||
BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
|
||||
|
||||
|
|
@ -25,7 +25,7 @@ BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
|
|||
SECRET_KEY = '+*j($q+46c*1qre8227=(b$(d@lro0)vllts%l%*8)z5$x#=tx'
|
||||
|
||||
# SECURITY WARNING: don't run with debug turned on in production!
|
||||
DEBUG = False
|
||||
DEBUG = conf.DEBUG
|
||||
|
||||
ALLOWED_HOSTS = ['*']
|
||||
|
||||
|
|
@ -98,20 +98,7 @@ CACHES = {
|
|||
# Database
|
||||
# https://docs.djangoproject.com/en/3.0/ref/settings/#databases
|
||||
|
||||
DATABASES = {
|
||||
'default': {
|
||||
'ENGINE': 'django.db.backends.postgresql',
|
||||
'NAME': 'zkfs',
|
||||
'USER':'ctcuser',
|
||||
'PASSWORD':'zkfs1234',
|
||||
'HOST':'localhost',
|
||||
'PORT':'5432',
|
||||
},
|
||||
# 'default': {
|
||||
# 'ENGINE': 'django.db.backends.sqlite3',
|
||||
# 'NAME': os.path.join(BASE_DIR, 'db.sqlite3'),
|
||||
# }
|
||||
}
|
||||
DATABASES = conf.DATABASES
|
||||
|
||||
|
||||
# Password validation
|
||||
|
|
@ -152,7 +139,7 @@ USE_TZ = True
|
|||
# https://docs.djangoproject.com/en/3.0/howto/static-files/
|
||||
|
||||
STATIC_URL = '/static/'
|
||||
STATIC_ROOT = os.path.join(BASE_DIR,'static')
|
||||
STATIC_ROOT = os.path.join(BASE_DIR, 'dist/static')
|
||||
|
||||
REST_FRAMEWORK = {
|
||||
'DEFAULT_AUTHENTICATION_CLASSES': [
|
||||
|
|
|
|||
|
|
@ -24,21 +24,25 @@ from utils.file import UploadFileView
|
|||
from utils.view import redirect
|
||||
|
||||
urlpatterns = [
|
||||
path('rbac/', include('rbac.urls')),
|
||||
path('vod/', include('vod.urls')),
|
||||
path('develop/', include('develop.urls')),
|
||||
path('crm/', include('crm.urls')),
|
||||
path('question/', include('question.urls')),
|
||||
path('examtest/', include('examtest.urls')),
|
||||
path('cms/', include('cms.urls')),
|
||||
path('analyse/', include('analyse.urls')),
|
||||
path('qtest/', include('qtest.urls')),
|
||||
path('token/', obtain_jwt_token),
|
||||
path('token/refresh/', refresh_jwt_token),
|
||||
path('token/verify/', verify_jwt_token),
|
||||
path('token/remove/', UserLogoutView.as_view()),
|
||||
path('uploadfile/', UploadFileView.as_view()),
|
||||
path('redirect/',redirect),
|
||||
path('admin/', admin.site.urls),
|
||||
path('docs/', include_docs_urls(title="答题平台接口文档",authentication_classes=[], permission_classes=[])),
|
||||
path('api/rbac/', include('rbac.urls')),
|
||||
path('api/vod/', include('vod.urls')),
|
||||
path('api/develop/', include('develop.urls')),
|
||||
path('api/crm/', include('crm.urls')),
|
||||
path('api/question/', include('question.urls')),
|
||||
path('api/examtest/', include('examtest.urls')),
|
||||
path('api/cms/', include('cms.urls')),
|
||||
path('api/analyse/', include('analyse.urls')),
|
||||
path('api/qtest/', include('qtest.urls')),
|
||||
path('api/token/', obtain_jwt_token),
|
||||
path('api/token/refresh/', refresh_jwt_token),
|
||||
path('api/token/verify/', verify_jwt_token),
|
||||
path('api/token/remove/', UserLogoutView.as_view()),
|
||||
path('api/uploadfile/', UploadFileView.as_view()),
|
||||
path('api/redirect/',redirect),
|
||||
|
||||
# django后台
|
||||
path('django/admin/doc/', include('django.contrib.admindocs.urls')),
|
||||
path('django/admin/', admin.site.urls),
|
||||
path('django/api-auth/', include('rest_framework.urls')),
|
||||
path('api/docs/', include_docs_urls(title="答题平台接口文档",authentication_classes=[], permission_classes=[])),
|
||||
]+ static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)+ static(settings.STATIC_URL, document_root=settings.STATIC_ROOT)
|
||||
|
|
|
|||