tijiaoshenghe

This commit is contained in:
shilixia 2020-09-15 15:11:38 +08:00
commit 2ea1d5b1c6
47 changed files with 2376 additions and 222 deletions

17
client/src/api/audit.js Normal file
View File

@ -0,0 +1,17 @@
import request from '@/utils/request'
export function getAuditTaskList(query) {
return request({
url: '/audit/mytask/',
method: 'get',
params: query
})
}
export function getAuditCertappList(query) {
return request({
url: '/audit/myauditcertapp/',
method: 'get',
params: query
})
}

View File

@ -31,3 +31,11 @@ export function updateMember(id, data) {
data
})
}
export function daysMember(id, data) {
return request({
url: `/plan/member/${id}/days/`,
method: 'put',
data
})
}

View File

@ -39,9 +39,16 @@ export function getProject(id) {
})
}
export function assginProject(id, data) {
export function nextProject(id) {
return request({
url: `/project/project/${id}/assgin/`,
url: `/project/project/${id}/next/`,
method: 'put'
})
}
export function edateProject(id, data) {
return request({
url: `/project/project/${id}/edate/`,
method: 'put',
data
})

View File

@ -100,10 +100,24 @@ export const asyncRoutes = [
hidden: true
},
{
path: 'certapp/:action/:kind/',
name: 'CertappForm',
component: () => import('@/views/certapp/certappform'),
meta: { title: '申请受理单', icon: 'example', perms: ['certapp_create', 'certapp_update'] },
path: 'certapp/create/:id/',
name: 'Certappcreate',
component: () => import('@/views/certapp/certappcreate'),
meta: { title: '申请受理单创建', icon: 'example', perms: ['certapp_create'] },
hidden: true
},
{
path: 'certapp/:id/update/',
name: 'Certappupdate',
component: () => import('@/views/certapp/certapphandle'),
meta: { title: '申请受理单修改', icon: 'example', perms: ['certapp_update'] },
hidden: true
},
{
path: 'certapp/:id/detail/',
name: 'Certappdetail',
component: () => import('@/views/certapp/certapphandle'),
meta: { title: '业务详情', icon: 'example', perms: ['certapp_detail'] },
hidden: true
},
]
@ -119,7 +133,7 @@ export const asyncRoutes = [
path: 'plan',
name: 'Plan',
component: () => import('@/views/plan/plan'),
meta: { title: '划', icon: 'example', perms: ['plan_view'] }
meta: { title: '划', icon: 'example', perms: ['plan_view'] }
},
{
path: 'paichai',
@ -128,26 +142,53 @@ export const asyncRoutes = [
meta: { title: '派差', icon: 'example', perms: ['plan_view'] }
},
{
path: 'project',
name: 'HandleProject',
component: () => import('@/views/plan/handle'),
meta: { title: '联系企业', icon: 'example', perms: ['project_view'] },
path: 'project/:id/',
name: 'PlanProject',
component: () => import('@/views/project/handle'),
meta: { title: '项目', icon: 'example', perms: ['project_view'] },
hidden: true
},
{
path: 'certapp/:id/:action/',
name: 'Certappmember',
component: () => import('@/views/certapp/certapphandle'),
meta: { title: '派人', icon: 'example', perms: ['plan_view'] },
hidden: true
},
]
},
{
path: '/spot',
path: '/audit',
component: Layout,
redirect: '/spot/spot',
name: 'SpotM',
redirect: '/audit/task',
name: 'Audit',
meta: { title: '现场审核', icon: 'example'},
children: [
{
path: 'spot',
name: 'Spot',
component: () => import('@/views/plan/plan'),
meta: { title: '现场审核', icon: 'example', perms: ['plan_view'] }
path: 'task',
name: 'AuditTask',
component: () => import('@/views/audit/task'),
meta: { title: '我的任务', icon: 'example', perms: ['audittask_view'] }
},
{
path: 'fee',
name: 'Fee',
component: () => import('@/views/audit/fee'),
meta: { title: '劳务费', icon: 'example', perms: ['taskfee_view'] }
},
{
path: 'project/:id/',
name: 'AuditProject',
component: () => import('@/views/project/handle'),
meta: { title: '项目', icon: 'example', perms: ['project_view'] },
hidden: true
},
{
path: 'certapp/:id/:action/',
name: 'Certappfeedback',
component: () => import('@/views/certapp/certapphandle'),
meta: { title: '业务审核反馈', icon: 'example', perms: ['certapp_feedback'] },
hidden: true
},
]
},

View File

@ -4,6 +4,7 @@ const getters = {
token: state => state.user.token,
avatar: state => state.user.avatar,
name: state => state.user.name,
username: state => state.user.username,
perms: state => state.user.perms,
permission_routes: state => state.permission.routes
}

View File

