提交检测实验室检测

This commit is contained in:
shilixia 2020-10-20 09:09:56 +08:00
commit b3b30cd67c
29 changed files with 1012 additions and 486 deletions

View File

@ -41,6 +41,13 @@ export function createsamplesCertappunit(id,data) {
data data
}) })
} }
export function createcompleteCertappunit(id,data) {
return request({
url: `/project/certappunit/${id}/createcomplete/`,
method: 'put',
data
})
}
// export function createAccess(data) { // export function createAccess(data) {
// return request({ // return request({
// url: '/accessment/certass/', // url: '/accessment/certass/',

View File

@ -39,9 +39,9 @@ export function getProject(id) {
}) })
} }
export function nextProject(id) { export function assginProject(id) {
return request({ return request({
url: `/project/project/${id}/next/`, url: `/project/project/${id}/assgin/`,
method: 'put' method: 'put'
}) })
} }
@ -61,3 +61,10 @@ export function planProject(data) {
data data
}) })
} }
export function acceptAudit(id) {
return request({
url: `/project/project/${id}/accept/`,
method: 'put',
})
}

View File

@ -68,17 +68,17 @@ export const asyncRoutes = [
name: 'ProjectManage', name: 'ProjectManage',
meta: { title: '认证项目', icon: 'example'}, meta: { title: '认证项目', icon: 'example'},
children: [ children: [
{ // {
path: 'application', // path: 'application',
name: 'Applicaion', // name: 'Applicaion',
component: () => import('@/views/application/application'), // component: () => import('@/views/application/application'),
meta: { title: '业务受理2', icon: 'example', perms: ['application_view'] } // meta: { title: '业务受理2', icon: 'example', perms: ['application_view'] }
}, // },
{ {
path: 'certapp', path: 'certapp',
name: 'Certapp', name: 'Certapp',
component: () => import('@/views/certapp/certapp'), component: () => import('@/views/certapp/certapp'),
meta: { title: '业务受理1', icon: 'example', perms: ['certapp_view'] } meta: { title: '业务受理', icon: 'example', perms: ['certapp_view'] }
}, },
// { // {
// path: 'application2', // path: 'application2',
@ -225,6 +225,13 @@ export const asyncRoutes = [
meta: { title: '任务反馈', noCache: true, icon: '', perms: ['feedback_create']}, meta: { title: '任务反馈', noCache: true, icon: '', perms: ['feedback_create']},
hidden: true hidden: true
}, },
{
path: 'feedbacks/create',
name: 'FeedbacksCreate',
component: () => import('@/views/testorg/feedbacks.vue'),
meta: { title: '任务反馈', noCache: true, icon: '', perms: ['feedbacks_create']},
hidden: true
},
] ]
}, },

View File

