This commit is contained in:
caoqianming 2020-09-02 11:12:51 +08:00
parent 328ea10969
commit 2a6fe56ed1
42 changed files with 2187 additions and 548 deletions

BIN
client/quota.dat Normal file

Binary file not shown.

View File

@ -6,19 +6,7 @@
<style type="text/css"> <style type="text/css">
.el-table--medium td,   .el-table--medium th {
padding: 2px 0;
}
.el-form-item {
margin-bottom: 16px;
}
.el-card__body {
padding: 10px;
}
.el-card__header {
padding: 10px;
}
</style> </style>
<script> <script>
export default { export default {

View File

@ -8,6 +8,15 @@ export function getEmployeeList(query) {
}) })
} }
export function getEmployeeMList(query) {
//配置审核组用
return request({
url: '/employee/employee/team/',
method: 'get',
params: query
})
}
export function createEmployee(data) { export function createEmployee(data) {
return request({ return request({
url: '/employee/employee/', url: '/employee/employee/',

33
client/src/api/member.js Normal file
View File

@ -0,0 +1,33 @@
import request from '@/utils/request'
//审核组
export function getMemberList(query) {
return request({
url: '/plan/member/',
method: 'get',
params: query
})
}
export function createMember(data) {
return request({
url: '/plan/member/',
method: 'post',
data
})
}
export function deleteMember(id) {
return request({
url: `/plan/member/${id}/`,
method: 'delete'
})
}
export function updateMember(id, data) {
return request({
url: `/plan/member/${id}/`,
method: 'put',
data
})
}

79
client/src/api/plan.js Normal file
View File

@ -0,0 +1,79 @@
import request from '@/utils/request'
export function getContactRecordList(query) {
return request({
url: '/plan/contactrecord/',
method: 'get',
params: query
})
}
export function createContactRecord(data) {
return request({
url: '/plan/contactrecord/',
method: 'post',
data
})
}
export function deleteContactRecord(id) {
return request({
url: `/plan/contactrecord/${id}/`,
method: 'delete'
})
}
export function updateContactRecord(id, data) {
return request({
url: `/plan/contactrecord/${id}/`,
method: 'put',
data
})
}
export function getContactRecord(id) {
return request({
url: `/plan/contactrecord/${id}/`,
method: 'get',
})
}
export function getPlanList(query) {
return request({
url: '/plan/plan/',
method: 'get',
params: query
})
}
export function createPlan(data) {
return request({
url: '/plan/plan/',
method: 'post',
data
})
}
export function deletePlan(id) {
return request({
url: `/plan/plan/${id}/`,
method: 'delete'
})
}
export function updatePlan(id, data) {
return request({
url: `/plan/plan/${id}/`,
method: 'put',
data
})
}
export function getPlan(id) {
return request({
url: `/plan/plan/${id}/`,
method: 'get',
})
}

View File

@ -45,4 +45,12 @@ export function assginProject(id, data) {
method: 'put', method: 'put',
data data
}) })
}
export function planProject(data) {
return request({
url: '/project/project/plan/',
method: 'put',
data
})
} }

View File

@ -117,15 +117,75 @@ export const asyncRoutes = [
children: [ children: [
{ {
path: 'plan', path: 'plan',
name: 'plan', name: 'Plan',
component: () => import('@/views/plan/plan'), component: () => import('@/views/plan/plan'),
meta: { title: '计划', icon: 'example', perms: ['plan_view'] } meta: { title: '计划', icon: 'example', perms: ['plan_view'] }
}, },
{ {
path: 'paichai', path: 'paichai',
name: 'paichai', name: 'Paichai',
component: () => import('@/views/project/project'), component: () => import('@/views/plan/paichai'),
meta: { title: '派差', icon: 'example', perms: ['project_view'] } meta: { title: '派差', icon: 'example', perms: ['plan_view'] }
},
{
path: 'project',
name: 'HandleProject',
component: () => import('@/views/plan/handle'),
meta: { title: '联系企业', icon: 'example', perms: ['project_view'] },
hidden: true
},
]
},
{
path: '/spot',
component: Layout,
redirect: '/spot/spot',
name: 'SpotM',
meta: { title: '现场审核', icon: 'example'},
children: [
{
path: 'spot',
name: 'Spot',
component: () => import('@/views/plan/plan'),
meta: { title: '现场审核', icon: 'example', perms: ['plan_view'] }
},
]
},
{
path: '/detectorg',
component: Layout,
redirect: '/detectorg/detectorg',
name: 'detectorg',
meta: { title: '产品检测', icon: 'example' },
children: [
{
path: 'detectorg',
name: 'DetectOrg',
component: () => import('@/views/detectorg/detectorg'),
meta: { title: '实验室信息', icon: 'example', perms: ['detectorg_manage'] }
},
{
path: 'detectorgnotice',
name: 'DetectOrgNotice',
component: () => import('@/views/detectorg/detectorgnotice'),
meta: { title: '实验室通知公告', icon: 'example', perms: ['detectorg_manage'] }
},
]
},
{
path: '/judge',
component: Layout,
redirect: '/judge/judge',
name: 'JudgeM',
meta: { title: '认证评定', icon: 'example'},
children: [
{
path: 'judge',
name: 'Judge',
component: () => import('@/views/plan/plan'),
meta: { title: '认证评定', icon: 'example', perms: ['plan_view'] }
}, },
] ]
}, },
@ -220,29 +280,6 @@ export const asyncRoutes = [
}, },
] ]
}, },
{
path: '/detectorg',
component: Layout,
redirect: '/detectorg/detectorg',
name: 'detectorg',
meta: { title: '实验室管理', icon: 'example' },
children: [
{
path: 'detectorg',
name: 'DetectOrg',
component: () => import('@/views/detectorg/detectorg'),
meta: { title: '实验室信息', icon: 'example', perms: ['detectorg_manage'] }
},
{
path: 'detectorgnotice',
name: 'DetectOrgNotice',
component: () => import('@/views/detectorg/detectorgnotice'),
meta: { title: '实验室通知公告', icon: 'example', perms: ['detectorg_manage'] }
},
]
},
{ {
path: '/certset', path: '/certset',
component: Layout, component: Layout,

View File

@ -61,5 +61,28 @@ div:focus {
// main-container global css // main-container global css
.app-container { .app-container {
padding: 20px; padding: 10px;
} }
.el-table--medium td,   .el-table--medium th {
padding: 2px 0;
}
.el-form-item {
margin-bottom: 16px;
}
.el-card__body {
padding: 6px;
}
.el-card__header {
padding: 6px;
}
.el-tabs--border-card>.el-tabs__content {
padding: 6px;
}
.el-dialog__header {
padding: 10px 10px 6px;
}
.el-dialog__body {
padding: 8px 12px;
}

View File

@ -0,0 +1,184 @@
<template>
<div>
<el-row :gutter="6">
<el-col :xs="24" :md="4">
<treeselect
v-model="listQuery.user__dept"
:multiple="false"
:options="deptOptions"
placeholder="所属组织"
:disable-branch-nodes="true"
@input="handleFilter"
clearable/>
</el-col>
<el-col :xs="24" :md="2">
<el-select
v-model="listQuery.is_fulltime"
placeholder="是否全职"
clearable
class="filter-item"
@change="handleFilter"
>
<el-option label="" value="true"/>
<el-option label="" value="false"/>
</el-select>
</el-col>
<el-col :xs="24" :md="6">
<el-input
v-model="listQuery.search"
placeholder="姓名/易记码/编号/注册领域/专业能力"
class="filter-item"
@keyup.enter.native="handleFilter"
/>
</el-col>
<el-col :xs="24" :md="4">
<el-button-group>
<el-button
class="filter-item"
type="primary"
icon="el-icon-search"
@click="handleFilter"
>搜索</el-button>
<el-button
class="filter-item"
type="warning"
icon="el-icon-refresh-left"
@click="resetFilter"
>刷新重置</el-button>
</el-button-group>
</el-col>
</el-row>
<el-table
v-loading="listLoading"
:data="tableData.results"
style="width: 100%;margin-top:10px;"
border
fit
stripe
highlight-current-row
max-height="600"
>
<el-table-column type="index" width="50" />
<el-table-column label="编号">
<template slot-scope="scope" v-if="scope.row.code">{{ scope.row.code }}</template>
</el-table-column>
<el-table-column label="账号">
<template slot-scope="scope">{{ scope.row.user_.username }}</template>
</el-table-column>
<el-table-column label="名称">
<template slot-scope="scope">{{ scope.row.user_.name }}</template>
</el-table-column>
<el-table-column label="所属部门">
<template slot-scope="scope">{{ scope.row.user_.dept_name }}</template>
</el-table-column>
<el-table-column label="注册领域">
<template slot-scope="scope" v-if="scope.row.fields">
<el-tag v-for="(item, index) in scope.row.fields.split(',')" :key="index" style="margin:2px" >{{item}}</el-tag>
</template>
</el-table-column>
<el-table-column label="专业能力">
<template slot-scope="scope" v-if="scope.row.majors">
<el-tooltip effect="dark" :content="item.abilitys.join('\n')" placement="top-start" v-for="(item, index) in scope.row.majors" :key="index">
<el-tag style="margin:2px" type="plain">
{{item.major}}
</el-tag>
</el-tooltip>
</template>
</el-table-column>
<el-table-column label="操作" fixed="right">
<template slot-scope="scope">
<el-button-group>
<el-button
type="primary"
size="small"
@click="handleChose(scope)"
>选中</el-button>
<el-button
type="info"
size="small"
@click="handleDelete(scope)"
>详情</el-button>
</el-button-group>
</template>
</el-table-column>
</el-table>
<pagination
v-show="tableData.count>0"
:total="tableData.count"
:page.sync="listQuery.page"
:limit.sync="listQuery.page_size"
@pagination="getList"
/>
</div>
</template>
<script>
import { getEmployeeMList, deleteEmployee } from "@/api/employee"
import { getOrgList } from "@/api/org"
import { getDictList } from "@/api/dict"
import Pagination from "@/components/Pagination"
import checkPermission from '@/utils/permission'
import Treeselect from '@riophae/vue-treeselect'
import '@riophae/vue-treeselect/dist/vue-treeselect.css'
import { genTree } from '../../utils'
export default {
name:'Userchose',
components: { Pagination, Treeselect },
props:['querydata'],
data() {
return {
tableData: {count:0},
listLoading: true,
listQuery: {
page: 1,
page_size: 10,
is_onjob:true
},
deptOptions: [],
};
},
created() {
this.getList();
this.getdeptOptions()
},
methods: {
checkPermission,
getList() {
this.listLoading = true;
getEmployeeMList(this.listQuery).then(response => {
if (response.data) {
this.tableData = response.data
}
this.listLoading = false
});
},
getdeptOptions() {
getOrgList().then(res=>{
this.deptOptions = genTree(res.data)
})
},
resetFilter() {
this.listQuery = {
page: 1,
page_size: 10,
is_onjob:true
}
this.getList()
},
handleFilter() {
this.listQuery.page = 1
this.getList()
},
// handleCreate() {
// this.$router.push({path:"/certset/implementrule/create"})
// },
handleChose(scope) {
this.$emit('handleChose',scope.row);
}
}
};
</script>

View File

@ -1,188 +1,182 @@
<template> <template>
<div class="app-container"> <div class="app-container">
<el-row :gutter="20">
<el-col :span="4">
<el-input placeholder="输入关键字进行过滤" v-model="filterText"></el-input>
<el-row :gutter="20"> <el-tree
<el-col :span="4"> class="filter-tree"
<el-input placeholder="输入关键字进行过滤" :data="orgList"
v-model="filterText"> :props="defaultProps"
</el-input> default-expand-all
:expand-on-click-node="false"
:filter-node-method="filterNode"
@node-click="handleOrgClick"
ref="tree"
>
<span class="custom-tree-node" slot-scope="{ node, data }">
<span>{{ node.label }}</span>
</span>
</el-tree>
</el-col>
<el-tree class="filter-tree" <el-col :span="13">
:data="orgList" <el-table
:props="defaultProps" ref="staffTable"
default-expand-all v-loading="listLoading"
:expand-on-click-node="false" :key="tableKey"
:filter-node-method="filterNode" :data="staffList"
@node-click="handleOrgClick" border
ref="tree"> fit
<span class="custom-tree-node" slot-scope="{ node, data }"> highlight-current-row
<span>{{ node.label }}</span> @selection-change="handleStaffChange"
</span> >
</el-tree> <el-table-column type="selection" :reserve-selection="true" width="55"></el-table-column>
</el-col> <el-table-column label="姓名" align="center">
<template slot-scope="{row}">
<el-col :span="13"> <span>{{ row.user.name }}</span>
</template>
<el-table ref="staffTable" </el-table-column>
v-loading="listLoading"
:key="tableKey"
:data="staffList"
border
fit
highlight-current-row
@selection-change="handleStaffChange">
<el-table-column type="selection" :reserve-selection="true" width="55"></el-table-column>
<el-table-column label="姓名" align="center">
<template slot-scope="{row}">
<span>{{ row.user.name }}</span>
</template>
</el-table-column>
<el-table-column label="职务" align="center"> <el-table-column label="职务" align="center">
<template slot-scope="{row}"> <template slot-scope="{row}">
<span>{{ row.user.position }}</span> <span>{{ row.user.position }}</span>
</template> </template>
</el-table-column> </el-table-column>
<el-table-column label="部门" align="center"> <el-table-column label="部门" align="center">
<template slot-scope="{row}"> <template slot-scope="{row}">
<span>{{ row.user.dept_name }}</span> <span>{{ row.user.dept_name }}</span>
</template> </template>
</el-table-column> </el-table-column>
</el-table> </el-table>
</el-col> </el-col>
<el-col :span="2" style="text-align:center;margin-top:20px"> <el-col :span="2" style="text-align:center;margin-top:20px">
<el-button @click="addStaff" <el-button
type="primary" @click="addStaff"
:disabled="!staffData.length" type="primary"
icon="el-icon-arrow-right" :disabled="!staffData.length"
circle></el-button> icon="el-icon-arrow-right"
<!--<el-button @click="removeStaff" circle
></el-button>
<!--<el-button @click="removeStaff"
type="primary" type="primary"
:disabled="!selectedStaffData.length" :disabled="!selectedStaffData.length"
icon="el-icon-arrow-left" icon="el-icon-arrow-left"
circle circle
style="margin-left: 0;margin-top: 10px;"></el-button>--> style="margin-left: 0;margin-top: 10px;"></el-button>-->
</el-col> </el-col>
<el-col :span="5"> <el-col :span="5">
<el-table ref="selectedStaffTable" <el-table
v-loading="listLoading" ref="selectedStaffTable"
:data="selectedStaffList" v-loading="listLoading"
border :data="selectedStaffList"
fit border
highlight-current-row fit
> highlight-current-row
>
<el-table-column label="姓名" align="center"> <el-table-column label="姓名" align="center">
<template slot-scope="{row}"> <template slot-scope="{row}">
<span>{{ row.user.name }}</span> <span>{{ row.user.name }}</span>
</template> </template>
</el-table-column> </el-table-column>
<el-table-column label="操作" align="center"> <el-table-column label="操作" align="center">
<template slot-scope="scope"> <template slot-scope="scope">
<el-button type="danger" icon="el-icon-delete" circle @click.native.prevent="deleteRow(scope.$index, selectedStaffList)"></el-button> <el-button
</template> type="danger"
</el-table-column> icon="el-icon-delete"
circle
</el-table> @click.native.prevent="deleteRow(scope.$index, selectedStaffList)"
</el-col> ></el-button>
</el-row> </template>
<el-row :gutter="20" > </el-table-column>
<el-button type="primary" @click="modifyStaff">提交</el-button> </el-table>
</el-col>
</el-row> </el-row>
</div> <el-row :gutter="20">
</template> <el-button type="primary" @click="modifyStaff">提交</el-button>
</el-row>
</div>
</template>
<script> <script>
import { getEmployeeList, deleteEmployee } from "@/api/employee" import { getEmployeeList, deleteEmployee } from "@/api/employee";
import { genTree } from "@/utils" import { genTree } from "@/utils";
import { getOrgAll } from "@/api/org" import { getOrgAll } from "@/api/org";
import "@riophae/vue-treeselect/dist/vue-treeselect.css" import "@riophae/vue-treeselect/dist/vue-treeselect.css";
export default { export default {
components: {}, name:'Userselet',
components: {},
props: [], props: [],
data() { data() {
return { return {
dialogVisible: false,
listLoading: true,
dialogVisible: false, staffTemp: {
listLoading: true,
staffTemp: {
name: "", name: "",
email: "", email: "",
staffTypeId: "" staffTypeId: "",
}, },
filterText: '', filterText: "",
orgList: [], orgList: [],
staffList: [], staffList: [],
userlist:{count:0}, userlist: { count: 0 },
listQuery: { listQuery: {
page: 1, page: 1,
page_size: 20 page_size: 20,
}, },
selectedStaffList: [], selectedStaffList: [],
staffData: [], staffData: [],
defaultProps: { defaultProps: {
"label": "name", label: "name",
"children": "children" children: "children",
}, },
selectedStaffData: [], selectedStaffData: [],
tableKey: 0, tableKey: 0,
rowKey: "rowKey", rowKey: "rowKey",
};
} },
}, watch: {
watch: { filterText(val) {
this.$refs.tree.filter(val);
filterText(val) { },
this.$refs.tree.filter(val); },
}, created() {
this.getStaffList(), this.getList();
}, },
created() { methods: {
this.getStaffList(),
this.getList()
},
methods: {
// 从后台获取左边表格的数据 // 从后台获取左边表格的数据
filterNode(value, data) { filterNode(value, data) {
if (!value) return true; if (!value) return true;
return data.label.indexOf(value) !== -1; return data.label.indexOf(value) !== -1;
}, },
getList() { getList() {
getOrgAll().then((response) => {
getOrgAll().then(response => {
this.orgList = genTree(response.data); this.orgList = genTree(response.data);
this.listLoading = false this.listLoading = false;
}) });
}, },
deleteRow(index, rows) { deleteRow(index, rows) {
rows.splice(index, 1); rows.splice(index, 1);
} },
, handleOrgClick(obj, node, vue) {
handleOrgClick(obj, node, vue) {
this.listQuery.page = 1; this.listQuery.page = 1;
this.listQuery.user__dept = obj.id; this.listQuery.user__dept = obj.id;
this.getStaffList(); this.getStaffList();
}, },
getStaffList() { getStaffList() {
getEmployeeList(this.listQuery).then(response => { getEmployeeList(this.listQuery).then((response) => {
this.staffList = response.data.results;
this.staffList = response.data.results;
}); });
this.listLoading = false; this.listLoading = false;
}, },
// 将左边表格选择项存入staffData中 // 将左边表格选择项存入staffData中
handleStaffChange(rows) { handleStaffChange(rows) {
this.staffData = []; this.staffData = [];
if (rows) { if (rows) {
rows.forEach(row => { rows.forEach((row) => {
if (row) { if (row) {
this.staffData.push(row); this.staffData.push(row);
} }
@ -196,7 +190,7 @@ methods: {
this.$refs["selectedStaffTable"].clearSelection(); this.$refs["selectedStaffTable"].clearSelection();
}, 0); }, 0);
let repeat = false; let repeat = false;
this.selectedStaffList.forEach(item => { this.selectedStaffList.forEach((item) => {
if (this.staffData[0] && item.id === this.staffData[0].id) { if (this.staffData[0] && item.id === this.staffData[0].id) {
repeat = true; repeat = true;
alert("此员工已添加"); alert("此员工已添加");
@ -204,7 +198,7 @@ methods: {
} }
}); });
if (repeat === false) { if (repeat === false) {
this.staffData.forEach(item => { this.staffData.forEach((item) => {
this.selectedStaffList.push(item); this.selectedStaffList.push(item);
}); });
for (let i = 0; i < this.staffList.length; i++) { for (let i = 0; i < this.staffList.length; i++) {
@ -226,7 +220,7 @@ methods: {
this.$refs["staffTable"].clearSelection(); this.$refs["staffTable"].clearSelection();
this.$refs["selectedStaffTable"].clearSelection(); this.$refs["selectedStaffTable"].clearSelection();
}, 0); }, 0);
this.selectedStaffData.forEach(item => { this.selectedStaffData.forEach((item) => {
this.staffList.push(item); this.staffList.push(item);
}); });
for (let i = 0; i < this.selectedStaffList.length; i++) { for (let i = 0; i < this.selectedStaffList.length; i++) {
@ -240,9 +234,6 @@ methods: {
} }
} }
} }
}, },
// 将右边表格选择项存入selectedStaffData中 // 将右边表格选择项存入selectedStaffData中
//handleSelectedStaffChange(rows) { //handleSelectedStaffChange(rows) {
@ -257,31 +248,24 @@ methods: {
//}, //},
// 提交 // 提交
modifyStaff() { modifyStaff() {
console.log(this.selectedStaffList); console.log(this.selectedStaffList);
var userlist = [];
var arrContact = new Array();
for (let i = 0; i < this.selectedStaffList.length; i++) {
var reVal = new Object();
reVal["id"]=this.selectedStaffList[i].id
reVal["name"]=this.selectedStaffList[i].user.name
arrContact.push(reVal);
}
userlist=arrContact;
this.$emit('closeMoule',userlist,)
this.dialogVisible = false var userlist = [];
var arrContact = new Array();
for (let i = 0; i < this.selectedStaffList.length; i++) {
} var reVal = new Object();
} reVal["id"] = this.selectedStaffList[i].id;
} reVal["name"] = this.selectedStaffList[i].user.name;
arrContact.push(reVal);
}
userlist = arrContact;
this.$emit("closeMoule", userlist);
this.dialogVisible = false;
},
},
};
</script> </script>

View File

@ -0,0 +1,528 @@
<template>
<div class="app-container">
<el-row :gutter="6">
<el-col :xs="24" :md="8">
<el-card class="box-card" style="overflow-y:auto;overflow-x:hidden;height:200px">
<div slot="header" class="clearfix">
<span>受审核方</span>
<el-button style="float: right; padding: 0px 0" type="text">更多企业信息</el-button>
</div>
<div class="item">{{auditee.name}}</div>
<div v-for="item in auditee.address_" :key="item.id" class="text item">
<span class="span">{{item.type}}</span>
{{item.address}}
</div>
<div class="text item">
<span class="span">常用联系人</span>
{{auditee.linkman1_name}}/{{auditee.linkman1_duty}}/{{auditee.linkman1_mobile}}
</div>
<div class="text item">
<span class="span">备用联系人</span>
{{auditee.linkman2_name}}/{{auditee.linkman2_duty}}/{{auditee.linkman2_mobile}}
</div>
</el-card>
</el-col>
<el-col :xs="24" :md="16">
<el-card class="box-card" style="overflow-y:auto;overflow-x:hidden;height:200px">
<div slot="header" class="clearfix">
<span>项目信息</span>
</div>
<div class="text item">
<span class="span">项目号</span>
{{project.number}}
<span class="span" >所属计划</span>
<span v-if="project.plan_">{{project.plan_.name}}</span>
<span v-else>暂无</span>
</div>
<div class="text item">
<span class="span">项目概况</span>
<el-tag
v-for="(item, index) in project.certapps"
:key="index"
style="margin:2px;font-size:12px"
>{{item}}</el-tag>
</div>
<div class="text item">
<span class="span">当前状态</span>
{{project.status}}
</div>
<div class="text item" v-if="project.assign_by_">
<span class="span">下达人</span>
{{project.assign_by_.name}}
</div>
<div class="text2 item">
<!-- <el-switch
style="display: block"
v-model="can_paichai"
active-color="#13ce66"
inactive-color="#FF0000"
active-text="是否可派差">
</el-switch>-->
<el-checkbox v-model="can_paichai" border @change="handlePaichai">可派差</el-checkbox>
</div>
</el-card>
</el-col>
</el-row>
<el-row style="margin-top:6px">
<el-col>
<el-card class="box-card">
<div slot="header" class="clearfix">
<span>业务信息</span>
</div>
<el-table
ref="projectTable"
v-loading="listLoading"
:data="certappData"
style="width: 100%;"
border
fit
stripe
highlight-current-row
max-height="300"
>
<el-table-column label="单号">
<template slot-scope="scope" v-if="scope.row.number">{{ scope.row.number }}</template>
</el-table-column>
<el-table-column label="认证领域/分类" width="300px">
<template slot-scope="scope">
<el-tag v-if="scope.row.cert_field_">{{scope.row.cert_field_.name}}</el-tag>
<el-tag
v-if="scope.row.cccpv_class_"
type="warning"
style="margin:2px"
>{{scope.row.cccpv_class_.name}}</el-tag>
</template>
</el-table-column>
<!-- <el-table-column label="申请信息" width="300px">
<template slot-scope="scope">
<div>
<span style="color:darkblue;font-weight:bold">申请方</span>
:{{ scope.row.applicant_v.name }}
</div>
<div v-if="scope.row.manufacture">
<span style="color:darkblue;font-weight:bold">制造商</span>
:{{ scope.row.manufacture_v.name }}
</div>
<div v-if="scope.row.factory">
<span style="color:darkblue;font-weight:bold">生产厂</span>
:{{ scope.row.factory_v.name }}
</div>
</template>
</el-table-column>-->
<el-table-column label="当前状态">
<template slot-scope="scope">{{ scope.row.status}}</template>
</el-table-column>
<el-table-column label="受理/确认人">
<template
slot-scope="scope"
v-if="scope.row.accept_by_"
>{{ scope.row.accept_by_.name}}</template>
</el-table-column>
<el-table-column label="创建日期">
<template slot-scope="scope">
<span>{{ scope.row.create_time }}</span>
</template>
</el-table-column>
<el-table-column label="操作" width="300">
<template slot-scope="scope">
<el-button-group>
<el-button
type="primary"
size="small"
:disabled="!checkPermission(['certapp_detail'])"
@click="handleDetail(scope)"
>详情</el-button>
</el-button-group>
</template>
</el-table-column>
</el-table>
</el-card>
</el-col>
</el-row>
<el-row :gutter="6" style="margin-top:6px">
<el-col :xs="24" :md="9">
<el-card class="box-card" style="overflow-y:auto;overflow-x:hidden;">
<div slot="header" class="clearfix">
<span>联系记录</span>
</div>
<el-table
ref="projectTable"
v-loading="listLoading"
:data="contactData"
style="width: 100%;"
border
fit
stripe
highlight-current-row
height="200"
>
<el-table-column label="联系时间">
<template slot-scope="scope">{{ scope.row.contact_date }}</template>
</el-table-column>
<el-table-column label="内容" >
<template slot-scope="scope">{{ scope.row.content }}</template>
</el-table-column>
<el-table-column label="操作人">
<template slot-scope="scope">{{ scope.row.create_by_.name }}</template>
</el-table-column>
</el-table>
<el-row :gutter="10">
<el-col :xs="24" :md="12">
<el-form
ref="elForm"
:model="formData"
:rules="rules"
size="medium"
label-width="80px"
style="margin-top:2px"
label-position="left"
>
<el-row>
<el-col>
<el-form-item label="联系时间" prop="contact_date">
<el-date-picker
v-model="formData.contact_date"
format="yyyy-MM-dd"
value-format="yyyy-MM-dd"
:style="{width: '100%'}"
placeholder="联系时间"
clearable
></el-date-picker>
</el-form-item>
</el-col>
</el-row>
<el-row>
<el-col>
<el-form-item label="内容" prop="content">
<el-input
v-model="formData.content"
type="textarea"
:autosize="{ minRows: 2, maxRows: 4}"
></el-input>
</el-form-item>
</el-col>
</el-row>
<el-row>
<div style="text-align:right;">
<el-button-group>
<el-button type="primary" @click="createNewRecord" size="mini">创建新记录</el-button>
<!-- <el-button type="primary" @click="updateNowRecord" size="mini">保存</el-button> -->
<el-button @click="resetForm" size="mini">重置</el-button>
</el-button-group>
</div>
</el-row>
</el-form>
</el-col>
<el-col :xs="24" :md="12">
<el-row>
<el-card shadow="never" style="margin-top:2px">
<div slot="header" class="clearfix">
<span>常用语</span>
</div>
<el-tag
v-for="(item, index) in useditems"
:key="index"
@click.native="handleClickTag(item)"
style="margin:2px;font-size:12px"
>{{item}}</el-tag>
</el-card>
</el-row>
</el-col>
</el-row>
</el-card>
</el-col>
<el-col :xs="24" :md="15">
<el-card class="box-card">
<div slot="header" class="clearfix">
<span>审核组成员</span>
</div>
<el-table
ref="memberTable"
v-loading="listLoading"
:data="memberData"
style="width: 100%;"
border
fit
stripe
highlight-current-row
height="200"
@row-click="handleMClick"
>
<el-table-column label="姓名">
<template slot-scope="scope">{{ scope.row.user_.name }}</template>
</el-table-column>
<el-table-column label="是否组长" >
<template slot-scope="scope">
<i class="el-icon-circle-check" v-if="scope.row.is_leader" style="color:green;"></i>
</template>
</el-table-column>
<el-table-column label="身份" >
<template slot-scope="scope" v-if="scope.row.identity">{{ scope.row.identity_.name }}</template>
</el-table-column>
</el-table>
<el-form ref="elForm2" :model="formDataMember" label-width="80px" label-position="right" :rules="rules2" style="margin-top:2px">
<el-col :xs="24" :md="12">
<el-form-item label="成员" prop="user" >
<el-input placeholder="请选择成员" readonly clearable v-model="formDataMember.user_.name">
<el-button slot="append" icon="el-icon-search" @click="choseMember"></el-button>
</el-input>
</el-form-item>
</el-col>
<el-col :xs="24" :md="12">
<el-form-item prop="is_leader">
<el-checkbox v-model="formDataMember.is_leader">组长</el-checkbox>
</el-form-item>
</el-col>
<el-col :xs="24" :md="12">
<el-form-item label="身份" prop="identity">
<el-select v-model="formDataMember.identity" placeholder="请选择">
<el-option
v-for="item in identityOptions"
:key="item.id"
:label="item.name"
:value="item.id">
</el-option>
</el-select>
</el-form-item>
</el-col>
</el-form>
<div style="text-align:right;">
<el-button-group>
<el-button type="primary" @click="appendNewM" size="mini">添加新成员</el-button>
<el-button type="warning" @click="updateNowM" size="mini">保存</el-button>
<el-button @click="resetForm2" size="mini">重置</el-button>
</el-button-group>
</div>
</el-card>
</el-col>
</el-row>
<el-dialog
title="选择组员"
:visible.sync="choseVisiable"
:close-on-click-modal="false"
width="80%"
:append-to-body="true"
>
<Userchose ref="Userchose" :queryData="queryData" @handleChose="choseComplete"></Userchose>
</el-dialog>
</div>
</template>
<style scoped>
.text {
font-size: 15px;
}
.el-checkbox__label {
font-size: 18px;
}
.item {
margin-bottom: 4px;
}
.span {
color: gray;
font-weight: bold;
}
</style>
<script>
import { getDictList } from "@/api/dict"
import { getCertappList } from "@/api/certapp";
import { getEnterprise } from "@/api/enterprise";
import { getProject, updateProject } from "@/api/project";
import { getContactRecordList, createContactRecord } from "@/api/plan";
import Pagination from "@/components/Pagination";
import checkPermission from "@/utils/permission";
import Userchose from "@/views/employee/userchose"
import { getMemberList, createMember, updateMember, deleteMember} from "@/api/member"
import { genTree, deepClone } from '@/utils'
export default {
components: { Pagination, Userchose },
props: [],
data() {
return {
auditee: {},
project: { assign_by_: null },
certappData: [],
contactData: [],
memberData:[],
can_paichai: false,
formData: {
content: "",
project: this.$route.query.project,
},
rules: {
contact_date: [
{
required: true,
message: "请选择日期",
trigger: "change",
},
],
content: [
{
required: true,
message: "请输入内容",
trigger: "change",
},
],
},
useditems: [
"可以,第一联系人",
"可以,第二联系人",
"不可以",
"C类企业飞行检查",
],
formDataMember:{
user:null,
user_:{},
is_leader:false,
project:this.$route.query.project
},
rules2:{
user: [
{
required: true,
message: "请选择组员",
trigger: "change",
},
],
},
choseVisiable:false,
queryData:{},
identityOptions:[]
};
},
computed: {},
watch: {},
created() {
this.getParams();
this.getMemberList_()
this.getCertappList_();
this.getContactRecordList_();
this.getIdOptions();
},
mounted() {},
methods: {
checkPermission,
getParams() {
getProject(this.$route.query.project).then((res) => {
this.project = res.data;
this.can_paichai = this.project.can_paichai;
}).then(()=>{
getEnterprise(this.project.auditee).then((res) => {
this.auditee = res.data;
})
})
},
getCertappList_() {
this.listLoading = true;
getCertappList({
project: this.$route.query.project,
pageoff: true,
}).then((res) => {
if (res.data) {
this.certappData = res.data;
}
this.listLoading = false;
});
},
getIdOptions(){
getDictList({type__code:'auditor_teamrole',pageoff:true}).then(res=>{
this.identityOptions = res.data
})
},
getContactRecordList_() {
getContactRecordList({
pageoff: true,
project: this.$route.query.project,
}).then((res) => {
this.contactData = res.data;
});
},
getMemberList_(){
getMemberList({project:this.$route.query.project, pageoff:true}).then(res=>{
this.memberData = res.data
})
},
submitForm() {
this.$refs["elForm"].validate((valid) => {
if (!valid) return;
// TODO 提交表单
});
},
resetForm() {
this.$refs["elForm"].resetFields();
},
resetForm2() {
this.$refs["elForm2"].resetFields();
this.formDataMember.user_ = {}
},
handleDetail() {},
handleClickTag(val) {
this.formData.content = val;
},
createNewRecord() {
createContactRecord(this.formData).then((rse) => {
this.$message.success("成功");
this.getContactRecordList_();
});
},
// contactClick(scope) {
// this.formData.scope
// },
handlePaichai(val) {
if (val) {
this.$confirm("确定标记为可派差?", "提示", {})
.then(() => {
updateProject(this.$route.query.project, {
can_paichai: true,
}).then((res) => {
this.$message.success("成功");
});
})
.catch((res) => {
this.can_paichai = false;
});
} else {
this.$confirm("取消派差标记?", "警告", { type: "warning" })
.then(() => {
this.$message.success("未写接口");
this.can_paichai = true;
})
.catch((res) => {
this.can_paichai = true;
});
}
},
choseMember(){
this.choseVisiable = true
},
appendNewM(){
createMember(this.formDataMember).then(res=>{
this.$message.success('成功')
this.getMemberList_()
})
},
updateNowM(){
if(this.formDataMember.id){
updateMember(this.formDataMember.id, this.formDataMember).then(res=>{
this.$message.success('成功')
this.getMemberList_()
})
}
},
choseComplete(val){
if(val){
this.formDataMember.user = val.user_.id
this.formDataMember.user_.name = val.user_.name
}
this.choseVisiable = false
},
handleMClick(row,c,e){
this.formDataMember = deepClone(row)
}
},
};
</script>

View File

@ -0,0 +1,220 @@
<template>
<div class="app-container">
<el-card class="box-card">
<div slot="header" class="clearfix">
<span>月计划</span>
</div>
<div>
<div>
<el-button type="primary" @click="handleCreatePlan" size="mini">新建计划</el-button>
</div>
<el-table
v-loading="listLoading"
:data="projectData.results"
style="width: 100%;margin-top:10px;"
border
fit
stripe
highlight-current-row
height="240"
>
<el-table-column type="index" width="55"></el-table-column>
<el-table-column label="项目号">
<template slot-scope="scope" v-if="scope.row.number">{{ scope.row.number }}</template>
</el-table-column>
<el-table-column label="受审核方" width="300px">
<template slot-scope="scope">{{ scope.row.auditee_v.name }}</template>
</el-table-column>
<el-table-column label="项目信息" width="300px" :show-overflow-tooltip="true">
<template slot-scope="scope" v-if="scope.row.certapps">
<el-tag
v-for="(item, index) in scope.row.certapps"
:key="index"
style="margin:2px"
>{{item}}</el-tag>
</template>
</el-table-column>
<el-table-column label="当前状态">
<template slot-scope="scope">{{ scope.row.status}}</template>
</el-table-column>
<el-table-column label="创建人">
<template slot-scope="scope">{{ scope.row.create_by_.name}}</template>
</el-table-column>
<el-table-column label="创建日期">
<template slot-scope="scope">
<span>{{ scope.row.create_time }}</span>
</template>
</el-table-column>
<el-table-column label="操作" width="300">
<template slot-scope="scope">
<el-button-group>
<el-button
type="primary"
size="small"
:disabled="!checkPermission(['plan_update'])"
@click="handleUpdatePlan(scope)"
>编辑</el-button>
<el-button
type="danger"
size="small"
:disabled="!checkPermission(['plan_delete'])"
@click="handleDeletePlan(scope)"
>删除</el-button>
</el-button-group>
</template>
</el-table-column>
</el-table>
<pagination
v-show="projectData.count>0"
:total="projectData.count"
:page.sync="listQuery_project.page"
:limit.sync="listQuery_project.page_size"
@pagination="getProjectList_"
/>
</div>
</el-card>
<el-card class="box-card" style="margin-top:2px">
<div slot="header" class="clearfix">
<span>待处理项目</span>
</div>
<div>
<el-table
v-loading="listLoading"
:data="projectData.results"
style="width: 100%;"
border
fit
stripe
highlight-current-row
height="280"
>
<el-table-column type="selection" width="55"></el-table-column>
<el-table-column label="项目号">
<template slot-scope="scope" v-if="scope.row.number">{{ scope.row.number }}</template>
</el-table-column>
<el-table-column label="受审核方" width="300px">
<template slot-scope="scope">{{ scope.row.auditee_v.name }}</template>
</el-table-column>
<el-table-column label="项目信息" width="300px" :show-overflow-tooltip="true">
<template slot-scope="scope" v-if="scope.row.certapps">
<el-tag
v-for="(item, index) in scope.row.certapps"
:key="index"
style="margin:2px"
>{{item}}</el-tag>
</template>
</el-table-column>
<el-table-column label="当前状态">
<template slot-scope="scope">{{ scope.row.status}}</template>
</el-table-column>
<el-table-column label="是否可派差">
<template slot-scope="scope">
<el-switch v-model="scope.row.can_paichai" disabled></el-switch>
</template>
</el-table-column>
<el-table-column label="下达人">
<template slot-scope="scope">{{ scope.row.assign_by_.name}}</template>
</el-table-column>
<el-table-column label="创建日期" width="190">
<template slot-scope="scope">
<span>{{ scope.row.create_time }}</span>
</template>
</el-table-column>
<el-table-column label="操作" width="300" fixed="right">
<template slot-scope="scope">
<el-button-group>
<el-button
type="primary"
size="small"
:disabled="!checkPermission(['project_update'])"
@click="contactCompany(scope)"
>联系企业</el-button>
<el-button
type="danger"
size="small"
:disabled="!checkPermission(['project_delete'])"
@click="handleDetailProject(scope)"
>详情</el-button>
</el-button-group>
</template>
</el-table-column>
</el-table>
<pagination
v-show="projectData.count>0"
:total="projectData.count"
:page.sync="listQuery_project.page"
:limit.sync="listQuery_project.page_size"
@pagination="getProjectList_"
/>
</div>
</el-card>
</div>
</template>
<script>
import { getCertappList } from "@/api/certapp";
import { getProjectList, createProject, assginProject } from "@/api/project";
import Pagination from "@/components/Pagination";
import checkPermission from "@/utils/permission";
import Treeselect from "@riophae/vue-treeselect";
import "@riophae/vue-treeselect/dist/vue-treeselect.css";
import { genTree } from "../../utils";
import router from '@/router';
export default {
components: { Pagination, Treeselect },
data() {
return {
listLoading: true,
listQuery: {
status: "已受理",
},
listQuery_project: {
page: 1,
page_size: 20,
status:"待派差"
},
projectData: { count: 0, results: [] },
};
},
watch: {
},
created() {
this.getProjectList_();
},
methods: {
checkPermission,
getProjectList_() {
this.listLoading = true;
getProjectList(this.listQuery_project).then((response) => {
if (response.data) {
this.projectData = response.data;
}
this.listLoading = false;
});
},
resetFilter() {
this.listQuery = {
status: "已受理",
};
this.getCertappList_();
},
handleFilter() {
this.getCertappList_();
},
contactCompany(scope) {
this.$router.push({name:"Contact", query:{auditee:scope.row.auditee, project:scope.row.id}})
},
handleCreatePlan(){
},
handleUpdatePlan(){
},
handleDeletePlan(){
},
handleDetailProject(){
}
},
};
</script>

View File

@ -1,265 +1,290 @@
<template> <template>
<div class="app-container"> <div class="app-container">
<el-card class="box-card"> <el-row :gutter="6">
<div slot="header" class="clearfix"> <el-col :xs="24" :md="8">
<span>月计划</span> <el-card class="box-card">
</div> <div slot="header" class="clearfix">
<div> <span>月计划</span>
(当前选择:
<span style="color:darkblue;font-weight:bold">
{{nowPlan.name}}</span>
)
</div>
<div>
<div>
<el-button type="primary" @click="handleCreatePlan" size="mini">新建计划</el-button>
</div>
<el-table
v-loading="listLoadingplan"
:data="planData.results"
style="width: 100%;margin-top:2px;"
border
fit
stripe
highlight-current-row
height="300"
@row-click="planClick"
>
<el-table-column label="计划名称">
<template slot-scope="scope" v-if="scope.row.name">{{ scope.row.name }}</template>
</el-table-column>
<el-table-column label="操作" width="120">
<template slot-scope="scope">
<el-button-group>
<el-button
type="primary"
size="small"
:disabled="!checkPermission(['plan_update'])"
@click="handleUpdatePlan(scope)"
icon="el-icon-edit"
></el-button>
<el-button
type="danger"
size="small"
:disabled="!checkPermission(['plan_delete'])"
@click="handleDeletePlan(scope)"
icon="el-icon-delete"
></el-button>
</el-button-group>
</template>
</el-table-column>
</el-table>
<pagination
v-show="planData.count>0"
:total="planData.count"
:page.sync="listQuery_plan.page"
:limit.sync="listQuery_plan.page_size"
@pagination="getPlanList_"
/>
</div>
</el-card>
</el-col>
<el-col :xs="24" :md="16">
<el-card class="box-card" style="margin-top:2px">
<div slot="header" class="clearfix">
<span>待处理项目</span>
</div>
<div>
<div style="margin-bottom:2px">
<el-button type="primary" @click="handleAppend" size="mini">添加到计划</el-button>
</div>
<el-table
v-loading="listLoading"
:data="projectData.results"
style="width: 100%;"
border
fit
stripe
highlight-current-row
height="300"
@selection-change="handleSelectionChange"
>
<el-table-column type="selection" width="55"></el-table-column>
<el-table-column label="项目号">
<template slot-scope="scope" v-if="scope.row.number">{{ scope.row.number }}</template>
</el-table-column>
<el-table-column label="受审核方" width="300px">
<template slot-scope="scope">{{ scope.row.auditee_v.name }}</template>
</el-table-column>
<el-table-column label="项目信息" width="300px" :show-overflow-tooltip="true">
<template slot-scope="scope" v-if="scope.row.certapps">
<el-tag
v-for="(item, index) in scope.row.certapps"
:key="index"
style="margin:2px"
>{{item}}</el-tag>
</template>
</el-table-column>
<el-table-column label="当前状态">
<template slot-scope="scope">{{ scope.row.status}}</template>
</el-table-column>
<el-table-column label="是否可派差">
<template slot-scope="scope">
<el-switch v-model="scope.row.can_paichai" disabled></el-switch>
</template>
</el-table-column>
<el-table-column label="下达人">
<template slot-scope="scope">{{ scope.row.assign_by_.name}}</template>
</el-table-column>
<el-table-column label="创建日期" width="190">
<template slot-scope="scope">
<span>{{ scope.row.create_time }}</span>
</template>
</el-table-column>
<el-table-column label="操作" width="200" fixed="right">
<template slot-scope="scope">
<el-button-group>
<el-button
type="primary"
size="small"
:disabled="!checkPermission(['project_update'])"
@click="contactCompany(scope)"
>联系企业</el-button>
<el-button
type="danger"
size="small"
:disabled="!checkPermission(['project_delete'])"
@click="handleDetailProject(scope)"
>详情</el-button>
</el-button-group>
</template>
</el-table-column>
</el-table>
<pagination
v-show="projectData.count>0"
:total="projectData.count"
:page.sync="listQuery_project.page"
:limit.sync="listQuery_project.page_size"
@pagination="getProjectList_"
/>
</div>
</el-card>
</el-col>
</el-row>
<el-row>
<el-card class="box-card" style="margin-top:2px">
<div slot="header" class="clearfix">
<span>月计划项目</span>
</div>
<div> <div>
<el-button type="primary" @click="genProject0" size="mini">新建计划</el-button> <el-table
v-loading="listLoadingplan2"
:data="projectData2.results"
style="width: 100%;"
border
fit
stripe
highlight-current-row
height="300"
>
<el-table-column label="项目号">
<template slot-scope="scope" v-if="scope.row.number">{{ scope.row.number }}</template>
</el-table-column>
<el-table-column label="受审核方" width="300px">
<template slot-scope="scope">{{ scope.row.auditee_v.name }}</template>
</el-table-column>
<el-table-column label="项目信息" width="300px" :show-overflow-tooltip="true">
<template slot-scope="scope" v-if="scope.row.certapps">
<el-tag
v-for="(item, index) in scope.row.certapps"
:key="index"
style="margin:2px"
>{{item}}</el-tag>
</template>
</el-table-column>
<el-table-column label="当前状态">
<template slot-scope="scope">{{ scope.row.status}}</template>
</el-table-column>
<el-table-column label="是否可派差">
<template slot-scope="scope">
<el-switch v-model="scope.row.can_paichai" disabled></el-switch>
</template>
</el-table-column>
<el-table-column label="下达人">
<template slot-scope="scope">{{ scope.row.assign_by_.name}}</template>
</el-table-column>
<el-table-column label="创建日期" width="190">
<template slot-scope="scope">
<span>{{ scope.row.create_time }}</span>
</template>
</el-table-column>
<el-table-column label="操作" width="200" fixed="right">
<template slot-scope="scope">
<el-button-group>
<el-button
type="primary"
size="small"
:disabled="!checkPermission(['project_update'])"
@click="contactCompany(scope)"
>计划</el-button>
<el-button
type="danger"
size="small"
:disabled="!checkPermission(['project_delete'])"
@click="handleDetailProject(scope)"
>详情</el-button>
</el-button-group>
</template>
</el-table-column>
</el-table>
<pagination
v-show="projectData2.count>0"
:total="projectData2.count"
:page.sync="listQuery2.page"
:limit.sync="listQuery2.page_size"
@pagination="getProjectList_2"
/>
</div> </div>
<el-table </el-card>
v-loading="listLoading" </el-row>
:data="projectData.results" <el-dialog :visible.sync="dialogVisible" :title="dialogType==='update'?'编辑':'新增'" >
style="width: 100%;margin-top:10px;" <el-form ref="elForm" :model="formData" label-width="80px" label-position="right" :rules="rules">
border <el-form-item label="计划名称" prop="name">
fit <el-input v-model="formData.name" placeholder="名称" />
stripe
highlight-current-row
height="240"
>
<el-table-column type="selection" width="55"></el-table-column>
<el-table-column label="项目号">
<template slot-scope="scope" v-if="scope.row.number">{{ scope.row.number }}</template>
</el-table-column>
<el-table-column label="受审核方" width="300px">
<template slot-scope="scope">{{ scope.row.auditee_v.name }}</template>
</el-table-column>
<el-table-column label="项目信息" width="300px" :show-overflow-tooltip="true">
<template slot-scope="scope" v-if="scope.row.certapps">
<el-tag
v-for="(item, index) in scope.row.certapps"
:key="index"
style="margin:2px"
>{{item}}</el-tag>
</template>
</el-table-column>
<el-table-column label="当前状态">
<template slot-scope="scope">{{ scope.row.status}}</template>
</el-table-column>
<el-table-column label="创建人">
<template slot-scope="scope">{{ scope.row.create_by_.name}}</template>
</el-table-column>
<el-table-column label="创建日期">
<template slot-scope="scope">
<span>{{ scope.row.create_time }}</span>
</template>
</el-table-column>
<el-table-column label="操作" width="300">
<template slot-scope="scope">
<el-button-group>
<el-button
v-if="scope.row.status == '待下达'"
type="warning"
size="small"
:disabled="!checkPermission(['project_assign'])"
@click="handleAssign(scope)"
>下达</el-button>
<el-button
type="primary"
size="small"
:disabled="!checkPermission(['project_update'])"
@click="handleUpdate(scope)"
>编辑</el-button>
<el-button
type="danger"
size="small"
:disabled="!checkPermission(['project_delete'])"
@click="handleDelete(scope)"
>删除</el-button>
</el-button-group>
</template>
</el-table-column>
</el-table>
<pagination
v-show="projectData.count>0"
:total="projectData.count"
:page.sync="listQuery_project.page"
:limit.sync="listQuery_project.page_size"
@pagination="getProjectList_"
/>
</div>
</el-card>
<el-card class="box-card" style="margin-top:2px">
<div slot="header" class="clearfix">
<span>待处理项目</span>
</div>
<div>
<el-table
v-loading="listLoading"
:data="projectData.results"
style="width: 100%;"
border
fit
stripe
highlight-current-row
height="280"
>
<el-table-column type="selection" width="55"></el-table-column>
<el-table-column label="项目号">
<template slot-scope="scope" v-if="scope.row.number">{{ scope.row.number }}</template>
</el-table-column>
<el-table-column label="受审核方" width="300px">
<template slot-scope="scope">{{ scope.row.auditee_v.name }}</template>
</el-table-column>
<el-table-column label="项目信息" width="300px" :show-overflow-tooltip="true">
<template slot-scope="scope" v-if="scope.row.certapps">
<el-tag
v-for="(item, index) in scope.row.certapps"
:key="index"
style="margin:2px"
>{{item}}</el-tag>
</template>
</el-table-column>
<el-table-column label="当前状态">
<template slot-scope="scope">{{ scope.row.status}}</template>
</el-table-column>
<el-table-column label="创建人">
<template slot-scope="scope">{{ scope.row.create_by_.name}}</template>
</el-table-column>
<el-table-column label="创建日期">
<template slot-scope="scope">
<span>{{ scope.row.create_time }}</span>
</template>
</el-table-column>
<el-table-column label="操作" width="300">
<template slot-scope="scope">
<el-button-group>
<el-button
type="primary"
size="small"
:disabled="!checkPermission(['project_update'])"
@click="handleUpdate(scope)"
>联系企业</el-button>
<el-button
type="danger"
size="small"
:disabled="!checkPermission(['project_delete'])"
@click="handleDelete(scope)"
>详情</el-button>
</el-button-group>
</template>
</el-table-column>
</el-table>
<pagination
v-show="projectData.count>0"
:total="projectData.count"
:page.sync="listQuery_project.page"
:limit.sync="listQuery_project.page_size"
@pagination="getProjectList_"
/>
</div>
</el-card>
<el-dialog :visible.sync="dialogvisible_project" title="创建项目">
<el-form
ref="elForm"
:model="formData"
label-width="80px"
label-position="right"
:rules="rules"
>
<div v-if="certapps_data.length > 0">
已选择
<span style="color:red;font-weight:bold">{{certapps_data.length}}</span>条已受理业务
</div>
<el-form-item label="受审核方" prop="auditee">
<el-input placeholder="请选择受审核方" readonly clearable v-model="formData.auditee_v.name">
<el-button
slot="append"
icon="el-icon-search"
@click="choose(0)"
v-if="certapps_data.length == 0"
></el-button>
</el-input>
</el-form-item>
<el-form-item label="联系人" prop="auditee_v.linkman_name">
<el-input v-model="formData.auditee_v.linkman_name"></el-input>
</el-form-item>
<el-form-item label="联系方式" prop="auditee_v.linkman_mobile">
<el-input v-model="formData.auditee_v.linkman_mobile"></el-input>
</el-form-item>
<el-form-item label="备注" prop="username">
<el-input
v-model="formData.remark"
type="textarea"
:autosize="{ minRows: 6, maxRows: 10}"
></el-input>
</el-form-item> </el-form-item>
</el-form> </el-form>
<div style="text-align:right;"> <div style="text-align:right;">
<el-button type="danger" @click="dialogvisible_project=false">取消</el-button> <el-button type="danger" @click="dialogVisible=false">取消</el-button>
<el-button type="primary" @click="confirm('Form')">确认</el-button> <el-button type="primary" @click="confirmPlan('Form')">确认</el-button>
</div> </div>
</el-dialog> </el-dialog>
</div> </div>
</template> </template>
<script> <script>
import { getCertappList } from "@/api/certapp"; import { getCertappList } from "@/api/certapp";
import { getProjectList, createProject, assginProject } from "@/api/project"; import { getPlanList, createPlan, updatePlan, deletePlan} from "@/api/plan"
import { getProjectList, createProject, assginProject, planProject } from "@/api/project";
import Pagination from "@/components/Pagination"; import Pagination from "@/components/Pagination";
import checkPermission from "@/utils/permission"; import checkPermission from "@/utils/permission";
import Treeselect from "@riophae/vue-treeselect"; import Treeselect from "@riophae/vue-treeselect";
import "@riophae/vue-treeselect/dist/vue-treeselect.css"; import "@riophae/vue-treeselect/dist/vue-treeselect.css";
import { genTree } from "../../utils"; import { genTree } from "../../utils";
import router from "@/router";
export default { export default {
components: { Pagination, Treeselect }, components: { Pagination, Treeselect },
data() { data() {
return { return {
certapps_data: [], listLoading: false,
certappData: [], listLoadingplan:false,
listLoading: true, listLoadingplan2:false,
listQuery: { listQuery_plan: {
status: "已受理", page: 1,
page_size: 20,
}, },
listQuery_project: { listQuery_project: {
page: 1, page: 1,
page_size: 20, page_size: 20,
status:"待派差" status: "待派差",
planoff:true
}, },
deptOptions: [], listQuery2:{
field_list: [], page: 1,
page_size: 20,
plan:''
},
planData: { count: 0, results: [] },
projectData: { count: 0, results: [] }, projectData: { count: 0, results: [] },
formData: { projectData2: { count: 0, results: [] },
certapps: [], dialogVisible:false,
auditee_v: {}, dialogType:'create',
auditee: null, formData:{
}, },
dialogvisible_project: false, nowPlan:{id:0},
rules: { rules: {
auditee: [ name: [{ required: true, message: '请输入名称', trigger: 'blur' }],
{
required: true,
message: "请选择受审核方",
trigger: "change",
},
],
}, },
multipleSelection:[],
multiprojects:[]
}; };
}, },
watch: { watch: {},
certapps_data: function (val) {
let certapps = [];
for (let i = 0; i < val.length; i++) {
certapps.push(val[i].id);
}
this.formData.certapps = certapps;
},
},
created() { created() {
this.getCertappList_();
this.getProjectList_(); this.getProjectList_();
this.getPlanList_()
}, },
methods: { methods: {
checkPermission, checkPermission,
getCertappList_() {
this.listLoading = true;
getCertappList(this.listQuery).then((response) => {
if (response.data) {
this.certappData = response.data;
}
this.listLoading = false;
});
},
getProjectList_() { getProjectList_() {
this.listLoading = true; this.listLoading = true;
getProjectList(this.listQuery_project).then((response) => { getProjectList(this.listQuery_project).then((response) => {
@ -269,10 +294,12 @@ export default {
this.listLoading = false; this.listLoading = false;
}); });
}, },
getdeptOptions() { getPlanList_() {
getOrgList().then((res) => { this.listLoadingplan = true
this.deptOptions = genTree(res.data); getPlanList(this.listQuery_plan).then(res=>{
}); this.planData = res.data
this.listLoadingplan = false
}).catch(e=>{this.listLoadingplan = false})
}, },
resetFilter() { resetFilter() {
this.listQuery = { this.listQuery = {
@ -283,50 +310,104 @@ export default {
handleFilter() { handleFilter() {
this.getCertappList_(); this.getCertappList_();
}, },
genProject() { contactCompany(scope) {
if (this.certapps_data.length > 0) { this.$router.push({
this.dialogvisible_project = true; name: "HandleProject",
this.formData.auditee = this.certapps_data[0].applicant; query: { project: scope.row.id },
this.formData.auditee_v = this.certapps_data[0].applicant_v;
} else {
this.$message.warning("请先选择已受理业务");
}
},
genProject0() {
this.$refs["projectTable"].clearSelection();
this.dialogvisible_project = true;
},
handleSelectionChange(val) {
this.certapps_data = val;
},
confirm() {
this.$refs["elForm"].validate((valid) => {
if (!valid) return;
// TODO 提交表单
createProject(this.formData).then((res) => {
this.getCertappList_();
this.getProjectList_();
this.dialogvisible_project = false;
this.$message.success("成功");
});
}); });
}, },
handleAssign(scope) { handleCreatePlan() {
if (scope.row.certapps.length == 0) { this.dialogVisible=true
this.$message.error("该项目不包含业务,无法下达!"); this.dialogType = 'create'
} else {
this.$confirm("确定下达并转入策划派差吗?", "提示", {
type: "warning",
})
.then(() => {
assginProject(scope.row.id, {}).then((res) => {
this.$message.success("下达成功");
this.getProjectList_();
});
})
.catch(() => {});
}
}, },
handleUpdatePlan(scope) {
this.formData = Object.assign({}, scope.row)
this.dialogType = 'update'
this.dialogVisible=true
this.$nextTick(() => {
this.$refs['elForm'].clearValidate()
})
},
handleDeletePlan(scope) {
this.$confirm('确定删除该计划?','警告',{type:'warning'}).then(()=>{
deletePlan(scope.row.id).then(res=>{
this.$message.success('成功')
})
}).catch(res=>{
})
},
handleDetailProject() {},
confirmPlan(){
this.$refs['elForm'].validate(valid => {
if (valid) {
const isEdit = this.dialogType === 'update'
if (isEdit) {
updatePlan(this.formData.id, this.formData).then(() => {
this.getPlanList_()
this.dialogVisible = false
this.$message.success('成功')
})
} else {
createPlan(this.formData).then(res => {
// this.org = res.data
// this.tableData.unshift(this.org)
this.getPlanList_()
this.dialogVisible = false
this.$message.success('成功')
})
}
} else {
return false
}
})
},
handleSelectionChange(val) {
var ddd = []
for(var i=0;i<val.length;i++){
ddd.push(val[i].id)
}
this.multiprojects = ddd
},
handleAppend(){
if(this.multiprojects.length>0){
if(this.nowPlan.id!=0){
this.$confirm('是否将该项目添加至('+this.nowPlan.name+')中','提示',{}).then(()=>{
planProject({'plan':this.nowPlan.id, 'projects':this.multiprojects}).then(res=>{
this.$message.success('成功')
this.getProjectList_()
})
}).catch(res=>{
})
}else{
this.$message.warning('请先选择一个计划')
}
}else{
this.$message.warning('请先选择待处理项目')
}
},
planClick(row, column, event){
if(this.nowPlan.id != row.id){
this.nowPlan = row
this.listQuery2.plan = row.id
this.listQuery2.page = 1
this.getProjectList_2()
}else{
this.getProjectList_2()
}
},
getProjectList_2(){
this.listLoadingplan2 = true
getProjectList(this.listQuery2).then(res=>{
this.listLoadingplan2 = false
this.projectData2 = res.data
}).catch(e=>{
this.listLoadingplan2 = false
})
}
}, },
}; };
</script> </script>

View File

@ -87,7 +87,7 @@
<el-table <el-table
ref="projectTable" ref="projectTable"
v-loading="listLoading" v-loading="listLoading"
:data="certappData" :data="certappData.results"
style="width: 100%;margin-top:10px;" style="width: 100%;margin-top:10px;"
border border
fit fit
@ -139,6 +139,13 @@
</el-table-column> </el-table-column>
</el-table> </el-table>
<pagination
v-show="certappData.count>0"
:total="certappData.count"
:page.sync="listQuery.page"
:limit.sync="listQuery.page_size"
@pagination="getCertappList_"
/>
</el-tab-pane> </el-tab-pane>
</el-tabs> </el-tabs>
<el-dialog :visible.sync="dialogvisible_project" title="创建项目"> <el-dialog :visible.sync="dialogvisible_project" title="创建项目">
@ -184,6 +191,8 @@ export default {
certappData: [], certappData: [],
listLoading: true, listLoading: true,
listQuery: { listQuery: {
page:1,
page_size:20,
status: "已受理", status: "已受理",
}, },
listQuery_project: { listQuery_project: {

View File

@ -89,14 +89,14 @@
icon="el-icon-edit" icon="el-icon-edit"
@click="handleEdit(scope)" @click="handleEdit(scope)"
/> />
<!-- <el-button <el-button
v-if="!scope.row.is_superuser" v-if="!scope.row.is_superuser"
:disabled="!checkPermission(['dict_delete'])" :disabled="!checkPermission(['dict_delete'])"
type="danger" type="danger"
size="small" size="small"
icon="el-icon-delete" icon="el-icon-delete"
@click="handleDelete(scope)" @click="handleDelete(scope)"
/> --> />
</template> </template>
</el-table-column> </el-table-column>
</el-table> </el-table>
@ -297,7 +297,7 @@ export default {
.then(async() => { .then(async() => {
const { code } = await deleteDict(scope.row.id) const { code } = await deleteDict(scope.row.id)
if (code>=200){ if (code>=200){
this.dictList.splice(scope.row.index, 1) this.getList()
this.$message({ this.$message({
type: 'success', type: 'success',
message: '成功删除!' message: '成功删除!'

View File

@ -4,13 +4,18 @@ from .models import Enterprise,EnterpriseAddress
from apps.system.serializers import DictSerializer from apps.system.serializers import DictSerializer
class EnterpriseSerializer(serializers.ModelSerializer):
class EnterpriseAddressSerializer(serializers.ModelSerializer):
class Meta: class Meta:
model = Enterprise model = EnterpriseAddress
fields = '__all__' fields = '__all__'
class EnterpriseListSerializer(serializers.ModelSerializer): class EnterpriseListSerializer(serializers.ModelSerializer):
type = DictSerializer() type = DictSerializer()
economy_class = DictSerializer() economy_class = DictSerializer()
class Meta: class Meta:
model = Enterprise model = Enterprise
fields = ['id','query_code', 'code', 'name','ename','type','legal','build_time','person_count','ceramics_output','gassets','linkman1_name','linkman1_tel','linkman1_mobile','country_code','parent','credit_code','professional','all_person','economy_class','economy_type','linkman1_duty','business_type'] fields = ['id','query_code', 'code', 'name','ename','type','legal','build_time','person_count','ceramics_output','gassets','linkman1_name','linkman1_tel','linkman1_mobile','country_code','parent','credit_code','professional','all_person','economy_class','economy_type','linkman1_duty','business_type']
@ -18,14 +23,16 @@ class EnterpriseListSerializer(serializers.ModelSerializer):
def setup_eager_loading(queryset): def setup_eager_loading(queryset):
""" Perform necessary eager loading of data. """ """ Perform necessary eager loading of data. """
queryset = queryset.select_related('type','economy_class') queryset = queryset.select_related('type','economy_class')
queryset = queryset.prefetch_related('enterpriseaddress_enterprise',)
return queryset return queryset
def get_cert_type(self, obj): class EnterpriseSerializer(serializers.ModelSerializer):
return obj.get_cert_type_display() address_ = EnterpriseAddressSerializer(source='enterpriseaddress_enterprise', many=True)
class EnterpriseAddressSerializer(serializers.ModelSerializer):
class Meta: class Meta:
model = EnterpriseAddress model = Enterprise
fields = '__all__' fields = '__all__'
def setup_eager_loading(queryset):
""" Perform necessary eager loading of data. """
# queryset = queryset.select_related('type','economy_class')
queryset = queryset.prefetch_related('enterpriseaddress_enterprise',)
return queryset

View File

@ -1,3 +1,4 @@
from utils import serializer
from rest_framework import serializers from rest_framework import serializers
from .models import * from .models import *
@ -5,6 +6,8 @@ from .models import *
from apps.system.serializers import DictSerializer, UserListSerializer from apps.system.serializers import DictSerializer, UserListSerializer
from apps.certset.serializers import ImplementRuleSerializer from apps.certset.serializers import ImplementRuleSerializer
class EmployeeSerializer(serializers.ModelSerializer): class EmployeeSerializer(serializers.ModelSerializer):
""" """
普通序列化 普通序列化
@ -24,6 +27,41 @@ class EmployeeSerializer(serializers.ModelSerializer):
return queryset return queryset
class TeamMemberSerializer(serializers.ModelSerializer):
"""
选人序列化
"""
user_ = UserListSerializer(source='user', read_only=True)
majors = serializers.SerializerMethodField()
class Meta:
model = Employee
fields = ['code', 'user', 'user_', 'photo', 'fields', 'majors']
def get_majors(self, obj):
majors = obj.ability_employee.all()
m = []
for i in majors:
n = {'major':'', 'abilitys':''}
if not i.is_paused:
if i.major:
n['major'] = i.major.code
n['abilitys'] = i.auditor_abilitys.values_list('name', flat=True)
m.append(n)
elif i.major_rule:
n['major'] = i.major_rule.code
n['abilitys'] = i.auditor_abilitys.values_list('name', flat=True)
m.append(n)
return m
@staticmethod
def setup_eager_loading(queryset):
""" Perform necessary eager loading of data. """
queryset = queryset.select_related('user')
return queryset
class QualificationSerializer(serializers.ModelSerializer): class QualificationSerializer(serializers.ModelSerializer):
""" """
普通序列化 普通序列化

View File

@ -9,5 +9,7 @@ router.register('ability', AbilityViewSet, basename="ability")
router.register('education', EducationViewSet, basename="education") router.register('education', EducationViewSet, basename="education")
router.register('train', TrainViewSet, basename="train") router.register('train', TrainViewSet, basename="train")
urlpatterns = [ urlpatterns = [
path('employee/team/', TeamMemberView.as_view()),
path('', include(router.urls)) path('', include(router.urls))
] ]

View File

@ -1,4 +1,5 @@
from django.shortcuts import render from django.shortcuts import render
from rest_framework.generics import ListAPIView
from rest_framework.viewsets import ModelViewSet from rest_framework.viewsets import ModelViewSet
from rest_framework.response import Response from rest_framework.response import Response
from rest_framework import status from rest_framework import status
@ -7,6 +8,17 @@ from .serializers import *
from apps.system.permission_data import RbacFilterSet from apps.system.permission_data import RbacFilterSet
from apps.system.mixins import CreateUpdateCustomMixin, OptimizationMixin from apps.system.mixins import CreateUpdateCustomMixin, OptimizationMixin
# Create your views here. # Create your views here.
class TeamMemberView(ListAPIView):
perms_map = {'get': '*'}
queryset = Employee.objects.all()
serializer_class = TeamMemberSerializer
filterset_fields = ['is_onjob', 'is_fulltime', 'user__dept']
search_fields = ['code', 'remember_code', 'user__name', 'fields', 'ability_employee__major__code', 'ability_employee__major_rule__code']
ordering = ['-pk']
class EmployeeViewSet(CreateUpdateCustomMixin, OptimizationMixin, ModelViewSet): class EmployeeViewSet(CreateUpdateCustomMixin, OptimizationMixin, ModelViewSet):
""" """
详细信息-增删改查 详细信息-增删改查
@ -17,7 +29,7 @@ class EmployeeViewSet(CreateUpdateCustomMixin, OptimizationMixin, ModelViewSet):
serializer_class = EmployeeSerializer serializer_class = EmployeeSerializer
search_fields = ['code', 'remember_code', 'user__name', 'fields'] search_fields = ['code', 'remember_code', 'user__name', 'fields']
filterset_fields = ['is_onjob', 'is_fulltime', 'user__dept'] filterset_fields = ['is_onjob', 'is_fulltime', 'user__dept']
ordering = ['-create_time'] ordering = ['-pk']
class QualificationViewSet(CreateUpdateCustomMixin, OptimizationMixin, ModelViewSet): class QualificationViewSet(CreateUpdateCustomMixin, OptimizationMixin, ModelViewSet):

View File

View File

@ -0,0 +1,3 @@
from django.contrib import admin
# Register your models here.

5
server/apps/plan/apps.py Normal file
View File

@ -0,0 +1,5 @@
from django.apps import AppConfig
class PlanConfig(AppConfig):
name = 'plan'

View File

View File

@ -0,0 +1,58 @@
# Generated by Django 3.0.7 on 2020-08-25 08:36
from django.conf import settings
from django.db import migrations, models
import django.db.models.deletion
import django.utils.timezone
class Migration(migrations.Migration):
initial = True
dependencies = [
migrations.swappable_dependency(settings.AUTH_USER_MODEL),
('system', '0031_delete_bscodeset'),
('project', '0026_merge_20200825_1636'),
]
operations = [
migrations.CreateModel(
name='Plan',
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_deleted', models.BooleanField(default=False, help_text='删除标记', verbose_name='删除标记')),
('name', models.CharField(max_length=1000, verbose_name='计划名称')),
('month', models.DateField(blank=True, null=True, verbose_name='计划审核月份')),
('belong_dept', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='plan_belong_dept', to='system.Organization', verbose_name='所属部门')),
('create_by', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='plan_create_by', to=settings.AUTH_USER_MODEL, verbose_name='创建人')),
('update_by', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='plan_update_by', to=settings.AUTH_USER_MODEL, verbose_name='最后编辑人')),
],
options={
'verbose_name': '审核计划',
'verbose_name_plural': '审核计划',
},
),
migrations.CreateModel(
name='ContactRecord',
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_deleted', models.BooleanField(default=False, help_text='删除标记', verbose_name='删除标记')),
('contact_date', models.DateField(verbose_name='联系时间')),
('content', models.TextField(verbose_name='内容')),
('belong_dept', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='contactrecord_belong_dept', to='system.Organization', verbose_name='所属部门')),
('certapp', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='contactrecord_certapp', to='project.CertApp', verbose_name='关联申请')),
('create_by', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='contactrecord_create_by', to=settings.AUTH_USER_MODEL, verbose_name='创建人')),
('project', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='contactrecord_project', to='project.Project', verbose_name='所属项目')),
('update_by', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='contactrecord_update_by', to=settings.AUTH_USER_MODEL, verbose_name='最后编辑人')),
],
options={
'verbose_name': '联系记录',
'verbose_name_plural': '联系记录',
},
),
]

View File

@ -0,0 +1,43 @@
# Generated by Django 3.0.7 on 2020-09-01 07:11
from django.conf import settings
from django.db import migrations, models
import django.db.models.deletion
import django.utils.timezone
class Migration(migrations.Migration):
dependencies = [
('system', '0031_delete_bscodeset'),
('project', '0027_auto_20200825_1636'),
migrations.swappable_dependency(settings.AUTH_USER_MODEL),
('plan', '0001_initial'),
]
operations = [
migrations.AlterField(
model_name='plan',
name='name',
field=models.CharField(max_length=1000, unique=True, verbose_name='计划名称'),
),
migrations.CreateModel(
name='Team',
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_deleted', models.BooleanField(default=False, help_text='删除标记', verbose_name='删除标记')),
('is_leader', models.BooleanField(default=False, verbose_name='是否是组长')),
('belong_dept', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='team_belong_dept', to='system.Organization', verbose_name='所属部门')),
('create_by', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='team_create_by', to=settings.AUTH_USER_MODEL, verbose_name='创建人')),
('identity', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, to='system.Dict', verbose_name='身份')),
('member', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to=settings.AUTH_USER_MODEL, verbose_name='成员')),
('project', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, to='project.Project', verbose_name='所属项目')),
('update_by', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='team_update_by', to=settings.AUTH_USER_MODEL, verbose_name='最后编辑人')),
],
options={
'abstract': False,
},
),
]

View File

@ -0,0 +1,42 @@
# Generated by Django 3.0.7 on 2020-09-01 07:55
from django.conf import settings
from django.db import migrations, models
import django.db.models.deletion
import django.utils.timezone
class Migration(migrations.Migration):
dependencies = [
('system', '0031_delete_bscodeset'),
migrations.swappable_dependency(settings.AUTH_USER_MODEL),
('project', '0027_auto_20200825_1636'),
('plan', '0002_auto_20200901_1511'),
]
operations = [
migrations.CreateModel(
name='Member',
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_deleted', models.BooleanField(default=False, help_text='删除标记', verbose_name='删除标记')),
('is_leader', models.BooleanField(default=False, verbose_name='是否是组长')),
('belong_dept', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='member_belong_dept', to='system.Organization', verbose_name='所属部门')),
('create_by', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='member_create_by', to=settings.AUTH_USER_MODEL, verbose_name='创建人')),
('identity', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='member_identity', to='system.Dict', verbose_name='身份')),
('project', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='member_project', to='project.Project', verbose_name='所属项目')),
('update_by', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='member_update_by', to=settings.AUTH_USER_MODEL, verbose_name='最后编辑人')),
('user', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='member_user', to=settings.AUTH_USER_MODEL, verbose_name='成员')),
],
options={
'verbose_name': '审核组成员',
'verbose_name_plural': '审核组成员',
},
),
migrations.DeleteModel(
name='Team',
),
]

View File

View File

@ -0,0 +1,57 @@
from utils import model
from django.contrib.postgres.fields import JSONField
from django.db import models
from rest_framework.exceptions import ParseError
from simple_history.models import HistoricalRecords
from apps.system.models import CommonAModel, CommonBModel, Dict, User
from apps.project.models import Project, CertApp
# Create your models here.
class Plan(CommonBModel):
"""
计划(项目组)
"""
name = models.CharField('计划名称', max_length = 1000, unique=True)
month = models.DateField('计划审核月份', null=True, blank=True)
class Meta:
verbose_name = '审核计划'
verbose_name_plural = verbose_name
def __str__(self):
return self.name
class ContactRecord(CommonBModel):
"""
联系记录
"""
project = models.ForeignKey(Project, on_delete=models.CASCADE, verbose_name='所属项目', related_name='contactrecord_project')
certapp = models.ForeignKey(CertApp, on_delete=models.CASCADE, verbose_name='关联申请', null=True, blank=True, related_name='contactrecord_certapp')
contact_date = models.DateField('联系时间')
content = models.TextField('内容')
class Meta:
verbose_name = '联系记录'
verbose_name_plural = verbose_name
def __str__(self):
return self.content
class Member(CommonBModel):
"""
审核组成员
"""
user = models.ForeignKey(User, on_delete=models.CASCADE, verbose_name='成员', related_name='member_user')
is_leader = models.BooleanField('是否是组长', default=False)
project = models.ForeignKey(Project, on_delete=models.SET_NULL, null=True, blank=True, verbose_name='所属项目', related_name='member_project')
identity = models.ForeignKey(Dict, on_delete=models.SET_NULL, null=True, blank=True, verbose_name='身份', related_name='member_identity')
class Meta:
verbose_name = '审核组成员'
verbose_name_plural = verbose_name
def __str__(self):
return self.member.name

View File

@ -0,0 +1,24 @@
from rest_framework import serializers
from .models import *
from apps.system.serializers import DictSerializer, UserListSerializer
from apps.certset.serializers import StandardSerializer
class ContactRecordSerializer(serializers.ModelSerializer):
create_by_=UserListSerializer(source='create_by', read_only=True)
class Meta:
model = ContactRecord
fields = '__all__'
class PlanSerializer(serializers.ModelSerializer):
class Meta:
model = Plan
fields = '__all__'
class MemberSerializer(serializers.ModelSerializer):
user_ = UserListSerializer(source='user', read_only=True)
identity_ = DictSerializer(source='identity', read_only=True)
class Meta:
model = Member
fields = '__all__'

View File

@ -0,0 +1,3 @@
from django.test import TestCase
# Create your tests here.

11
server/apps/plan/urls.py Normal file
View File

@ -0,0 +1,11 @@
from django.urls import path, include
from .views import *
from rest_framework import routers
router = routers.DefaultRouter()
router.register('contactrecord', ContactRecordViewSet, basename="contactrecord")
router.register('plan', PlanViewSet, basename='plan')
router.register('member', MemberViewSet, basename='member')
urlpatterns = [
path('', include(router.urls))
]

55
server/apps/plan/views.py Normal file
View File

@ -0,0 +1,55 @@
from django.shortcuts import render
import rest_framework
from rest_framework.serializers import ModelSerializer
from rest_framework.viewsets import ModelViewSet, GenericViewSet
from rest_framework.response import Response
from rest_framework import status
from .models import *
from .serializers import *
from apps.system.models import Dict
from apps.system.permission_data import RbacFilterSet
from apps.system.mixins import CreateUpdateCustomMixin, OptimizationMixin
import random
from rest_framework.decorators import action
from .filters import *
from utils.pagination import PageOrNot
# Create your views here.
class ContactRecordViewSet(CreateUpdateCustomMixin, PageOrNot, ModelViewSet):
"""
联系记录
"""
perms_map = {'get': 'contactrecord_view', 'post':'contactrecord_create', 'put':'contactrecord_update','delete': 'contactrecord_delete'}
queryset = ContactRecord.objects.all()
serializer_class = ContactRecordSerializer
ordering = ['pk']
filterset_fields = ['project', 'certapp']
class PlanViewSet(RbacFilterSet, PageOrNot, ModelViewSet):
"""
计划
"""
perms_map = {'get': 'plan_view', 'post':'plan_create', 'put':'plan_update','delete': 'plan_delete'}
queryset = Plan.objects.all()
serializer_class = PlanSerializer
ordering = ['pk']
# filterset_fields = ['project', 'certapp']
class MemberViewSet(CreateUpdateCustomMixin, PageOrNot, ModelViewSet):
"""
审核组成员
"""
perms_map = {'get': '*', 'post':'member_create', 'put':'member_update','delete': 'member_delete'}
queryset = Member.objects.all()
serializer_class = MemberSerializer
ordering = ['pk']
filterset_fields = ['project']
def create(self, request, *args, **kwargs):
serializer = self.get_serializer(data=request.data)
serializer.is_valid(raise_exception=True)
if Member.objects.filter(user = request.data['user'], project=request.data['project'], is_deleted=False).exists():
return Response('已存在该成员', status= status.HTTP_400_BAD_REQUEST)
self.perform_create(serializer)
headers = self.get_success_headers(serializer.data)
return Response(serializer.data, status=status.HTTP_201_CREATED, headers=headers)

View File

@ -5,4 +5,10 @@ class CertAppFilter(filters.FilterSet):
noproject = filters.BooleanFilter(field_name='project', lookup_expr='isnull') noproject = filters.BooleanFilter(field_name='project', lookup_expr='isnull')
class Meta: class Meta:
model = CertApp model = CertApp
fields = ['status', 'noproject'] fields = ['status', 'noproject']
class ProjectFilter(filters.FilterSet):
planoff = filters.BooleanFilter(field_name='plan', lookup_expr='isnull')
class Meta:
model = Project
fields = ['plan', 'planoff']

View File

@ -0,0 +1,14 @@
# Generated by Django 3.0.7 on 2020-08-25 08:36
from django.db import migrations
class Migration(migrations.Migration):
dependencies = [
('project', '0022_auto_20200821_1435'),
('project', '0025_auto_20200821_1541'),
]
operations = [
]

View File

@ -0,0 +1,30 @@
# Generated by Django 3.0.7 on 2020-08-25 08:36
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),
('plan', '0001_initial'),
('project', '0026_merge_20200825_1636'),
]
operations = [
migrations.AddField(
model_name='certapp',
name='accept_by',
field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, to=settings.AUTH_USER_MODEL, verbose_name='受理人'),
),
migrations.AlterField(
model_name='project',
name='plan',
field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, to='plan.Plan', verbose_name='所属计划'),
),
migrations.DeleteModel(
name='Plan',
),
]