@ -5,6 +5,7 @@ import { resetRouter } from '@/router'
const getDefaultState = () => {
return {
token: getToken(),
username: '',
name: '',
avatar: '',
perms: []
@ -23,6 +24,9 @@ const mutations = {
SET_NAME: (state, name) => {
state.name = name
},
SET_USERNAME: (state, username) => {
state.username = username
},
SET_AVATAR: (state, avatar) => {
state.avatar = avatar
},
@ -57,7 +61,7 @@ const actions = {
reject('验证失败,重新登陆.')
}
const { perms, name, avatar } = data
const { perms, name, avatar, username } = data
// perms must be a non-empty array
if (!perms || perms.length <= 0) {
@ -66,6 +70,7 @@ const actions = {
commit('SET_PERMS', perms)
commit('SET_NAME', name)
commit('SET_USERNAME', username)
commit('SET_AVATAR', avatar)
resolve(data)
}).catch(error => {

View File

@ -85,4 +85,10 @@ div:focus {
}
.el-dialog__body {
padding: 8px 12px;
}
// .el-form-item--medium .el-form-item__label {
// line-height: 16px;
// }
.el-form--label-top .el-form-item__label {
line-height: 16px;
}

View File

@ -0,0 +1,24 @@
<template>
<div>
</div>
</template>
<script>
export default {
name: "Conclusion",
components: {},
props:['certapp'],
data() {
return {
formData:{}
};
},
watch:{
},
created() {
},
methods: {
},
};
</script>

View File

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

View File

@ -0,0 +1,293 @@
<template>
<div>
<el-table
ref="memberTable"
v-loading="listLoading"
:data="memberData"
style="width: 100%;"
border
fit
stripe
highlight-current-row
height="160"
@row-click="handleMClick"
>
<el-table-column label="姓名">
<template slot-scope="scope">{{ scope.row.user_.name }}</template>
</el-table-column>
<el-table-column label="是否组长">
<template slot-scope="scope">
<i class="el-icon-circle-check" v-if="scope.row.is_leader" style="color:green;"></i>
</template>
</el-table-column>
<el-table-column label="身份">
<template slot-scope="scope" v-if="scope.row.identity">{{ scope.row.identity_.name }}</template>
</el-table-column>
<el-table-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-column label="人日数">
<template slot-scope="scope">{{ scope.row.man_days }}</template>
</el-table-column>
<el-table-column label="审核天数">
<template slot-scope="scope">{{ scope.row.days }}</template>
</el-table-column>
</el-table>
<el-row :gutter="6">
<el-col :xs="24" :md="12">
<el-card style="margin-top:6px">
<div slot="header" class="clearfix">
<span>成员配置</span>
</div>
<el-form
ref="elForm_member"
:model="formDataMember"
label-width="60px"
:rules="rules_member"
style="margin-top:10px"
>
<el-row>
<el-col :xs="24" :md="8">
<el-form-item label="成员" prop="user">
<el-input
placeholder="请选择成员"
readonly
clearable
v-model="formDataMember.user_.name"
@focus="choseMember"
>
<el-button slot="append" icon="el-icon-search" @click="choseMember"></el-button>
</el-input>
</el-form-item>
</el-col>
<el-col :xs="24" :md="8">
<el-form-item label="身份" prop="identity">
<el-select
v-model="formDataMember.identity"
placeholder="请选择"
:style="{width: '100%'}"
>
<el-option
v-for="item in identityOptions"
:key="item.id"
:label="item.name"
:value="item.id"
></el-option>
</el-select>
</el-form-item>
</el-col>
<el-col :xs="24" :md="8">
<el-form-item prop="is_leader">
<el-checkbox v-model="formDataMember.is_leader">组长</el-checkbox>
</el-form-item>
</el-col>
</el-row>
<el-row style="text-align:left;">
<el-button-group>
<el-button type="primary" @click="appendNewM">添加新成员</el-button>
<el-button type="warning" @click="updateNowM">保存</el-button>
<el-button @click="resetForm_member">重置</el-button>
</el-button-group>
</el-row>
</el-form>
</el-card>
</el-col>
<el-col :xs="24" :md="12">
<el-card style="margin-top:6px">
<div slot="header" class="clearfix">
<span>审核员参与天数/人日数</span>
</div>
<el-form
ref="elForm_days"
:model="formDataDays"
label-width="80px"
label-position="right"
:rules="rules_day"
style="margin-top:10px"
>
<el-row>
<el-col :xs="24" :md="12">
<el-form-item label="人日数" prop="man_days">
<el-input-number
v-model="formDataDays.man_days"
:precision="2"
:max="10"
:min="0"
:style="{width: '100%'}"
></el-input-number>
</el-form-item>
</el-col>
<el-col :xs="24" :md="12">
<el-form-item label="审核天数" prop="days">
<el-input-number
v-model="formDataDays.days"
:precision="2"
:max="10"
:min="0"
:style="{width: '100%'}"
></el-input-number>
</el-form-item>
</el-col>
</el-row>
<el-row style="text-align:left;">
<el-button-group>
<el-button type="warning" @click="saveDays">保存</el-button>
</el-button-group>
</el-row>
</el-form>
</el-card>
</el-col>
</el-row>
<el-dialog
title="选择组员"
:visible.sync="choseVisiable"
:close-on-click-modal="false"
width="80%"
:append-to-body="true"
>
<Userchose ref="Userchose" :queryData="queryData" @handleChose="choseComplete"></Userchose>
</el-dialog>
</div>
</template>
<script>
import { getDictList } from "@/api/dict";
import Userchose from "@/views/employee/userchose";
import {
getMemberList,
createMember,
updateMember,
deleteMember,
daysMember
} from "@/api/member";
import { genTree, deepClone } from "@/utils";
export default {
components: { Userchose },
props: ["certapp"],
data() {
return {
listLoading: false,
memberData: [],
identityOptions: [],
formDataMember: {
user: null,
user_: {},
is_leader: false,
certapp: this.certapp,
},
rules_member: {
user: [
{
required: true,
message: "请选择组员",
trigger: "change",
},
],
},
choseVisiable: false,
queryData: {},
formDataDays: {
man_days: 0,
days: 0,
},
rules_day: {
man_days: [
{
required: true,
message: "请输入人日数",
trigger: "change",
},
],
days: [
{
required: true,
message: "请输入审核天数",
trigger: "change",
},
],
},
};
},
created() {
this.getMemberList_();
this.getIdOptions()
},
methods: {
getMemberList_() {
this.listLoading = true;
getMemberList({ certapp: this.certapp, pageoff: true })
.then((res) => {
this.listLoading = false;
this.memberData = res.data;
})
.catch((e) => {
this.listLoading = false;
});
},
resetForm_member() {
this.$refs["elForm_member"].resetFields();
this.formDataMember.user_ = {};
},
choseMember() {
this.choseVisiable = true;
},
appendNewM() {
this.$refs["elForm_member"].validate((valid) => {
if (!valid) return;
// TODO 提交表单
createMember(this.formDataMember).then((res) => {
this.$message.success("成功");
this.getMemberList_();
}).catch(err=>{});
});
},
updateNowM() {
if (this.formDataMember.id) {
updateMember(this.formDataMember.id, this.formDataMember).then(
(res) => {
this.$message.success("成功");
this.getMemberList_();
}
);
}else{
this.$message.warning('请选择一条记录')
}
},
choseComplete(val) {
if (val) {
this.formDataMember.user = val.user_.id;
this.formDataMember.user_.name = val.user_.name;
}
this.choseVisiable = false;
},
handleMClick(row, c, e) {
this.formDataMember = deepClone(row);
this.formDataDays = deepClone(row);
},
getIdOptions() {
getDictList({ type__code: "auditor_teamrole", pageoff: true }).then(
(res) => {
this.identityOptions = res.data;
}
);
},
saveDays() {
if(this.formDataDays.id){
daysMember(this.formDataDays.id, {id:this.formDataDays.id,man_days:this.formDataDays.man_days,days:this.formDataDays.days}).then(res=>{
this.getMemberList_()
this.$message.success('成功')
}).catch(e=>{})
}else{
this.$message.warning('请选择一条记录')
}
},
},
};
</script>

View File

@ -0,0 +1,259 @@
<template>
<div class="app-container">
<el-card style="margin-top:6px">
<div slot="header" class="clearfix">
<span>我的项目</span>
</div>
<el-row :gutter="6">
<el-col :xs="24" :md="6">
<el-input
v-model="listQuery.search"
placeholder="受审核方/所属计划"
class="filter-item"
@keyup.enter.native="handleFilter"
/>
</el-col>
<el-col :xs="24" :md="6">
<el-button-group>
<el-button
class="filter-item"
type="primary"
icon="el-icon-search"
@click="handleFilter"
>搜索</el-button>
<el-button
class="filter-item"
type="primary"
icon="el-icon-refresh-left"
@click="resetFilter"
>重置</el-button>
</el-button-group>
</el-col>
</el-row>
<el-table
v-loading="listLoading"
:data="projectData.results"
style="width: 100%;margin-top:6px"
border
fit
stripe
highlight-current-row
height="300"
@row-click = "handleRclick"
>
<el-table-column type="selection" width="55"></el-table-column>
<el-table-column label="项目号">
<template slot-scope="scope" v-if="scope.row.number">{{ scope.row.number }}</template>
</el-table-column>
<el-table-column label="所属计划">
<template slot-scope="scope" v-if="scope.row.plan">{{ scope.row.plan_.name }}</template>
</el-table-column>
<el-table-column label="受审核方" >
<template slot-scope="scope">{{ scope.row.auditee_v.name }}</template>
</el-table-column>
<el-table-column label="业务信息" >
<template slot-scope="scope" v-if="scope.row.certapps">
<el-tag
v-for="(item, index) in scope.row.certapps"
:key="index"
style="margin:2px"
>{{item}}</el-tag>
</template>
</el-table-column>
<el-table-column label="当前状态">
<template slot-scope="scope">{{ scope.row.status}}</template>
</el-table-column>
<el-table-column label="审核组成员">
<template slot-scope="scope" 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-tooltip> -->
</template>
</el-table-column>
<el-table-column label="创建日期" width="190">
<template slot-scope="scope">
<span>{{ scope.row.create_time }}</span>
</template>
</el-table-column>
<el-table-column label="操作" width="300" fixed="right">
<template slot-scope="scope">
<el-button-group>
<el-button
type="primary"
size="small"
:disabled="!checkPermission(['project_update'])"
@click="handleTask(scope)"
>处理</el-button>
<el-button
type="danger"
size="small"
:disabled="!checkPermission(['project_delete'])"
@click="handleDetailProject(scope)"
>详情</el-button>
</el-button-group>
</template>
</el-table-column>
</el-table>
<pagination
v-show="projectData.count>0"
:total="projectData.count"
:page.sync="listQuery.page"
:limit.sync="listQuery.page_size"
@pagination="getProjectList_"
/>
</el-card>
<el-card style="margin-top:6px">
<div slot="header" class="clearfix">
<span>项目下我的业务</span>
</div>
<el-table
v-loading="listLoading2"
:data="certappData"
style="width: 100%;margin-top:6px"
border
fit
stripe
highlight-current-row
height="300"
>
<el-table-column type="index" width="55"></el-table-column>
<el-table-column label="申请单号">
<template slot-scope="scope" v-if="scope.row.number">{{ scope.row.number }}</template>
</el-table-column>
<el-table-column label="认证领域/分类">
<template slot-scope="scope">
<el-tag >{{scope.row.cert_field_.name}}</el-tag>
<el-tag v-if="scope.row.cccpv_class_" type="warning" style="margin:2px">{{scope.row.cccpv_class_.name}}</el-tag>
</template>
</el-table-column>
<el-table-column label="申请信息" width="300px">
<template slot-scope="scope">
<div><span style="color:darkblue;font-weight:bold">申请方</span>:{{ scope.row.applicant_v.name }}</div>
<div v-if="scope.row.manufacture"><span style="color:darkblue;font-weight:bold">制造商</span>:{{ scope.row.manufacture_v.name }}</div>
<div v-if="scope.row.factory"><span style="color:darkblue;font-weight:bold">生产厂</span>:{{ scope.row.factory_v.name }}</div>
</template>
</el-table-column>
<el-table-column label="当前状态">
<template slot-scope="scope">
{{ scope.row.status}}
</template>
</el-table-column>
<el-table-column label="审核组成员">
<template slot-scope="scope" v-if="scope.row.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>
</template>
</el-table-column>
<el-table-column label="创建日期" width="190">
<template slot-scope="scope">
<span>{{ scope.row.create_time }}</span>
</template>
</el-table-column>
<el-table-column label="操作" width="300" fixed="right">
<template slot-scope="scope">
<el-button-group>
<el-button
type="primary"
size="small"
:disabled="!checkPermission(['certapp_feedback'])"
@click="handleCertappFeedback(scope)"
>反馈</el-button>
<el-button
type="danger"
size="small"
:disabled="!checkPermission(['certapp_detail'])"
@click="handleCertappDetail(scope)"
>详情</el-button>
</el-button-group>
</template>
</el-table-column>
</el-table>
</el-card>
</div>
</template>
<script>
import { getProjectList } from "@/api/project";
import { getAuditTaskList, getAuditCertappList } from "@/api/audit"
import Pagination from "@/components/Pagination";
import checkPermission from "@/utils/permission";
import Treeselect from "@riophae/vue-treeselect";
import "@riophae/vue-treeselect/dist/vue-treeselect.css";
import { genTree } from "../../utils";
import router from '@/router';
import store from '@/store'
export default {
components: { Pagination, Treeselect },
data() {
return {
listLoading: false,
listLoading2: false,
listQuery: {
page: 1,
page_size: 20,
},
projectData: { count: 0, results: [] },
certappData: []
};
},
watch: {
},
created() {
this.getProjectList_();
},
methods: {
checkPermission,
getProjectList_() {
this.listLoading = true;
getAuditTaskList(this.listQuery).then((response) => {
if (response.data) {
this.projectData = response.data;
}
this.listLoading = false;
});
},
resetFilter() {
this.listQuery = {
page: 1,
page_size: 20,
}
this.getProjectList_()
},
handleFilter() {
this.getProjectList_();
},
handleTask(scope) {
this.$router.push({
name: "AuditProject",
params: { id: scope.row.id },
});
},
handleRclick(row, column, event){
this.listLoading2 = true
getAuditCertappList({project:row.id, pageoff:true}).then(res=>{
this.certappData = res.data
this.listLoading2 = false
}).catch(e=>{this.listLoading2=false})
},
handleCertappFeedback(scope) {
this.$router.push({
name: "Certappfeedback",
params: { id: scope.row.id },
});
},
handleCertappDetail(scope) {
this.$router.push({
name: "Certappdetail",
params: { id: scope.row.id },
});
}
},
};
</script>

View File

@ -269,10 +269,9 @@ export default {
name: "CCCform",
inheritAttrs: false,
components: { Enterprisechose, Treeselect },
props: ["action", "certapp"],
props: ["certapp"],
data() {
return {
// act:this.action,
formData: {
field_code: 'CCC',
applicant: null,
@ -372,11 +371,12 @@ export default {
},
created() {
console.log(this.certapp)
if(this.action!='create'){
this.formData = this.certapp
if(this.certapp!=null){
this.formData = this.certapp
}
this.getCCCOptions();
this.getlevelOptions();
@ -398,7 +398,7 @@ export default {
}else{
createCertapp(this.formData).then((res) => {
this.$message.success('成功')
this.$router.replace({name:"CertappForm", params:{action:'update', kind:'CCC'}, query:{id:res.data.id}})
this.$router.replace({name:"Certappupdate", params:{id:res.data.id}})
});
}

View File

@ -184,10 +184,10 @@ export default {
this.getList()
},
handleCreate(item, index) {
this.$router.push({name:"CertappForm", params:{kind:item.code, action:'create'}})
this.$router.push({name:"Certappcreate", params:{kind:item.code}})
},
handleUpdate(scope) {
this.$router.push({name:"CertappForm", params:{action:'update', kind:scope.row.cert_field_.code}, query:{id:scope.row.id}})
this.$router.push({name:"Certappupdate", params:{ id:scope.row.id}})
},
handleDelete(scope) {
deleteCertapp(scope.row.id).then(res=>{

View File

@ -0,0 +1,49 @@
<template>
<div class="app-container">
<el-tabs type="border-card" >
<el-tab-pane label="申请信息" style="overflow-y:auto;overflow-x:hidden;">
<CCCform @handleCommit="save" :certapp="certapp" v-if="kind=='CCC'"></CCCform>
<QMSform @handleCommit="save" :certapp="certapp" v-if="kind=='QMS'"></QMSform>
</el-tab-pane>
</el-tabs>
</div>
</template>
<script>
import CCCform from "@/views/certapp/cccform"
import Productunit from "@/views/certapp/productunit"
import { getCertapp, completeCertapp } from "@/api/certapp"
import router from '@/router';
import QMSform from "@/views/certapp/qmsform"
export default {
components: { CCCform, Productunit, QMSform},
props: [],
data() {
return {
certapp:null,
kind:'CCC',
};
},
computed: {},
watch: {
// "formData.cert_field": "changeRules"
},
created() {
this.getParams()
},
mounted() {},
methods: {
getParams(){
this.kind = this.$route.params.kind
},
save(val){
this.certapp=val
},
handleComplete(){
completeCertapp(this.certapp.id).then(res=>{
this.$message.success('成功')
this.$router.go(-1)
})
}
}
};
</script>

View File

@ -0,0 +1,89 @@
<template>
<div class="app-container">
<el-tabs type="card" v-model="activeName">
<el-tab-pane label="申请信息" name="Basic" style="overflow-y:auto;overflow-x:hidden;">
<CCCform @handleCommit="save" :certapp="certappdata" v-if="kind=='CCC'&isLoad"></CCCform>
<QMSform @handleCommit="save" :certapp="certappdata" v-if="kind=='QMS'&isLoad"></QMSform>
</el-tab-pane>
<el-tab-pane label="产品单元" name="Productunit" v-if="certapp" lazy>
<Productunit :certapp="certapp"></Productunit>
</el-tab-pane>
<el-tab-pane label="原材料供应商" name="Productunit1" v-if="certapp" lazy>
</el-tab-pane>
<el-tab-pane label="检测设备" name="Productunit2" v-if="certapp" lazy>
</el-tab-pane>
<el-tab-pane label="资料评审" name="Productunit3" v-if="certapp" lazy>
</el-tab-pane>
<el-tab-pane label="收费信息" name="Productunit4" v-if="certapp" lazy>
<CHARGE :certapp="certapp"></CHARGE>
</el-tab-pane>
<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>
</el-tabs>
</div>
</template>
<script>
import CCCform from "@/views/certapp/cccform"
import Productunit from "@/views/certapp/productunit"
import CHARGE from "@/views/certapp/charge"
import { getCertapp, completeCertapp } from "@/api/certapp"
import router from '@/router';
import QMSform from "@/views/certapp/qmsform"
import Conclusion from "@/views/audit/conclusion"
import Member from "@/views/audit/member"
export default {
components: { CCCform, Productunit, QMSform,CHARGE, Conclusion, Member},
props: [],
data() {
return {
activeName:'Basic',
certapp:null,
certappdata:null,
kind:'CCC',
isLoad:false
};
},
computed: {},
watch: {
// "formData.cert_field": "changeRules"
},
created() {
this.getParams()
},
mounted() {},
methods: {
getParams(){
var id = this.$route.params.id
this.certapp = id
getCertapp(id).then(res=>{
this.certappdata = res.data
this.kind = res.data.cert_field_.code
this.isLoad = true
})
if(this.$route.name=='Certappupdate' || this.$route.name=='Certappdetail'){
this.activeName = 'Basic'
}else{
this.activeName = this.$route.name
}
},
save(val){
this.certapp=val
},
handleComplete(){
completeCertapp(this.certapp.id).then(res=>{
this.$message.success('成功')
this.$router.go(-1)
})
}
}
};
</script>

View File

@ -21,19 +21,20 @@
<el-input v-model="scope.row.itemkind"></el-input>
</template>
</el-table-column>
<el-table-column label="单元数量">
<el-table-column label="单元数量" align="center">
<template slot-scope="scope">
<el-input v-model="scope.row.unitcount"></el-input>
</template>
</el-table-column>
<el-table-column label="单价">
<el-table-column label="单价" align="center">
<template slot-scope="scope">
<el-input v-model="scope.row.perfee"></el-input>
</template>
</el-table-column>
<el-table-column label="小计">
<el-table-column label="小计" align="center">
<template slot-scope="scope">
<el-input v-model="scope.row.pertotal"></el-input>
{{ (scope.row.pertotal = scope.row.unitcount *scope.row.perfee) | keepTwoNum}}
</template>
</el-table-column>
@ -142,7 +143,7 @@
<el-col :xs="24" :md="22" font="left">
<el-form-item label="备注" prop="remark">
<el-input type="textarea" :rows="2" v-model="formData.remarks"
<el-input type="textarea" :rows="2" v-model="formData.remark"
clearable
:style="{width: '100%'}"></el-input>
</el-form-item>
@ -175,16 +176,17 @@ import "@riophae/vue-treeselect/dist/vue-treeselect.css";
inheritAttrs: false,
components: { Treeselect },
props: ["action", "certapp"],
props: ["certapp"],
data() {
return {
tableData: [],
selectlistRow: [],
rowNum:1,
formData: {
number:this.certapp.id,
number:this.certapp,
totalfee: null,
deductions:null,
exchangetype: "人名币-RMB-¥",
exchangerate: null,
paidrmb: null,
paidwb: null,
@ -221,9 +223,12 @@ import "@riophae/vue-treeselect/dist/vue-treeselect.css";
created() {
this.getDiclist();
this.getChareList();
if(this.certapp!=null){
this.getChareList();
}
},
mounted() {},
@ -267,29 +272,26 @@ import "@riophae/vue-treeselect/dist/vue-treeselect.css";
getChareList() {
getBillList({ number:this.certapp.id }).then((response) => {
console.log(response.data[0])
if (response.data[0] != 'undefined') {
getBillList({ number:this.certapp }).then((response) => {
this.listLoading = true;
if (response.data.length) {
this.formData = response.data[0];
getChargeitemList({ bills:response.data[0].bills }).then((response) => {
getChargeitemList({ bills:response.data[0].feecode }).then((response) => {
if (response.data) {
this.tableData = response.data.results;
this.tableData = response.data;
}
});
}
this.listLoading = false;
});
},
@ -308,6 +310,7 @@ import "@riophae/vue-treeselect/dist/vue-treeselect.css";
this.$refs["elForm"].validate(valid => {
if (!valid) return;
// TODO 提交表单
createBill(this.formData).then(response => {
this.$message({
@ -315,12 +318,16 @@ import "@riophae/vue-treeselect/dist/vue-treeselect.css";
message: '成功!'
})
var billid = response.data.feecode;
for (var i=0; i < val.length; i++) {
this.chargeIetm = val[i]
this.chargeIetm.bills = billid;
this.chargeIetm.bills = this.formData.feecode;
createChargeitem(this.chargeIetm).then(response => {
this.$message({
type: 'success',
message: '成功!'
})
})
}

View File

@ -3,7 +3,7 @@
<el-table
v-loading="listLoading"
:data="tableData.results"
style="width: 100%;margin-top:10px;"
style="width: 100%;"
border
fit
stripe
@ -158,10 +158,10 @@ export default {
listQuery: {
page: 1,
page_size: 20,
certapp:this.certapp.id
certapp:this.certapp
},
formData: {
certapp:this.certapp.id,
certapp:this.certapp,
implementrule: undefined,
unittype: undefined,
standard: undefined,
@ -224,8 +224,11 @@ export default {
getList() {
this.listLoading = true;
getUnitList(this.listQuery).then((response) => {
if (response.data) {
this.tableData = response.data;
}
this.listLoading = false;
});

View File

@ -328,9 +328,9 @@ export default {
},
created() {
console.log(this.certapp)
if(this.action!='create'){
this.formData = this.certapp
if(this.certapp!=null){
this.formData = this.certapp
}
this.getTypeOptions();
this.getProfOptions();
@ -364,7 +364,7 @@ export default {
}else{
createCertapp(this.formData).then((res) => {
this.$message.success('成功')
this.$emit("handleCommit", res.data);
this.$router.replace({name:"Certappupdate", params:{id:res.data.id}})
});
}

View File

@ -499,10 +499,15 @@ export default {
this.choseVisiable = true
},
appendNewM(){
createMember(this.formDataMember).then(res=>{
this.$refs["elForm2"].validate((valid) => {
if (!valid) return;
// TODO 提交表单
createMember(this.formDataMember).then(res=>{
this.$message.success('成功')
this.getMemberList_()
})
});
},
updateNowM(){
if(this.formDataMember.id){

View File

@ -170,7 +170,7 @@ export default {
listQuery_project: {
page: 1,
page_size: 20,
status:"派差"
status:"策划"
},
projectData: { count: 0, results: [] },
};

View File

@ -6,9 +6,8 @@
<div slot="header" class="clearfix">
<span>月计划</span>
(当前选择:
<span style="color:darkblue;font-weight:bold">
{{nowPlan.name}}</span>
)
<span style="color:darkblue;font-weight:bold">{{nowPlan.name}}</span>
)
</div>
<div>
<div>
@ -62,7 +61,7 @@
<el-col :xs="24" :md="16">
<el-card class="box-card" style="margin-top:2px">
<div slot="header" class="clearfix">
<span>处理项目</span>
<span>策划项目</span>
</div>
<div>
<div style="margin-bottom:2px">
@ -98,27 +97,22 @@
<el-table-column label="当前状态">
<template slot-scope="scope">{{ scope.row.status}}</template>
</el-table-column>
<el-table-column label="是否可派差">
<template slot-scope="scope">
<el-switch v-model="scope.row.can_paichai" disabled></el-switch>
</template>
</el-table-column>
<el-table-column label="下达人">
<template slot-scope="scope">{{ scope.row.assign_by_.name}}</template>
<el-table-column label="创建人">
<template slot-scope="scope">{{ scope.row.create_by_.name}}</template>
</el-table-column>
<el-table-column label="创建日期" width="190">
<template slot-scope="scope">
<span>{{ scope.row.create_time }}</span>
</template>
</el-table-column>
<el-table-column label="操作" width="200" fixed="right">
<!-- <el-table-column label="操作" width="200" fixed="right">
<template slot-scope="scope">
<el-button-group>
<el-button
type="primary"
size="small"
:disabled="!checkPermission(['project_update'])"
@click="contactCompany(scope)"
@click="planProject(scope)"
>联系企业</el-button>
<el-button
type="danger"
@ -128,7 +122,7 @@
>详情</el-button>
</el-button-group>
</template>
</el-table-column>
</el-table-column>-->
</el-table>
<pagination
v-show="projectData.count>0"
@ -145,6 +139,9 @@
<el-card class="box-card" style="margin-top:2px">
<div slot="header" class="clearfix">
<span>月计划项目</span>
(当前选择:
<span style="color:darkblue;font-weight:bold">{{nowPlan.name}}</span>
)
</div>
<div>
<el-table
@ -180,23 +177,30 @@
<el-switch v-model="scope.row.can_paichai" disabled></el-switch>
</template>
</el-table-column>
<el-table-column label="下达">
<template slot-scope="scope">{{ scope.row.assign_by_.name}}</template>
<el-table-column label="创建">
<template slot-scope="scope">{{ scope.row.create_by_.name}}</template>
</el-table-column>
<el-table-column label="创建日期" width="190">
<template slot-scope="scope">
<span>{{ scope.row.create_time }}</span>
</template>
</el-table-column>
<el-table-column label="操作" width="200" fixed="right">
<el-table-column label="操作" width="300" fixed="right">
<template slot-scope="scope">
<el-button-group>
<el-button
type="primary"
size="small"
:disabled="!checkPermission(['project_update'])"
@click="contactCompany(scope)"
@click="planProject(scope)"
>计划</el-button>
<el-button
v-if="scope.row.status !='待现场审核'"
type="primary"
size="small"
:disabled="!checkPermission(['project_assgin'])||!scope.row.can_paichai"
@click="nextProject(scope)"
>任务下达</el-button>
<el-button
type="danger"
size="small"
@ -217,8 +221,14 @@
</div>
</el-card>
</el-row>
<el-dialog :visible.sync="dialogVisible" :title="dialogType==='update'?'编辑':'新增'" >
<el-form ref="elForm" :model="formData" label-width="80px" label-position="right" :rules="rules">
<el-dialog :visible.sync="dialogVisible" :title="dialogType==='update'?'编辑':'新增'">
<el-form
ref="elForm"
:model="formData"
label-width="80px"
label-position="right"
:rules="rules"
>
<el-form-item label="计划名称" prop="name">
<el-input v-model="formData.name" placeholder="名称" />
</el-form-item>
@ -231,9 +241,15 @@
</div>
</template>
<script>
import { nextProject } from "@/api/project"
import { getCertappList } from "@/api/certapp";
import { getPlanList, createPlan, updatePlan, deletePlan} from "@/api/plan"
import { getProjectList, createProject, assginProject, planProject } from "@/api/project";
import { getPlanList, createPlan, updatePlan, deletePlan } from "@/api/plan";
import {
getProjectList,
createProject,
assginProject,
planProject,
} from "@/api/project";
import Pagination from "@/components/Pagination";
import checkPermission from "@/utils/permission";
import Treeselect from "@riophae/vue-treeselect";
@ -245,8 +261,8 @@ export default {
data() {
return {
listLoading: false,
listLoadingplan:false,
listLoadingplan2:false,
listLoadingplan: false,
listLoadingplan2: false,
listQuery_plan: {
page: 1,
page_size: 20,
@ -254,34 +270,32 @@ export default {
listQuery_project: {
page: 1,
page_size: 20,
status: "派差",
planoff:true
status: "策划",
planoff: true,
},
listQuery2:{
listQuery2: {
page: 1,
page_size: 20,
plan:''
plan: "",
},
planData: { count: 0, results: [] },
projectData: { count: 0, results: [] },
projectData2: { count: 0, results: [] },
dialogVisible:false,
dialogType:'create',
formData:{
},
nowPlan:{id:0},
dialogVisible: false,
dialogType: "create",
formData: {},
nowPlan: { id: 0 },
rules: {
name: [{ required: true, message: '请输入名称', trigger: 'blur' }],
name: [{ required: true, message: "请输入名称", trigger: "blur" }],
},
multipleSelection:[],
multiprojects:[]
multipleSelection: [],
multiprojects: [],
};
},
watch: {},
created() {
this.getProjectList_();
this.getPlanList_()
this.getPlanList_();
},
methods: {
checkPermission,
@ -295,11 +309,20 @@ export default {
});
},
getPlanList_() {
this.listLoadingplan = true
getPlanList(this.listQuery_plan).then(res=>{
this.planData = res.data
this.listLoadingplan = false
}).catch(e=>{this.listLoadingplan = false})
this.listLoadingplan = true;
getPlanList(this.listQuery_plan)
.then((res) => {
this.planData = res.data;
this.listLoadingplan = false;
if (res.data && res.data.results.length) {
this.nowPlan = res.data.results[0];
this.listQuery2.plan = res.data.results[0].id;
this.getProjectList_2();
}
})
.catch((e) => {
this.listLoadingplan = false;
});
},
resetFilter() {
this.listQuery = {
@ -310,104 +333,128 @@ export default {
handleFilter() {
this.getCertappList_();
},
contactCompany(scope) {
planProject(scope) {
this.$router.push({
name: "HandleProject",
query: { project: scope.row.id },
name: "PlanProject",
params: { id: scope.row.id },
});
},
handleCreatePlan() {
this.dialogVisible=true
this.dialogType = 'create'
this.dialogVisible = true;
this.dialogType = "create";
},
handleUpdatePlan(scope) {
this.formData = Object.assign({}, scope.row)
this.dialogType = 'update'
this.dialogVisible=true
this.formData = Object.assign({}, scope.row);
this.dialogType = "update";
this.dialogVisible = true;
this.$nextTick(() => {
this.$refs['elForm'].clearValidate()
})
this.$refs["elForm"].clearValidate();
});
},
handleDeletePlan(scope) {
this.$confirm('确定删除该计划?','警告',{type:'warning'}).then(()=>{
deletePlan(scope.row.id).then(res=>{
this.$message.success('成功')
})
}).catch(res=>{
})
this.$confirm("确定删除该计划?", "警告", { type: "warning" })
.then(() => {
deletePlan(scope.row.id).then((res) => {
this.$message.success("成功");
});
})
.catch((res) => {});
},
handleDetailProject() {},
confirmPlan(){
this.$refs['elForm'].validate(valid => {
handleDetailProject(scope) {
this.$router.push({
name: "PlanProject",
params: { id: scope.row.id },
});
},
confirmPlan() {
this.$refs["elForm"].validate((valid) => {
if (valid) {
const isEdit = this.dialogType === 'update'
const isEdit = this.dialogType === "update";
if (isEdit) {
updatePlan(this.formData.id, this.formData).then(() => {
this.getPlanList_()
this.dialogVisible = false
this.$message.success('成功')
})
this.getPlanList_();
this.dialogVisible = false;
this.$message.success("成功");
});
} else {
createPlan(this.formData).then(res => {
createPlan(this.formData).then((res) => {
// this.org = res.data
// this.tableData.unshift(this.org)
this.getPlanList_()
this.dialogVisible = false
this.$message.success('成功')
})
this.getPlanList_();
this.dialogVisible = false;
this.$message.success("成功");
});
}
} else {
return false
return false;
}
})
});
},
handleSelectionChange(val) {
var ddd = []
for(var i=0;i<val.length;i++){
ddd.push(val[i].id)
}
this.multiprojects = ddd
},
handleAppend(){
if(this.multiprojects.length>0){
if(this.nowPlan.id!=0){
this.$confirm('是否将该项目添加至('+this.nowPlan.name+')中','提示',{}).then(()=>{
planProject({'plan':this.nowPlan.id, 'projects':this.multiprojects}).then(res=>{
this.$message.success('成功')
this.getProjectList_()
})
}).catch(res=>{
})
}else{
this.$message.warning('请先选择一个计划')
}
}else{
this.$message.warning('请先选择待处理项目')
}
},
planClick(row, column, event){
if(this.nowPlan.id != row.id){
this.nowPlan = row
this.listQuery2.plan = row.id
this.listQuery2.page = 1
this.getProjectList_2()
}else{
this.getProjectList_2()
}
},
getProjectList_2(){
this.listLoadingplan2 = true
getProjectList(this.listQuery2).then(res=>{
this.listLoadingplan2 = false
this.projectData2 = res.data
}).catch(e=>{
this.listLoadingplan2 = false
})
var ddd = [];
for (var i = 0; i < val.length; i++) {
ddd.push(val[i].id);
}
this.multiprojects = ddd;
},
handleAppend() {
if (this.multiprojects.length > 0) {
if (this.nowPlan.id != 0) {
this.$confirm(
"是否将该项目添加至(" + this.nowPlan.name + ")中",
"提示",
{}
)
.then(() => {
planProject({
plan: this.nowPlan.id,
projects: this.multiprojects,
}).then((res) => {
this.$message.success("成功");
this.getProjectList_();
this.getProjectList_2();
});
})
.catch((res) => {});
} else {
this.$message.warning("请先选择一个计划");
}
} else {
this.$message.warning("请先选择待策划项目");
}
},
planClick(row, column, event) {
if (this.nowPlan.id != row.id) {
this.nowPlan = row;
this.listQuery2.plan = row.id;
this.listQuery2.page = 1;
this.getProjectList_2();
} else {
this.nowPlan = row;
this.listQuery2.plan = row.id;
this.getProjectList_2();
}
},
getProjectList_2() {
this.listLoadingplan2 = true;
getProjectList(this.listQuery2).then(res=>{
// console.log(res.data)
this.projectData2 = res.data
this.listLoadingplan2 = false
}).catch(e=>{
this.listLoadingplan2 = false
})
},
nextProject(scope) {
this.$confirm("确定下达审核任务?", "警告", { type: "warning" }).then(
() => {
nextProject(scope.row.id).then((res) => {
this.$message.success("成功");
this.getProjectList_2();
});
}
).catch(e=>{})
},
},
};
</script>

View File

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

@ -44,12 +44,12 @@
<template slot-scope="scope">
<el-button-group>
<el-button
v-if="scope.row.status == '待下达'"
v-if="scope.row.status == '创建中'"
type="warning"
size="small"
:disabled="!checkPermission(['project_assign'])"
@click="handleAssign(scope)"
>下达</el-button>
@click="handleNext(scope)"
>转策划</el-button>
<el-button
type="primary"
size="small"
@ -177,7 +177,7 @@
</template>
<script>
import { getCertappList } from "@/api/certapp";
import { getProjectList, createProject, assginProject } from "@/api/project"
import { getProjectList, createProject, nextProject } from "@/api/project"
import Pagination from "@/components/Pagination";
import checkPermission from "@/utils/permission";
import Treeselect from "@riophae/vue-treeselect";
@ -248,7 +248,9 @@ export default {
this.listLoading = true;
getProjectList(this.listQuery_project).then((response) => {
if (response.data) {
this.projectData = response.data;
}
this.listLoading = false;
});
@ -295,15 +297,15 @@ export default {
})
})
},
handleAssign(scope) {
handleNext(scope) {
if(scope.row.certapps.length == 0){
this.$message.error('该项目不包含业务,无法下达!')
this.$message.error('该项目不包含业务,无法继续!')
}else{
this.$confirm("确定下达并转入策划派差吗?", "提示", {
this.$confirm("确定转入策划派差吗?", "提示", {
type: "warning",
}).then(() => {
assginProject(scope.row.id, {}).then(res=>{
this.$message.success('下达成功')
nextProject(scope.row.id, {}).then(res=>{
this.$message.success('成功')
this.getProjectList_()
})
}).catch(()=>{

View File

View File

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

View File

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

View File

View File

@ -0,0 +1,17 @@
from utils import model
from django.contrib.postgres.fields import JSONField
from django.db import models
from rest_framework.exceptions import ParseError
from simple_history.models import HistoricalRecords
from apps.certset.models import ImplementRule, UnitType, EvaluationItem, Standard
from apps.crm.models import Enterprise
from apps.project.models import CertApp
from apps.system.models import CommonAModel, CommonBModel, Dict, User
# class AuditNumber(CommonAModel):
# user = models.ForeignKey(User, on_delete=models.CASCADE, verbose_name='审核成员', related_name='auditnumber_user')
# class Meta:
# verbose_name = '审核天数/人日数'
# verbose_name_plural = verbose_name

View File

@ -0,0 +1,61 @@
from utils import serializer
from rest_framework import serializers
from .models import *
from apps.system.serializers import DictSerializer, UserListSerializer
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)
certapps = serializers.SerializerMethodField()
plan_ = PlanSerializer(source='plan', read_only=True)
members = serializers.SerializerMethodField()
class Meta:
model = Project
fields = '__all__'
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
def get_members(self, obj):
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')
serializer = MemberSerializer(members, many=True)
return serializer.data
@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_ = DictSerializer(source='cert_field', read_only=True)
cccpv_class_ = DictSerializer(source='cccpv_class' , read_only=True)
cnas_scopes_ = DictSerializer(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)
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_accepted=True, is_deleted=False).order_by('-is_leader')
serializer = MemberSerializer(members, many=True)
return serializer.data

View File

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

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

@ -0,0 +1,11 @@
from django.urls import path, include
from .views import *
from rest_framework import routers
router = routers.DefaultRouter()
urlpatterns = [
path('mytask/', MyAuditTaskList.as_view()),
path('myauditcertapp/', MyAuditCertappList.as_view()),
path('', include(router.urls))
]

View File

@ -0,0 +1,49 @@
from typing import List
from rest_framework.viewsets import ModelViewSet
from apps.plan.serializers import MemberSerializer
from logging import setLoggerClass
from utils import queryset
from rest_framework.views import APIView
from rest_framework.generics import ListAPIView
from apps.system.models import Dict
from apps.system.permission_data import RbacFilterSet
from apps.system.mixins import CreateUpdateCustomMixin, OptimizationMixin
import random
from rest_framework.decorators import action
from utils.pagination import PageOrNot
from apps.project.models import Project
from apps.project.filters import ProjectFilter
from apps.audit.serializers import *
class MyAuditTaskList(ListAPIView):
perms_map = {'get': 'myaudittask_view'}
serializer_class = ProjectSerializerX
filterset_class = ProjectFilter
search_fields = ['auditee__name', 'plan__name']
ordering=['-pk']
def get_queryset(self):
queryset = Project.objects.filter(certapp_project__member_certapp__user=self.request.user)
if hasattr(self.get_serializer_class(), 'setup_eager_loading'):
queryset = self.get_serializer_class().setup_eager_loading(queryset)
return queryset
# class AuditNumberViewSet(CreateUpdateCustomMixin, ModelViewSet):
# perms_map = {'get': 'myaudittask_view'}
# serializer_class = ProjectSerializerX
# filterset_class = ProjectFilter
# search_fields = ['auditee__name', 'plan__name']
# ordering=['-pk']
class MyAuditCertappList(PageOrNot, ListAPIView):
perms_map = {'get': 'myaudittask_view'}
serializer_class = CertappSerializerX
filterset_fields = ['project']
ordering=['-pk']
def get_queryset(self):
queryset = CertApp.objects.filter(member_certapp__user=self.request.user)
if hasattr(self.get_serializer_class(), 'setup_eager_loading'):
queryset = self.get_serializer_class().setup_eager_loading(queryset)
return queryset

View File

@ -0,0 +1,18 @@
# Generated by Django 3.0.7 on 2020-09-03 03:19
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('plan', '0003_auto_20200901_1555'),
]
operations = [
migrations.AddField(
model_name='member',
name='is_accepted',
field=models.BooleanField(default=None, null=True, verbose_name='是否接受任务'),
),
]

View File

@ -0,0 +1,50 @@
# Generated by Django 3.0.7 on 2020-09-10 06:31
from django.db import migrations, models
import django.db.models.deletion
class Migration(migrations.Migration):
dependencies = [
('system', '0031_delete_bscodeset'),
('project', '0029_auto_20200904_1553'),
('plan', '0004_member_is_accepted'),
]
operations = [
migrations.RemoveField(
model_name='member',
name='belong_dept',
),
migrations.RemoveField(
model_name='member',
name='project',
),
migrations.AddField(
model_name='member',
name='certapp',
field=models.ForeignKey(default=3, on_delete=django.db.models.deletion.CASCADE, related_name='member_certapp', to='project.CertApp', verbose_name='参与申请'),
preserve_default=False,
),
migrations.AddField(
model_name='member',
name='days',
field=models.DecimalField(decimal_places=2, default=0, max_digits=4, verbose_name='审核天数'),
),
migrations.AddField(
model_name='member',
name='man_days',
field=models.DecimalField(decimal_places=2, default=0, max_digits=4, verbose_name='人日数'),
),
migrations.AlterField(
model_name='member',
name='identity',
field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='member_identity', to='system.Dict', verbose_name='组内身份'),
),
migrations.AlterField(
model_name='member',
name='is_leader',
field=models.BooleanField(default=False, verbose_name='是否组长'),
),
]

View File

@ -0,0 +1,22 @@
# Generated by Django 3.0.7 on 2020-09-11 01:44
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('plan', '0005_auto_20200910_1431'),
]
operations = [
migrations.RemoveField(
model_name='member',
name='is_leader',
),
migrations.AlterField(
model_name='member',
name='is_accepted',
field=models.BooleanField(default=False, null=True, verbose_name='是否接受任务'),
),
]

View File

@ -0,0 +1,23 @@
# Generated by Django 3.0.7 on 2020-09-11 01:54
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('plan', '0006_auto_20200911_0944'),
]
operations = [
migrations.AddField(
model_name='member',
name='is_leader',
field=models.BooleanField(default=False, verbose_name='是否组长'),
),
migrations.AlterField(
model_name='member',
name='is_accepted',
field=models.BooleanField(default=False, null=True, verbose_name='是否接受'),
),
]

View File

@ -38,15 +38,18 @@ class ContactRecord(CommonBModel):
def __str__(self):
return self.content
class Member(CommonBModel):
class Member(CommonAModel):
"""
审核成员
业务审核成员
"""
user = models.ForeignKey(User, on_delete=models.CASCADE, verbose_name='成员', related_name='member_user')
is_leader = models.BooleanField('是否是组长', default=False)
project = models.ForeignKey(Project, on_delete=models.SET_NULL, null=True, blank=True, verbose_name='所属项目', related_name='member_project')
identity = models.ForeignKey(Dict, on_delete=models.SET_NULL, null=True, blank=True, verbose_name='身份', related_name='member_identity')
is_accepted = models.BooleanField('是否接受', null=True, default=False)
certapp = models.ForeignKey(CertApp, on_delete=models.CASCADE, verbose_name='参与申请', related_name='member_certapp')
man_days = models.DecimalField('人日数', max_digits=4, decimal_places=2, default=0)
days = models.DecimalField('审核天数', max_digits=4, decimal_places=2, default=0)
identity = models.ForeignKey(Dict, on_delete=models.SET_NULL, null=True, blank=True, verbose_name='组内身份', related_name='member_identity')
is_leader = models.BooleanField('是否组长', default=False)
class Meta:
verbose_name = '审核组成员'
verbose_name_plural = verbose_name

View File

@ -22,7 +22,7 @@ class ContactRecordViewSet(CreateUpdateCustomMixin, PageOrNot, ModelViewSet):
perms_map = {'get': 'contactrecord_view', 'post':'contactrecord_create', 'put':'contactrecord_update','delete': 'contactrecord_delete'}
queryset = ContactRecord.objects.all()
serializer_class = ContactRecordSerializer
ordering = ['pk']
ordering = ['-pk']
filterset_fields = ['project', 'certapp']
class PlanViewSet(RbacFilterSet, PageOrNot, ModelViewSet):
@ -32,7 +32,7 @@ class PlanViewSet(RbacFilterSet, PageOrNot, ModelViewSet):
perms_map = {'get': 'plan_view', 'post':'plan_create', 'put':'plan_update','delete': 'plan_delete'}
queryset = Plan.objects.all()
serializer_class = PlanSerializer
ordering = ['pk']
ordering = ['-pk']
# filterset_fields = ['project', 'certapp']
class MemberViewSet(CreateUpdateCustomMixin, PageOrNot, ModelViewSet):
@ -42,14 +42,26 @@ class MemberViewSet(CreateUpdateCustomMixin, PageOrNot, ModelViewSet):
perms_map = {'get': '*', 'post':'member_create', 'put':'member_update','delete': 'member_delete'}
queryset = Member.objects.all()
serializer_class = MemberSerializer
ordering = ['pk']
filterset_fields = ['project']
ordering = ['-is_leader', 'pk']
filterset_fields = ['certapp']
def create(self, request, *args, **kwargs):
serializer = self.get_serializer(data=request.data)
serializer.is_valid(raise_exception=True)
if Member.objects.filter(user = request.data['user'], project=request.data['project'], is_deleted=False).exists():
if Member.objects.filter(user = request.data['user'], certapp=request.data['certapp'], is_deleted=False).exists():
return Response('已存在该成员', status= status.HTTP_400_BAD_REQUEST)
self.perform_create(serializer)
headers = self.get_success_headers(serializer.data)
return Response(serializer.data, status=status.HTTP_201_CREATED, headers=headers)
return Response(serializer.data, status=status.HTTP_201_CREATED, headers=headers)
@action(methods=['put'], detail=True, perms_map={'put':'audit_days'},
url_name='audit_days')
def days(self, request, *args, **kwargs):
"""
反馈审核员的人日数等
"""
obj = self.get_object()
obj.man_days = request.data['man_days']
obj.days = request.data['days']
obj.save()
return Response(status=status.HTTP_200_OK)

View File

@ -11,4 +11,4 @@ class ProjectFilter(filters.FilterSet):
planoff = filters.BooleanFilter(field_name='plan', lookup_expr='isnull')
class Meta:
model = Project
fields = ['plan', 'planoff']
fields = ['plan', 'planoff', 'status', 'certapp_project__member_certapp__user']

View File

@ -0,0 +1,26 @@
# Generated by Django 3.0.7 on 2020-09-03 03:19
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('project', '0027_auto_20200825_1636'),
]
operations = [
migrations.RemoveField(
model_name='project',
name='assign_by',
),
migrations.RemoveField(
model_name='project',
name='assign_date',
),
migrations.AlterField(
model_name='project',
name='status',
field=models.CharField(choices=[('创建中', '创建中'), ('待策划', '待策划'), ('策划中', '策划中'), ('审核任务已下达', '审核任务已下达'), ('审核任务已接受', '审核任务已接受'), ('现场审核中', '现场审核中')], default='创建中', max_length=50, verbose_name='项目状态'),
),
]

View File

@ -0,0 +1,41 @@
# Generated by Django 3.0.7 on 2020-09-04 07:53
from django.conf import settings
from django.db import migrations, models
import django.db.models.deletion
class Migration(migrations.Migration):
dependencies = [
migrations.swappable_dependency(settings.AUTH_USER_MODEL),
('project', '0028_auto_20200903_1119'),
]
operations = [
migrations.AddField(
model_name='project',
name='assgin_by',
field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, to=settings.AUTH_USER_MODEL, verbose_name='审核任务下达人'),
),
migrations.AddField(
model_name='project',
name='assgin_date',
field=models.DateTimeField(blank=True, null=True, verbose_name='任务下达时间'),
),
migrations.AddField(
model_name='project',
name='edate0',
field=models.DateTimeField(blank=True, null=True, verbose_name='预计审核开始时间'),
),
migrations.AddField(
model_name='project',
name='edate1',
field=models.DateTimeField(blank=True, null=True, verbose_name='预计审核结束时间'),
),
migrations.AlterField(
model_name='project',
name='status',
field=models.CharField(choices=[('创建中', '创建中'), ('待策划', '待策划'), ('策划中', '策划中'), ('审核任务已下达', '审核任务已下达'), ('审核任务已接受', '审核任务已接受'), ('待现场审核', '待现场审核'), ('现场审核中', '现场审核中'), ('任务已反馈', '任务已反馈')], default='创建中', max_length=50, verbose_name='项目状态'),
),
]

View File

@ -16,21 +16,26 @@ class Project(CommonBModel):
认证项目
"""
status_choices = (
('待下达', '待下达'),
('待派差', '待派差'),
('进行中', '进行中'),
('已中止', '已中止'),
('已完成', '已完成')
('创建中', '创建中'),
('待策划', '待策划'),
('策划中', '策划中'),
('审核任务已下达', '审核任务已下达'),
('审核任务已接受', '审核任务已接受'),
('待现场审核', '待现场审核'),
('现场审核中', '现场审核中'),
('任务已反馈', '任务已反馈')
)
status = models.CharField('项目状态', choices=status_choices, default='待下达', max_length=50)
status = models.CharField('项目状态', choices=status_choices, default='创建中', max_length=50)
number = models.CharField('项目编号', max_length = 100, null=True, blank=True)
auditee = models.ForeignKey(Enterprise, related_name='project_auditee', on_delete=models.DO_NOTHING, verbose_name='受审核方')
auditee_v = JSONField(verbose_name='受审核方', default=dict)
remark = models.TextField('备注', null=True, blank=True)
assign_date = models.DateField('下达日期', null=True, blank=True)
assign_by = models.ForeignKey(User, verbose_name='下达人', on_delete=models.SET_NULL, null=True, blank=True)
can_paichai = models.BooleanField('是否可派差', default = False)
plan = models.ForeignKey('plan.Plan', verbose_name='所属计划', on_delete=models.SET_NULL, null=True, blank=True)
assgin_date = models.DateTimeField('任务下达时间', null=True, blank=True)
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)
class Meta:

View File

@ -80,7 +80,7 @@ class ProjectSerializer(serializers.ModelSerializer):
def get_certapps(self, obj):
certapps = []
for i in CertApp.objects.filter(is_deleted=False, project=obj):
for i in obj.certapp_project.filter(is_deleted=False):
certapps.append(i.cert_field.code +'(' + i.cccpv_class.name +')')
return certapps
@ -88,6 +88,7 @@ class ProjectSerializer(serializers.ModelSerializer):
def setup_eager_loading(queryset):
""" Perform necessary eager loading of data. """
queryset = queryset.select_related('create_by', 'assign_by', 'plan')
queryset = queryset.prefetch_related('certapp_project')
return queryset
class ProjectUpdateSerializer(serializers.ModelSerializer):

View File

@ -15,6 +15,7 @@ from rest_framework.decorators import action
from .filters import *
from utils.pagination import PageOrNot
from rest_framework.exceptions import ParseError, NotAuthenticated
from django.utils import timezone
# Create your views here.
class ApplicationViewSet(RbacFilterSet, ModelViewSet):
"""
@ -135,6 +136,7 @@ class ProjectViewSet(RbacFilterSet, ModelViewSet):
serializer_class = ProjectSerializer
ordering = ['pk']
filterset_class = ProjectFilter
search_fields = ['auditee__name', 'plan__name']
def get_serializer_class(self):
if self.action == 'update':
@ -155,21 +157,25 @@ class ProjectViewSet(RbacFilterSet, ModelViewSet):
else:
return NotAuthenticated()
@action(methods=['put'], detail=True, perms_map={'put':'project_assgin'},
url_name='project_assgin')
def assgin(self, request, pk=None):
@action(methods=['put'], detail=True, perms_map={'put':'project_next'},
url_name='project_next')
def next(self, request, pk=None):
"""
下达项目
项目流转
"""
obj = self.get_object()
if obj.status == '待下达':
obj.status = '待派差'
obj.assgin_by = request.user
if obj.status == '创建中':
obj.status = '待策划'
obj.save()
return Response(status=status.HTTP_200_OK)
elif obj.status == '策划中' and obj.can_paichai:
obj.status = '待现场审核'
obj.save()
return Response(status=status.HTTP_200_OK)
else:
return Response('状态有误', status=status.HTTP_400_BAD_REQUEST)
return Response('项目状态异常,操作失败', status=status.HTTP_400_BAD_REQUEST)
@action(methods=['put'], detail=False, perms_map={'put':'project_plan'},
url_name='project_plan')
def plan(self, request, *args, **kwargs):
@ -179,5 +185,22 @@ class ProjectViewSet(RbacFilterSet, ModelViewSet):
projects = request.data['projects']
plan = request.data['plan']
if projects:
Project.objects.filter(pk__in=projects).update(plan=plan)
objs = Project.objects.filter(pk__in=projects)
for i in objs:
i.plan=plan
if i.status == '待策划':
i.status == '策划中'
i.save()
return Response(status=status.HTTP_200_OK)
@action(methods=['put'], detail=True, perms_map={'put':'project_edate'},
url_name='project_edate')
def edate(self, request, *args, **kwargs):
"""
制定预期审核时间
"""
obj = self.get_object()
obj.edate0 = request.data['edate0']
obj.edate1 = request.data['edate1']
obj.save()
return Response(status=status.HTTP_200_OK)

View File

@ -203,6 +203,12 @@ class UserViewSet(ModelViewSet):
Employee.objects.create(user=instance,create_by=request.user)
return Response(serializer.data)
def perform_update(self, serializer):
instance = serializer.save()
from apps.employee.models import Employee
if not Employee.objects.filter(user=instance).exists():
Employee.objects.create(user=instance,create_by=self.request.user)
@action(methods=['put'], detail=False, permission_classes=[IsAuthenticated], # perms_map={'put':'change_password'}
url_name='change_password')
def password(self, request, pk=None):

View File

@ -51,7 +51,8 @@ INSTALLED_APPS = [
'apps.project',
'apps.financial',
'apps.laboratory',
'apps.plan'
'apps.plan',
'apps.audit'
]
MIDDLEWARE = [

View File

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