@ -101,3 +101,6 @@ div:focus {
// .el-button { // .el-button {
// border-radius: 0px; // border-radius: 0px;
// } // }
.el-tabs__header {
margin: 0 0 6px;
}

View File

@ -71,14 +71,9 @@
<el-table-column label="单元名称"> <el-table-column label="单元名称">
<template slot-scope="scope" v-if="scope.row.certunit_">{{ scope.row.certunit_.name }}</template> <template slot-scope="scope" v-if="scope.row.certunit_">{{ scope.row.certunit_.name }}</template>
</el-table-column> </el-table-column>
<el-table-column label="证书信息"> <el-table-column label="已有证书信息">
<template slot-scope="scope"> <template slot-scope="scope" v-if="scope.row.certificate_">
<!-- <el-button {{ scope.row.certificate_.number }}
type="danger"
size="small"
:disabled="!checkPermission(['certapps_update'])"
@click="handleDelete(scope)"
>删除</el-button> -->
</template> </template>
</el-table-column> </el-table-column>
<el-table-column label="认证决定"> <el-table-column label="认证决定">

View File

@ -42,7 +42,7 @@
</el-table> </el-table>
<el-row :gutter="6"> <el-row :gutter="6">
<el-col :xs="24" :md="12"> <el-col :xs="24" :md="12">
<el-card style="margin-top:6px"> <el-card style="margin-top:6px" v-if="$route.params.action=='member'">
<div slot="header" class="clearfix"> <div slot="header" class="clearfix">
<span>成员配置</span> <span>成员配置</span>
</div> </div>
@ -99,7 +99,7 @@
</el-card> </el-card>
</el-col> </el-col>
<el-col :xs="24" :md="12"> <el-col :xs="24" :md="12">
<el-card style="margin-top:6px"> <el-card style="margin-top:6px" v-if="$route.params.action=='feedback'">
<div slot="header" class="clearfix"> <div slot="header" class="clearfix">
<span>审核员参与天数/人日数</span> <span>审核员参与天数/人日数</span>
</div> </div>
@ -136,7 +136,8 @@
</el-col> </el-col>
</el-row> </el-row>
<el-row style="text-align:right;"> <el-row style="text-align:right;">
<el-button type="warning" @click="saveDays">保存</el-button> <el-button type="warning" @click="saveDays"
>保存</el-button>
</el-row> </el-row>
</el-form> </el-form>
</el-card> </el-card>

View File

@ -1,198 +1,245 @@
<template> <template>
<div class="app-container"> <div class="app-container">
<el-card >
<el-card style="margin-top:6px"> <el-row :gutter="6">
<div slot="header" class="clearfix"> <el-col :xs="24" :md="3">
<span>我的项目</span> <el-select
</div> v-model="listQuery.state"
<el-row :gutter="6"> placeholder="接受状态"
<el-col :xs="24" :md="6"> clearable
class="filter-item"
@change="handleFilter"
>
<el-option label="全部" value=""/>
<el-option label="待接受" value="审核任务已下达"/>
</el-select>
</el-col>
<el-col :xs="24" :md="6">
<el-input <el-input
v-model="listQuery.search" v-model="listQuery.search"
placeholder="受审核方/所属计划" placeholder="受审核方/所属计划"
class="filter-item" class="filter-item"
@keyup.enter.native="handleFilter" @keyup.enter.native="handleFilter"
/> />
</el-col> </el-col>
<el-col :xs="24" :md="6"> <el-col :xs="24" :md="6">
<el-button-group> <el-button
<el-button class="filter-item"
class="filter-item" type="primary"
type="primary" icon="el-icon-search"
icon="el-icon-search" @click="handleFilter"
@click="handleFilter" >搜索</el-button
>搜索</el-button> >
<el-button <el-button
class="filter-item" class="filter-item"
type="primary" type="primary"
icon="el-icon-refresh-left" icon="el-icon-refresh-left"
@click="resetFilter" @click="resetFilter"
>重置</el-button> >重置</el-button
</el-button-group> >
</el-col> </el-col>
</el-row> </el-row>
<el-table <el-table
v-loading="listLoading" v-loading="listLoading"
:data="projectData.results" :data="projectData.results"
style="width: 100%;margin-top:6px" style="width: 100%; margin-top: 6px"
border border
fit fit
stripe stripe
highlight-current-row highlight-current-row
height="300" height="320"
@row-click = "handleRclick" @row-click="handleRclick"
> >
<el-table-column type="selection" width="55"></el-table-column> <el-table-column type="selection" width="55"></el-table-column>
<el-table-column label="项目号"> <el-table-column label="项目号">
<template slot-scope="scope" v-if="scope.row.number">{{ scope.row.number }}</template> <template slot-scope="scope" v-if="scope.row.number">{{
</el-table-column> scope.row.number
<el-table-column label="所属计划"> }}</template>
<template slot-scope="scope" v-if="scope.row.plan">{{ scope.row.plan_.name }}</template> </el-table-column>
</el-table-column> <el-table-column label="所属计划">
<el-table-column label="受审核方" > <template slot-scope="scope" v-if="scope.row.plan">{{
<template slot-scope="scope">{{ scope.row.auditee_v.name }}</template> scope.row.plan_.name
</el-table-column> }}</template>
<el-table-column label="业务信息" > </el-table-column>
<template slot-scope="scope" v-if="scope.row.certapps"> <el-table-column label="受审核方">
<el-tag <template slot-scope="scope">{{ scope.row.auditee_v.name }}</template>
v-for="(item, index) in scope.row.certapps" </el-table-column>
:key="index" <el-table-column label="业务信息">
style="margin:2px" <template slot-scope="scope" v-if="scope.row.certapps">
>{{item}}</el-tag> <el-tag
</template> v-for="(item, index) in scope.row.certapps"
</el-table-column> :key="index"
<el-table-column label="当前状态"> style="margin: 2px"
<template slot-scope="scope">{{ scope.row.state}}</template> >{{ item }}</el-tag
</el-table-column> >
<el-table-column label="审核组成员"> </template>
<template slot-scope="scope" v-if="scope.row.members"> </el-table-column>
<!-- <el-tooltip effect="dark" :content="item.identity_?item.identity_.name:'组员' " placement="top-start" > --> <el-table-column label="项目状态">
<el-tag style="margin:2px" :type="item.is_leader?'danger':''" effect="plain" v-for="(item, index) in scope.row.members" :key="index"> <template slot-scope="scope">{{ scope.row.state }}</template>
{{item.user_.name}} </el-table-column>
<el-table-column label="审核组成员">
<template slot-scope="scope" v-if="scope.row.members">
<!-- <el-tooltip effect="dark" :content="item.identity_?item.identity_.name:'组员' " placement="top-start" > -->
<el-tag
style="margin: 2px"
:type="item.is_leader ? 'danger' : ''"
effect="plain"
v-for="(item, index) in scope.row.members"
:key="index"
>
{{ item.user_.name }}
</el-tag> </el-tag>
<!-- </el-tooltip> --> <!-- </el-tooltip> -->
</template> </template>
</el-table-column> </el-table-column>
<el-table-column label="创建日期" width="190"> <el-table-column label="创建日期" width="190">
<template slot-scope="scope"> <template slot-scope="scope">
<span>{{ scope.row.create_time }}</span> <span>{{ scope.row.create_time }}</span>
</template> </template>
</el-table-column> </el-table-column>
<el-table-column label="操作" width="300" fixed="right"> <el-table-column label="操作" width="300" fixed="right">
<template slot-scope="scope"> <template slot-scope="scope">
<el-button-group> <el-button
<el-button v-if="scope.row.state=='审核任务已下达'"
type="primary" type="primary"
size="small" size="small"
:disabled="!checkPermission(['project_update'])" :disabled="!checkPermission(['audit_accept'])"
@click="handleTask(scope)" @click="handleAccept(scope)"
>处理</el-button> >接受任务</el-button
<el-button >
type="danger" <el-button
size="small" size="small"
:disabled="!checkPermission(['project_delete'])" :disabled="!checkPermission(['project_delete'])"
@click="handleDetailProject(scope)" @click="handleDetailProject(scope)"
>详情</el-button> >详情</el-button
</el-button-group> >
</template> </template>
</el-table-column> </el-table-column>
</el-table> </el-table>
<pagination <pagination
v-show="projectData.count>0" v-show="projectData.count > 0"
:total="projectData.count" :total="projectData.count"
:page.sync="listQuery.page" :page.sync="listQuery.page"
:limit.sync="listQuery.page_size" :limit.sync="listQuery.page_size"
@pagination="getProjectList_" @pagination="getProjectList_"
/> />
</el-card> </el-card>
<el-card style="margin-top:6px"> <el-card style="margin-top: 6px">
<div slot="header" class="clearfix"> <div slot="header" class="clearfix">
<span>项目下我的业务</span> <span>项目下我的业务</span>
</div> </div>
<el-table <el-table
v-loading="listLoading2" v-loading="listLoading2"
:data="certappData" :data="certappData"
style="width: 100%;margin-top:6px" style="width: 100%; margin-top: 6px"
border border
fit fit
stripe stripe
highlight-current-row highlight-current-row
height="300" height="300"
> >
<el-table-column type="index" width="55"></el-table-column> <el-table-column type="index" width="55"></el-table-column>
<el-table-column label="申请单号"> <el-table-column label="申请单号">
<template slot-scope="scope" v-if="scope.row.number">{{ scope.row.number }}</template> <template slot-scope="scope" v-if="scope.row.number">{{
</el-table-column> scope.row.number
<el-table-column label="认证领域/分类"> }}</template>
<template slot-scope="scope"> </el-table-column>
<el-tag >{{scope.row.cert_field_.name}}</el-tag> <el-table-column label="认证领域/分类">
<el-tag v-if="scope.row.cccpv_class_" type="warning" style="margin:2px">{{scope.row.cccpv_class_.name}}</el-tag> <template slot-scope="scope">
</template> <el-tag>{{ scope.row.cert_field_.name }}</el-tag>
</el-table-column> <el-tag
<el-table-column label="申请信息" width="300px"> v-if="scope.row.cccpv_class_"
<template slot-scope="scope"> type="warning"
<div><span style="color:darkblue;font-weight:bold">申请方</span>:{{ scope.row.applicant_v.name }}</div> style="margin: 2px"
<div v-if="scope.row.manufacture"><span style="color:darkblue;font-weight:bold">制造商</span>:{{ scope.row.manufacture_v.name }}</div> >{{ scope.row.cccpv_class_.name }}</el-tag
<div v-if="scope.row.factory"><span style="color:darkblue;font-weight:bold">生产厂</span>:{{ scope.row.factory_v.name }}</div> >
</template> </template>
</el-table-column> </el-table-column>
<el-table-column label="当前状态"> <el-table-column label="申请信息" width="300px">
<template slot-scope="scope"> <template slot-scope="scope">
{{ scope.row.state}} <div>
</template> <span style="color: darkblue; font-weight: bold">申请方</span>:{{
</el-table-column> scope.row.applicant_v.name
<el-table-column label="审核组成员"> }}
<template slot-scope="scope" v-if="scope.row.members"> </div>
<el-tooltip effect="dark" :content="item.identity_?item.identity_.name:'' " placement="top-start" v-for="(item, index) in scope.row.members" :key="index"> <div v-if="scope.row.manufacture">
<el-tag style="margin:2px" :type="item.is_leader?'danger':''" effect="plain" > <span style="color: darkblue; font-weight: bold">制造商</span>:{{
{{item.user_.name}} scope.row.manufacture_v.name
}}
</el-tag> </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.state }}
</template>
</el-table-column>
<el-table-column label="审核组成员">
<template slot-scope="scope" v-if="scope.row.members">
<el-tooltip
effect="dark"
:content="item.identity_ ? item.identity_.name : ''"
placement="top-start"
v-for="(item, index) in scope.row.members"
:key="index"
>
<el-tag
style="margin: 2px"
:type="item.is_leader ? 'danger' : ''"
effect="plain"
>
{{ item.user_.name }}
</el-tag>
</el-tooltip> </el-tooltip>
</template> </template>
</el-table-column> </el-table-column>
<el-table-column label="创建日期" width="190"> <el-table-column label="创建日期" width="190">
<template slot-scope="scope"> <template slot-scope="scope">
<span>{{ scope.row.create_time }}</span> <span>{{ scope.row.create_time }}</span>
</template> </template>
</el-table-column> </el-table-column>
<el-table-column label="操作" width="300" fixed="right"> <el-table-column label="操作" width="300" fixed="right">
<template slot-scope="scope"> <template slot-scope="scope">
<el-button-group> <el-button
<el-button type="primary"
type="primary" size="small"
size="small" :disabled="!checkPermission(['certapp_feedback']) || projectstate != '现场审核中'"
:disabled="!checkPermission(['certapp_feedback'])" @click="handleCertappFeedback(scope)"
@click="handleCertappFeedback(scope)" >反馈</el-button
>反馈</el-button> >
<el-button <el-button
type="danger" type="danger"
size="small" size="small"
:disabled="!checkPermission(['certapp_detail'])" :disabled="!checkPermission(['certapp_detail'])"
@click="handleCertappDetail(scope)" @click="handleCertappDetail(scope)"
>详情</el-button> >详情</el-button
</el-button-group> >
</template> </template>
</el-table-column> </el-table-column>
</el-table> </el-table>
</el-card> </el-card>
</div> </div>
</template> </template>
<script> <script>
import { getProjectList } from "@/api/project"; import { getProjectList, acceptAudit } from "@/api/project";
import { getAuditTaskList, getAuditCertappList } from "@/api/audit" import { getAuditTaskList, getAuditCertappList } from "@/api/audit";
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'; import router from "@/router";
import store from '@/store' import store from "@/store";
export default { export default {
components: { Pagination, Treeselect }, components: { Pagination, Treeselect },
data() { data() {
return { return {
projectstate:'',
listLoading: false, listLoading: false,
listLoading2: false, listLoading2: false,
listQuery: { listQuery: {
@ -200,11 +247,10 @@ export default {
page_size: 20, page_size: 20,
}, },
projectData: { count: 0, results: [] }, projectData: { count: 0, results: [] },
certappData: [] certappData: [],
}; };
}, },
watch: { watch: {},
},
created() { created() {
this.getProjectList_(); this.getProjectList_();
}, },
@ -223,8 +269,8 @@ export default {
this.listQuery = { this.listQuery = {
page: 1, page: 1,
page_size: 20, page_size: 20,
} };
this.getProjectList_() this.getProjectList_();
}, },
handleFilter() { handleFilter() {
this.getProjectList_(); this.getProjectList_();
@ -235,12 +281,23 @@ export default {
params: { id: scope.row.id }, params: { id: scope.row.id },
}); });
}, },
handleRclick(row, column, event){ handleRclick(row, column, event) {
this.listLoading2 = true this.listLoading2 = true;
getAuditCertappList({project:row.id, pageoff:true}).then(res=>{ this.projectstate = row.state
this.certappData = res.data getAuditCertappList({ project: row.id, pageoff: true })
this.listLoading2 = false .then((res) => {
}).catch(e=>{this.listLoading2=false}) this.certappData = res.data;
this.listLoading2 = false;
})
.catch((e) => {
this.listLoading2 = false;
});
},
handleAccept(scope) {
acceptAudit(scope.row.id).then(res=>{
this.getProjectList_()
this.$message.success('成功')
}).catch(e=>{})
}, },
handleCertappFeedback(scope) { handleCertappFeedback(scope) {
this.$router.push({ this.$router.push({
@ -249,10 +306,16 @@ export default {
}); });
}, },
handleCertappDetail(scope) { handleCertappDetail(scope) {
this.$router.push({ this.$router.push({
name: "Certappdetail", name: "Certappdetail",
params: { id: scope.row.id }, params: { id: scope.row.id },
}); });
},
handleDetailProject(scope) {
this.$router.push({
name: "AuditProject",
params: { id: scope.row.id },
});
} }
}, },
}; };

View File