View File

@ -7,23 +7,10 @@ from simple_history.models import HistoricalRecords
from apps.certset.models import ImplementRule, UnitType, EvaluationItem, Standard from apps.certset.models import ImplementRule, UnitType, EvaluationItem, Standard
from apps.crm.models import Enterprise from apps.crm.models import Enterprise
from apps.system.models import CommonAModel, CommonBModel, Dict, User from apps.system.models import CommonAModel, CommonBModel, Dict, User
# from apps.plan.models import Plan
# Create your models here. # Create your models here.
class Plan(CommonBModel):
"""
计划(项目组)
"""
name = models.CharField('计划名称', max_length = 1000)
month = models.DateField('计划审核月份', null=True, blank=True)
class Meta:
verbose_name = '审核计划'
verbose_name_plural = verbose_name
def __str__(self):
return self.name
class Project(CommonBModel): class Project(CommonBModel):
""" """
认证项目 认证项目
@ -43,7 +30,7 @@ class Project(CommonBModel):
assign_date = models.DateField('下达日期', null=True, blank=True) assign_date = models.DateField('下达日期', null=True, blank=True)
assign_by = models.ForeignKey(User, verbose_name='下达人', on_delete=models.SET_NULL, null=True, blank=True) assign_by = models.ForeignKey(User, verbose_name='下达人', on_delete=models.SET_NULL, null=True, blank=True)
can_paichai = models.BooleanField('是否可派差', default = False) can_paichai = models.BooleanField('是否可派差', default = False)
plan = models.ForeignKey(Plan, verbose_name='所属计划', on_delete=models.SET_NULL, null=True, blank=True) plan = models.ForeignKey('plan.Plan', verbose_name='所属计划', on_delete=models.SET_NULL, null=True, blank=True)
class Meta: class Meta:
@ -53,6 +40,7 @@ class Project(CommonBModel):
def __str__(self): def __str__(self):
return self.number return self.number
class CertApp(CommonBModel): class CertApp(CommonBModel):
""" """
认证受理 认证受理
@ -74,7 +62,7 @@ class CertApp(CommonBModel):
number = models.CharField('受理编号', max_length = 100, null=True, blank=True) number = models.CharField('受理编号', max_length = 100, null=True, blank=True)
apply_date = models.DateField('申请日期', null=True, blank=True) apply_date = models.DateField('申请日期', null=True, blank=True)
accept_date = models.DateField('受理日期', null=True, blank=True) accept_date = models.DateField('受理日期', null=True, blank=True)
accept_by = models.ForeignKey(User, verbose_name='受理人', on_delete=models.SET_NULL, null=True, blank=True)
applicant_v = JSONField(verbose_name='申请方') applicant_v = JSONField(verbose_name='申请方')
applicant = models.ForeignKey(Enterprise, related_name='certapp_applicant', on_delete=models.DO_NOTHING) applicant = models.ForeignKey(Enterprise, related_name='certapp_applicant', on_delete=models.DO_NOTHING)

