certapp流程状态设置

This commit is contained in:
caoqianming 2020-10-22 16:13:24 +08:00
parent b3b30cd67c
commit cb734240e2
29 changed files with 645 additions and 221 deletions

View File

@ -62,3 +62,18 @@ export function accessCertapp(id, data) {
data
})
}
export function feedbackCertapp(id, data) {
return request({
url: `/project/certapp/${id}/feedback/`,
method: 'put',
data
})
}
export function flowCertapp(id) {
return request({
url: `/project/certapp/${id}/flow/`,
method: 'get',
})
}

View File

@ -68,3 +68,19 @@ export function acceptAudit(id) {
method: 'put',
})
}
export function startProject(id, data) {
return request({
url: `/project/project/${id}/start/`,
method: 'put',
data
})
}
export function feedbackProject(id, data) {
return request({
url: `/project/project/${id}/feedback/`,
method: 'put',
data
})
}

View File

@ -184,10 +184,17 @@ export const asyncRoutes = [
hidden: true
},
{
path: 'certapp/:id/:action/',
path: 'certapp/:id/feedback/',
name: 'Certappfeedback',
component: () => import('@/views/certapp/certapphandle'),
meta: { title: '业务审核反馈', icon: 'example', perms: ['certapp_feedback'] },
meta: { title: '审核反馈', icon: 'example', perms: ['certapp_feedback'] },
hidden: true
},
{
path: 'certapp/:id/test/',
name: 'Certapptest',
component: () => import('@/views/certapp/certapphandle'),
meta: { title: '检测任务', icon: 'example', perms: ['certapp_test'] },
hidden: true
},
]
@ -232,7 +239,6 @@ export const asyncRoutes = [
meta: { title: '任务反馈', noCache: true, icon: '', perms: ['feedbacks_create']},
hidden: true
},
]
},
{

View File

@ -104,3 +104,7 @@ div:focus {
.el-tabs__header {
margin: 0 0 6px;
}
ul {
padding-inline-start: 6px;
}

View File

@ -49,7 +49,7 @@
</el-form-item>
</el-col>
<div style="text-align:center">
<el-button type="primary" @click="save">保存</el-button>
<el-button type="primary" @click="save" v-if="formData.state=='产品检测'||formData.state=='评定'">保存</el-button>
</div>
</el-form>
</el-card>
@ -71,9 +71,15 @@
<el-table-column label="单元名称">
<template slot-scope="scope" v-if="scope.row.certunit_">{{ scope.row.certunit_.name }}</template>
</el-table-column>
<el-table-column label="已有证书信息">
<template slot-scope="scope" v-if="scope.row.certificate_">
{{ scope.row.certificate_.number }}
<el-table-column label="检测信息">
<template slot-scope="scope" >
{{ scope.row.teststate }}
</template>
</el-table-column>
<el-table-column label="证书信息">
<template slot-scope="scope">
<span v-if="scope.row.certificate_">{{ scope.row.certificate_.number }}</span>
<span v-else>暂无</span>
</template>
</el-table-column>
<el-table-column label="认证决定">
@ -218,6 +224,9 @@ getDictList({type__code:'cert_decision', pageoff:true}).then(res=>{
handleAcessunit(val,id){
accessCertappunit(id, {'decision':val}).then(res=>{
this.$message.success('成功')
this.formData.state = res.data.state
this.$emit("stateChange", res.data.state);
this.$emit("flowChange");
})
}

View File

@ -1,8 +1,10 @@
<template>
<div>
<el-button type="primary" @click="handleConfirm" v-if="$route.name=='Certappfeedback'||$route.name=='Certapptest'">提交反馈</el-button>
</div>
</template>
<script>
import { feedbackCertapp } from "@/api/certapp"
export default {
name: "Conclusion",
@ -18,7 +20,13 @@ export default {
created() {
},
methods: {
handleConfirm() {
feedbackCertapp(this.certapp, this.formData).then(res=>{
this.$message.success('成功')
this.$emit("stateChange", res.data.state);
this.$emit("flowChange");
})
}
},
};
</script>

View File

@ -99,7 +99,7 @@
</el-card>
</el-col>
<el-col :xs="24" :md="12">
<el-card style="margin-top:6px" v-if="$route.params.action=='feedback'">
<el-card style="margin-top:6px" v-if="this.$route.name=='Certappfeedback' || this.$route.name=='Certapptest'">
<div slot="header" class="clearfix">
<span>审核员参与天数/人日数</span>
</div>

View File

@ -1,6 +1,6 @@
<template>
<div class="app-container">
<el-card >
<el-card>
<el-row :gutter="6">
<el-col :xs="24" :md="3">
<el-select
@ -10,8 +10,8 @@
class="filter-item"
@change="handleFilter"
>
<el-option label="全部" value=""/>
<el-option label="待接受" value="审核任务已下达"/>
<el-option label="全部" value="" />
<el-option label="待接受" value="审核任务已下达" />
</el-select>
</el-col>
<el-col :xs="24" :md="6">
@ -100,19 +100,38 @@
<el-table-column label="操作" width="300" fixed="right">
<template slot-scope="scope">
<el-button
v-if="scope.row.state=='审核任务已下达'"
v-if="scope.row.state == '审核任务已接受'"
type="primary"
size="small"
:disabled="!checkPermission(['audit_edate'])"
@click="handleEdate(scope)"
>安排时间</el-button>
<el-button
v-if="scope.row.state == '待现场审核'"
type="primary"
size="small"
:disabled="!checkPermission(['audit_edate'])"
@click="handleStart(scope)"
>开始审核</el-button>
<el-button
v-if="scope.row.state == '审核任务已下达'"
type="primary"
size="small"
:disabled="!checkPermission(['audit_accept'])"
@click="handleAccept(scope)"
>接受任务</el-button
>
>接受任务</el-button>
<el-button
v-if="scope.row.state == '现场审核中'"
type="primary"
size="small"
:disabled="!checkPermission(['project_feedback'])"
@click="handleFeedbackp(scope)"
>反馈</el-button>
<el-button
size="small"
:disabled="!checkPermission(['project_delete'])"
@click="handleDetailProject(scope)"
>详情</el-button
>
>详情</el-button>
</template>
</el-table-column>
</el-table>
@ -208,12 +227,21 @@
<el-button
type="primary"
size="small"
:disabled="!checkPermission(['certapp_feedback']) || projectstate != '现场审核中'"
:disabled="
!checkPermission(['certapp_feedback'])
"
@click="handleCertappFeedback(scope)"
>反馈</el-button
>
<el-button
type="danger"
size="small"
:disabled="
!checkPermission(['certapp_test'])
"
@click="handleCertappTest(scope)"
>安排检测</el-button
>
<el-button
size="small"
:disabled="!checkPermission(['certapp_detail'])"
@click="handleCertappDetail(scope)"
@ -239,7 +267,7 @@ export default {
components: { Pagination, Treeselect },
data() {
return {
projectstate:'',
projectstate: "",
listLoading: false,
listLoading2: false,
listQuery: {
@ -281,9 +309,27 @@ export default {
params: { id: scope.row.id },
});
},
handleEdate(scope) {
this.$router.push({
name: "AuditProject",
params: { id: scope.row.id },
});
},
handleFeedbackp(scope){
this.$router.push({
name: "AuditProject",
params: { id: scope.row.id },
});
},
handleStart(scope) {
this.$router.push({
name: "AuditProject",
params: { id: scope.row.id },
});
},
handleRclick(row, column, event) {
this.listLoading2 = true;
this.projectstate = row.state
this.projectstate = row.state;
getAuditCertappList({ project: row.id, pageoff: true })
.then((res) => {
this.certappData = res.data;
@ -294,17 +340,26 @@ export default {
});
},
handleAccept(scope) {
acceptAudit(scope.row.id).then(res=>{
this.getProjectList_()
this.$message.success('成功')
}).catch(e=>{})
},
handleCertappFeedback(scope) {
this.$router.push({
name: "Certappfeedback",
params: { id: scope.row.id },
this.$confirm("确认接受该项目吗?", "", {
confirmButtonText: "确认",
cancelButtonText: "取消",
type: "warning",
}).then(() => {
acceptAudit(scope.row.id)
.then((res) => {
this.getProjectList_();
this.$message.success("成功");
})
.catch((e) => {});
});
},
handleCertappFeedback(scope) {
this.$router.push({name:"Certappfeedback", params:{action:'feedback', id:scope.row.id}})
},
handleCertappTest(scope) {
this.$router.push({name:"Certapptest", params:{action:'test', id:scope.row.id}})
},
handleCertappDetail(scope) {
this.$router.push({
name: "Certappdetail",
@ -316,7 +371,7 @@ export default {
name: "AuditProject",
params: { id: scope.row.id },
});
}
},
},
};
</script>

View File

@ -243,8 +243,8 @@
</el-row>
</el-form>
<div slot="footer" align="center">
<el-button @click="cancel()">返回列表</el-button>
<el-button type="primary" @click="handelConfirm">保存</el-button>
<el-button @click="cancel()">返回</el-button>
<el-button type="primary" @click="handelConfirm" v-if="$route.name=='Certappupdate' || $route.name =='Certappcreate'">保存</el-button>
</div>
<el-dialog
title="选择企业"

View File

@ -101,7 +101,6 @@
</el-table-column>
<el-table-column label="操作">
<template slot-scope="scope">
<el-button-group>
<el-button
type="primary"
size="small"
@ -114,7 +113,6 @@
:disabled="!checkPermission(['case_delete'])"
@click="handleDelete(scope)"
>删除</el-button>
</el-button-group>
</template>
</el-table-column>
</el-table>
@ -190,10 +188,17 @@ export default {
this.$router.push({name:"Certappupdate", params:{ id:scope.row.id}})
},
handleDelete(scope) {
deleteCertapp(scope.row.id).then(res=>{
this.$confirm('确认删除?', '警告', {
confirmButtonText: '确认',
cancelButtonText: '取消',
type: 'error'
}).then(()=>{
deleteCertapp(scope.row.id).then(res=>{
this.$message.success('成功')
this.getList()
})
}).catch(e=>{})
},
getfields(){
getDictList({type__code:'cert_field'}).then(res=>{

View File

@ -35,14 +35,14 @@
<el-tab-pane label="审核成员" name="Certappmember" v-if="certapp" lazy>
<Member :certapp="certapp"></Member>
</el-tab-pane>
<el-tab-pane label="现场审核反馈" name="Certappfeedback" v-if="certapp" lazy>
<Conclusion :certapp="certapp"></Conclusion>
<el-tab-pane label="审核反馈" name="Certappfeedback" v-if="certapp" lazy>
<Conclusion :certapp="certapp" @stateChange="stateChange" @flowChange="flowChange"></Conclusion>
</el-tab-pane>
<el-tab-pane label="安排检测任务" name="Certapptask" v-if="certapp" lazy>
<el-tab-pane label="检测任务" name="Certapptest" v-if="certapp" lazy>
<Detectiontask :certapp="certapp"></Detectiontask>
</el-tab-pane>
<el-tab-pane label="认证评定" name="Certappaccess" v-if="certapp" lazy>
<access :certapp="certapp" :key="Certappaccesskey"></access>
<access :certapp="certapp" :key="Certappaccesskey" @stateChange="stateChange" @flowChange="flowChange"></access>
</el-tab-pane>
<el-tab-pane label="证书颁发/通知" name="Certissue" v-if="certapp" lazy>
<issue :certapp="certapp"></issue>
@ -56,10 +56,12 @@
</div>
<el-timeline style="margin-top:6px">
<el-timeline-item
v-for="(activity, index) in activities"
v-for="(item, index) in activities"
:key="index"
:timestamp="activity.timestamp">
{{activity.content}}
:timestamp="item.create_time"
placement="top">
<span>{{item.handler_.name}}</span>
<span>{{item.operation}}</span>
</el-timeline-item>
</el-timeline>
</el-card>
@ -73,7 +75,7 @@
import CCCform from "@/views/certapp/cccform"
import Certunit from "@/views/certapp/certunit"
import CHARGE from "@/views/certapp/charge"
import { getCertapp, completeCertapp } from "@/api/certapp"
import { getCertapp, completeCertapp, flowCertapp } from "@/api/certapp"
import router from '@/router';
import QMSform from "@/views/certapp/qmsform"
import Conclusion from "@/views/audit/conclusion"
@ -90,24 +92,16 @@ export default {
props: [],
data() {
return {
states:['申请', '受理', '策划', '现场审核', '产品检测', '评定', '出证', '归档'],
states:['申请', '受理', '策划', '现场审核', '产品检测', '评定', '出证', '完成'],
stateIndex:1,
activeName:'Basic',
certapp:null,
certappdata:null,
kind:'CCC',
isLoad:false,
activities: [{
content: '活动按期开始',
timestamp: '2018-04-15'
}, {
content: '通过审核',
timestamp: '2018-04-13'
}, {
content: '创建成功',
timestamp: '2018-04-11'
}],
activities: [ ],
Certunitkey:'',
Certappaccesskey:''
};
},
computed: {},
@ -128,6 +122,7 @@ export default {
},
getParams(){
var id = this.$route.params.id
this.getFlow(id)
this.certapp = id
getCertapp(id).then(res=>{
this.certappdata = res.data
@ -150,6 +145,17 @@ export default {
this.$message.success('成功')
this.$router.go(-1)
})
},
stateChange(val){
this.stateIndex = this.states.indexOf(val)
},
getFlow(val){
flowCertapp(val).then(res=>{
this.activities = res.data
})
},
flowChange(){
this.getFlow(this.certapp)
}
}
};

View File

@ -26,7 +26,7 @@
<span>{{ scope.row.create_time }}</span>
</template>
</el-table-column>
<el-table-column label="操作">
<el-table-column label="操作" v-if="$route.name=='Certappupdate'">
<template slot-scope="scope">
<el-button
type="danger"
@ -120,7 +120,7 @@
></el-input>
</el-form-item>
</el-col>
<el-col :span="24">
<el-col :span="24" v-if="this.$route.name=='Certappupdate'">
<el-form-item size="large">
<el-button type="primary" @click="createNew">创建新记录</el-button>
<el-button type="primary" @click="updateNow">保存</el-button>

View File

@ -29,7 +29,7 @@
<template slot-scope="scope" >{{ scope.row.charge }}</template>
</el-table-column>
<el-table-column label="被委托检测机构">
<template slot-scope="scope" >{{ scope.row.testorg_.name}}</template>
<template slot-scope="scope" v-if="scope.row.testorg_">{{ scope.row.testorg_.name}}</template>
</el-table-column>
<el-table-column label="检验项目">
<template slot-scope="scope" >{{ scope.row.testitem}}</template>
@ -39,22 +39,14 @@
<span>{{ scope.row.create_time }}</span>
</template>
</el-table-column>
<el-table-column label="操作">
<el-table-column label="操作" width="200">
<template slot-scope="scope">
<el-button-group>
<el-button
type="danger"
size="small"
:disabled="!checkPermission(['certapps_update'])"
@click="handleDelete(scope)"
>删除</el-button>
<el-button
type="primary"
size="small"
:disabled="!checkPermission(['certapps_update'])"
@click="handlestate(scope.row.id)"
>下达实验室</el-button>
</el-button-group>
</template>
</el-table-column>
</el-table>

View File

@ -38,7 +38,7 @@
</el-row>
</el-form>
<div slot="footer" align="center" style="margin-top:6px">
<div slot="footer" align="center" style="margin-top:6px" v-if="$route.name=='Certappupdate'">
<el-button type="primary" @click="handelConfirm">保存</el-button>
</div>

View File

@ -6,7 +6,7 @@
<div slot="header" class="clearfix">
<span>项目信息</span>
</div>
<el-col :xs="24" :md="8" >
<el-col :xs="24" :md="10" >
<el-card shadow="hover" style="height:150px">
<div class="text item">
<span class="span">项目号</span>
@ -31,27 +31,29 @@
<span class="span">任务下达人</span>
{{project.assign_by_.name}}
</div>
<div class="text item" v-if="edate_.length">
<div class="text item" v-if="project.edate0">
<span class="span">预计审核时间</span>
{{edate_[0].substring(0,16)}}-{{edate_[1].substring(0,16)}}
{{edate_[0].substring(0,16)}} -{{edate_[1].substring(0,16)}}
</div>
<div class="text2 item" v-if="$route.name=='PlanProject'">
<div class="text item" v-if="project.start_date">
<span class="span">实际审核时间</span>
{{project.start_date.substring(0,16)}}
<span v-if="project.end_date">-{{project.end_date.substring(0,16)}}</span>
</div>
<div class="text2 item" v-if="$route.name=='PlanProject' && project.state == '策划中'">
<el-checkbox v-model="can_paichai" border @change="handlePaichai">可派差</el-checkbox>
</div>
</el-card>
</el-col>
<el-col :xs="24" :md="16" v-if="$route.name=='AuditProject'">
<el-col :xs="24" :md="14" v-if="$route.name=='AuditProject'">
<el-card shadow="hover" style="height:150px">
<el-form
ref="elForm"
size="medium"
label-width="120px"
v-if="project.state=='审核任务已接受'"
ref="edateForm"
style="margin-top:2px"
label-position="left"
:inline="true"
>
<el-row :gutter="6">
<el-col :span="16">
<el-form-item label="预计审核时间">
<el-form-item label="预计审核">
<el-date-picker
v-model="edate"
type="datetimerange"
@ -64,11 +66,28 @@
:default-time="['08:00:00', '17:00:00']"
></el-date-picker>
</el-form-item>
</el-col>
<el-col :span="8">
<el-button type="primary" @click="eDate">保存</el-button>
</el-col>
</el-row>
<el-form-item>
<el-button type="primary" @click="handleEdate">保存</el-button>
</el-form-item>
</el-form>
<el-form
v-if="project.state=='待现场审核'"
ref="sdateForm"
style="margin-top:2px"
:inline="true"
>
<el-form-item label="开始时间">
<el-date-picker
v-model="start_date"
placeholder="开始审核"
format="yyyy-MM-dd HH:mm"
:style="{width: '100%'}"
value-format="yyyy-MM-dd HH:mm"
></el-date-picker>
</el-form-item>
<el-form-item>
<el-button type="primary" @click="handleStart">开始审核</el-button>
</el-form-item>
</el-form>
</el-card>
</el-col>
@ -98,6 +117,16 @@
</el-col>
</el-row>
<el-card style="margin-top:6px">
<div slot="header" class="clearfix">
<span>项目进度</span>
</div>
<el-steps :active="states.indexOf(project.state)" finish-status="success">
<el-step v-for="item in states" :title="item"
:key="item"
></el-step>
</el-steps>
</el-card>
<el-row style="margin-top:6px">
<el-col>
<el-card class="box-card">
@ -164,14 +193,20 @@
v-if="$route.name == 'AuditProject'"
type="primary"
size="small"
:disabled="!checkPermission(['certapp_detail']) || project.state != '现场审核中'"
:disabled="!checkPermission(['certapp_detail'])"
@click="handleFeedback(scope)"
>反馈</el-button>
<el-button
v-if="$route.name == 'AuditProject'"
size="small"
:disabled="!checkPermission(['certapp_detail'])"
@click="handleCertappTest(scope)"
>安排检测</el-button>
<el-button
v-if="$route.name == 'PlanProject'"
type="primary"
size="small"
:disabled="!checkPermission(['certapp_detail']) || project.state != '策划中'"
:disabled="!checkPermission(['certapp_detail'])"
@click="handlePlan(scope)"
>派人</el-button>
<el-button
@ -280,7 +315,7 @@
<el-col :xs="24" :md="8">
<el-card class="box-card" style="overflow-y:auto;overflow-x:hidden;height:380px">
<div slot="header" class="clearfix">
<span>审核组成员</span>
<span>项目成员</span>
</div>
<el-table
ref="memberTable"
@ -369,8 +404,9 @@
<span>审核总反馈</span>
</div>
<el-form
ref="elForm"
ref="backform"
:model="backformData"
:rules="backrules"
size="medium"
label-width="80px"
style="margin-top:2px"
@ -378,9 +414,9 @@
>
<el-row>
<el-col>
<el-form-item label="实际实施时间">
<el-form-item label="实际实施时间" prop="backdate">
<el-date-picker
v-model="rdate"
v-model="backformData.backdate"
type="datetimerange"
range-separator=""
start-placeholder="开始日期"
@ -393,19 +429,19 @@
</el-form-item>
</el-col>
</el-row>
<el-row>
<!-- <el-row>
<el-col>
<el-form-item label="法律法规合规性">
<el-radio v-model="backformData.is_legal" label=true>合规</el-radio>
<el-radio v-model="backformData.is_legal" label=false>存在问题</el-radio>
</el-form-item>
</el-col>
</el-row>
</el-row> -->
<el-row>
<el-col>
<el-form-item label="备注">
<el-form-item label="备注" prop="feedback_remark">
<el-input
v-model="backformData.content"
v-model="backformData.feedback_remark"
type="textarea"
:autosize="{ minRows: 2, maxRows: 4}"
></el-input>
@ -415,7 +451,7 @@
<el-row>
<div style="text-align:center;" v-if="$route.name=='AuditProject'">
<el-button-group>
<el-button type="primary" @click="createNewRecord" :disabled="project.state != '现场审核中'">提交反馈</el-button>
<el-button type="primary" @click="handlePback" :disabled="project.state != '现场审核中'">提交反馈</el-button>
</el-button-group>
</div>
</el-row>
@ -453,7 +489,7 @@
import { getDictList } from "@/api/dict";
import { getCertappList } from "@/api/certapp";
import { getEnterprise } from "@/api/enterprise";
import { getProject, updateProject, edateProject } from "@/api/project";
import { getProject, updateProject, edateProject, startProject, feedbackProject } from "@/api/project";
import { getContactRecordList, createContactRecord } from "@/api/plan";
import Pagination from "@/components/Pagination";
import checkPermission from "@/utils/permission";
@ -470,6 +506,8 @@ export default {
props: [],
data() {
return {
states:['创建中', '待策划', '策划中', '审核任务已下达', '审核任务已接受', '待现场审核', '现场审核中', '任务已反馈', '检测评定出证', '完成'],
stateIndex:1,
auditee: {},
project: { assign_by_: null },
certappData: [],
@ -522,14 +560,26 @@ export default {
identityOptions: [],
edate:[],
edate_:[],
start_date:null,
rdate:[],
backformData:{
backdate:null,
feedback_remark:''
},
backrules:{
backdate: [
{
required: true,
message: "请选择日期",
trigger: "change",
},
],
}
};
},
computed: {},
watch: {},
watch: {
},
created() {
this.getParams();
this.getMemberList_();
@ -549,6 +599,10 @@ export default {
this.edate = [this.project.edate0, this.project.edate1]
this.edate_ = [this.project.edate0, this.project.edate1]
}
if(this.project.end_date){
this.backformData.backdate = [this.project.start_date, this.project.end_date]
this.backformData.feedback_remark = this.project.feedback_remark
}
})
.then(() => {
getEnterprise(this.project.auditee).then((res) => {
@ -673,23 +727,50 @@ export default {
handleMClick(row, c, e) {
this.formDataMember = deepClone(row);
},
eDate(){
handleEdate(){
if(this.edate.length){
edateProject(this.project.id, {edate0:this.edate[0], edate1:this.edate[1]}).then(res=>{
this.$message.success('成功')
this.edate_ = this.edate
this.project.state = res.data.state
this.project.edate0 = res.data.edate0
this.project.edate1 = res.data.edate1
}).catch(e=>{})
}
},
handleStart(scope){
startProject(this.project.id, {start_date:this.start_date}).then(res=>{
this.$message.success('成功')
this.project.state = res.data.state
this.project.start_date = res.data.start_date
}).catch(e=>{})
},
handlePback(){
this.$refs['backform'].validate(valid => {
if (valid) {
feedbackProject(this.project.id, {start_date:this.backformData.backdate[0], end_date:this.backformData.backdate[1], feedback_remark:this.backformData.feedback_remark}).then(res=>{
this.$message.success('成功')
this.project.state = res.data.state
this.project.start_date = res.data.start_date
this.project.end_date = res.data.end_date
}).catch(e=>{})}
else{
return false
}})
},
handleFeedback(scope){
this.$router.push({name:"Certappfeedback", params:{action:'feedback', id:scope.row.id}})
},
handleCertappTest(scope) {
this.$router.push({name:"Certapptest", params:{action:'test', id:scope.row.id}})
},
handlePlan(scope){
this.$router.push({name:"Certappmember", params:{action:'member', id:scope.row.id}})
},
handleDetail(scope){
this.$router.push({name:"Certappdetail", params:{id:scope.row.id}})
}
},
},
};
</script>

View File

@ -1,26 +1,61 @@
# from apps.system.models import Dict
# from rest_framework import serializers
from utils import serializer
from rest_framework import serializers
# from .models import Certaccess, Unitaccess
from .models import *
# from apps.system.serializers import DictSerializer
from apps.system.serializers import DictSimpleSerializer, UserListSerializer, UserSimpleSerializer
from apps.project.models import Project
from apps.plan.models import Member
from apps.project.serializers import PlanSerializer
from apps.plan.serializers import MemberSerializer
class ProjectSerializerX(serializers.ModelSerializer):
create_by_ = UserSimpleSerializer(source='create_by', read_only=True)
certapps = serializers.SerializerMethodField()
plan_ = PlanSerializer(source='plan', read_only=True)
members = serializers.SerializerMethodField()
class Meta:
model = Project
fields = '__all__'
# class CertaccessSerializer(serializers.ModelSerializer):
# conclusion_ = DictSerializer(source='conclusion', read_only=True)
# nonitems_ = DictSerializer(source='nonitems', read_only=True, many=True)
def get_certapps(self, obj):
certapps = []
for i in obj.certapp_project.filter(is_deleted=False):
certapps.append(i.cert_field.code +'(' + i.cccpv_class.name +')')
return certapps
# class Meta:
# model = Certaccess
# fields = '__all__'
def get_members(self, obj):
queryset = obj.certapp_project.all()
members = Member.objects.filter(certapp__in=queryset, is_deleted=False).distinct('is_leader','user').order_by('-is_leader')
serializer = MemberSerializer(members, many=True)
return serializer.data
# @staticmethod
# def setup_eager_loading(queryset):
# """ Perform necessary eager loading of data. """
# queryset = queryset.select_related('conclusion',)
# queryset = queryset.prefetch_related('nonitems',)
# return queryset
# class UnitaccessSerializer(serializers.ModelSerializer):
# class Meta:
# model = Unitaccess
# fields = '__all__'
@staticmethod
def setup_eager_loading(queryset):
""" Perform necessary eager loading of data. """
queryset = queryset.select_related('create_by', 'plan')
queryset = queryset.prefetch_related('certapp_project',)
return queryset
class CertappSerializerX(serializers.ModelSerializer):
cert_field_ = DictSimpleSerializer(source='cert_field', read_only=True)
cccpv_class_ = DictSimpleSerializer(source='cccpv_class' , read_only=True)
cnas_scopes_ = DictSimpleSerializer(source='cnas_scopes', many=True , read_only=True)
create_by_ = UserSimpleSerializer(source='create_by', read_only=True)
accept_by_ = UserSimpleSerializer(source='accept_by', read_only=True)
members = serializers.SerializerMethodField()
class Meta:
model = CertApp
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', 'member_certapp')
return queryset
def get_members(self, obj):
members = Member.objects.filter(certapp=obj, is_deleted=False).order_by('-is_leader')
serializer = MemberSerializer(members, many=True)
return serializer.data

View File

@ -1,30 +1,17 @@
# import random
from rest_framework.viewsets import GenericViewSet
from utils.pagination import PageOrNot
from rest_framework.mixins import ListModelMixin
from .models import *
from .serializers import *
# from django.shortcuts import render
# from django.utils import timezone
# from rest_framework import status
# from rest_framework.decorators import action
# from rest_framework.exceptions import NotAuthenticated, ParseError
# from rest_framework.response import Response
# from rest_framework.serializers import ModelSerializer
# from rest_framework.views import APIView
# from rest_framework.viewsets import GenericViewSet, ModelViewSet
# from apps.system.mixins import CreateUpdateCustomMixin, OptimizationMixin
# from apps.system.models import Dict
# from apps.system.permission_data import RbacFilterSet
# from utils.pagination import PageOrNot
# from .models import *
# from .serializers import *
# # Create your views here.
# class CertaccessViewSet(PageOrNot, CreateUpdateCustomMixin, ModelViewSet):
# """
# 业务评定
# """
# perms_map = {'get': 'certapp_view', 'post':'certaccess_create', 'put':'certaccess_update','delete': 'certaccess_delete'}
# queryset = Certaccess.objects.all()
# serializer_class = CertaccessSerializer
# filterset_fields = ['certapp']
# ordering = ['-create_time']
from apps.project.models import *
# Create your views here.
class CertaccessViewSet(PageOrNot, ListModelMixin, GenericViewSet):
"""
业务评定
"""
perms_map = {'get': 'access_view'}
queryset = CertApp.objects.all()
serializer_class = CertappSerializerX
filterset_fields = []
ordering = ['-create_time']

View File

@ -3,13 +3,13 @@ from rest_framework import serializers
from .models import *
from apps.system.serializers import DictSimpleSerializer, UserListSerializer
from apps.system.serializers import DictSimpleSerializer, UserListSerializer, UserSimpleSerializer
from apps.project.models import Project
from apps.plan.models import Member
from apps.project.serializers import PlanSerializer
from apps.plan.serializers import MemberSerializer
class ProjectSerializerX(serializers.ModelSerializer):
create_by_ = UserListSerializer(source='create_by', read_only=True)
create_by_ = UserSimpleSerializer(source='create_by', read_only=True)
certapps = serializers.SerializerMethodField()
plan_ = PlanSerializer(source='plan', read_only=True)
members = serializers.SerializerMethodField()
@ -41,8 +41,8 @@ class CertappSerializerX(serializers.ModelSerializer):
cert_field_ = DictSimpleSerializer(source='cert_field', read_only=True)
cccpv_class_ = DictSimpleSerializer(source='cccpv_class' , read_only=True)
cnas_scopes_ = DictSimpleSerializer(source='cnas_scopes', many=True , read_only=True)
create_by_ = UserListSerializer(source='create_by', read_only=True)
accept_by_ = UserListSerializer(source='accept_by', read_only=True)
create_by_ = UserSimpleSerializer(source='create_by', read_only=True)
accept_by_ = UserSimpleSerializer(source='accept_by', read_only=True)
members = serializers.SerializerMethodField()
class Meta:
model = CertApp

View File

@ -0,0 +1,17 @@
# Generated by Django 3.0.7 on 2020-10-21 05:45
from django.db import migrations
class Migration(migrations.Migration):
dependencies = [
('crm', '0015_certunit_testorgs'),
]
operations = [
migrations.RemoveField(
model_name='certunit',
name='testorgs',
),
]

View File

@ -91,4 +91,4 @@ class Certunit(CommonAModel):
unittype = models.ForeignKey(UnitType, verbose_name='单元类型', on_delete = models.DO_NOTHING, related_name='certunit_unittype')
standard = models.ForeignKey(Standard, verbose_name='采用标准', on_delete = models.DO_NOTHING, related_name='certunit_standard')
enterprise = models.ForeignKey(Enterprise, verbose_name='所属公司', on_delete = models.DO_NOTHING, related_name='certunit_enterprise')
testorgs = models.ManyToManyField(TestOrg, verbose_name='检测机构')
# testorgs = models.ManyToManyField(TestOrg, verbose_name='检测机构')

View File

@ -0,0 +1,14 @@
# Generated by Django 3.0.7 on 2020-10-20 06:02
from django.db import migrations
class Migration(migrations.Migration):
dependencies = [
('project', '0044_auto_20201014_1412'),
('project', '0049_certappunit_inspectionstate'),
]
operations = [
]

View File

@ -0,0 +1,28 @@
# Generated by Django 3.0.7 on 2020-10-20 06:02
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('project', '0050_merge_20201020_1402'),
]
operations = [
migrations.AddField(
model_name='project',
name='start_date',
field=models.DateTimeField(blank=True, null=True, verbose_name='现场审核开始时间'),
),
migrations.AlterField(
model_name='certapp',
name='state',
field=models.CharField(choices=[('申请', '申请'), ('受理', '受理'), ('策划', '策划'), ('现场审核', '现场审核'), ('产品检测', '产品检测'), ('评定', '评定'), ('出证', '出证'), ('完成', '完成')], default='申请', max_length=50, verbose_name='申请状态'),
),
migrations.AlterField(
model_name='project',
name='state',
field=models.CharField(choices=[('创建中', '创建中'), ('待策划', '待策划'), ('策划中', '策划中'), ('审核任务已下达', '审核任务已下达'), ('审核任务已接受', '审核任务已接受'), ('待现场审核', '待现场审核'), ('现场审核中', '现场审核中'), ('任务已反馈', '任务已反馈'), ('检测评定', '检测评定'), ('完成', '完成')], default='创建中', max_length=50, verbose_name='项目状态'),
),
]

View File

@ -0,0 +1,23 @@
# Generated by Django 3.0.7 on 2020-10-20 07:00
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('project', '0051_auto_20201020_1402'),
]
operations = [
migrations.AddField(
model_name='project',
name='end_date',
field=models.DateTimeField(blank=True, null=True, verbose_name='实际现场审核结束时间'),
),
migrations.AlterField(
model_name='project',
name='start_date',
field=models.DateTimeField(blank=True, null=True, verbose_name='实际现场审核开始时间'),
),
]

View File

@ -0,0 +1,18 @@
# Generated by Django 3.0.7 on 2020-10-20 08:30
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('project', '0052_auto_20201020_1500'),
]
operations = [
migrations.AddField(
model_name='project',
name='feedback_remark',
field=models.TextField(blank=True, null=True, verbose_name='反馈备注'),
),
]

View File

@ -94,7 +94,8 @@ class Project(CommonBModel):
('待现场审核', '待现场审核'),
('现场审核中', '现场审核中'),
('任务已反馈', '任务已反馈'),
('归档', '归档')
('检测评定', '检测评定'),
('完成', '完成')
)
state = models.CharField('项目状态', choices=state_choices, default='创建中', max_length=50)
number = models.CharField('项目编号', max_length = 100, null=True, blank=True)
@ -107,6 +108,9 @@ class Project(CommonBModel):
assgin_by = models.ForeignKey(User, on_delete=models.SET_NULL, verbose_name='审核任务下达人', null=True, blank=True)
edate0 = models.DateTimeField('预计审核开始时间', null=True, blank=True)
edate1 = models.DateTimeField('预计审核结束时间', null=True, blank=True)
start_date = models.DateTimeField('实际现场审核开始时间', null=True, blank=True)
end_date = models.DateTimeField('实际现场审核结束时间', null=True, blank=True)
feedback_remark = models.TextField('反馈备注', null=True, blank=True)
class Meta:
@ -129,7 +133,7 @@ class CertApp(CommonBModel):
('产品检测', '产品检测'),
('评定', '评定'),
('出证', '出证'),
('归档', '归档'),
('完成', '完成'),
)
result_choices = (
('未评审', '未评审'),

View File

@ -39,6 +39,12 @@ from apps.laboratory.serializers import TestOrgSerializer
# class Meta:
# model = SubApplication
# fields = '__all__'
class CertappflowSerializer(serializers.ModelSerializer):
handler_ = UserSimpleSerializer(source='handler', read_only=True)
class Meta:
model = CertAppFlow
fields = ['handler_', 'create_time', 'operation', 'state']
class CertappSerializer(serializers.ModelSerializer):
cert_field_ = DictSerializer(source='cert_field', read_only=True)

View File

@ -19,7 +19,7 @@ from .filters import *
from utils.pagination import PageOrNot
from rest_framework.exceptions import ParseError, NotAuthenticated
from django.utils import timezone
from rest_framework.mixins import ListModelMixin
# Create your views here.
# class ApplicationViewSet(RbacFilterSet, ModelViewSet):
# """
@ -90,8 +90,8 @@ class CertappViewset(PageOrNot, RbacFilterSet, ModelViewSet):
serializer = self.get_serializer(data=postdata)
serializer.is_valid(raise_exception=True)
# 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='申请')
obj = serializer.save(create_by = self.request.user, belong_dept=self.request.user.dept, state='受理')
CertAppFlow.objects.create(certapp = obj, handler=self.request.user, data=serializer.data, operation='创建申请', state='申请')
headers = self.get_success_headers(serializer.data)
return Response(serializer.data, status=status.HTTP_201_CREATED, headers=headers)
@ -104,7 +104,7 @@ class CertappViewset(PageOrNot, RbacFilterSet, ModelViewSet):
obj = self.get_object()
obj.state = '策划'
obj.save()
CertAppFlow.objects.create(certapp = obj, handler=self.request.user, data=self.get_serializer(obj), operation='完成受理', state='受理')
CertAppFlow.objects.create(certapp = obj, handler=self.request.user, operation='完成受理', state='受理')
return Response(status=status.HTTP_200_OK)
@action(methods=['put'], detail=False, perms_map={'put':'certapp_review'},
@ -116,8 +116,8 @@ class CertappViewset(PageOrNot, RbacFilterSet, ModelViewSet):
certapps = request.data['certapps']
rlist = request.data['rlist']
for i in rlist:
instance = EvaluationDetail.objects.create(item=Evaluations.objects.get(id=i['id']),item_v=i['content'], create_by=request.user, result=i['result'] if 'result' in i and i['result'] else None)
instance.cert_app.add(*certapps)
obj = EvaluationDetail.objects.create(item=Evaluations.objects.get(id=i['id']),item_v=i['content'], create_by=request.user, result=i['result'] if 'result' in i and i['result'] else None)
obj.cert_app.add(*certapps)
return Response(status=status.HTTP_200_OK)
@action(methods=['put'], detail=True, perms_map={'put':'certapp_access'}, url_name='certapp_access')
@ -125,17 +125,49 @@ class CertappViewset(PageOrNot, RbacFilterSet, ModelViewSet):
"""
评定
"""
# instance, ok = Certaccess.objects.get_or_create(certapp=self.get_object(), defaults={'certapp':self.get_object()
# obj, 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']})
# if not ok:
instance = self.get_object()
instance.conclusion = Dict.objects.get(pk=request.data['conclusion'])
instance.score = request.data['score']
instance.state = '出证'
instance.save()
instance.nonitems.clear()
instance.nonitems.add(*request.data['nonitems'])
return Response(status=status.HTTP_200_OK)
obj = self.get_object()
oldstate = obj.state
obj.conclusion = Dict.objects.get(pk=request.data['conclusion'])
obj.score = request.data['score']
obj.state = '出证'
obj.save()
obj.nonitems.clear()
obj.nonitems.add(*request.data['nonitems'])
CertAppFlow.objects.create(certapp = obj, handler=self.request.user, operation='提交评定结论', state=oldstate)
return Response({'state':obj.state}, status=status.HTTP_200_OK)
@action(methods=['put'], detail=True, perms_map={'put':'certapp_feedback'},
url_name='certapp_feedback')
def feedback(self, request, *args, **kwargs):
"""
业务反馈
"""
obj = self.get_object()
if obj.state in ['现场审核', '产品检测']:
oldstate = obj.state
if obj.cert_field.parent.code == 'PRO':
obj.state = '产品检测'
else:
obj.state = '评定'
obj.save()
CertAppFlow.objects.create(certapp = obj, handler=self.request.user, operation='提交现场审核反馈', state=oldstate)
return Response({'state':obj.state}, status=status.HTTP_200_OK)
else:
return Response('项目状态异常,操作失败', status=status.HTTP_400_BAD_REQUEST)
@action(methods=['get'], detail=True, perms_map={'get':'*'},
url_name='certapp_flow')
def flow(self, request, *args, **kwargs):
"""
业务流程进度
"""
objs = CertAppFlow.objects.filter(certapp__pk=kwargs['pk'])
serializer = CertappflowSerializer(objs, many=True)
return Response(serializer.data)
class EvaluationDetailViewset(CreateUpdateCustomMixin, PageOrNot,ModelViewSet):
@ -155,7 +187,7 @@ class EvaluationDetailViewset(CreateUpdateCustomMixin, PageOrNot,ModelViewSet):
rlist = request.data['rlist']
for i in rlist:
instance = EvaluationDetail.objects.update(item=Evaluations.objects.get(id=i['id']),item_v=i['content'], update_by=request.user, result=i['result'] )
obj = EvaluationDetail.objects.update(item=Evaluations.objects.get(id=i['id']),item_v=i['content'], update_by=request.user, result=i['result'] )
return Response(status=status.HTTP_200_OK)
@ -255,11 +287,11 @@ class ProjectViewSet(RbacFilterSet, ModelViewSet):
postdata['number'] = random.randrange(8000,9000)
serializer = self.get_serializer(data=postdata)
serializer.is_valid(raise_exception=True)
instance = serializer.save(create_by = self.request.user, belong_dept=self.request.user.dept)
obj = serializer.save(create_by = self.request.user, belong_dept=self.request.user.dept)
if 'certapps' in postdata and postdata['certapps']:
CertApp.objects.filter(pk__in = postdata['certapps']).update(project=instance)
instance.state = '待策划'
instance.save()
CertApp.objects.filter(pk__in = postdata['certapps']).update(project=obj)
obj.state = '待策划'
obj.save()
headers = self.get_success_headers(serializer.data)
return Response(serializer.data, status=status.HTTP_201_CREATED, headers=headers)
@ -302,10 +334,33 @@ class ProjectViewSet(RbacFilterSet, ModelViewSet):
制定预期审核时间
"""
obj = self.get_object()
if obj.state == '审核任务已接受':
obj.edate0 = request.data['edate0']
obj.edate1 = request.data['edate1']
obj.state = '待现场审核'
obj.save()
return Response(status=status.HTTP_200_OK)
for i in obj.certapp_project.all():
CertAppFlow.objects.create(certapp = i, handler=self.request.user, operation='已安排现场审核时间', state='现场审核')
return Response({'edate0':obj.edate0, 'edate1':obj.edate1, 'state':obj.state}, status=status.HTTP_200_OK)
else:
return Response('项目状态异常,操作失败', status=status.HTTP_400_BAD_REQUEST)
@action(methods=['put'], detail=True, perms_map={'put':'project_start'},
url_name='project_start')
def start(self, request, *args, **kwargs):
"""
开始审核
"""
obj = self.get_object()
if obj.state == '待现场审核':
obj.start_date = request.data['start_date']
obj.state = '现场审核中'
obj.save()
for i in obj.certapp_project.all():
CertAppFlow.objects.create(certapp = i, handler=self.request.user, operation='现场审核中', state='现场审核')
return Response({'start_date':obj.start_date,'state':obj.state}, status=status.HTTP_200_OK)
else:
return Response('项目状态异常,操作失败', status=status.HTTP_400_BAD_REQUEST)
@action(methods=['put'], detail=True, perms_map={'put':'audit_accept'},url_name='audit_accept')
def accept(self, request, *args, **kwargs):
@ -317,9 +372,26 @@ class ProjectViewSet(RbacFilterSet, ModelViewSet):
obj.state = '审核任务已接受'
obj.save()
Member.objects.filter(certapp__project=obj).update(is_accepted=True)
obj.certapp_project.all().update(state='审核')
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)
@action(methods=['put'], detail=True, perms_map={'put':'project_feedback'},
url_name='project_feedback')
def feedback(self, request, *args, **kwargs):
"""
项目反馈
"""
obj = self.get_object()
if obj.state == '现场审核中':
obj.start_date = request.data['start_date']
obj.end_date = request.data['end_date']
obj.feedback_remark = request.data['feedback_remark']
obj.state = '任务已反馈'
obj.save()
return Response({'start_date':obj.start_date, 'end_date':obj.end_date,'state':obj.state}, status=status.HTTP_200_OK)
else:
return Response('项目状态异常,操作失败', status=status.HTTP_400_BAD_REQUEST)

View File

@ -0,0 +1,23 @@
# Generated by Django 3.0.7 on 2020-10-22 07:04
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('system', '0031_delete_bscodeset'),
]
operations = [
migrations.AlterField(
model_name='dict',
name='code',
field=models.CharField(db_index=True, max_length=30, unique=True, verbose_name='编号'),
),
migrations.AlterField(
model_name='dicttype',
name='code',
field=models.CharField(db_index=True, max_length=30, unique=True, verbose_name='代号'),
),
]

View File

@ -131,7 +131,7 @@ class DictType(SoftModel):
数据字典类型
"""
name = models.CharField('名称', max_length=30)
code = models.CharField('代号', unique=True, max_length=30)
code = models.CharField('代号', unique=True, max_length=30, db_index=True)
parent = models.ForeignKey('self', null=True, blank=True,
on_delete=models.SET_NULL, verbose_name='')
@ -148,7 +148,7 @@ class Dict(SoftModel):
数据字典
"""
name = models.CharField('名称', max_length=1000)
code = models.CharField('编号', max_length=30, unique=True)
code = models.CharField('编号', max_length=30, unique=True, db_index=True)
description = models.TextField('描述', blank=True, null=True)
other = JSONField('其它信息', blank=True, null=True)
type = models.ForeignKey(