@ -1,27 +1,22 @@
<template> <template>
<div class="app-container"> <div class="app-container">
<el-card> <el-card>
<el-steps :active="1" finish-status="success"> <el-steps :active="stateIndex" finish-status="success">
<el-step title="申请"></el-step> <el-step v-for="item in states" :title="item"
<el-step title="受理"></el-step> :key="item"
<el-step title="策划"></el-step> ></el-step>
<el-step title="现场审核"></el-step>
<el-step title="产品检测"></el-step>
<el-step title="评定"></el-step>
<el-step title="出证"></el-step>
<el-step title="归档"></el-step>
</el-steps> </el-steps>
</el-card> </el-card>
<el-row :gutter="6" style="margin-top:6px"> <el-row :gutter="6" style="margin-top:6px">
<el-col :xs="24" :md="20"> <el-col :xs="24" :md="20">
<el-tabs type="border-card" v-model="activeName"> <el-tabs type="border-card" v-model="activeName" @tab-click="handleLoad">
<el-tab-pane label="申请信息" name="Basic" style="overflow-y:auto;overflow-x:hidden;"> <el-tab-pane label="申请信息" name="Basic" style="overflow-y:auto;overflow-x:hidden;">
<CCCform @handleCommit="save" :certapp="certappdata" v-if="kind=='CCC'&isLoad"></CCCform> <CCCform @handleCommit="save" :certapp="certappdata" v-if="kind=='CCC'&isLoad"></CCCform>
<QMSform @handleCommit="save" :certapp="certappdata" v-if="kind=='QMS'&isLoad"></QMSform> <QMSform @handleCommit="save" :certapp="certappdata" v-if="kind=='QMS'&isLoad"></QMSform>
</el-tab-pane> </el-tab-pane>
<el-tab-pane label="产品单元" name="Certunit" v-if="certapp" lazy> <el-tab-pane label="产品单元" name="Certunit" v-if="certapp" lazy>
<Certunit :certapp="certapp"></Certunit> <Certunit :certapp="certapp" :key="Certunitkey"></Certunit>
</el-tab-pane> </el-tab-pane>
<el-tab-pane label="原材料供应商" name="Certunit1" v-if="certapp" lazy> <el-tab-pane label="原材料供应商" name="Certunit1" v-if="certapp" lazy>
</el-tab-pane> </el-tab-pane>
@ -47,9 +42,9 @@
<Detectiontask :certapp="certapp"></Detectiontask> <Detectiontask :certapp="certapp"></Detectiontask>
</el-tab-pane> </el-tab-pane>
<el-tab-pane label="认证评定" name="Certappaccess" v-if="certapp" lazy> <el-tab-pane label="认证评定" name="Certappaccess" v-if="certapp" lazy>
<access :certapp="certapp"></access> <access :certapp="certapp" :key="Certappaccesskey"></access>
</el-tab-pane> </el-tab-pane>
<el-tab-pane label="证书颁发" name="Certissue" v-if="certapp" lazy> <el-tab-pane label="证书颁发/通知" name="Certissue" v-if="certapp" lazy>
<issue :certapp="certapp"></issue> <issue :certapp="certapp"></issue>
</el-tab-pane> </el-tab-pane>
</el-tabs> </el-tabs>
@ -95,7 +90,8 @@ export default {
props: [], props: [],
data() { data() {
return { return {
// steps:['申请', '受理', ''], states:['申请', '受理', '策划', '现场审核', '产品检测', '评定', '出证', '归档'],
stateIndex:1,
activeName:'Basic', activeName:'Basic',
certapp:null, certapp:null,
certappdata:null, certappdata:null,
@ -110,7 +106,8 @@ export default {
}, { }, {
content: '创建成功', content: '创建成功',
timestamp: '2018-04-11' timestamp: '2018-04-11'
}] }],
Certunitkey:'',
}; };
}, },
computed: {}, computed: {},
@ -122,6 +119,13 @@ export default {
}, },
mounted() {}, mounted() {},
methods: { methods: {
handleLoad(){
if(this.activeName=="Certunit"){
this.Certunitkey = new Date().getTime()
}else if(this.activeName == "Certappaccess"){
this.Certappaccesskey = new Date().getTime()
}
},
getParams(){ getParams(){
var id = this.$route.params.id var id = this.$route.params.id
this.certapp = id this.certapp = id
@ -129,6 +133,7 @@ export default {
this.certappdata = res.data this.certappdata = res.data
this.kind = res.data.cert_field_.code this.kind = res.data.cert_field_.code
this.isLoad = true this.isLoad = true
this.stateIndex = this.states.indexOf(res.data.state)
}) })
if(this.$route.name=='Certappupdate' || this.$route.name=='Certappdetail'){ if(this.$route.name=='Certappupdate' || this.$route.name=='Certappdetail'){
this.activeName = 'Basic' this.activeName = 'Basic'

View File

@ -1,6 +1,7 @@
<template> <template>
<div class="app-container"> <div class="app-container">
<div style="display:flex"> <el-row :gutter="6">
<!-- <el-col :xs="24" :md="4">
<treeselect <treeselect
v-model="listQuery.user__dept" v-model="listQuery.user__dept"
:multiple="false" :multiple="false"
@ -8,15 +9,18 @@
placeholder="所属组织" placeholder="所属组织"
:disable-branch-nodes="true" :disable-branch-nodes="true"
@input="handleFilter" @input="handleFilter"
style="width: 280px" clearable/> style="width: 100%" clearable/>
</el-col> -->
<el-col :xs="24" :md="4">
<el-input <el-input
v-model="listQuery.search" v-model="listQuery.search"
placeholder="姓名/易记码/编号/注册领域" placeholder="证书编号/企业/产品单元"
style="width: 300px;margin-left:10px" style="width: 100%"
class="filter-item" class="filter-item"
@keyup.enter.native="handleFilter" @keyup.enter.native="handleFilter"
/> />
</el-col>
<el-col :xs="24" :md="4">
<el-button <el-button
class="filter-item" class="filter-item"
type="primary" type="primary"
@ -28,8 +32,9 @@
type="primary" type="primary"
icon="el-icon-refresh-left" icon="el-icon-refresh-left"
@click="resetFilter" @click="resetFilter"
>刷新重置</el-button> >刷新</el-button>
</div> </el-col>
</el-row>
<el-table <el-table
v-loading="listLoading" v-loading="listLoading"
:data="tableData.results" :data="tableData.results"
@ -41,43 +46,48 @@
> >
<el-table-column type="index" width="50" /> <el-table-column type="index" width="50" />
<el-table-column label="申请单"> <el-table-column label="证书">
<template slot-scope="scope" v-if="scope.row.number">{{ scope.row.number }}</template> <template slot-scope="scope" v-if="scope.row.number">{{ scope.row.number }}</template>
</el-table-column> </el-table-column>
<el-table-column label="认证领域/分类"> <el-table-column label="企业" width="300px">
<template slot-scope="scope"> <template slot-scope="scope">
<el-tag >{{scope.row.cert_field_.name}}</el-tag> {{ scope.row.enterprise_.name}}
<el-tag v-if="scope.row.cccpv_class_" type="warning" style="margin:2px">{{scope.row.cccpv_class_.name}}</el-tag>
</template> </template>
</el-table-column> </el-table-column>
<el-table-column label="申请信息" width="300px"> <el-table-column label="认证单元">
<template slot-scope="scope"> <template slot-scope="scope">
<div><span style="color:darkblue;font-weight:bold">申请方</span>:{{ scope.row.applicant_v.name }}</div> {{ scope.row.certunit_.name}}
<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> </template>
</el-table-column> </el-table-column>
<el-table-column label="当前状态">
<el-table-column label="证书状态">
<template slot-scope="scope"> <template slot-scope="scope">
{{ scope.row.state}} {{ scope.row.status_.name}}
</template> </template>
</el-table-column> </el-table-column>
<el-table-column label="创建人"> <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"> <template slot-scope="scope">
<span>{{ scope.row.create_time }}</span> <span>{{ scope.row.first_send }}</span>
</template>
</el-table-column>
<el-table-column label="有效期开始">
<template slot-scope="scope">
<span>{{ scope.row.used_start }}</span>
</template>
</el-table-column>
<el-table-column label="有效期结束">
<template slot-scope="scope">
<span>{{ scope.row.used_end }}</span>
</template> </template>
</el-table-column> </el-table-column>
<el-table-column label="操作" fixed="right"> <el-table-column label="操作" fixed="right">
<template slot-scope="scope" > <template slot-scope="scope" >
<el-button <!-- <el-button
type="primary" type="primary"
size="small" size="small"
:disabled="!checkPermission(['certapp_accessment'])" :disabled="!checkPermission(['certapp_accessment'])"
@click="handleAccessment(scope)" @click="handleAccessment(scope)"
>评定</el-button> >评定</el-button> -->
<el-button <el-button
size="small" size="small"
:disabled="!checkPermission(['certapp_detail'])" :disabled="!checkPermission(['certapp_detail'])"
@ -97,7 +107,7 @@
</div> </div>
</template> </template>
<script> <script>
import { getCertappList, deleteCertapp } from "@/api/certapp" import { getCertificateList } from "@/api/certificate"
import { getOrgList } from "@/api/org" import { getOrgList } from "@/api/org"
import { getDictList } from "@/api/dict" import { getDictList } from "@/api/dict"
import Pagination from "@/components/Pagination" import Pagination from "@/components/Pagination"
@ -122,13 +132,12 @@ export default {
created() { created() {
this.getList() this.getList()
this.getdeptOptions() this.getdeptOptions()
this.getfields()
}, },
methods: { methods: {
checkPermission, checkPermission,
getList() { getList() {
this.listLoading = true; this.listLoading = true;
getCertappList(this.listQuery).then(response => { getCertificateList(this.listQuery).then(response => {
if (response.data) { if (response.data) {
this.tableData = response.data this.tableData = response.data
} }
@ -151,30 +160,6 @@ export default {
this.listQuery.page = 1 this.listQuery.page = 1
this.getList() this.getList()
}, },
getfields(){
getDictList({type__code:'cert_field'}).then(res=>{
let fields = []
for(var i=0;i<res.data.length;i++){
if(res.data[i].parent!=null){
fields.push({id:res.data[i].id, name:res.data[i].name, code:res.data[i].code})
}
}
this.field_list = fields
})
},
handleCertappDetail(scope) {
this.$router.push({
name: "Certappdetail",
params: { id: scope.row.id },
});
},
handleAccessment(scope) {
this.$router.push({
name: "Certappaccess",
params: { id: scope.row.id, action:'access' },
});
}
} }
}; };
</script> </script>

View File

@ -14,16 +14,16 @@
<el-table-column label="单元名称"> <el-table-column label="单元名称">
<template slot-scope="scope" v-if="scope.row.certunit_">{{ scope.row.certunit_.name }}</template> <template slot-scope="scope" v-if="scope.row.certunit_">{{ scope.row.certunit_.name }}</template>
</el-table-column> </el-table-column>
<el-table-column label="证书信息">
<template slot-scope="scope" v-if="scope.row.certificate_">
{{scope.row.certificate_.number}}
</template>
</el-table-column>
<el-table-column label="认证决定"> <el-table-column label="认证决定">
<template slot-scope="scope" v-if="scope.row.decision_"> <template slot-scope="scope" v-if="scope.row.decision_">
{{ scope.row.decision_.name }} {{ scope.row.decision_.name }}
</template> </template>
</el-table-column> </el-table-column>
<el-table-column label="证书信息">
<template slot-scope="scope" v-if="scope.row.certificate_">
{{scope.row.certificate_.number}}
</template>
</el-table-column>
<el-table-column label="操作"> <el-table-column label="操作">
<template slot-scope="scope"> <template slot-scope="scope">
<el-button <el-button
@ -32,6 +32,11 @@
:disabled="!checkPermission(['certificate_issue'])" :disabled="!checkPermission(['certificate_issue'])"
@click="handleIssue(scope)" @click="handleIssue(scope)"
>发证</el-button> >发证</el-button>
<el-button
size="small"
:disabled="!checkPermission(['certificate_issue'])"
@click="handleIssue(scope)"
>发通知书</el-button>
</template> </template>
</el-table-column> </el-table-column>
</el-table> </el-table>

View File

@ -189,20 +189,20 @@
<template slot-scope="scope"> <template slot-scope="scope">
<el-button-group> <el-button-group>
<el-button <el-button
v-if="scope.row.state =='策划中'"
type="primary" type="primary"
size="small" size="small"
:disabled="!checkPermission(['project_update'])" :disabled="!checkPermission(['project_update'])"
@click="planProject(scope)" @click="planProject(scope)"
>计划</el-button> >计划</el-button>
<el-button <el-button
v-if="scope.row.state !='待现场审核'" v-if="scope.row.state =='策划中'"
type="primary" type="primary"
size="small" size="small"
:disabled="!checkPermission(['project_assgin'])||!scope.row.can_paichai" :disabled="!checkPermission(['project_assgin'])||!scope.row.can_paichai"
@click="nextProject(scope)" @click="assginProject(scope)"
>任务下达</el-button> >任务下达</el-button>
<el-button <el-button
type="danger"
size="small" size="small"
:disabled="!checkPermission(['project_delete'])" :disabled="!checkPermission(['project_delete'])"
@click="handleDetailProject(scope)" @click="handleDetailProject(scope)"
@ -241,7 +241,6 @@
</div> </div>
</template> </template>
<script> <script>
import { nextProject } from "@/api/project"
import { getCertappList } from "@/api/certapp"; import { getCertappList } from "@/api/certapp";
import { getPlanList, createPlan, updatePlan, deletePlan } from "@/api/plan"; import { getPlanList, createPlan, updatePlan, deletePlan } from "@/api/plan";
import { import {
@ -445,10 +444,10 @@ export default {
this.listLoadingplan2 = false this.listLoadingplan2 = false
}) })
}, },
nextProject(scope) { assginProject(scope) {
this.$confirm("确定下达审核任务?", "警告", { type: "warning" }).then( this.$confirm("确定下达审核任务?", "警告", { type: "warning" }).then(
() => { () => {
nextProject(scope.row.id).then((res) => { assginProject(scope.row.id).then((res) => {
this.$message.success("成功"); this.$message.success("成功");
this.getProjectList_2(); this.getProjectList_2();
}); });

View File

@ -160,29 +160,25 @@
</el-table-column> </el-table-column>
<el-table-column label="操作" width="300" fixed="right"> <el-table-column label="操作" width="300" fixed="right">
<template slot-scope="scope"> <template slot-scope="scope">
<el-button-group>
<el-button <el-button
v-if="$route.name == 'AuditProject'" v-if="$route.name == 'AuditProject'"
type="primary" type="primary"
size="small" size="small"
:disabled="!checkPermission(['certapp_detail'])" :disabled="!checkPermission(['certapp_detail']) || project.state != '现场审核中'"
@click="handleFeedback(scope)" @click="handleFeedback(scope)"
>反馈</el-button> >反馈</el-button>
<el-button <el-button
v-if="$route.name == 'PlanProject'" v-if="$route.name == 'PlanProject'"
type="primary" type="primary"
size="small" size="small"
:disabled="!checkPermission(['certapp_detail'])" :disabled="!checkPermission(['certapp_detail']) || project.state != '策划中'"
@click="handlePlan(scope)" @click="handlePlan(scope)"
>派人</el-button> >派人</el-button>
<el-button <el-button
type="primary"
size="small" size="small"
:disabled="!checkPermission(['certapp_detail'])" :disabled="!checkPermission(['certapp_detail'])"
@click="handleDetail(scope)" @click="handleDetail(scope)"
>详情</el-button> >详情</el-button>
</el-button-group>
</template> </template>
</el-table-column> </el-table-column>
</el-table> </el-table>
@ -295,7 +291,6 @@
fit fit
stripe stripe
highlight-current-row highlight-current-row
height="160"
@row-click="handleMClick" @row-click="handleMClick"
> >
<el-table-column label="姓名"> <el-table-column label="姓名">
@ -309,8 +304,18 @@
<el-table-column label="身份"> <el-table-column label="身份">
<template slot-scope="scope" v-if="scope.row.identity">{{ scope.row.identity_.name }}</template> <template slot-scope="scope" v-if="scope.row.identity">{{ scope.row.identity_.name }}</template>
</el-table-column> </el-table-column>
<el-table-column label="是否接受">
<template slot-scope="scope">
<el-switch
v-model="scope.row.is_accepted"
disabled
active-color="#13ce66"
inactive-color="#ff0000"
></el-switch>
</template>
</el-table-column>
</el-table> </el-table>
<el-form <!-- <el-form
ref="elForm2" ref="elForm2"
:model="formDataMember" :model="formDataMember"
label-width="80px" label-width="80px"
@ -355,7 +360,7 @@
<el-button @click="resetForm2" size="mini">重置</el-button> <el-button @click="resetForm2" size="mini">重置</el-button>
</el-button-group> </el-button-group>
</div> </div>
</el-form> </el-form> -->
</el-card> </el-card>
</el-col> </el-col>
<el-col :xs="24" :md="8"> <el-col :xs="24" :md="8">
@ -408,9 +413,9 @@
</el-col> </el-col>
</el-row> </el-row>
<el-row> <el-row>
<div style="text-align:right;" v-if="$route.name=='AuditProject'"> <div style="text-align:center;" v-if="$route.name=='AuditProject'">
<el-button-group> <el-button-group>
<el-button type="primary" @click="createNewRecord" size="mini">提交反馈</el-button> <el-button type="primary" @click="createNewRecord" :disabled="project.state != '现场审核中'">提交反馈</el-button>
</el-button-group> </el-button-group>
</div> </div>
</el-row> </el-row>
@ -573,13 +578,13 @@ export default {
getContactRecordList_() { getContactRecordList_() {
getContactRecordList({ getContactRecordList({
pageoff: true, pageoff: true,
project: this.$route.query.project, project: this.$route.params.id,
}).then((res) => { }).then((res) => {
this.contactData = res.data; this.contactData = res.data;
}); });
}, },
getMemberList_() { getMemberList_() {
getMemberList({ project: this.$route.query.project, pageoff: true }).then( getMemberList({ certapp__project: this.$route.params.id, pageoff: true }).then(
(res) => { (res) => {
this.memberData = res.data; this.memberData = res.data;
} }
@ -615,7 +620,7 @@ export default {
if (val) { if (val) {
this.$confirm("确定标记为可派差?", "提示", {}) this.$confirm("确定标记为可派差?", "提示", {})
.then(() => { .then(() => {
updateProject(this.$route.query.project, { updateProject(this.$route.params.id, {
can_paichai: true, can_paichai: true,
}).then((res) => { }).then((res) => {
this.$message.success("成功"); this.$message.success("成功");

View File

@ -188,12 +188,13 @@ export default {
data() { data() {
return { return {
certapps_data:[], certapps_data:[],
certappData: [], certappData: {count:0,results:[]},
listLoading: true, listLoading: true,
listQuery: { listQuery: {
page:1, page:1,
page_size:20, page_size:20,
state: "已受理", state: "策划",
noproject:true
}, },
listQuery_project: { listQuery_project: {
page:1, page:1,
@ -262,7 +263,8 @@ export default {
}, },
resetFilter() { resetFilter() {
this.listQuery = { this.listQuery = {
state: "已受理", state: "策划",
noproject:true
}; };
this.getCertappList_(); this.getCertappList_();
}, },

View File

@ -0,0 +1,273 @@
<template>
<div class="app-container">
<el-tabs type="border-card" v-model="activeName" >
<el-form ref="Form"
:model="formData"
label-width="130px"
label-position="right"
:rules="rule1">
<el-col :span="12">
<el-form-item label="检测任务号" prop="detnumber">
<el-input v-model="formData.detnumber" />
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="认证性质" prop="name">
<el-input v-model="formData.name" />
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="生产企业" prop="">
<el-input v-model="formData.certunit_.enterprise_.name" />
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="生产单位地址" prop="contactman">
<el-input v-model="formData.contactman" />
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="单元描述" prop="ontactManTel">
<el-input v-model="formData.certunit_.description" />
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="样品描述" prop="sampledec">
<el-input v-model="formData.sampledec" />
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="到样日期" prop="sampledate">
<el-date-picker v-model="formData.sampledate"
type="date"
placeholder="选择日期"
format="yyyy 年 MM 月 dd 日"
value-format="yyyy-MM-dd":style="{width: '100%'}">
</el-date-picker>
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="完成日期" prop="completedate">
<el-date-picker v-model="formData.completedate"
type="date"
placeholder="选择日期"
format="yyyy 年 MM 月 dd 日"
value-format="yyyy-MM-dd":style="{width: '100%'}">
</el-date-picker>
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="报告签发日期" prop="issuancedate">
<el-date-picker v-model="formData.issuancedate"
type="date"
placeholder="选择日期"
format="yyyy 年 MM 月 dd 日"
value-format="yyyy-MM-dd":style="{width: '100%'}">
</el-date-picker>
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="检验结论" prop="conclusion">
<el-select placeholder="请选择检验结论" v-model="formData.conclusion" filterable allow-create :style="{width: '100%'}"
>
<el-option
v-for="(item, index) in conclusionOptions"
:key="index"
:label="item.label"
:value="item.value"
:disabled="item.disabled"
></el-option>
</el-select>
</el-form-item>
</el-col>
<el-col :span="8">
<el-form-item label="检测状态" prop="inspectionstate">
<el-select placeholder="请选择检测状态" v-model="formData.inspectionstate" filterable allow-create :style="{width: '100%'}"
>
<el-option
v-for="(item, index) in inspectionOptions"
:key="index"
:label="item.label"
:value="item.value"
:disabled="item.disabled"
></el-option>
</el-select>
</el-form-item>
</el-col>
<el-col :span="8">
<el-form-item label="确认的收费方式" prop="password">
<el-select placeholder="请选择收费方式" v-model="formData.charge" filterable allow-create :style="{width: '100%'}"
>
<el-option
v-for="(item, index) in chargeOptions"
:key="index"
:label="item.label"
:value="item.value"
:disabled="item.disabled"
></el-option>
</el-select>
</el-form-item>
</el-col>
<el-col :span="24">
<el-form-item label="不符合项目描述" prop="resultremark">
<el-input type="textarea"
:rows="2"
v-model="formData.resultremark">
</el-input>
</el-form-item>
</el-col>
<el-col :span="24">
<el-form-item label="备注" prop="remarks">
<el-input type="textarea"
:rows="2"
v-model="formData.remarks">
</el-input>
</el-form-item>
</el-col>
<el-col :span="24">
<el-form-item label="相关文件资料" prop="path">
<el-upload
:on-preview="handlePreview"
:on-success="handleSuccess"
:action="upUrl"
:headers="upHeaders"
:limit="1"
:file-list="fileList"
>
<el-button size="small" type="primary">点击上传</el-button>
</el-upload>
</el-form-item>
</el-col>
<el-col :span="24" style="margin-top:4px">
<el-form-item size="large">
<el-button type="danger" @click="resetForm">取消</el-button>
<el-button type="primary" @click="submitForm">确认</el-button>
</el-form-item>
</el-col>
</el-form>
</el-tab-pane>
</el-tabs>
</div>
</template>
<script>
import { getTestOrgList, createTestOrg, updateTestOrg, deleteTestOrg } from "@/api/laboratory"
import { getCertappunitList,getCertappunit,testtaskCertappunit, createcompleteCertappunit,createsamplesCertappunit,teststateCertappunit } from "@/api/certappunit";
import Pagination from "@/components/Pagination"
import checkPermission from '@/utils/permission'
import { upUrl, upHeaders } from "@/api/file";
export default {
components: { Pagination },
data() {
return {
fileList: [],
upUrl: upUrl(),
upHeaders: upHeaders(),
detectoryList: { count: 0 },
formData: {
detnumber: undefined,
testitem:undefined,
sampledate:undefined,
completedate:undefined,
issuancedate:undefined,
conclusion:undefined,
resultremark:undefined,
remarks:undefined
},
chargeOptions:[
{
label: "CTC代收",
value: "CTC代收",
},
{
label: "自收",
value: "自收",
}
],
inspectionOptions:[
{
label: "待检测",
value: "待检测",
},
{
label: "在检测",
value: "在检测",
}
,
{
label: "已检测",
value: "已检测",
}
],
conclusionOptions:[
{
label: "合格",
value: "合格",
},
{
label: "不合格",
value: "不合格",
}
],
listLoading: true,
listQuery: {
page: 1,
page_size: 20
},
dialogVisible: false,
dialogType: 'create',
rule1: {
},
fileList: []
};
},
created() {
this.getData();
},
methods: {
checkPermission,
getData() {
console.log(this.$route.query.taskid)
getCertappunit(this.$route.query.taskid).then(response => {
this.formData = response.data
})
},
handlePreview(file) {
if ("url" in file) {
window.open(file.url);
} else {
window.open(file.response.data.path);
}
},
handleSuccess(response, file, fileList) {
this.formData.path = response.data.path;
},
submitForm() {
this.$refs["Form"].validate(valid => {
if (!valid) return;
// TODO 提交表单
createcompleteCertappunit(this.$route.query.taskid,this.formData).then(response => {
this.$message.success('成功')
this.close(true);
});
});
},
resetForm() {
this.$refs["Form"].resetFields();
}
}
};
</script>

View File

@ -57,10 +57,18 @@
<el-button-group> <el-button-group>
<el-button <el-button
v-if="scope.row.teststate=='待实验室检验'"
type="primary" type="primary"
size="small" size="small"
:disabled="!checkPermission(['certapps_update'])" :disabled="!checkPermission(['certapps_update'])"
@click="handleCreate(scope)" @click="handleCreate(scope)"
>任务反馈</el-button>
<el-button
v-if="scope.row.teststate=='到样检测中'"
type="primary"
size="small"
:disabled="!checkPermission(['certapps_update'])"
@click="handleCreate2(scope)"
>任务反馈</el-button> >任务反馈</el-button>
<el-button <el-button
type="primary" type="primary"
@ -95,7 +103,6 @@ export default {
data() { data() {
return { return {
tableData: [], tableData: [],
listLoading: true, listLoading: true,
taskOptions:[ taskOptions:[
{ {
@ -146,6 +153,9 @@ export default {
handleCreate(scope) { handleCreate(scope) {
this.$router.push({path:"/testorg/feedback/create",query:{taskid:scope.row.id}}) this.$router.push({path:"/testorg/feedback/create",query:{taskid:scope.row.id}})
}, },
handleCreate2(scope) {
this.$router.push({path:"/testorg/feedbacks/create",query:{taskid:scope.row.id}})
},
}, },
}; };

View File

@ -3,7 +3,7 @@ from rest_framework import serializers
from .models import * from .models import *
from apps.system.serializers import DictSerializer, UserListSerializer from apps.system.serializers import DictSimpleSerializer, UserListSerializer
from apps.project.models import Project from apps.project.models import Project
from apps.plan.models import Member from apps.plan.models import Member
from apps.project.serializers import PlanSerializer from apps.project.serializers import PlanSerializer
@ -25,7 +25,7 @@ class ProjectSerializerX(serializers.ModelSerializer):
def get_members(self, obj): def get_members(self, obj):
queryset = obj.certapp_project.all() queryset = obj.certapp_project.all()
members = Member.objects.filter(certapp__in=queryset, is_accepted=True, is_deleted=False).distinct('is_leader','user').order_by('-is_leader') members = Member.objects.filter(certapp__in=queryset, is_deleted=False).distinct('is_leader','user').order_by('-is_leader')
serializer = MemberSerializer(members, many=True) serializer = MemberSerializer(members, many=True)
return serializer.data return serializer.data
@ -38,9 +38,9 @@ class ProjectSerializerX(serializers.ModelSerializer):
return queryset return queryset
class CertappSerializerX(serializers.ModelSerializer): class CertappSerializerX(serializers.ModelSerializer):
cert_field_ = DictSerializer(source='cert_field', read_only=True) cert_field_ = DictSimpleSerializer(source='cert_field', read_only=True)
cccpv_class_ = DictSerializer(source='cccpv_class' , read_only=True) cccpv_class_ = DictSimpleSerializer(source='cccpv_class' , read_only=True)
cnas_scopes_ = DictSerializer(source='cnas_scopes', many=True , read_only=True) cnas_scopes_ = DictSimpleSerializer(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) accept_by_ = UserListSerializer(source='accept_by', read_only=True)
members = serializers.SerializerMethodField() members = serializers.SerializerMethodField()
@ -56,6 +56,6 @@ class CertappSerializerX(serializers.ModelSerializer):
return queryset return queryset
def get_members(self, obj): def get_members(self, obj):
members = Member.objects.filter(certapp=obj, is_accepted=True, is_deleted=False).order_by('-is_leader') members = Member.objects.filter(certapp=obj, is_deleted=False).order_by('-is_leader')
serializer = MemberSerializer(members, many=True) serializer = MemberSerializer(members, many=True)
return serializer.data return serializer.data

View File

@ -1,14 +1,24 @@
from apps.crm.models import Certunit, Enterprise
from rest_framework import serializers from rest_framework import serializers
from .models import * from .models import *
from apps.system.serializers import DictSerializer from apps.system.serializers import DictSimpleSerializer
from apps.crm.serializers import EnterpriseSimpleSerializer
from apps.crm.serializers import CertunitSimpleSerializer
class CertificateSerializer(serializers.ModelSerializer): class CertificateSerializer(serializers.ModelSerializer):
status_ = DictSimpleSerializer(source='status', read_only=True)
enterprise_ = EnterpriseSimpleSerializer(source='certunit.enterprise', read_only=True)
certunit_ = CertunitSimpleSerializer(source='certunit', read_only=True)
class Meta: class Meta:
model = Certificate model = Certificate
fields = '__all__' fields = '__all__'
@staticmethod
def setup_eager_loading(queryset):
""" Perform necessary eager loading of data. """
queryset = queryset.select_related('certunit','certunit__enterprise')
return queryset
class CertificateCreateSerializer(serializers.ModelSerializer): class CertificateCreateSerializer(serializers.ModelSerializer):
number = serializers.CharField(read_only = True) number = serializers.CharField(read_only = True)
status = serializers.CharField(read_only = True) status = serializers.CharField(read_only = True)
@ -20,3 +30,9 @@ class CertificateSimpleSerializer(serializers.ModelSerializer):
class Meta: class Meta:
model = Certificate model = Certificate
fields = ['id', 'number'] fields = ['id', 'number']
# class CertificateListSerializer(serializers.ModelSerializer):
# status_ = DictSerializer(source='status', read_only=True)
# class Meta:
# model = Certificate
# fields = '__all__'

View File

@ -24,6 +24,8 @@ class CertificateViewSet(PageOrNot, OptimizationMixin, ModelViewSet):
queryset = Certificate.objects.all() queryset = Certificate.objects.all()
serializer_class = CertificateSerializer serializer_class = CertificateSerializer
ordering = ['-create_time'] ordering = ['-create_time']
filterset_fields = ['number', 'certunit__unittype']
search_fields = ['number', 'certunit__name', 'certunit__enterprise__name']
def create(self, request, *args, **kwargs): def create(self, request, *args, **kwargs):
""" """

View File

@ -45,3 +45,9 @@ class CertunitSimpleSerializer(serializers.ModelSerializer):
class Meta: class Meta:
model = Certunit model = Certunit
fields = ['id', 'name','description','enterprise','enterprise_'] fields = ['id', 'name','description','enterprise','enterprise_']
class EnterpriseSimpleSerializer(serializers.ModelSerializer):
class Meta:
model = Enterprise
fields = ['id', 'name']

View File

@ -43,11 +43,13 @@ class MemberViewSet(CreateUpdateCustomMixin, PageOrNot, ModelViewSet):
queryset = Member.objects.all() queryset = Member.objects.all()
serializer_class = MemberSerializer serializer_class = MemberSerializer
ordering = ['-is_leader', 'pk'] ordering = ['-is_leader', 'pk']
filterset_fields = ['certapp'] filterset_fields = ['certapp', 'certapp__project']
def create(self, request, *args, **kwargs): def create(self, request, *args, **kwargs):
serializer = self.get_serializer(data=request.data) serializer = self.get_serializer(data=request.data)
serializer.is_valid(raise_exception=True) serializer.is_valid(raise_exception=True)
if CertApp.object.get(pk=request.data['certapp'])!='策划':
return Response('业务状态异常,操作失败', status = status.HTTP_400_BAD_REQUEST)
if Member.objects.filter(user = request.data['user'], certapp=request.data['certapp'], is_deleted=False).exists(): if Member.objects.filter(user = request.data['user'], certapp=request.data['certapp'], is_deleted=False).exists():
return Response('已存在该成员', status= status.HTTP_400_BAD_REQUEST) return Response('已存在该成员', status= status.HTTP_400_BAD_REQUEST)
self.perform_create(serializer) self.perform_create(serializer)

View File

@ -1,5 +1,4 @@
from apps.project.views import ApplicationViewSet
from django.contrib import admin from django.contrib import admin
from .models import * from .models import *
# Register your models here. # Register your models here.
admin.site.register(Application)

View File

@ -0,0 +1,82 @@
# Generated by Django 3.0.7 on 2020-10-14 04:15
from django.conf import settings
import django.contrib.postgres.fields.jsonb
from django.db import migrations, models
import django.db.models.deletion
import django.utils.timezone
class Migration(migrations.Migration):
dependencies = [
migrations.swappable_dependency(settings.AUTH_USER_MODEL),
('project', '0042_auto_20201009_1550'),
]
operations = [
migrations.CreateModel(
name='CertAppFlow',
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='删除标记')),
('operation', models.TextField(verbose_name='操作描述')),
('remark', models.TextField(blank=True, default='', verbose_name='操作备注')),
('state', models.CharField(max_length=200, verbose_name='业务状态')),
('data', django.contrib.postgres.fields.jsonb.JSONField(blank=True, null=True, verbose_name='certapp数据json')),
('certapp', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='project.CertApp', verbose_name='业务')),
('hander', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to=settings.AUTH_USER_MODEL, verbose_name='处理人')),
],
options={
'abstract': False,
},
),
migrations.RemoveField(
model_name='subapplication',
name='application',
),
migrations.RemoveField(
model_name='subapplication',
name='belong_dept',
),
migrations.RemoveField(
model_name='subapplication',
name='cccpv_class',
),
migrations.RemoveField(
model_name='subapplication',
name='cert_field',
),
migrations.RemoveField(
model_name='subapplication',
name='cnas_scopes',
),
migrations.RemoveField(
model_name='subapplication',
name='create_by',
),
migrations.RemoveField(
model_name='subapplication',
name='factory',
),
migrations.RemoveField(
model_name='subapplication',
name='manufacture',
),
migrations.RemoveField(
model_name='subapplication',
name='project',
),
migrations.RemoveField(
model_name='subapplication',
name='update_by',
),
migrations.DeleteModel(
name='Application',
),
migrations.DeleteModel(
name='SubApplication',
),
]

View File

@ -0,0 +1,18 @@
# Generated by Django 3.0.7 on 2020-10-14 06:12
from django.db import migrations
class Migration(migrations.Migration):
dependencies = [
('project', '0043_auto_20201014_1215'),
]
operations = [
migrations.RenameField(
model_name='certappflow',
old_name='hander',
new_name='handler',
),
]

View File

@ -1,3 +1,4 @@
from django.contrib.postgres.fields.jsonb import JsonAdapter
from utils import model from utils import model
from django.contrib.postgres.fields import JSONField from django.contrib.postgres.fields import JSONField
from django.db import models from django.db import models
@ -10,6 +11,76 @@ from apps.system.models import CommonAModel, CommonBModel, Dict, User
# Create your models here. # Create your models here.
# class Application(CommonBModel):
# """
# 主申请
# """
# status_choices = (
# ('草稿', '草稿'),
# ('已申请', '已申请'),
# ('已受理', '已受理'),
# ('进行中', '进行中'),
# ('已中止', '已中止'),
# ('已完成', '已完成')
# )
# result_choices = (
# ('未评审', '未评审'),
# ('合格', '合格'),
# ('不合格', '不合格'),
# ('有条件放行', '有条件放行')
# )
# stage_choices = (
# (0, '基本信息'),
# (1, '申请内容')
# )
# number = models.CharField('申请编号', max_length = 100)
# apply_date = models.DateField('申请日期', null=True, blank=True)
# accept_date = models.DateField('受理日期', null=True, blank=True)
# applicant_v = JSONField(verbose_name='申请方')
# applicant = models.ForeignKey(Enterprise, related_name='application_applicant', on_delete=models.DO_NOTHING)
# fields = models.TextField('认证领域', blank=True)
# status = models.CharField('申请状态', choices=status_choices, default='草稿', max_length=50)
# stage = models.IntegerField('步骤状态', choices=stage_choices, default=0)
# evresult = models.CharField('评审结论', choices = result_choices, default='未评审', max_length=50)
# evremark = models.TextField('备注', blank=True)
# level = models.ForeignKey(Dict, related_name='application_level', on_delete = models.DO_NOTHING)
# class Meta:
# verbose_name = '认证主申请'
# verbose_name_plural = verbose_name
# def __str__(self):
# return self.number
# class SubApplication(CommonBModel):
# """
# 子申请
# """
# pattern_choices = (
# ('正常', '正常'),
# ('ODM', 'ODM'),
# ('OEM', 'OEM')
# )
# number = models.CharField('子申请编号', max_length = 100)
# application = models.ForeignKey(Application, on_delete=models.CASCADE, related_name='subapplication_application')
# cert_field = models.ForeignKey(Dict, verbose_name='认证领域', related_name='subapplication_cert_field', on_delete=models.DO_NOTHING)
# cccpv_class = models.ForeignKey(Dict, verbose_name='涉及CCC/PV分类', related_name='subapplication_cccpv_class', on_delete=models.DO_NOTHING, null=True, blank=True)
# cnas_scopes = models.ManyToManyField(Dict, verbose_name='涉及cnas分类', related_name='subapplication_cnas_sopes', blank=True)
# project = models.ForeignKey(Project, related_name='subapplication_project', on_delete=models.SET_NULL, null=True)
# is_approve = models.BooleanField('是否认可', default=True)
# pattern = models.CharField('申请模式', choices=pattern_choices, max_length=50, null=True, blank=True)
# manufacture = models.ForeignKey(Enterprise, on_delete=models.CASCADE, related_name='subapplication_manufacture', null=True, blank=True)
# manufacture_v = JSONField(verbose_name='制造商', null=True)
# factory = models.ForeignKey(Enterprise, on_delete=models.CASCADE, related_name='subapplication_factory', null=True, blank=True)
# factory_v = JSONField(verbose_name='生产厂', null=True)
# class Meta:
# verbose_name = '认证子申请'
# verbose_name_plural = verbose_name
# def __str__(self):
# return self.number
class Project(CommonBModel): class Project(CommonBModel):
""" """
认证项目 认证项目
@ -117,76 +188,16 @@ class CertApp(CommonBModel):
verbose_name = '认证受理' verbose_name = '认证受理'
verbose_name_plural = verbose_name verbose_name_plural = verbose_name
class Application(CommonBModel): class CertAppFlow(model.BaseModel):
""" """
主申请 certapp流转记录
""" """
status_choices = ( certapp = models.ForeignKey(CertApp, on_delete=models.CASCADE, verbose_name='业务')
('草稿', '草稿'), handler = models.ForeignKey(User, on_delete=models.CASCADE, verbose_name='处理人')
('已申请', '已申请'), operation = models.TextField('操作描述')
('已受理', '已受理'), remark = models.TextField('操作备注', default='', blank=True)
('进行中', '进行中'), state = models.CharField('业务状态', max_length=200)
('已中止', '已中止'), data = JSONField('certapp数据json', null=True, blank=True)
('已完成', '已完成')
)
result_choices = (
('未评审', '未评审'),
('合格', '合格'),
('不合格', '不合格'),
('有条件放行', '有条件放行')
)
stage_choices = (
(0, '基本信息'),
(1, '申请内容')
)
number = models.CharField('申请编号', max_length = 100)
apply_date = models.DateField('申请日期', null=True, blank=True)
accept_date = models.DateField('受理日期', null=True, blank=True)
applicant_v = JSONField(verbose_name='申请方')
applicant = models.ForeignKey(Enterprise, related_name='application_applicant', on_delete=models.DO_NOTHING)
fields = models.TextField('认证领域', blank=True)
status = models.CharField('申请状态', choices=status_choices, default='草稿', max_length=50)
stage = models.IntegerField('步骤状态', choices=stage_choices, default=0)
evresult = models.CharField('评审结论', choices = result_choices, default='未评审', max_length=50)
evremark = models.TextField('备注', blank=True)
level = models.ForeignKey(Dict, related_name='application_level', on_delete = models.DO_NOTHING)
class Meta:
verbose_name = '认证主申请'
verbose_name_plural = verbose_name
def __str__(self):
return self.number
class SubApplication(CommonBModel):
"""
子申请
"""
pattern_choices = (
('正常', '正常'),
('ODM', 'ODM'),
('OEM', 'OEM')
)
number = models.CharField('子申请编号', max_length = 100)
application = models.ForeignKey(Application, on_delete=models.CASCADE, related_name='subapplication_application')
cert_field = models.ForeignKey(Dict, verbose_name='认证领域', related_name='subapplication_cert_field', on_delete=models.DO_NOTHING)
cccpv_class = models.ForeignKey(Dict, verbose_name='涉及CCC/PV分类', related_name='subapplication_cccpv_class', on_delete=models.DO_NOTHING, null=True, blank=True)
cnas_scopes = models.ManyToManyField(Dict, verbose_name='涉及cnas分类', related_name='subapplication_cnas_sopes', blank=True)
project = models.ForeignKey(Project, related_name='subapplication_project', on_delete=models.SET_NULL, null=True)
is_approve = models.BooleanField('是否认可', default=True)
pattern = models.CharField('申请模式', choices=pattern_choices, max_length=50, null=True, blank=True)
manufacture = models.ForeignKey(Enterprise, on_delete=models.CASCADE, related_name='subapplication_manufacture', null=True, blank=True)
manufacture_v = JSONField(verbose_name='制造商', null=True)
factory = models.ForeignKey(Enterprise, on_delete=models.CASCADE, related_name='subapplication_factory', null=True, blank=True)
factory_v = JSONField(verbose_name='生产厂', null=True)
class Meta:
verbose_name = '认证子申请'
verbose_name_plural = verbose_name
def __str__(self):
return self.number
class EvaluationDetail(CommonBModel): class EvaluationDetail(CommonBModel):
@ -206,6 +217,7 @@ class Certappunit(CommonBModel):
""" """
认证单元,一个单元一张证书 认证单元,一个单元一张证书
""" """
certunit = models.ForeignKey('crm.Certunit', verbose_name='单元', on_delete=models.CASCADE, related_name='certappunit_certunit') certunit = models.ForeignKey('crm.Certunit', verbose_name='单元', on_delete=models.CASCADE, related_name='certappunit_certunit')
certapp = models.ForeignKey(CertApp, verbose_name='所属业务', on_delete = models.CASCADE, related_name='certappunit_certapp') certapp = models.ForeignKey(CertApp, verbose_name='所属业务', on_delete = models.CASCADE, related_name='certappunit_certapp')
decision = models.ForeignKey(Dict,verbose_name='认证决定', on_delete = models.CASCADE, related_name='unitaccess_decision', null=True, blank=True) decision = models.ForeignKey(Dict,verbose_name='认证决定', on_delete = models.CASCADE, related_name='unitaccess_decision', null=True, blank=True)
@ -256,6 +268,7 @@ class Certappunit(CommonBModel):
remarks = models.TextField('检验反馈备注', null=True, blank=True) remarks = models.TextField('检验反馈备注', null=True, blank=True)
path = models.CharField('文件地址', max_length=1000, null=True, blank=True) path = models.CharField('文件地址', max_length=1000, null=True, blank=True)
inspectionstate = models.CharField('实验室检验状态', choices=charge_choices,null=True, blank=True, max_length=50) inspectionstate = models.CharField('实验室检验状态', choices=charge_choices,null=True, blank=True, max_length=50)
class Meta: class Meta:
verbose_name = '认证单元' verbose_name = '认证单元'
verbose_name_plural = verbose_name verbose_name_plural = verbose_name

View File

@ -9,36 +9,36 @@ from apps.certset.serializers import StandardSerializer
from apps.plan.serializers import PlanSerializer from apps.plan.serializers import PlanSerializer
from apps.laboratory.serializers import TestOrgSerializer from apps.laboratory.serializers import TestOrgSerializer
class ApplicationCreateSerializer(serializers.ModelSerializer): # class ApplicationCreateSerializer(serializers.ModelSerializer):
number = serializers.CharField(required=False) # number = serializers.CharField(required=False)
class Meta: # class Meta:
model = Application # model = Application
fields = '__all__' # fields = '__all__'
class ApplicationUpdateSerializer(serializers.ModelSerializer): # class ApplicationUpdateSerializer(serializers.ModelSerializer):
number = serializers.CharField(read_only=True) # number = serializers.CharField(read_only=True)
stage_ = serializers.SerializerMethodField(source='stage', read_only=True) # stage_ = serializers.SerializerMethodField(source='stage', read_only=True)
class Meta: # class Meta:
model = Application # model = Application
fields = '__all__' # fields = '__all__'
def get_stage_(self, obj): # def get_stage_(self, obj):
return obj.get_stage_display() # return obj.get_stage_display()
class SubApplicationCreateSerializer(serializers.ModelSerializer): # class SubApplicationCreateSerializer(serializers.ModelSerializer):
number = serializers.CharField(required=False) # number = serializers.CharField(required=False)
class Meta: # class Meta:
model = SubApplication # model = SubApplication
fields = '__all__' # fields = '__all__'
class SubApplicationUpdateSerializer(serializers.ModelSerializer): # class SubApplicationUpdateSerializer(serializers.ModelSerializer):
number = serializers.CharField(read_only=True) # number = serializers.CharField(read_only=True)
cert_field_ = DictSerializer(source='cert_field') # cert_field_ = DictSerializer(source='cert_field')
cccpv_class_ = DictSerializer(source='cccpv_class') # cccpv_class_ = DictSerializer(source='cccpv_class')
cnas_scopes_ = DictSerializer(source='cnas_scopes', many=True) # cnas_scopes_ = DictSerializer(source='cnas_scopes', many=True)
class Meta: # class Meta:
model = SubApplication # model = SubApplication
fields = '__all__' # fields = '__all__'
class CertappSerializer(serializers.ModelSerializer): class CertappSerializer(serializers.ModelSerializer):
cert_field_ = DictSerializer(source='cert_field', read_only=True) cert_field_ = DictSerializer(source='cert_field', read_only=True)
@ -62,7 +62,9 @@ from apps.certificate.models import Certificate
class CertappunitSerializer(serializers.ModelSerializer): class CertappunitSerializer(serializers.ModelSerializer):
certunit_ = CertunitSimpleSerializer(source = 'certunit', read_only=True) certunit_ = CertunitSimpleSerializer(source = 'certunit', read_only=True)
decision_ = DictSimpleSerializer(source = 'decision', read_only=True) decision_ = DictSimpleSerializer(source = 'decision', read_only=True)
testorg_ = TestOrgSerializer(source = 'testorg', read_only=True) testorg_ = TestOrgSerializer(source = 'testorg', read_only=True)
certificate_ = serializers.SerializerMethodField() certificate_ = serializers.SerializerMethodField()
class Meta: class Meta:
model = Certappunit model = Certappunit

View File

@ -3,8 +3,8 @@ from .views import *
from rest_framework import routers from rest_framework import routers
router = routers.DefaultRouter() router = routers.DefaultRouter()
router.register('application', ApplicationViewSet, basename="application") # router.register('application', ApplicationViewSet, basename="application")
router.register('subapplication', SubApplicationViewSet, basename="subapplication") # router.register('subapplication', SubApplicationViewSet, basename="subapplication")
router.register('certapp', CertappViewset, basename="certapp") router.register('certapp', CertappViewset, basename="certapp")
router.register('certappunit', CertappunitViewset, basename="certappunit") router.register('certappunit', CertappunitViewset, basename="certappunit")
router.register('evaluationdetail', EvaluationDetailViewset, basename="evaluationdetail") router.register('evaluationdetail', EvaluationDetailViewset, basename="evaluationdetail")

View File

@ -21,54 +21,54 @@ from rest_framework.exceptions import ParseError, NotAuthenticated
from django.utils import timezone from django.utils import timezone
# Create your views here. # Create your views here.
class ApplicationViewSet(RbacFilterSet, ModelViewSet): # class ApplicationViewSet(RbacFilterSet, ModelViewSet):
""" # """
认证申请 # 认证申请
""" # """
perms_map = {'get': 'application_view', 'post':'application_create', 'put':'application_update','delete': 'application_delete'} # perms_map = {'get': 'application_view', 'post':'application_create', 'put':'application_update','delete': 'application_delete'}
queryset = Application.objects.all() # queryset = Application.objects.all()
serializer_class = ApplicationCreateSerializer # serializer_class = ApplicationCreateSerializer
ordering = ['-create_time'] # ordering = ['-create_time']
def get_serializer_class(self): # def get_serializer_class(self):
if self.action == 'create': # if self.action == 'create':
return ApplicationCreateSerializer # return ApplicationCreateSerializer
else: # else:
return ApplicationUpdateSerializer # return ApplicationUpdateSerializer
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(RbacFilterSet, ModelViewSet): # class SubApplicationViewSet(RbacFilterSet, ModelViewSet):
""" # """
子认证申请 # 子认证申请
""" # """
perms_map = {'get': 'application_view', 'post':'application_create', 'put':'application_update','delete': 'application_delete'} # perms_map = {'get': 'application_view', 'post':'application_create', 'put':'application_update','delete': 'application_delete'}
queryset = SubApplication.objects.all() # queryset = SubApplication.objects.all()
serializer_class = SubApplicationCreateSerializer # serializer_class = SubApplicationCreateSerializer
filterset_fields = ['application'] # filterset_fields = ['application']
ordering = ['-create_time'] # ordering = ['-create_time']
def get_serializer_class(self): # def get_serializer_class(self):
if self.action == 'create': # if self.action == 'create':
return SubApplicationCreateSerializer # return SubApplicationCreateSerializer
else: # else:
return SubApplicationUpdateSerializer # return SubApplicationUpdateSerializer
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)
serializer = self.get_serializer(data=postdata) # serializer = self.get_serializer(data=postdata)
serializer.is_valid(raise_exception=True) # serializer.is_valid(raise_exception=True)
self.perform_create(serializer) # self.perform_create(serializer)
headers = self.get_success_headers(serializer.data) # headers = self.get_success_headers(serializer.data)
return Response(serializer.data, status=status.HTTP_201_CREATED, headers=headers) # return Response(serializer.data, status=status.HTTP_201_CREATED, headers=headers)
def paginate_queryset(self, queryset): # def paginate_queryset(self, queryset):
if ((not self.request.query_params.get('page', None)) and (self.request.query_params.get('application', None))) or (self.paginator is None): # if ((not self.request.query_params.get('page', None)) and (self.request.query_params.get('application', None))) or (self.paginator is None):
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(PageOrNot, RbacFilterSet, ModelViewSet): class CertappViewset(PageOrNot, RbacFilterSet, ModelViewSet):
""" """
@ -89,7 +89,9 @@ class CertappViewset(PageOrNot, RbacFilterSet, ModelViewSet):
postdata['cert_field'] = Dict.objects.get(code=postdata['field_code']).id postdata['cert_field'] = Dict.objects.get(code=postdata['field_code']).id
serializer = self.get_serializer(data=postdata) serializer = self.get_serializer(data=postdata)
serializer.is_valid(raise_exception=True) serializer.is_valid(raise_exception=True)
self.perform_create(serializer) # self.perform_create(serializer)
instance = serializer.save(create_by = self.request.user, belong_dept=self.request.user.dept, state='受理')
CertAppFlow.objects.create(certapp = instance, handler=self.request.user, data=serializer.data, operation='创建申请', state='申请')
headers = self.get_success_headers(serializer.data) headers = self.get_success_headers(serializer.data)
return Response(serializer.data, status=status.HTTP_201_CREATED, headers=headers) return Response(serializer.data, status=status.HTTP_201_CREATED, headers=headers)
@ -102,6 +104,7 @@ class CertappViewset(PageOrNot, RbacFilterSet, ModelViewSet):
obj = self.get_object() obj = self.get_object()
obj.state = '策划' obj.state = '策划'
obj.save() obj.save()
CertAppFlow.objects.create(certapp = obj, handler=self.request.user, data=self.get_serializer(obj), operation='完成受理', state='受理')
return Response(status=status.HTTP_200_OK) return Response(status=status.HTTP_200_OK)
@action(methods=['put'], detail=False, perms_map={'put':'certapp_review'}, @action(methods=['put'], detail=False, perms_map={'put':'certapp_review'},
@ -120,7 +123,7 @@ class CertappViewset(PageOrNot, RbacFilterSet, ModelViewSet):
@action(methods=['put'], detail=True, perms_map={'put':'certapp_access'}, url_name='certapp_access') @action(methods=['put'], detail=True, perms_map={'put':'certapp_access'}, url_name='certapp_access')
def access(self, request, pk=None): def access(self, request, pk=None):
""" """
认证评定 评定
""" """
# instance, ok = Certaccess.objects.get_or_create(certapp=self.get_object(), defaults={'certapp':self.get_object() # instance, ok = Certaccess.objects.get_or_create(certapp=self.get_object(), defaults={'certapp':self.get_object()
# , 'conclusion':Dict.objects.get(pk=request.data['conclusion']), 'score':request.data['score']}) # , 'conclusion':Dict.objects.get(pk=request.data['conclusion']), 'score':request.data['score']})
@ -204,20 +207,23 @@ class CertappunitViewset(PageOrNot, ModelViewSet):
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=True, perms_map={'put':'certapp_createsamples'}, url_name='certappunit_createsamples') @action(methods=['put'], detail=True, perms_map={'put':'certapp_createsamples'}, url_name='certappunit_createsamples')
def createsamples(self, request, pk=None): def createsamples(self, request, pk=None):
""" """
实验室任务反馈 实验室任务反馈
""" """
obj = self.get_object() obj = self.get_object()
obj.teststate = '到样检测中'
obj.sampledate = request.data['sampledate'] obj.sampledate = request.data['sampledate']
obj.inspectionstate = request.data['inspectionstate'] obj.save()
if request.data['inspectionstate']=="已检测": return Response(status=status.HTTP_200_OK)
obj.teststate = '待评定' @action(methods=['put'], detail=True, perms_map={'put':'certapp_createcomplete'}, url_name='certappunit_createcomplete')
else: def createcomplete(self, request, pk=None):
obj.teststate = '到样检测中' """
实验室任务反馈
"""
obj = self.get_object()
obj.teststate = '待提取报告'
obj.path = request.data['path'] obj.path = request.data['path']
obj.conclusion = request.data['conclusion'] obj.conclusion = request.data['conclusion']
obj.completedate = request.data['completedate'] obj.completedate = request.data['completedate']
@ -230,6 +236,7 @@ class CertappunitViewset(PageOrNot, ModelViewSet):
from apps.plan.models import Member
class ProjectViewSet(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()
@ -248,28 +255,23 @@ class ProjectViewSet(RbacFilterSet, ModelViewSet):
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)
if self.request.user is not None: instance = serializer.save(create_by = self.request.user, belong_dept=self.request.user.dept)
instance = serializer.save(create_by = self.request.user, belong_dept=self.request.user.dept) if 'certapps' in postdata and postdata['certapps']:
if 'certapps' in postdata and postdata['certapps']: CertApp.objects.filter(pk__in = postdata['certapps']).update(project=instance)
CertApp.objects.filter(pk__in = postdata['certapps']).update(project=instance, state='进行中') instance.state = '待策划'
headers = self.get_success_headers(serializer.data) instance.save()
return Response(serializer.data, status=status.HTTP_201_CREATED, headers=headers) headers = self.get_success_headers(serializer.data)
else: return Response(serializer.data, status=status.HTTP_201_CREATED, headers=headers)
return NotAuthenticated()
@action(methods=['put'], detail=True, perms_map={'put':'project_next'}, @action(methods=['put'], detail=True, perms_map={'put':'project_assgin'},
url_name='project_next') url_name='project_assgin')
def next(self, request, pk=None): def assgin(self, request, pk=None):
""" """
项目流转 审核任务下达
""" """
obj = self.get_object() obj = self.get_object()
if obj.state == '创建中': if obj.state == '策划中':
obj.state = '待策划' obj.state = '审核任务已下达'
obj.save()
return Response(status=status.HTTP_200_OK)
elif obj.state == '策划中' and obj.can_paichai:
obj.state = '待现场审核'
obj.save() obj.save()
return Response(status=status.HTTP_200_OK) return Response(status=status.HTTP_200_OK)
else: else:
@ -280,16 +282,16 @@ class ProjectViewSet(RbacFilterSet, ModelViewSet):
url_name='project_plan') url_name='project_plan')
def plan(self, request, *args, **kwargs): def plan(self, request, *args, **kwargs):
""" """
项目计划 加入计划
""" """
projects = request.data['projects'] projects = request.data['projects']
plan = request.data['plan'] plan = request.data['plan']
if projects: if projects:
objs = Project.objects.filter(pk__in=projects) objs = Project.objects.filter(pk__in=projects)
for i in objs: for i in objs:
i.plan=plan i.plan=Plan.objects.get(pk=plan)
if i.state == '待策划': if i.state == '待策划':
i.state == '策划中' i.state = '策划中'
i.save() i.save()
return Response(status=status.HTTP_200_OK) return Response(status=status.HTTP_200_OK)
@ -304,3 +306,20 @@ class ProjectViewSet(RbacFilterSet, ModelViewSet):
obj.edate1 = request.data['edate1'] obj.edate1 = request.data['edate1']
obj.save() obj.save()
return Response(status=status.HTTP_200_OK) return Response(status=status.HTTP_200_OK)
@action(methods=['put'], detail=True, perms_map={'put':'audit_accept'},url_name='audit_accept')
def accept(self, request, *args, **kwargs):
"""
接受项目审核任务
"""
obj = self.get_object()
if obj.state == '审核任务已下达':
obj.state = '审核任务已接受'
obj.save()
Member.objects.filter(certapp__project=obj).update(is_accepted=True)
obj.certapp_project.all().update(state='审核')
for i in obj.certapp_project.all():
CertAppFlow.objects.create(certapp = i, handler=self.request.user, operation='审核任务已接受', state='策划')
return Response(status=status.HTTP_200_OK)
return Response('项目状态异常,操作失败', status=status.HTTP_400_BAD_REQUEST)

View File

@ -42,7 +42,7 @@ class DictSerializer(serializers.ModelSerializer):
class DictSimpleSerializer(serializers.ModelSerializer): class DictSimpleSerializer(serializers.ModelSerializer):
class Meta: class Meta:
model = Dict model = Dict
fields = ['pk', 'name', 'code'] fields = ['id', 'name', 'code']
class PositionSerializer(serializers.ModelSerializer): class PositionSerializer(serializers.ModelSerializer):
""" """