View File

@ -1,9 +1,11 @@
from apps.plan.models import Plan
from rest_framework import serializers from rest_framework import serializers
from .models import * from .models import *
from apps.system.serializers import DictSerializer, UserListSerializer from apps.system.serializers import DictSerializer, UserListSerializer
from apps.certset.serializers import StandardSerializer from apps.certset.serializers import StandardSerializer
from apps.plan.serializers import PlanSerializer
class ApplicationCreateSerializer(serializers.ModelSerializer): class ApplicationCreateSerializer(serializers.ModelSerializer):
number = serializers.CharField(required=False) number = serializers.CharField(required=False)
@ -41,9 +43,17 @@ class CertappSerializer(serializers.ModelSerializer):
cccpv_class_ = DictSerializer(source='cccpv_class' , read_only=True) cccpv_class_ = DictSerializer(source='cccpv_class' , read_only=True)
cnas_scopes_ = DictSerializer(source='cnas_scopes', many=True , read_only=True) cnas_scopes_ = DictSerializer(source='cnas_scopes', many=True , read_only=True)
create_by_ = UserListSerializer(source='create_by', read_only=True) create_by_ = UserListSerializer(source='create_by', read_only=True)
accept_by_ = UserListSerializer(source='accept_by', read_only=True)
class Meta: class Meta:
model = CertApp model = CertApp
fields = '__all__' fields = '__all__'
@staticmethod
def setup_eager_loading(queryset):
""" Perform necessary eager loading of data. """
queryset = queryset.select_related('cert_field', 'cccpv_class', 'create_by', 'accept_by')
queryset = queryset.prefetch_related('cnas_scopes',)
return queryset
class UnitSerializer(serializers.ModelSerializer): class UnitSerializer(serializers.ModelSerializer):
standard_ = StandardSerializer(source='standard', read_only=True) standard_ = StandardSerializer(source='standard', read_only=True)
@ -53,7 +63,10 @@ class UnitSerializer(serializers.ModelSerializer):
class ProjectSerializer(serializers.ModelSerializer): class ProjectSerializer(serializers.ModelSerializer):
create_by_ = UserListSerializer(source='create_by', read_only=True) create_by_ = UserListSerializer(source='create_by', read_only=True)
assign_by_ = UserListSerializer(source='assign_by', read_only=True)
certapps = serializers.SerializerMethodField() certapps = serializers.SerializerMethodField()
plan_ = PlanSerializer(source='plan', read_only=True)
class Meta: class Meta:
model = Project model = Project
fields = '__all__' fields = '__all__'
@ -62,4 +75,16 @@ class ProjectSerializer(serializers.ModelSerializer):
certapps = [] certapps = []
for i in CertApp.objects.filter(is_deleted=False, project=obj): for i in CertApp.objects.filter(is_deleted=False, project=obj):
certapps.append(i.cert_field.code +'(' + i.cccpv_class.name +')') certapps.append(i.cert_field.code +'(' + i.cccpv_class.name +')')
return certapps return certapps
@staticmethod
def setup_eager_loading(queryset):
""" Perform necessary eager loading of data. """
queryset = queryset.select_related('create_by', 'assign_by', 'plan')
return queryset
class ProjectUpdateSerializer(serializers.ModelSerializer):
class Meta:
model = Project
fields = ['remark', 'can_paichai']

View File

@ -1,5 +1,6 @@
from rest_framework.views import APIView
from apps import project
from django.shortcuts import render from django.shortcuts import render
import rest_framework
from rest_framework.serializers import ModelSerializer from rest_framework.serializers import ModelSerializer
from rest_framework.viewsets import ModelViewSet, GenericViewSet from rest_framework.viewsets import ModelViewSet, GenericViewSet
from rest_framework.response import Response from rest_framework.response import Response
@ -12,8 +13,10 @@ from apps.system.mixins import CreateUpdateCustomMixin, OptimizationMixin
import random import random
from rest_framework.decorators import action from rest_framework.decorators import action
from .filters import * from .filters import *
from utils.pagination import PageOrNot
from rest_framework.exceptions import ParseError, NotAuthenticated
# Create your views here. # Create your views here.
class ApplicationViewSet(CreateUpdateCustomMixin, RbacFilterSet, ModelViewSet): class ApplicationViewSet(RbacFilterSet, ModelViewSet):
""" """
认证申请 认证申请
""" """
@ -31,7 +34,7 @@ class ApplicationViewSet(CreateUpdateCustomMixin, RbacFilterSet, ModelViewSet):
def perform_create(self, serializer): def perform_create(self, serializer):
serializer.save(create_by = self.request.user, belong_dept=self.request.user.dept, number=random.randrange(1000,2000)) serializer.save(create_by = self.request.user, belong_dept=self.request.user.dept, number=random.randrange(1000,2000))
class SubApplicationViewSet(CreateUpdateCustomMixin, RbacFilterSet, ModelViewSet): class SubApplicationViewSet(RbacFilterSet, ModelViewSet):
""" """
子认证申请 子认证申请
""" """
@ -62,7 +65,7 @@ class SubApplicationViewSet(CreateUpdateCustomMixin, RbacFilterSet, ModelViewSet
return None return None
return self.paginator.paginate_queryset(queryset, self.request, view=self) return self.paginator.paginate_queryset(queryset, self.request, view=self)
class CertappViewset(CreateUpdateCustomMixin, RbacFilterSet, ModelViewSet): class CertappViewset(PageOrNot, RbacFilterSet, ModelViewSet):
""" """
申请受理 申请受理
""" """
@ -72,14 +75,8 @@ class CertappViewset(CreateUpdateCustomMixin, RbacFilterSet, ModelViewSet):
ordering = ['-create_time'] ordering = ['-create_time']
filterset_fields = ['status', 'project'] filterset_fields = ['status', 'project']
# filterset_class = CertAppFilter # filterset_class = CertAppFilter
def paginate_queryset(self, queryset):
if ((not self.request.query_params.get('page', None)) and (self.request.query_params.get('status', None))) or (self.paginator is None):
return None
return self.paginator.paginate_queryset(queryset, self.request, view=self)
return queryset
def create(self, request, *args, **kwargs): def create(self, request, *args, **kwargs):
postdata = request.data postdata = request.data
postdata['number'] = random.randrange(1000,2000) postdata['number'] = random.randrange(1000,2000)
@ -102,7 +99,7 @@ class CertappViewset(CreateUpdateCustomMixin, RbacFilterSet, ModelViewSet):
obj.save() obj.save()
return Response(status=status.HTTP_200_OK) return Response(status=status.HTTP_200_OK)
class UnitViewSet(CreateUpdateCustomMixin, RbacFilterSet, ModelViewSet): class UnitViewSet(RbacFilterSet, ModelViewSet):
""" """
产品单元 产品单元
""" """
@ -112,22 +109,33 @@ class UnitViewSet(CreateUpdateCustomMixin, RbacFilterSet, ModelViewSet):
ordering = ['pk'] ordering = ['pk']
filterset_fields = ['certapp'] filterset_fields = ['certapp']
class ProjectViewSet(CreateUpdateCustomMixin, RbacFilterSet, ModelViewSet):
class ProjectViewSet(RbacFilterSet, ModelViewSet):
perms_map = {'get': 'project_view', 'post':'project_create', 'put':'project_update','delete': 'project_delete'} perms_map = {'get': 'project_view', 'post':'project_create', 'put':'project_update','delete': 'project_delete'}
queryset = Project.objects.all() queryset = Project.objects.all()
serializer_class = ProjectSerializer serializer_class = ProjectSerializer
ordering = ['pk'] ordering = ['pk']
filterset_class = ProjectFilter
def get_serializer_class(self):
if self.action == 'update':
return ProjectUpdateSerializer
return ProjectSerializer
def create(self, request, *args, **kwargs): def create(self, request, *args, **kwargs):
postdata = request.data postdata = request.data
postdata['number'] = random.randrange(8000,9000) postdata['number'] = random.randrange(8000,9000)
serializer = self.get_serializer(data=postdata) serializer = self.get_serializer(data=postdata)
serializer.is_valid(raise_exception=True) serializer.is_valid(raise_exception=True)
instance = serializer.save(create_by = self.request.user, belong_dept=self.request.user.dept) if self.request.user is not None:
if 'certapps' in postdata and postdata['certapps']: instance = serializer.save(create_by = self.request.user, belong_dept=self.request.user.dept)
CertApp.objects.filter(pk__in = postdata['certapps']).update(project=instance, status='进行中') if 'certapps' in postdata and postdata['certapps']:
headers = self.get_success_headers(serializer.data) CertApp.objects.filter(pk__in = postdata['certapps']).update(project=instance, status='进行中')
return Response(serializer.data, status=status.HTTP_201_CREATED, headers=headers) headers = self.get_success_headers(serializer.data)
return Response(serializer.data, status=status.HTTP_201_CREATED, headers=headers)
else:
return NotAuthenticated()
@action(methods=['put'], detail=True, perms_map={'put':'project_assgin'}, @action(methods=['put'], detail=True, perms_map={'put':'project_assgin'},
url_name='project_assgin') url_name='project_assgin')
@ -138,7 +146,20 @@ class ProjectViewSet(CreateUpdateCustomMixin, RbacFilterSet, ModelViewSet):
obj = self.get_object() obj = self.get_object()
if obj.status == '待下达': if obj.status == '待下达':
obj.status = '待派差' obj.status = '待派差'
obj.assgin_by = request.user
obj.save() obj.save()
return Response(status=status.HTTP_200_OK) return Response(status=status.HTTP_200_OK)
else: else:
return Response('状态有误', status=status.HTTP_400_BAD_REQUEST) return Response('状态有误', status=status.HTTP_400_BAD_REQUEST)
@action(methods=['put'], detail=False, perms_map={'put':'project_plan'},
url_name='project_plan')
def plan(self, request, *args, **kwargs):
"""
项目计划
"""
projects = request.data['projects']
plan = request.data['plan']
if projects:
Project.objects.filter(pk__in=projects).update(plan=plan)
return Response(status=status.HTTP_200_OK)

View File

@ -1,11 +1,11 @@
from django.db.models import Q from django.db.models import Q
from django.db.models.query import QuerySet from django.db.models.query import QuerySet
from rest_framework.generics import GenericAPIView from rest_framework.generics import GenericAPIView
from apps.system.mixins import CreateUpdateModelBMixin from apps.system.mixins import CreateUpdateModelBMixin, CreateUpdateCustomMixin
from utils.queryset import get_child_queryset2 from utils.queryset import get_child_queryset2
class RbacFilterSet(CreateUpdateModelBMixin, object): class RbacFilterSet(CreateUpdateCustomMixin, object):
""" """
数据权限控权返回的queryset 数据权限控权返回的queryset
在必须的View下继承 在必须的View下继承
@ -21,8 +21,6 @@ class RbacFilterSet(CreateUpdateModelBMixin, object):
) )
queryset = self.queryset queryset = self.queryset
if hasattr(self.get_serializer_class(), 'setup_eager_loading'):
queryset = self.get_serializer_class().setup_eager_loading(queryset) # 性能优化
if isinstance(queryset, QuerySet): if isinstance(queryset, QuerySet):
# Ensure queryset is re-evaluated on each request. # Ensure queryset is re-evaluated on each request.
queryset = queryset.all() queryset = queryset.all()
@ -51,6 +49,8 @@ class RbacFilterSet(CreateUpdateModelBMixin, object):
elif '仅本人' in data_range: elif '仅本人' in data_range:
queryset = queryset.filter(Q(create_by=user)|Q(update_by=user)) queryset = queryset.filter(Q(create_by=user)|Q(update_by=user))
return queryset return queryset
if hasattr(self.get_serializer_class(), 'setup_eager_loading'):
queryset = self.get_serializer_class().setup_eager_loading(queryset) # 性能优化
return queryset return queryset

View File

@ -49,7 +49,8 @@ INSTALLED_APPS = [
'apps.certset', 'apps.certset',
'apps.employee', 'apps.employee',
'apps.project', 'apps.project',
'apps.laboratory' 'apps.laboratory',
'apps.plan'
] ]
MIDDLEWARE = [ MIDDLEWARE = [

View File

@ -36,6 +36,7 @@ urlpatterns = [
path('crm/', include('apps.crm.urls')), path('crm/', include('apps.crm.urls')),
path('employee/', include('apps.employee.urls')), path('employee/', include('apps.employee.urls')),
path('project/', include('apps.project.urls')), path('project/', include('apps.project.urls')),
path('plan/', include('apps.plan.urls')),
path('laboratory/', include('apps.laboratory.urls')), path('laboratory/', include('apps.laboratory.urls')),
path('docs/', include_docs_urls(title="接口文档", path('docs/', include_docs_urls(title="接口文档",
authentication_classes=[], permission_classes=[])), authentication_classes=[], permission_classes=[])),

View File

@ -1,6 +1,16 @@
from rest_framework.pagination import PageNumberPagination from rest_framework.pagination import PageNumberPagination
from rest_framework.exceptions import ParseError
class MyPagination(PageNumberPagination): class MyPagination(PageNumberPagination):
page_size = 10 page_size = 10
page_size_query_param = 'page_size' page_size_query_param = 'page_size'
class PageOrNot:
def paginate_queryset(self, queryset):
if (self.paginator is None):
return None
elif self.request.query_params.get('pageoff', None) and self.get_queryset().count()<500:
return None
elif self.request.query_params.get('pageoff', None) and self.get_queryset().count()>=500:
return ParseError('单次请求数据量大,请求中止')
return self.paginator.paginate_queryset(queryset, self.request, view=self)