tijiaoguanlitixi

This commit is contained in:
shilixia 2020-09-14 10:31:10 +08:00
commit 6b37154bc4
79 changed files with 4300 additions and 408 deletions

BIN
client/quota.dat Normal file

Binary file not shown.

View File

@ -6,6 +6,7 @@
<style type="text/css"> <style type="text/css">
.el-table--medium td,   .el-table--medium th { .el-table--medium td,   .el-table--medium th {
padding: 5px 0; padding: 5px 0;
} }

View File

@ -32,6 +32,13 @@ export function updateCertapp(id, data) {
}) })
} }
export function completeCertapp(id) {
return request({
url: `/project/certapp/${id}/complete/`,
method: 'put',
})
}
export function getCertapp(id) { export function getCertapp(id) {
return request({ return request({
url: `/project/certapp/${id}/`, url: `/project/certapp/${id}/`,

View File

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

View File

@ -0,0 +1,69 @@
import request from '@/utils/request'
export function getBillList(query) {
return request({
url: '/financial/bill/',
method: 'get',
params: query
})
}
export function getBill(id) {
return request({
url: `/financial/bill/${id}/`,
method: 'get'
})
}
export function createBill(data) {
return request({
url: '/financial/bill/',
method: 'post',
data
})
}
export function updateBill(id, data) {
return request({
url: `/financial/bill/${id}/`,
method: 'put',
data
})
}
export function deleteBill(id) {
return request({
url: `/financial/bill/${id}/`,
method: 'delete'
})
}
export function getChargeitemList(query) {
return request({
url: '/financial/chargeitem/',
method: 'get',
params: query
})
}
export function createChargeitem(data) {
return request({
url: '/financial/chargeitem/',
method: 'post',
data
})
}
export function updateChargeitem(id, data) {
return request({
url: `/financial/chargeitem/${id}/`,
method: 'put',
data
})
}
export function deleteChargeitem(id) {
return request({
url: `/financial/chargeitem/${id}/`,
method: 'delete'
})
}

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

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

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

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

56
client/src/api/project.js Normal file
View File

@ -0,0 +1,56 @@
import request from '@/utils/request'
export function getProjectList(query) {
return request({
url: '/project/project/',
method: 'get',
params: query
})
}
export function createProject(data) {
return request({
url: '/project/project/',
method: 'post',
data
})
}
export function deleteProject(id) {
return request({
url: `/project/project/${id}/`,
method: 'delete'
})
}
export function updateProject(id, data) {
return request({
url: `/project/project/${id}/`,
method: 'put',
data
})
}
export function getProject(id) {
return request({
url: `/project/project/${id}/`,
method: 'get',
})
}
export function assginProject(id, data) {
return request({
url: `/project/project/${id}/assgin/`,
method: 'put',
data
})
}
export function planProject(data) {
return request({
url: '/project/project/plan/',
method: 'put',
data
})
}

40
client/src/api/unit.js Normal file
View File

@ -0,0 +1,40 @@
import request from '@/utils/request'
export function getUnitList(query) {
return request({
url: '/project/unit/',
method: 'get',
params: query
})
}
export function createUnit(data) {
return request({
url: '/project/unit/',
method: 'post',
data
})
}
export function deleteUnit(id) {
return request({
url: `/project/unit/${id}/`,
method: 'delete'
})
}
export function updateUnit(id, data) {
return request({
url: `/project/unit/${id}/`,
method: 'put',
data
})
}
export function getUnit(id) {
return request({
url: `/project/unit/${id}/`,
method: 'get',
})
}

View File

@ -93,7 +93,7 @@ export default {
<style scoped> <style scoped>
.pagination-container { .pagination-container {
background: #fff; background: #fff;
padding: 0px 16px; padding: 0px 2px;
} }
.pagination-container.hidden { .pagination-container.hidden {
display: none; display: none;

View File

@ -64,7 +64,7 @@ export const asyncRoutes = [
{ {
path: '/project', path: '/project',
component: Layout, component: Layout,
redirect: '/project/case', redirect: '/project/certapp',
name: 'ProjectManage', name: 'ProjectManage',
meta: { title: '认证项目', icon: 'example'}, meta: { title: '认证项目', icon: 'example'},
children: [ children: [
@ -72,19 +72,25 @@ export const asyncRoutes = [
path: 'application', path: 'application',
name: 'Applicaion', name: 'Applicaion',
component: () => import('@/views/application/application'), component: () => import('@/views/application/application'),
meta: { title: '认证受理', icon: 'example', perms: ['application_view'] } meta: { title: '业务受理2', icon: 'example', perms: ['application_view'] }
}, },
{ {
path: 'certapp', path: 'certapp',
name: 'Certapp', name: 'Certapp',
component: () => import('@/views/certapp/certapp'), component: () => import('@/views/certapp/certapp'),
meta: { title: '认证受理', icon: 'example', perms: ['certapp_view'] } meta: { title: '业务受理1', icon: 'example', perms: ['certapp_view'] }
}, },
// {
// path: 'application2',
// name: 'Applicaion2',
// component: () => import('@/views/employee/train'),
// meta: { title: '客户申请受理', icon: 'example', perms: ['application_accept'] }
// },
{ {
path: 'application2', path: 'project',
name: 'Applicaion2', name: 'Project',
component: () => import('@/views/employee/train'), component: () => import('@/views/project/project'),
meta: { title: '客户申请受理', icon: 'example', perms: ['application_accept'] } meta: { title: '项目制定', icon: 'example', perms: ['project_view'] }
}, },
{ {
path: 'application/applicationform/', path: 'application/applicationform/',
@ -97,11 +103,70 @@ export const asyncRoutes = [
path: 'certapp/:action/:kind/', path: 'certapp/:action/:kind/',
name: 'CertappForm', name: 'CertappForm',
component: () => import('@/views/certapp/certappform'), component: () => import('@/views/certapp/certappform'),
meta: { title: '认证受理单', icon: 'example', perms: ['certapp_create', 'certapp_update'] }, meta: { title: '申请受理单', icon: 'example', perms: ['certapp_create', 'certapp_update'] },
hidden: true hidden: true
}, },
] ]
}, },
{
path: '/plan',
component: Layout,
redirect: '/plan/plan',
name: 'PlanManage',
meta: { title: '审核策划', icon: 'example'},
children: [
{
path: 'plan',
name: 'Plan',
component: () => import('@/views/plan/plan'),
meta: { title: '计划', icon: 'example', perms: ['plan_view'] }
},
{
path: 'paichai',
name: 'Paichai',
component: () => import('@/views/plan/paichai'),
meta: { title: '派差', icon: 'example', perms: ['plan_view'] }
},
{
path: 'project',
name: 'HandleProject',
component: () => import('@/views/plan/handle'),
meta: { title: '联系企业', icon: 'example', perms: ['project_view'] },
hidden: true
},
]
},
{
path: '/spot',
component: Layout,
redirect: '/spot/spot',
name: 'SpotM',
meta: { title: '现场审核', icon: 'example'},
children: [
{
path: 'spot',
name: 'Spot',
component: () => import('@/views/plan/plan'),
meta: { title: '现场审核', icon: 'example', perms: ['plan_view'] }
},
]
},
{
path: '/judge',
component: Layout,
redirect: '/judge/judge',
name: 'JudgeM',
meta: { title: '认证评定', icon: 'example'},
children: [
{
path: 'judge',
name: 'Judge',
component: () => import('@/views/plan/plan'),
meta: { title: '认证评定', icon: 'example', perms: ['plan_view'] }
},
]
},
{ {
path: '/employee', path: '/employee',
component: Layout, component: Layout,
@ -157,6 +222,7 @@ export const asyncRoutes = [
}, },
] ]
}, },
{ {
path: '/certset', path: '/certset',
component: Layout, component: Layout,
@ -213,6 +279,7 @@ export const asyncRoutes = [
] ]
}, },
{ {
path: '/crm', path: '/crm',
component: Layout, component: Layout,
redirect: '/crm/enterprise', redirect: '/crm/enterprise',
@ -253,7 +320,7 @@ export const asyncRoutes = [
component: Layout, component: Layout,
redirect: '/testorg/testorg', redirect: '/testorg/testorg',
name: 'testorg', name: 'testorg',
meta: { title: '实验室管理', icon: 'example' }, meta: { title: '产品检测', icon: 'example' },
children: [ children: [
{ {
@ -272,6 +339,7 @@ export const asyncRoutes = [
] ]
}, },
{ {
path: '/system', path: '/system',
component: Layout, component: Layout,
redirect: '/system/user', redirect: '/system/user',

View File

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

View File

@ -226,10 +226,24 @@
<el-switch v-model="formData.is_approve"></el-switch> <el-switch v-model="formData.is_approve"></el-switch>
</el-form-item> </el-form-item>
</el-col> </el-col>
</el-row>
<el-row>
<!-- <el-col :xs="24" :md="12">
<el-form-item label="认证范围" >
<el-input readonly placeholder="填写产品单元后自动生成"></el-input>
</el-form-item>
</el-col> -->
<el-col :xs="24" :md="12">
<el-form-item label="备注" >
<el-input v-model="formData.remark" type="textarea"
:autosize="{ minRows: 2, maxRows: 4}"></el-input>
</el-form-item>
</el-col>
</el-row> </el-row>
</el-form> </el-form>
<div slot="footer" align="center"> <div slot="footer" align="center">
<el-button @click="close(false)">取消</el-button> <el-button @click="cancel()">返回列表</el-button>
<el-button type="primary" @click="handelConfirm">保存</el-button> <el-button type="primary" @click="handelConfirm">保存</el-button>
</div> </div>
<el-dialog <el-dialog
@ -244,7 +258,7 @@
</div> </div>
</template> </template>
<script> <script>
import { createCertapp, updateCertapp, getCertapp } from "@/api/certapp"; import { createCertapp, updateCertapp } from "@/api/certapp";
import Enterprisechose from "@/views/enterprise/enterprisechoose"; import Enterprisechose from "@/views/enterprise/enterprisechoose";
import { getAddressList } from "@/api/enterprise"; import { getAddressList } from "@/api/enterprise";
import { genTree } from "../../utils"; import { genTree } from "../../utils";
@ -269,7 +283,8 @@ export default {
factory_v: {}, factory_v: {},
cccpv_class: null, cccpv_class: null,
pattern: "正常", pattern: "正常",
is_approve:true is_approve:true,
level:null
}, },
rules: { rules: {
apply_date: [ apply_date: [
@ -357,23 +372,20 @@ export default {
}, },
created() { created() {
console.log(this.certapp)
if(this.action!='create'){
this.formData = this.certapp
}
this.getCCCOptions(); this.getCCCOptions();
this.getlevelOptions(); this.getlevelOptions();
if(this.action!='create'){
this.formData.id = this.certapp
this.getCertapp_()
}
}, },
mounted() {}, mounted() {},
methods: { methods: {
close(val) { cancel(val) {
// this.$refs['elForm'].resetFields() // this.$refs['elForm'].resetFields()
this.$emit("closeDg", val); this.$router.go(-1)
},
getCertapp_(){
getCertapp(this.formData.id).then(res=>{
this.formData = res.data
})
}, },
handelConfirm() { handelConfirm() {
this.$refs["elForm"].validate((valid) => { this.$refs["elForm"].validate((valid) => {
@ -386,7 +398,7 @@ export default {
}else{ }else{
createCertapp(this.formData).then((res) => { createCertapp(this.formData).then((res) => {
this.$message.success('成功') this.$message.success('成功')
this.$emit("handleCommit", res.data); this.$router.replace({name:"CertappForm", params:{action:'update', kind:'CCC'}, query:{id:res.data.id}})
}); });
} }
@ -398,6 +410,7 @@ export default {
}, },
chooseComplete(val) { chooseComplete(val) {
this.dgVisiable = false; this.dgVisiable = false;
console.log(val)
if (val) { if (val) {
if (this.dgType == 0) { if (this.dgType == 0) {
this.formData.applicant = val.id; this.formData.applicant = val.id;
@ -408,6 +421,24 @@ export default {
linkman_duty: val.linkman1_duty, linkman_duty: val.linkman1_duty,
person_count: val.person_count, person_count: val.person_count,
}; };
}else if(this.dgType==1){
this.formData.manufacture = val.id;
this.formData.manufacture_v = {
name: val.name,
linkman_name: val.linkman1_name,
linkman_mobile: val.linkman1_mobile,
linkman_duty: val.linkman1_duty,
person_count: val.person_count,
};
}else{
this.formData.factory = val.id;
this.formData.factory_v = {
name: val.name,
linkman_name: val.linkman1_name,
linkman_mobile: val.linkman1_mobile,
linkman_duty: val.linkman1_duty,
person_count: val.person_count,
};
} }
} }
this.getAddressList_(val.id); this.getAddressList_(val.id);

View File

@ -38,12 +38,12 @@
class="filter-item" class="filter-item"
@keyup.enter.native="handleFilter" @keyup.enter.native="handleFilter"
/> />
<el-button-group style="margin-left:2px">
<el-button <el-button
class="filter-item" class="filter-item"
type="primary" type="primary"
icon="el-icon-search" icon="el-icon-search"
@click="handleFilter" @click="handleFilter"
style="margin-left:10px"
>搜索</el-button> >搜索</el-button>
<el-button <el-button
class="filter-item" class="filter-item"
@ -51,10 +51,13 @@
icon="el-icon-refresh-left" icon="el-icon-refresh-left"
@click="resetFilter" @click="resetFilter"
>刷新重置</el-button> >刷新重置</el-button>
</el-button-group>
</div> </div>
<div style="margin-top:6px"> <div style="margin-top:6px">
<el-button-group>
<el-button type="primary" icon="el-icon-plus" v-for="(item, index) in field_list" :key="'field_list' + index" @click="handleCreate(item,index)" size="mini">{{item.name}}</el-button> <el-button type="primary" icon="el-icon-plus" v-for="(item, index) in field_list" :key="'field_list' + index" @click="handleCreate(item,index)" size="mini">{{item.name}}</el-button>
<el-button type="warning" size="mini">+批量多体系</el-button> <el-button type="warning" size="mini" icon="el-icon-plus">批量多体系</el-button>
</el-button-group>
</div> </div>
<el-table <el-table
v-loading="listLoading" v-loading="listLoading"
@ -67,7 +70,7 @@
max-height="600" max-height="600"
> >
<el-table-column type="index" width="50" /> <el-table-column type="index" width="50" />
<el-table-column label="单号"> <el-table-column label="申请单号">
<template slot-scope="scope" v-if="scope.row.number">{{ scope.row.number }}</template> <template slot-scope="scope" v-if="scope.row.number">{{ scope.row.number }}</template>
</el-table-column> </el-table-column>
<el-table-column label="认证领域/分类"> <el-table-column label="认证领域/分类">
@ -84,7 +87,9 @@
</template> </template>
</el-table-column> </el-table-column>
<el-table-column label="当前状态"> <el-table-column label="当前状态">
<template slot-scope="scope"><el-tag>{{ scope.row.status}}</el-tag></template> <template slot-scope="scope">
{{ scope.row.status}}
</template>
</el-table-column> </el-table-column>
<el-table-column label="创建人"> <el-table-column label="创建人">
<template slot-scope="scope">{{ scope.row.create_by_.name}}</template> <template slot-scope="scope">{{ scope.row.create_by_.name}}</template>
@ -96,6 +101,7 @@
</el-table-column> </el-table-column>
<el-table-column label="操作"> <el-table-column label="操作">
<template slot-scope="scope"> <template slot-scope="scope">
<el-button-group>
<el-button <el-button
type="primary" type="primary"
size="small" size="small"
@ -108,6 +114,7 @@
:disabled="!checkPermission(['case_delete'])" :disabled="!checkPermission(['case_delete'])"
@click="handleDelete(scope)" @click="handleDelete(scope)"
>删除</el-button> >删除</el-button>
</el-button-group>
</template> </template>
</el-table-column> </el-table-column>
</el-table> </el-table>

View File

@ -1,43 +1,50 @@
<template> <template>
<div class="app-container"> <div class="app-container">
<el-tabs type="border-card"> <el-tabs type="border-card">
<el-tab-pane label="申请信息" style="height:700px;overflow-y:auto;overflow-x:hidden;"> <el-tab-pane label="申请信息" style="overflow-y:auto;overflow-x:hidden;">
<CCCform :action="action" @handleCommit="save" :certapp="certapp" v-if="kind=='CCC'"></CCCform> <CCCform :action="action" @handleCommit="save" :certapp="certapp" v-if="kind=='CCC'&isLoad"></CCCform>
<QMSform :action="action" @handleCommit="save" :certapp="certapp" v-if="kind=='QMS'"></QMSform> <QMSform :action="action" @handleCommit="save" :certapp="certapp" v-if="kind=='QMS'&isLoad"></QMSform>
</el-tab-pane> </el-tab-pane>
<el-tab-pane label="受理信息" style="height:700px;overflow-y:auto;overflow-x:hidden;" v-if="certapp&&kind=='QMS'">
<review :action="action" :certapp="certapp" v-if="kind=='QMS'"></review> <el-tab-pane label="产品单元" v-if="certapp">
<Productunit :certapp="certapp"></Productunit>
</el-tab-pane> </el-tab-pane>
<el-tab-pane label="产品单元" style="height:700px;overflow-y:auto;overflow-x:hidden;" v-if="certapp"> <el-tab-pane label="原材料供应商" v-if="certapp">
</el-tab-pane>
<el-tab-pane label="检测设备" v-if="certapp">
</el-tab-pane> </el-tab-pane>
<el-tab-pane label="原材料供应商" style="height:700px;overflow-y:auto;overflow-x:hidden;" v-if="certapp"> <el-tab-pane label="资料评审" v-if="certapp">
<REVIEW :certapp="certapp"></REVIEW>
</el-tab-pane> </el-tab-pane>
<el-tab-pane label="检测设备" style="height:700px;overflow-y:auto;overflow-x:hidden;" v-if="certapp"> <el-tab-pane label="收费信息" v-if="certapp">
<CHARGE :certapp="certapp"></CHARGE>
</el-tab-pane> <!--<el-button type="primary"
<el-tab-pane label="资料评审" style="height:700px;overflow-y:auto;overflow-x:hidden;" v-if="certapp"> @click="handleComplete()">完成受理</el-button>-->
</el-tab-pane>
<el-tab-pane label="收费信息" style="height:700px;overflow-y:auto;overflow-x:hidden;" v-if="certapp">
<charge :action="action" @handleCommit="save" :certapp="certapp" v-if="kind=='QMS'"></charge>
</el-tab-pane> </el-tab-pane>
</el-tabs> </el-tabs>
</div> </div>
</template> </template>
<script> <script>
import CCCform from "@/views/certapp/cccform" import CCCform from "@/views/certapp/cccform"
import REVIEW from "@/views/certapp/review"
import CHARGE from "@/views/certapp/charge"
import Productunit from "@/views/certapp/productunit"
import { getCertapp, completeCertapp } from "@/api/certapp"
import router from '@/router';
import QMSform from "@/views/certapp/qmsform" import QMSform from "@/views/certapp/qmsform"
import review from "@/views/certapp/review"
import charge from "@/views/certapp/charge"
export default { export default {
components: { CCCform,QMSform,review ,charge}, components: { CCCform, Productunit, QMSform,REVIEW,CHARGE},
props: [], props: [],
data() { data() {
return { return {
action:null, action:'create',
certapp:null, certapp:null,
kind:null kind:'CCC',
isLoad:false
}; };
}, },
computed: {}, computed: {},
@ -55,11 +62,22 @@ export default {
this.action = action this.action = action
this.kind = kind this.kind = kind
if(action=='update'){ if(action=='update'){
this.certapp = this.$route.query.id getCertapp(this.$route.query.id).then(res=>{
this.certapp = res.data
this.isLoad = true
})
}else{
this.isLoad = true
} }
}, },
save(val){ save(val){
this.certapp=val.id this.certapp=val
},
handleComplete(){
completeCertapp(this.certapp.id).then(res=>{
this.$message.success('成功')
this.$router.go(-1)
})
} }
} }
}; };

View File

@ -1,134 +1,336 @@
<template> <template>
<div> <div>
<div class="tableDate">
<div class="button" style="width:6%;float:right;">
<P><el-button class="el-icon-plus" @click.prevent="addRow()"></el-button></P>
<p><el-button class="el-icon-minus" @click.prevent="delData()"></el-button></p>
</div>
<div class="table">
<el-table :data="tableData"
ref="table"
tooltip-effect="dark"
border
stripe
style="width: 93%"
@selection-change='selectRow'>
<el-table-column type="selection" width="45" align="center"></el-table-column>
<el-table-column label="序号" type="index" width="60" align="center"></el-table-column>
<el-table-column label="收费项目" align="center">
<template slot-scope="scope">
<el-input v-model="scope.row.itemkind"></el-input>
</template>
</el-table-column>
<el-table-column label="单元数量">
<template slot-scope="scope">
<el-input v-model="scope.row.unitcount"></el-input>
</template>
</el-table-column>
<el-table-column label="单价">
<template slot-scope="scope">
<el-input v-model="scope.row.perfee"></el-input>
</template>
</el-table-column>
<el-table-column label="小计">
<template slot-scope="scope">
<el-input v-model="scope.row.pertotal"></el-input>
</template>
</el-table-column>
</el-table>
</div>
</div>
<div style="padding-top:20px">
<el-form ref="elForm" :model="formData" size="medium" label-width="100px"> <el-form ref="elForm" :model="formData" size="medium" label-width="100px">
<el-row :gutter="12"> <el-row :gutter="24">
<el-col :span="8">
<el-card shadow="always">
<el-row> <el-row>
<el-col font="left"> <el-col :xs="24" :md="11" font="left">
<el-form-item label="收费单号" prop="feecode"> <el-form-item label="收费单号" prop="feecode">
<el-input placeholder="请输入收费单号" <el-input placeholder="请输入收费单号" v-model="formData.feecode"
clearable clearable
:style="{width: '100%'}"></el-input> :style="{width: '100%'}"></el-input>
</el-form-item> </el-form-item>
</el-col> </el-col>
</el-row>
<el-row> <el-col :xs="24" :md="11" font="left">
<el-col font="left">
<el-form-item label="费用性质" prop="feecharacter"> <el-form-item label="费用性质" prop="feecharacter">
<el-input placeholder="请输入费用性质" <el-select filterable v-model="formData.feecharacter"
placeholder="请输入费用性质"
clearable clearable
:style="{width: '100%'}"></el-input> :style="{width: '100%'}">
<el-option v-for="(item, index) in feeOptions"
:key="index"
:label="item.name"
:value="item.value"
:disabled="item.disabled">
</el-option>
</el-select>
</el-form-item> </el-form-item>
</el-col> </el-col>
</el-row> </el-row>
<el-row> <el-row>
<el-col font="left"> <el-col :xs="24" :md="11" font="left">
<el-form-item label="申请放名称" prop="query_code"> <el-form-item label="总计" prop="totalfee">
<el-input placeholder="请输入申请方名称"
clearable
:style="{width: '100%'}"></el-input>
</el-form-item>
</el-col>
</el-row>
<el-row>
<el-col font="left">
<el-form-item label="工厂名称" prop="query_code">
<el-input placeholder="请输入工厂名称"
clearable
:style="{width: '100%'}"></el-input>
</el-form-item>
</el-col>
</el-row>
<el-row>
<el-col font="left">
<el-form-item label="工厂编号" prop="query_code">
<el-input placeholder="请输入工厂编号"
clearable
:style="{width: '100%'}"></el-input>
</el-form-item>
</el-col>
</el-row>
<el-row>
<el-col font="left">
<el-form-item label="总计" prop="query_code">
<el-input placeholder="请输入总计" <el-input placeholder="请输入总计"
v-model="formData.totalfee"
clearable clearable
:style="{width: '100%'}"></el-input> :style="{width: '100%'}"></el-input>
</el-form-item> </el-form-item>
</el-col> </el-col>
</el-row>
<el-row> <el-col :xs="24" :md="11" font="left">
<el-col font="left"> <el-form-item label="扣减额" prop="deductions">
<el-form-item label="扣减额" prop="query_code">
<el-input placeholder="请输入扣减额" <el-input placeholder="请输入扣减额"
v-model="formData.deductions"
clearable clearable
:style="{width: '100%'}"></el-input> :style="{width: '100%'}"></el-input>
</el-form-item> </el-form-item>
</el-col> </el-col>
</el-row> </el-row>
<el-row> <el-row>
<el-col font="left"> <el-col :xs="24" :md="11" font="left">
<el-form-item label="外汇类型" prop="query_code"> <el-form-item label="外汇类型" prop="exchangetype">
<el-input placeholder="请输入外汇类型" <el-select v-model="formData.exchangetype"
clearable placeholder="请选择外汇类型"
:style="{width: '100%'}"></el-input> filterable
allow-create
:style="{width: '100%'}">
<el-option v-for="(item, index) in exchangetypeOptions"
:key="index"
:label="item.label"
:value="item.value"
:disabled="item.disabled"></el-option>
</el-select>
</el-form-item> </el-form-item>
</el-col> </el-col>
</el-row>
<el-row> <el-col :xs="24" :md="11" font="left">
<el-col font="left">
<el-form-item label="外币汇率" prop="query_code"> <el-form-item label="外币汇率" prop="exchangerate">
<el-input placeholder="请输入外币汇率" <el-input placeholder="请输入外币汇率"
v-model="formData.exchangerate"
clearable clearable
:style="{width: '100%'}"></el-input> :style="{width: '100%'}"></el-input>
</el-form-item> </el-form-item>
</el-col> </el-col>
</el-row> </el-row>
<el-row> <el-row>
<el-col font="left"> <el-col :xs="24" :md="11" font="left">
<el-form-item label="实收人名币" prop="query_code"> <el-form-item label="实收人名币" prop="paidrmb">
<el-input placeholder="请输入金额" <el-input placeholder="请输入金额"
v-model="formData.paidrmb"
clearable clearable
:style="{width: '100%'}"></el-input> :style="{width: '100%'}"></el-input>
</el-form-item> </el-form-item>
</el-col> </el-col>
</el-row>
<el-row> <el-col :xs="24" :md="11" font="left">
<el-col font="left"> <el-form-item label="实收外币" prop="paidwb">
<el-form-item label="实收外币" prop="query_code">
<el-input placeholder="请输入金额" <el-input placeholder="请输入金额"
v-model="formData.paidwb"
clearable clearable
:style="{width: '100%'}"></el-input> :style="{width: '100%'}"></el-input>
</el-form-item> </el-form-item>
</el-col> </el-col>
</el-row> </el-row>
<el-row> <el-row>
<el-col font="left"> <el-col :xs="24" :md="22" font="left">
<el-form-item label="备注" prop="query_code"> <el-form-item label="备注" prop="remark">
<el-input placeholder="请输入备注"
<el-input type="textarea" :rows="2" v-model="formData.remarks"
clearable clearable
:style="{width: '100%'}"></el-input> :style="{width: '100%'}"></el-input>
</el-form-item> </el-form-item>
</el-col> </el-col>
</el-row> </el-row>
</el-card> <el-row>
<el-col font="right">
<el-button style="float: right;" type="primary" @click="submitForm">保存</el-button>
</el-col> </el-col>
<el-col :span="16"> </el-row>
<el-card shadow="always">
历次合同内容
</el-card>
</el-col>
</el-row> </el-row>
</el-form> </el-form>
</div>
</div> </div>
</template> </template>
<script> <script>
import { getChargeitemList,getBillList,getBill,createChargeitem,createBill,updateChargeitem} from "@/api/finanacial";
import { getDictList } from "@/api/dict";
import { genTree } from "@/utils";
import checkPermission from '@/utils/permission'
import Treeselect from "@riophae/vue-treeselect";
import "@riophae/vue-treeselect/dist/vue-treeselect.css";
export default {
inheritAttrs: false,
components: { Treeselect },
props: ["action", "certapp"],
data() {
return {
tableData: [],
selectlistRow: [],
rowNum:1,
formData: {
number:this.certapp.id,
totalfee: null,
deductions:null,
exchangerate: null,
paidrmb: null,
paidwb: null,
remark: null,
feecode:null
},
feeOptions:[],
listLoading: true,
dialogVisible:false,
dialogType: 'create',
exchangetypeOptions: [
{
label: "人民币-RMB-¥",
value: "人民币-RMB-¥",
},
{
label: "欧元-EURO-€",
value: "欧元-EURO-€",
},
{
label: "美元-USD—$",
value: "美元-USD—$",
},
],
dgVisiable: false,
};
},
computed: {},
watch: {
},
created() {
this.getDiclist();
this.getChareList();
},
mounted() {},
methods: {
checkPermission,
// 获取表格选中时的数据
selectRow (val) {
this.selectlistRow = val
console.log(this.selectlistRow)
},
// 增加行
addRow () {
var list = {
rowNum:this.rowNum,
itemkind:'',
unitcount: '',
perfee: '',
pertotal:''
};
this.tableData.unshift(list)
this.rowNum += 1;
},
// 删除方法
// 删除选中行
delData () {
for (let i = 0; i < this.selectlistRow.length; i++) {
let val = this.selectlistRow
val.forEach((val, index) => {
this.tableData.forEach((v, i) => {
if (val.rowNum === v.rowNum) {
// i 为选中的索引
this.tableData.splice(i, 1)
}
})
})
}
// 删除完数据之后清除勾选框
this.$refs.table.clearSelection()
}
,
getChareList() {
getBillList({ number:this.certapp.id }).then((response) => {
console.log(response.data[0])
if (response.data[0] != 'undefined') {
this.formData = response.data[0];
getChargeitemList({ bills:response.data[0].bills }).then((response) => {
if (response.data) {
this.tableData = response.data.results;
}
});
}
});
},
//费用性质
getDiclist() {
getDictList({ type__code: "cost_nature" }).then(response => {
this.feeOptions = genTree(response.data);
});
}
,
submitForm() {
let val = this.selectlistRow
this.$refs["elForm"].validate(valid => {
if (!valid) return;
// TODO 提交表单
createBill(this.formData).then(response => {
this.$message({
type: 'success',
message: '成功!'
})
var billid = response.data.feecode;
for (var i=0; i < val.length; i++) {
this.chargeIetm = val[i]
this.chargeIetm.bills = billid;
createChargeitem(this.chargeIetm).then(response => {
})
}
});
});
},
}
};
</script> </script>

View File

@ -0,0 +1,317 @@
<template>
<div>
<el-table
v-loading="listLoading"
:data="tableData.results"
style="width: 100%;margin-top:10px;"
border
fit
stripe
highlight-current-row
height="380"
@row-click="rowClick"
>
<el-table-column type="index" width="50" />
<el-table-column label="单元名称">
<template slot-scope="scope" >{{ scope.row.name }}</template>
</el-table-column>
<el-table-column label="单元描述">
<template slot-scope="scope" >{{ scope.row.description }}</template>
</el-table-column>
<el-table-column label="采用标准">
<template slot-scope="scope" >{{ scope.row.standard_.fullname }}</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="操作">
<template slot-scope="scope">
<el-button
type="danger"
size="small"
:disabled="!checkPermission(['certapps_update'])"
@click="handleDelete(scope)"
>删除</el-button>
</template>
</el-table-column>
</el-table>
<pagination
v-show="tableData.count>0"
:total="tableData.count"
:page.sync="listQuery.page"
:limit.sync="listQuery.page_size"
@pagination="getList"
/>
<el-form ref="elForm" :model="formData" :rules="rules" size="medium" label-width="80px" style="margin-top:10px">
<el-col :xs="24" :md="12">
<el-form-item label="实施规则" prop="implementrule">
<el-select
v-model="formData.implementrule"
placeholder="请选择实施规则"
clearable
:style="{width: '100%'}"
@change="changeTypeOptions"
>
<el-option
v-for="(item, index) in implementruleOptions"
:key="index"
:label="item.fullname"
:value="item.id"
:disabled="item.disabled"
></el-option>
</el-select>
</el-form-item>
</el-col>
<el-col :xs="24" :md="12">
<el-form-item label="单元类型" prop="unittype">
<el-select
v-model="formData.unittype"
placeholder="请选择单元类型"
clearable
:style="{width: '100%'}"
@change="changeUnit"
>
<el-option
v-for="(item, index) in unittypeOptions"
:key="index"
:label="item.label"
:value="item.value"
:disabled="item.disabled"
></el-option>
</el-select>
</el-form-item>
</el-col>
<el-col :xs="24" :md="12">
<el-form-item label="采用标准" prop="standard">
<el-input
v-model="formData.standard_.fullname"
placeholder="请输入采用标准"
readonly
clearable
:style="{width: '100%'}"
></el-input>
</el-form-item>
</el-col>
<el-col :xs="24" :md="12">
<el-form-item label="检测机构" prop="testorg">
<el-select v-model="formData.testorg" placeholder="请选择检测机构" clearable :style="{width: '100%'}">
<el-option
v-for="(item, index) in testorgOptions"
:key="index"
:label="item.label"
:value="item.value"
:disabled="item.disabled"
></el-option>
</el-select>
</el-form-item>
</el-col>
<el-col :xs="24" :md="8">
<el-form-item label="单元名称" prop="name">
<el-input
v-model="formData.name"
placeholder="请输入单元名称"
clearable
:style="{width: '100%'}"
></el-input>
</el-form-item>
</el-col>
<el-col :xs="24" :md="16">
<el-form-item label="单元描述" prop="description">
<el-input
v-model="formData.description"
placeholder="请输入单元描述"
clearable
:style="{width: '100%'}"
></el-input>
</el-form-item>
</el-col>
<el-col :span="24">
<el-form-item size="large">
<el-button type="primary" @click="createNew">创建新记录</el-button>
<el-button type="primary" @click="updateNow">保存</el-button>
<el-button @click="resetForm">重置</el-button>
</el-form-item>
</el-col>
</el-form>
</div>
</template>
<script>
import { getImplementRuleList, getUnitTypeList } from "@/api/implementrule"
import { getUnitList, deleteUnit, createUnit, updateUnit } from "@/api/unit";
import { getDictList } from "@/api/dict";
import Pagination from "@/components/Pagination";
import checkPermission from "@/utils/permission";
import Treeselect from "@riophae/vue-treeselect";
import "@riophae/vue-treeselect/dist/vue-treeselect.css";
import { genTree } from "../../utils";
export default {
name: "Productunit",
components: { Pagination, Treeselect },
props:['certapp'],
data() {
return {
tableData: { count: 0 },
listLoading: true,
listQuery: {
page: 1,
page_size: 20,
certapp:this.certapp.id
},
formData: {
certapp:this.certapp.id,
implementrule: undefined,
unittype: undefined,
standard: undefined,
standard_:{},
testorg: undefined,
name: undefined,
description: undefined,
},
rules: {
implementrule: [
{
required: true,
message: "请选择实施规则",
trigger: "change",
},
],
unittype: [
{
required: true,
message: "请选择单元类型",
trigger: "change",
},
],
standard: [],
testorg: [],
name: [
{
required: true,
message: "请输入单元名称",
trigger: "blur",
},
],
description: [
{
required: true,
message: "请输入单元描述",
trigger: "blur",
},
],
},
implementruleOptions: [
],
unittypeOptions: [
],
testorgOptions: [
],
};
},
watch:{
'formData.implementrule': function(val){
this.changeTypeOptions()
},
},
created() {
this.getList();
this.getImplementRuleOptions()
},
methods: {
checkPermission,
getList() {
this.listLoading = true;
getUnitList(this.listQuery).then((response) => {
if (response.data) {
this.tableData = response.data;
}
this.listLoading = false;
});
},
resetFilter() {
this.listQuery = {
page: 1,
page_size: 20,
};
this.getList();
},
handleFilter() {
this.listQuery.page = 1;
this.getList();
},
handleCreate(item, index) {
this.$router.push({
name: "CertappForm",
params: { kind: item.code, action: "create" },
});
},
handleUpdate(scope) {
this.$router.push({
name: "CertappForm",
params: { action: "update", kind: scope.row.cert_field_.code },
query: { id: scope.row.id },
});
},
handleDelete(scope) {
this.$confirm("确定删除?", "警告", {
// confirmButtonText: '确定',
// cancelButtonText: '取消',
type: "warning",
}).then(() => {
deleteUnit(scope.row.id).then((res) => {
this.$message.success("成功");
this.getList();
});
}).catch(()=>{});
},
createNew() {
this.$refs['elForm'].validate(valid => {
if (!valid) return
// TODO 提交表单
createUnit(this.formData).then(res=>{
this.getList()
this.$message.success('成功')
})
})
},
updateNow(){
this.$refs['elForm'].validate(valid => {
if (!valid) return
// TODO 提交表单
updateUnit(this.formData.id, this.formData).then(res=>{
this.getList()
this.$message.success('成功')
})
})
},
resetForm() {
this.$refs['elForm'].resetFields()
},
getImplementRuleOptions(){
var query = {ccc_list:this.certapp.cccpv_class}
getImplementRuleList(query).then(res=>{
this.implementruleOptions = res.data.results
})
},
changeTypeOptions(){
getUnitTypeList({implementrule:this.formData.implementrule}).then(res=>{
this.unittypeOptions = genTree(res.data)
})
},
changeUnit(val){
let obj = {};
obj = this.unittypeOptions.find((item)=>{//这里的userList就是上面遍历的数据源
return item.id === val;//筛选出匹配数据
});
this.formData.name = obj.name
this.formData.standard = obj.standard
this.formData.standard_ = obj.standard_
},
rowClick(row, column, event){
this.formData = Object.assign({}, row);
}
},
};
</script>

View File

@ -328,12 +328,12 @@ export default {
}, },
created() { created() {
console.log(this.certapp)
if(this.action!='create'){ if(this.action!='create'){
this.formData.id = this.certapp this.formData = this.certapp
this.getCertapp_()
} }
this.getTypeOptions(); this.getTypeOptions();
this.getProfOptions() this.getProfOptions();
}, },
mounted() {}, mounted() {},
methods: { methods: {
@ -352,11 +352,7 @@ export default {
}); });
}, },
getCertapp_(){
getCertapp(this.formData.id).then(res=>{
this.formData = res.data
})
},
handelConfirm() { handelConfirm() {
this.$refs["elForm"].validate((valid) => { this.$refs["elForm"].validate((valid) => {
if (!valid) return; if (!valid) return;

View File

@ -6,14 +6,16 @@
<el-col> <el-col>
<el-card shadow="always"> <el-card shadow="always">
<el-table id="evl" <el-table id="evl"
ref="multipleTable"
:data="eltList" :data="eltList"
style="width: 100%;margin-top:10px;" style="width: 100%;margin-top:10px;"
border border
fit fit
highlight-current-row highlight-current-row
max-height="600">
<el-table-column type="index" width="50" />
@selection-change='selectRow'
max-height="600">
<el-table-column type="selection" label="选择" align="center" width="55"></el-table-column>
<el-table-column align="center" label="项目内容" width="750"> <el-table-column align="center" label="项目内容" width="750">
<template slot-scope="scope"> <template slot-scope="scope">
@ -23,11 +25,8 @@
<el-table-column label="符合"> <el-table-column label="符合">
<template slot-scope="scope"> <template slot-scope="scope">
<el-radio-group v-model="radio"> <el-radio-group v-model="radio[scope.$index]" @change="changeHandler">
<el-radio :label="1">符合</el-radio> <el-radio :label="item.id" :key="item.id" v-for="item in scope.row.options ">{{item.name}}</el-radio>
<el-radio :label="2">不符合</el-radio>
<el-radio :label="3">不适用</el-radio>
<el-radio :label="4">需说明</el-radio>
</el-radio-group> </el-radio-group>
</template> </template>
@ -41,7 +40,7 @@
</el-form> </el-form>
<div slot="footer" align="center"> <div slot="footer" align="center">
<el-button @click="close(false)">取消</el-button> <el-button @click="close(false)">取消</el-button>
<el-button type="primary" @click="handelConfirm">保存</el-button> <el-button type="primary" @click="dialogFormAdd">保存</el-button>
</div> </div>
</div> </div>
@ -51,6 +50,7 @@
import { getEvaluationsList } from "@/api/evaluationitem"; import { getEvaluationsList } from "@/api/evaluationitem";
import Treeselect from "@riophae/vue-treeselect"; import Treeselect from "@riophae/vue-treeselect";
import "@riophae/vue-treeselect/dist/vue-treeselect.css"; import "@riophae/vue-treeselect/dist/vue-treeselect.css";
import { options } from "runjs";
export default { export default {
inheritAttrs: false, inheritAttrs: false,
@ -68,7 +68,27 @@ export default {
}, },
radio: 3, radio: [],
review_options:[
{
id : "1",
name : "符合"
},
{
id : "2",
name : "不符合"
}
,
{
id : "3",
name : "不适用"
}
,
{
id : "4",
name : "需说明"
}
],
eltList: [], eltList: [],
@ -92,29 +112,35 @@ export default {
getEvaluationsList().then(response => { getEvaluationsList().then(response => {
this.eltList = response.data.results this.eltList = response.data.results
for (var i = 0; i < this.eltList.length; i++) {
this.eltList[i].options = this.review_options;
}
}); });
}, },
// 获取表格选中时的数据
selectRow (val) {
this.selectlistRow = val
},
changeHandler(value) {
this.radioresult = value;
}
,
handleSelectionChange(val) {
this.multipleTable = val; // this.multipleTable 选中的值
console.log(val);
},
dialogFormAdd() {
//for (var i = 0; i < this.multipleTable.length; i++) {
// var halo = this.multipleTable[i];
// console.log(halo);
//}
console.log(this.selectlistRow);
},
handelConfirm() { handelConfirm() {
this.$refs["elForm"].validate((valid) => { let val = this.selectlistRow
if (!valid) return; console.log(this.selectlistRow);
if(this.formData.id){
updateEvaluationDetail(this.formData.id, this.formData).then((res) => {
this.$message.success('成功')
this.$emit("handleCommit", res.data);
});
}else{
for (var i = 0; i < this.evl.length; i++) {
var halo = this.evl[i];
console.log(halo);
}
}
});
}, },

View File

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

View File

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

View File

@ -21,7 +21,7 @@
<template slot-scope="scope">{{ scope.row.description }}</template> <template slot-scope="scope">{{ scope.row.description }}</template>
</el-table-column> </el-table-column>
<el-table-column align="header-center" label="采用标准"> <el-table-column align="header-center" label="采用标准">
<template slot-scope="scope">{{ scope.row.standard_.code }} {{ scope.row.standard_.name }}</template> <template slot-scope="scope" v-if="scope.row.standard_">{{ scope.row.standard_.code }} {{ scope.row.standard_.name }}</template>
</el-table-column> </el-table-column>
<el-table-column align="center" label="操作" width="260px"> <el-table-column align="center" label="操作" width="260px">
<template slot-scope="scope"> <template slot-scope="scope">

View File

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

View File

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

View File

@ -0,0 +1,413 @@
<template>
<div class="app-container">
<el-row :gutter="6">
<el-col :xs="24" :md="8">
<el-card class="box-card">
<div slot="header" class="clearfix">
<span>月计划</span>
(当前选择:
<span style="color:darkblue;font-weight:bold">
{{nowPlan.name}}</span>
)
</div>
<div>
<div>
<el-button type="primary" @click="handleCreatePlan" size="mini">新建计划</el-button>
</div>
<el-table
v-loading="listLoadingplan"
:data="planData.results"
style="width: 100%;margin-top:2px;"
border
fit
stripe
highlight-current-row
height="300"
@row-click="planClick"
>
<el-table-column label="计划名称">
<template slot-scope="scope" v-if="scope.row.name">{{ scope.row.name }}</template>
</el-table-column>
<el-table-column label="操作" width="120">
<template slot-scope="scope">
<el-button-group>
<el-button
type="primary"
size="small"
:disabled="!checkPermission(['plan_update'])"
@click="handleUpdatePlan(scope)"
icon="el-icon-edit"
></el-button>
<el-button
type="danger"
size="small"
:disabled="!checkPermission(['plan_delete'])"
@click="handleDeletePlan(scope)"
icon="el-icon-delete"
></el-button>
</el-button-group>
</template>
</el-table-column>
</el-table>
<pagination
v-show="planData.count>0"
:total="planData.count"
:page.sync="listQuery_plan.page"
:limit.sync="listQuery_plan.page_size"
@pagination="getPlanList_"
/>
</div>
</el-card>
</el-col>
<el-col :xs="24" :md="16">
<el-card class="box-card" style="margin-top:2px">
<div slot="header" class="clearfix">
<span>待处理项目</span>
</div>
<div>
<div style="margin-bottom:2px">
<el-button type="primary" @click="handleAppend" size="mini">添加到计划</el-button>
</div>
<el-table
v-loading="listLoading"
:data="projectData.results"
style="width: 100%;"
border
fit
stripe
highlight-current-row
height="300"
@selection-change="handleSelectionChange"
>
<el-table-column type="selection" width="55"></el-table-column>
<el-table-column label="项目号">
<template slot-scope="scope" v-if="scope.row.number">{{ scope.row.number }}</template>
</el-table-column>
<el-table-column label="受审核方" width="300px">
<template slot-scope="scope">{{ scope.row.auditee_v.name }}</template>
</el-table-column>
<el-table-column label="项目信息" width="300px" :show-overflow-tooltip="true">
<template slot-scope="scope" v-if="scope.row.certapps">
<el-tag
v-for="(item, index) in scope.row.certapps"
:key="index"
style="margin:2px"
>{{item}}</el-tag>
</template>
</el-table-column>
<el-table-column label="当前状态">
<template slot-scope="scope">{{ scope.row.status}}</template>
</el-table-column>
<el-table-column label="是否可派差">
<template slot-scope="scope">
<el-switch v-model="scope.row.can_paichai" disabled></el-switch>
</template>
</el-table-column>
<el-table-column label="下达人">
<template slot-scope="scope">{{ scope.row.assign_by_.name}}</template>
</el-table-column>
<el-table-column label="创建日期" width="190">
<template slot-scope="scope">
<span>{{ scope.row.create_time }}</span>
</template>
</el-table-column>
<el-table-column label="操作" width="200" fixed="right">
<template slot-scope="scope">
<el-button-group>
<el-button
type="primary"
size="small"
:disabled="!checkPermission(['project_update'])"
@click="contactCompany(scope)"
>联系企业</el-button>
<el-button
type="danger"
size="small"
:disabled="!checkPermission(['project_delete'])"
@click="handleDetailProject(scope)"
>详情</el-button>
</el-button-group>
</template>
</el-table-column>
</el-table>
<pagination
v-show="projectData.count>0"
:total="projectData.count"
:page.sync="listQuery_project.page"
:limit.sync="listQuery_project.page_size"
@pagination="getProjectList_"
/>
</div>
</el-card>
</el-col>
</el-row>
<el-row>
<el-card class="box-card" style="margin-top:2px">
<div slot="header" class="clearfix">
<span>月计划项目</span>
</div>
<div>
<el-table
v-loading="listLoadingplan2"
:data="projectData2.results"
style="width: 100%;"
border
fit
stripe
highlight-current-row
height="300"
>
<el-table-column label="项目号">
<template slot-scope="scope" v-if="scope.row.number">{{ scope.row.number }}</template>
</el-table-column>
<el-table-column label="受审核方" width="300px">
<template slot-scope="scope">{{ scope.row.auditee_v.name }}</template>
</el-table-column>
<el-table-column label="项目信息" width="300px" :show-overflow-tooltip="true">
<template slot-scope="scope" v-if="scope.row.certapps">
<el-tag
v-for="(item, index) in scope.row.certapps"
:key="index"
style="margin:2px"
>{{item}}</el-tag>
</template>
</el-table-column>
<el-table-column label="当前状态">
<template slot-scope="scope">{{ scope.row.status}}</template>
</el-table-column>
<el-table-column label="是否可派差">
<template slot-scope="scope">
<el-switch v-model="scope.row.can_paichai" disabled></el-switch>
</template>
</el-table-column>
<el-table-column label="下达人">
<template slot-scope="scope">{{ scope.row.assign_by_.name}}</template>
</el-table-column>
<el-table-column label="创建日期" width="190">
<template slot-scope="scope">
<span>{{ scope.row.create_time }}</span>
</template>
</el-table-column>
<el-table-column label="操作" width="200" fixed="right">
<template slot-scope="scope">
<el-button-group>
<el-button
type="primary"
size="small"
:disabled="!checkPermission(['project_update'])"
@click="contactCompany(scope)"
>计划</el-button>
<el-button
type="danger"
size="small"
:disabled="!checkPermission(['project_delete'])"
@click="handleDetailProject(scope)"
>详情</el-button>
</el-button-group>
</template>
</el-table-column>
</el-table>
<pagination
v-show="projectData2.count>0"
:total="projectData2.count"
:page.sync="listQuery2.page"
:limit.sync="listQuery2.page_size"
@pagination="getProjectList_2"
/>
</div>
</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-form-item label="计划名称" prop="name">
<el-input v-model="formData.name" placeholder="名称" />
</el-form-item>
</el-form>
<div style="text-align:right;">
<el-button type="danger" @click="dialogVisible=false">取消</el-button>
<el-button type="primary" @click="confirmPlan('Form')">确认</el-button>
</div>
</el-dialog>
</div>
</template>
<script>
import { getCertappList } from "@/api/certapp";
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";
import "@riophae/vue-treeselect/dist/vue-treeselect.css";
import { genTree } from "../../utils";
import router from "@/router";
export default {
components: { Pagination, Treeselect },
data() {
return {
listLoading: false,
listLoadingplan:false,
listLoadingplan2:false,
listQuery_plan: {
page: 1,
page_size: 20,
},
listQuery_project: {
page: 1,
page_size: 20,
status: "待派差",
planoff:true
},
listQuery2:{
page: 1,
page_size: 20,
plan:''
},
planData: { count: 0, results: [] },
projectData: { count: 0, results: [] },
projectData2: { count: 0, results: [] },
dialogVisible:false,
dialogType:'create',
formData:{
},
nowPlan:{id:0},
rules: {
name: [{ required: true, message: '请输入名称', trigger: 'blur' }],
},
multipleSelection:[],
multiprojects:[]
};
},
watch: {},
created() {
this.getProjectList_();
this.getPlanList_()
},
methods: {
checkPermission,
getProjectList_() {
this.listLoading = true;
getProjectList(this.listQuery_project).then((response) => {
if (response.data) {
this.projectData = response.data;
}
this.listLoading = false;
});
},
getPlanList_() {
this.listLoadingplan = true
getPlanList(this.listQuery_plan).then(res=>{
this.planData = res.data
this.listLoadingplan = false
}).catch(e=>{this.listLoadingplan = false})
},
resetFilter() {
this.listQuery = {
status: "已受理",
};
this.getCertappList_();
},
handleFilter() {
this.getCertappList_();
},
contactCompany(scope) {
this.$router.push({
name: "HandleProject",
query: { project: scope.row.id },
});
},
handleCreatePlan() {
this.dialogVisible=true
this.dialogType = 'create'
},
handleUpdatePlan(scope) {
this.formData = Object.assign({}, scope.row)
this.dialogType = 'update'
this.dialogVisible=true
this.$nextTick(() => {
this.$refs['elForm'].clearValidate()
})
},
handleDeletePlan(scope) {
this.$confirm('确定删除该计划?','警告',{type:'warning'}).then(()=>{
deletePlan(scope.row.id).then(res=>{
this.$message.success('成功')
})
}).catch(res=>{
})
},
handleDetailProject() {},
confirmPlan(){
this.$refs['elForm'].validate(valid => {
if (valid) {
const isEdit = this.dialogType === 'update'
if (isEdit) {
updatePlan(this.formData.id, this.formData).then(() => {
this.getPlanList_()
this.dialogVisible = false
this.$message.success('成功')
})
} else {
createPlan(this.formData).then(res => {
// this.org = res.data
// this.tableData.unshift(this.org)
this.getPlanList_()
this.dialogVisible = false
this.$message.success('成功')
})
}
} else {
return false
}
})
},
handleSelectionChange(val) {
var ddd = []
for(var i=0;i<val.length;i++){
ddd.push(val[i].id)
}
this.multiprojects = ddd
},
handleAppend(){
if(this.multiprojects.length>0){
if(this.nowPlan.id!=0){
this.$confirm('是否将该项目添加至('+this.nowPlan.name+')中','提示',{}).then(()=>{
planProject({'plan':this.nowPlan.id, 'projects':this.multiprojects}).then(res=>{
this.$message.success('成功')
this.getProjectList_()
})
}).catch(res=>{
})
}else{
this.$message.warning('请先选择一个计划')
}
}else{
this.$message.warning('请先选择待处理项目')
}
},
planClick(row, column, event){
if(this.nowPlan.id != row.id){
this.nowPlan = row
this.listQuery2.plan = row.id
this.listQuery2.page = 1
this.getProjectList_2()
}else{
this.getProjectList_2()
}
},
getProjectList_2(){
this.listLoadingplan2 = true
getProjectList(this.listQuery2).then(res=>{
this.listLoadingplan2 = false
this.projectData2 = res.data
}).catch(e=>{
this.listLoadingplan2 = false
})
}
},
};
</script>

View File

@ -0,0 +1,178 @@
<template>
<div class="app-container">
<el-card class="box-card">
<div slot="header" class="clearfix">
<span>项目</span>
</div>
<el-table
v-loading="listLoading"
:data="tableData"
style="width: 100%;margin-top:10px;"
border
fit
stripe
highlight-current-row
height="300"
>
<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">
<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">{{ 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>
</el-card>
<el-card class="box-card" style="margin-top:10px">
<div slot="header" class="clearfix">
<span>待处理申请</span>
</div>
<div>
<el-button type="primary">生成项目</el-button>
</div>
<el-table
v-loading="listLoading"
:data="tableData"
style="width: 100%;margin-top:10px;"
border
fit
stripe
highlight-current-row
height="300"
>
<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">
<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">{{ 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>
</el-card>
</div>
</template>
<script>
import { getCertappList } from "@/api/certapp";
import Pagination from "@/components/Pagination";
import checkPermission from "@/utils/permission";
import Treeselect from "@riophae/vue-treeselect";
import "@riophae/vue-treeselect/dist/vue-treeselect.css";
import { genTree } from "../../utils";
export default {
components: { Pagination, Treeselect },
data() {
return {
tableData: [],
listLoading: true,
listQuery: {
status: "已受理",
},
deptOptions: [],
field_list: [],
};
},
created() {
this.getList();
},
methods: {
checkPermission,
getList() {
this.listLoading = true;
getCertappList(this.listQuery).then((response) => {
if (response.data) {
this.tableData = response.data;
}
this.listLoading = false;
});
},
getdeptOptions() {
getOrgList().then((res) => {
this.deptOptions = genTree(res.data);
});
},
resetFilter() {
this.listQuery = {
status: "已受理",
};
this.getList();
},
handleFilter() {
this.getList();
},
},
};
</script>

View File

@ -0,0 +1,316 @@
<template>
<div class="app-container">
<el-tabs>
<el-tab-pane label="认证项目">
<div>
<el-button type="primary" @click="genProject0" 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
max-height="600"
>
<el-table-column type="selection" width="55"></el-table-column>
<el-table-column label="项目号">
<template slot-scope="scope" v-if="scope.row.number">{{ scope.row.number }}</template>
</el-table-column>
<el-table-column label="受审核方" width="300px">
<template slot-scope="scope">
{{ scope.row.auditee_v.name }}
</template>
</el-table-column>
<el-table-column label="项目信息" width="300px" :show-overflow-tooltip="true" >
<template slot-scope="scope" v-if="scope.row.certapps">
<el-tag v-for="(item, index) in scope.row.certapps" :key="index" style="margin:2px" >{{item}}</el-tag>
</template>
</el-table-column>
<el-table-column label="当前状态" >
<template slot-scope="scope">{{ scope.row.status}}</template>
</el-table-column>
<el-table-column label="创建人">
<template slot-scope="scope">{{ scope.row.create_by_.name}}</template>
</el-table-column>
<el-table-column label="创建日期">
<template slot-scope="scope">
<span>{{ scope.row.create_time }}</span>
</template>
</el-table-column>
<el-table-column label="操作">
<template slot-scope="scope">
<el-button-group>
<el-button
v-if="scope.row.status == '待下达'"
type="warning"
size="small"
:disabled="!checkPermission(['project_assign'])"
@click="handleAssign(scope)"
>下达</el-button>
<el-button
type="primary"
size="small"
:disabled="!checkPermission(['project_update'])"
@click="handleUpdate(scope)"
>编辑</el-button>
<el-button
type="danger"
size="small"
:disabled="!checkPermission(['project_delete'])"
@click="handleDelete(scope)"
>删除</el-button>
</el-button-group>
</template>
</el-table-column>
</el-table>
<pagination
v-show="projectData.count>0"
:total="projectData.count"
:page.sync="listQuery_project.page"
:limit.sync="listQuery_project.page_size"
@pagination="getProjectList_"
/>
</el-tab-pane>
<el-tab-pane label="待处理业务">
<div>
<el-button type="primary" @click="genProject" size="mini">生成项目</el-button>
</div>
<div style="margin-top:10px">
<template>
已选择<span style="color:red;font-weight:bold">{{certapps_data.length}}</span>条已受理业务
</template>
</div>
<el-table
ref="projectTable"
v-loading="listLoading"
:data="certappData.results"
style="width: 100%;margin-top:10px;"
border
fit
stripe
highlight-current-row
max-height="600"
@selection-change="handleSelectionChange"
>
<el-table-column type="selection" width="55"></el-table-column>
<el-table-column label="单号">
<template slot-scope="scope" v-if="scope.row.number">{{ scope.row.number }}</template>
</el-table-column>
<el-table-column label="认证领域/分类">
<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">{{ 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>
<pagination
v-show="certappData.count>0"
:total="certappData.count"
:page.sync="listQuery.page"
:limit.sync="listQuery.page_size"
@pagination="getCertappList_"
/>
</el-tab-pane>
</el-tabs>
<el-dialog :visible.sync="dialogvisible_project" title="创建项目">
<el-form ref="elForm" :model="formData" label-width="80px" label-position="right" :rules="rules">
<div v-if="certapps_data.length > 0">已选择<span style="color:red;font-weight:bold">{{certapps_data.length}}</span>条已受理业务</div>
<el-form-item label="受审核方" prop="auditee">
<el-input placeholder="请选择受审核方" readonly clearable v-model="formData.auditee_v.name">
<el-button slot="append" icon="el-icon-search" @click="choose(0)" v-if="certapps_data.length == 0"></el-button>
</el-input>
</el-form-item>
<el-form-item label="联系人" prop="auditee_v.linkman_name">
<el-input v-model="formData.auditee_v.linkman_name"></el-input>
</el-form-item>
<el-form-item label="联系方式" prop="auditee_v.linkman_mobile">
<el-input v-model="formData.auditee_v.linkman_mobile"></el-input>
</el-form-item>
<el-form-item label="备注" prop="username">
<el-input v-model="formData.remark" type="textarea"
:autosize="{ minRows: 6, maxRows: 10}"></el-input>
</el-form-item>
</el-form>
<div style="text-align:right;">
<el-button type="danger" @click="dialogvisible_project=false">取消</el-button>
<el-button type="primary" @click="confirm('Form')">确认</el-button>
</div>
</el-dialog>
</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";
export default {
components: { Pagination, Treeselect },
data() {
return {
certapps_data:[],
certappData: [],
listLoading: true,
listQuery: {
page:1,
page_size:20,
status: "已受理",
},
listQuery_project: {
page:1,
page_size:20
},
deptOptions: [],
field_list: [],
projectData:{count:0,results:[]},
formData:{
certapps:[],
auditee_v:{},
auditee:null
},
dialogvisible_project:false,
rules: {
auditee: [
{
required: true,
message: "请选择受审核方",
trigger: "change",
},
],
},
};
},
watch:{
certapps_data:function(val){
let certapps = []
for(let i=0;i<val.length;i++){
certapps.push(val[i].id)
}
this.formData.certapps = certapps
}
},
created() {
this.getCertappList_();
this.getProjectList_()
},
methods: {
checkPermission,
getCertappList_() {
this.listLoading = true;
getCertappList(this.listQuery).then((response) => {
if (response.data) {
this.certappData = response.data;
}
this.listLoading = false;
});
},
getProjectList_() {
this.listLoading = true;
getProjectList(this.listQuery_project).then((response) => {
if (response.data) {
this.projectData = response.data;
}
this.listLoading = false;
});
},
getdeptOptions() {
getOrgList().then((res) => {
this.deptOptions = genTree(res.data);
});
},
resetFilter() {
this.listQuery = {
status: "已受理",
};
this.getCertappList_();
},
handleFilter() {
this.getCertappList_();
},
genProject() {
if(this.certapps_data.length >0){
this.dialogvisible_project = true
this.formData.auditee = this.certapps_data[0].applicant
this.formData.auditee_v = this.certapps_data[0].applicant_v
}else{
this.$message.warning('请先选择已受理业务')
}
},
genProject0() {
this.$refs['projectTable'].clearSelection()
this.dialogvisible_project = true
},
handleSelectionChange(val){
this.certapps_data = val
},
confirm(){
this.$refs['elForm'].validate(valid => {
if (!valid) return
// TODO 提交表单
createProject(this.formData).then(res=>{
this.getCertappList_()
this.getProjectList_()
this.dialogvisible_project = false
this.$message.success('成功')
})
})
},
handleAssign(scope) {
if(scope.row.certapps.length == 0){
this.$message.error('该项目不包含业务,无法下达!')
}else{
this.$confirm("确定下达并转入策划派差吗?", "提示", {
type: "warning",
}).then(() => {
assginProject(scope.row.id, {}).then(res=>{
this.$message.success('下达成功')
this.getProjectList_()
})
}).catch(()=>{
});
}
}
},
};
</script>

View File

@ -253,6 +253,19 @@ export default {
this.$refs['Form'].clearValidate() this.$refs['Form'].clearValidate()
}) })
}, },
handleDelete(scope) {
this.$confirm('确定删除?', '警告', {
// confirmButtonText: '确定',
// cancelButtonText: '取消',
type: 'warning'
}).then(() => {
deleteStandard(scope.row.id).then(res=>{
this.$message.success('成功')
this.getList()
})
})
},
handlePreview(file) { handlePreview(file) {
if ('url' in file){ if ('url' in file){
window.open(file.url) window.open(file.url)

View File

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

View File

@ -0,0 +1,17 @@
# Generated by Django 3.0.5 on 2020-09-03 08:58
from django.db import migrations
class Migration(migrations.Migration):
dependencies = [
('certset', '0020_evaluations_conform'),
]
operations = [
migrations.RemoveField(
model_name='evaluations',
name='conform',
),
]

View File

@ -22,7 +22,7 @@ class Standard(CommonAModel):
verbose_name_plural = verbose_name verbose_name_plural = verbose_name
def __str__(self): def __str__(self):
return self.name return self.code + '-' + self.name
class ImplementRule(CommonAModel): class ImplementRule(CommonAModel):
@ -44,7 +44,7 @@ class ImplementRule(CommonAModel):
verbose_name_plural = verbose_name verbose_name_plural = verbose_name
def __str__(self): def __str__(self):
return self.name return self.code +'-'+ self.name
class UnitType(CommonAModel): class UnitType(CommonAModel):
@ -73,7 +73,6 @@ class EvaluationItem(CommonAModel):
return self.cert_field return self.cert_field
class Evaluations(CommonAModel): class Evaluations(CommonAModel):
content = models.TextField('内容', blank=True) content = models.TextField('内容', blank=True)
conform = models.TextField('是否符合', default='符合')
evItem = models.ForeignKey(EvaluationItem, on_delete=models.SET_NULL, null=True, blank=True, verbose_name='评审标准', related_name='Evaluations_evItem') evItem = models.ForeignKey(EvaluationItem, on_delete=models.SET_NULL, null=True, blank=True, verbose_name='评审标准', related_name='Evaluations_evItem')
class Meta: class Meta:
verbose_name = '评审列' verbose_name = '评审列'

View File

@ -6,31 +6,50 @@ from apps.system.serializers import DictSerializer
class StandardSerializer(serializers.ModelSerializer): class StandardSerializer(serializers.ModelSerializer):
fullname = serializers.SerializerMethodField(read_only=True)
class Meta: class Meta:
model = Standard model = Standard
fields = '__all__' fields = '__all__'
def get_fullname(self, obj):
fullname = obj.code + ' ' + obj.name
if obj.code in obj.name:
fullname = obj.name
return fullname
class ImplementRuleSerializer(serializers.ModelSerializer): class ImplementRuleSerializer(serializers.ModelSerializer):
cert_field_ = DictSerializer(source='cert_field', read_only=True) cert_field_ = DictSerializer(source='cert_field', read_only=True)
fullname = serializers.SerializerMethodField(read_only=True)
class Meta: class Meta:
model = ImplementRule model = ImplementRule
fields = '__all__' fields = '__all__'
def get_fullname(self, obj):
fullname = obj.code + ' ' + obj.name
if obj.code in obj.name:
fullname = obj.name
return fullname
class ImplementRuleListSerializer(serializers.ModelSerializer): class ImplementRuleListSerializer(serializers.ModelSerializer):
pv_scope = DictSerializer() pv_scope = DictSerializer()
pv_class = DictSerializer() pv_class = DictSerializer()
cert_field = DictSerializer() cert_field = DictSerializer()
ccc_list = DictSerializer(many=True) ccc_list = DictSerializer(many=True)
fullname = serializers.SerializerMethodField(read_only=True)
class Meta: class Meta:
model = ImplementRule model = ImplementRule
fields = ['id', 'code', 'name', 'cert_field', 'pv_scope', 'pv_class', 'create_time', 'ccc_list'] fields = ['id', 'code', 'name', 'cert_field', 'pv_scope', 'pv_class', 'create_time', 'ccc_list', 'fullname']
@staticmethod @staticmethod
def setup_eager_loading(queryset): def setup_eager_loading(queryset):
""" Perform necessary eager loading of data. """ """ Perform necessary eager loading of data. """
queryset = queryset.select_related('pv_scope','pv_class', 'cert_field') queryset = queryset.select_related('pv_scope','pv_class', 'cert_field')
queryset = queryset.prefetch_related('ccc_list',) queryset = queryset.prefetch_related('ccc_list',)
return queryset return queryset
def get_fullname(self, obj):
fullname = obj.code + ' ' + obj.name
if obj.code in obj.name:
fullname = obj.name
return fullname
# def get_cert_field(self, obj): # def get_cert_field(self, obj):
# return obj.get_cert_field_display() # return obj.get_cert_field_display()

View File

@ -21,7 +21,7 @@ class ImplementRuleViewSet(CreateUpdateCustomMixin, OptimizationMixin, ModelView
queryset = ImplementRule.objects.all() queryset = ImplementRule.objects.all()
serializer_class = ImplementRuleSerializer serializer_class = ImplementRuleSerializer
search_fields = ['name', 'code', 'cert_field'] search_fields = ['name', 'code', 'cert_field']
filterset_fields = ['pv_scope', 'cert_field', 'cert_field__code'] filterset_fields = ['pv_scope', 'cert_field', 'cert_field__code', 'ccc_list']
ordering = ['-create_time'] ordering = ['-create_time']
def get_serializer_class(self): def get_serializer_class(self):

View File

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

View File

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

View File

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

View File

@ -0,0 +1,49 @@
# Generated by Django 3.0.5 on 2020-09-03 08:58
from django.conf import settings
from django.db import migrations, models
import django.db.models.deletion
import django.utils.timezone
class Migration(migrations.Migration):
dependencies = [
migrations.swappable_dependency(settings.AUTH_USER_MODEL),
('system', '0031_delete_bscodeset'),
('financial', '0001_initial'),
]
operations = [
migrations.AlterModelOptions(
name='bill',
options={'verbose_name': '收费信息', 'verbose_name_plural': '收费信息'},
),
migrations.RemoveField(
model_name='bill',
name='applicant',
),
migrations.CreateModel(
name='Chargeitem',
fields=[
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('create_time', models.DateTimeField(default=django.utils.timezone.now, help_text='创建时间', verbose_name='创建时间')),
('update_time', models.DateTimeField(auto_now=True, help_text='修改时间', verbose_name='修改时间')),
('is_deleted', models.BooleanField(default=False, help_text='删除标记', verbose_name='删除标记')),
('itemkind', models.CharField(max_length=300, verbose_name='收费项目')),
('eitemkind', models.CharField(max_length=300, verbose_name='收费英文项目')),
('unitcount', models.FloatField(blank=True, default=0, null=True, verbose_name='单元数量')),
('perfee', models.FloatField(blank=True, default=0, null=True, verbose_name='单价')),
('pertotal', models.FloatField(blank=True, default=0, null=True, verbose_name='小计')),
('remark', models.CharField(max_length=300, verbose_name='备注')),
('belong_dept', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='chargeitem_belong_dept', to='system.Organization', verbose_name='所属部门')),
('bills', models.ForeignKey(on_delete=django.db.models.deletion.DO_NOTHING, related_name='chargeitem_bill', to='financial.Bill')),
('create_by', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='chargeitem_create_by', to=settings.AUTH_USER_MODEL, verbose_name='创建人')),
('update_by', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='chargeitem_update_by', to=settings.AUTH_USER_MODEL, verbose_name='最后编辑人')),
],
options={
'verbose_name': '收费项目',
'verbose_name_plural': '收费项目',
},
),
]

View File

@ -0,0 +1,24 @@
# Generated by Django 3.0.5 on 2020-09-07 01:56
from django.db import migrations, models
import django.db.models.deletion
class Migration(migrations.Migration):
dependencies = [
('financial', '0002_auto_20200903_1658'),
]
operations = [
migrations.AlterField(
model_name='bill',
name='feecode',
field=models.CharField(max_length=300, unique=True, verbose_name='收费单号'),
),
migrations.AlterField(
model_name='chargeitem',
name='bills',
field=models.ForeignKey(on_delete=django.db.models.deletion.DO_NOTHING, related_name='chargeitem_bill', to='financial.Bill', to_field='feecode'),
),
]

View File

@ -0,0 +1,34 @@
# Generated by Django 3.0.5 on 2020-09-07 07:51
from django.db import migrations, models
import django.db.models.deletion
class Migration(migrations.Migration):
dependencies = [
('financial', '0003_auto_20200907_0956'),
]
operations = [
migrations.AlterField(
model_name='chargeitem',
name='bills',
field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.DO_NOTHING, related_name='chargeitem_bill', to='financial.Bill', to_field='feecode'),
),
migrations.AlterField(
model_name='chargeitem',
name='eitemkind',
field=models.CharField(blank=True, max_length=300, null=True, verbose_name='收费英文项目'),
),
migrations.AlterField(
model_name='chargeitem',
name='itemkind',
field=models.CharField(blank=True, max_length=300, null=True, verbose_name='收费项目'),
),
migrations.AlterField(
model_name='chargeitem',
name='remark',
field=models.CharField(blank=True, max_length=300, null=True, verbose_name='备注'),
),
]

View File

@ -0,0 +1,17 @@
# Generated by Django 3.0.5 on 2020-09-07 07:55
from django.db import migrations
class Migration(migrations.Migration):
dependencies = [
('financial', '0004_auto_20200907_1551'),
]
operations = [
migrations.RemoveField(
model_name='chargeitem',
name='eitemkind',
),
]

View File

@ -0,0 +1,19 @@
# Generated by Django 3.0.5 on 2020-09-08 03:43
from django.db import migrations, models
import django.db.models.deletion
class Migration(migrations.Migration):
dependencies = [
('financial', '0005_remove_chargeitem_eitemkind'),
]
operations = [
migrations.AlterField(
model_name='chargeitem',
name='bills',
field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.DO_NOTHING, related_name='chargeitem_bill', to='financial.Bill'),
),
]

View File

@ -0,0 +1,19 @@
# Generated by Django 3.0.5 on 2020-09-08 03:46
from django.db import migrations, models
import django.db.models.deletion
class Migration(migrations.Migration):
dependencies = [
('financial', '0006_auto_20200908_1143'),
]
operations = [
migrations.AlterField(
model_name='chargeitem',
name='bills',
field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.DO_NOTHING, related_name='chargeitem_bill', to='financial.Bill', to_field='feecode'),
),
]

View File

@ -10,10 +10,9 @@ class Bill(CommonBModel):
""" """
收费单表 收费单表
""" """
feecode = models.CharField('收费单号', max_length=300) feecode = models.CharField('收费单号',unique=True, max_length=300)
number = models.ForeignKey(CertApp, related_name='bill_number', on_delete=models.DO_NOTHING) number = models.ForeignKey(CertApp, related_name='bill_number', on_delete=models.DO_NOTHING)
feecharacter = models.ForeignKey(Dict, verbose_name='费用性质', related_name='bill_feecharacter', on_delete=models.DO_NOTHING) feecharacter = models.ForeignKey(Dict, verbose_name='费用性质', related_name='bill_feecharacter', on_delete=models.DO_NOTHING)
applicant = models.ForeignKey(Enterprise, related_name='bill_applicant', on_delete=models.DO_NOTHING)
totalfee = models.FloatField('总金额',null=True, blank=True, default=0) totalfee = models.FloatField('总金额',null=True, blank=True, default=0)
deductions = models.FloatField('扣减额',null=True, blank=True, default=0) deductions = models.FloatField('扣减额',null=True, blank=True, default=0)
exchangetype = models.CharField('外汇类型', max_length=300) exchangetype = models.CharField('外汇类型', max_length=300)
@ -21,3 +20,24 @@ class Bill(CommonBModel):
paidrmb = models.FloatField('实收人名币',null=True, blank=True, default=0) paidrmb = models.FloatField('实收人名币',null=True, blank=True, default=0)
paidwb = models.FloatField('实收外币',null=True, blank=True, default=0) paidwb = models.FloatField('实收外币',null=True, blank=True, default=0)
remark = models.CharField('备注', max_length=300) remark = models.CharField('备注', max_length=300)
class Meta:
verbose_name = '收费信息'
verbose_name_plural = verbose_name
def __str__(self):
return self.feecode
class Chargeitem(CommonBModel):
"""
收费项目
"""
bills = models.ForeignKey(Bill, related_name='chargeitem_bill',to_field='feecode',null=True, blank=True, on_delete=models.DO_NOTHING)
itemkind = models.CharField('收费项目',null=True, blank=True, max_length=300)
unitcount = models.FloatField('单元数量',null=True, blank=True, default=0)
perfee = models.FloatField('单价',null=True, blank=True, default=0)
pertotal = models.FloatField('小计',null=True, blank=True, default=0)
remark = models.CharField('备注',null=True, blank=True, max_length=300)
class Meta:
verbose_name = '收费项目'
verbose_name_plural = verbose_name
def __str__(self):
return self.itemkind

View File

@ -1,11 +1,24 @@
from rest_framework import serializers from rest_framework import serializers
from .models import Bill from .models import Bill,Chargeitem
class BillSerializer(serializers.ModelSerializer): class BillSerializer(serializers.ModelSerializer):
class Meta: class Meta:
model = Bill model = Bill
fields = '__all__' fields = '__all__'
class ChargeitemSerializer(serializers.ModelSerializer):
class Meta:
model = Chargeitem
fields = '__all__'
class BillsSerializer(serializers.ModelSerializer):
number_=ChargeitemSerializer(source='chargeitem_number')
class Meta:
model = Bill
fields = '__all__'
def setup_eager_loading(queryset):
""" Perform necessary eager loading of data. """
# queryset = queryset.select_related('type','economy_class')
queryset = queryset.prefetch_related('chargeitem_bill',)
return queryset

View File

@ -1,9 +1,10 @@
from django.urls import path, include from django.urls import path, include
from rest_framework import routers from rest_framework import routers
from .views import BillViewSet from .views import BillViewSet,ChargeitemViewSet
router = routers.DefaultRouter() router = routers.DefaultRouter()
router.register('bill', BillViewSet, basename="bill") router.register('bill', BillViewSet, basename="bill")
router.register('chargeitem', ChargeitemViewSet, basename="chargeitem")
urlpatterns = [ urlpatterns = [
path('', include(router.urls)) path('', include(router.urls))

View File

@ -1,9 +1,9 @@
from django.shortcuts import render from django.shortcuts import render
from rest_framework.viewsets import ModelViewSet from rest_framework.viewsets import ModelViewSet
from .models import Bill from .models import Bill,Chargeitem
from utils.queryset import get_child_queryset2 from utils.queryset import get_child_queryset2
from .serializers import BillSerializer from .serializers import BillSerializer,ChargeitemSerializer
from apps.system.permission_data import RbacFilterSet from apps.system.permission_data import RbacFilterSet
from apps.system.mixins import CreateUpdateCustomMixin, OptimizationMixin from apps.system.mixins import CreateUpdateCustomMixin, OptimizationMixin
# Create your views here. # Create your views here.
@ -13,6 +13,25 @@ class BillViewSet(CreateUpdateCustomMixin, OptimizationMixin, ModelViewSet):
'put': 'Bill_update', 'delete': 'Bill_delete'} 'put': 'Bill_update', 'delete': 'Bill_delete'}
queryset = Bill.objects queryset = Bill.objects
serializer_class = BillSerializer serializer_class = BillSerializer
search_fields = ['name','query_code', 'code'] search_fields = ['feecode']
ordering = ['-create_time'] ordering = ['-create_time']
filterset_fields = ['number']
ordering = ['-create_time']
def paginate_queryset(self, queryset):
if ((not self.request.query_params.get('page', None)) and (self.request.query_params.get('number', None))) or (self.paginator is None):
return None
return self.paginator.paginate_queryset(queryset, self.request, view=self)
class ChargeitemViewSet(CreateUpdateCustomMixin, OptimizationMixin, ModelViewSet):
perms_map = {'get': '*', 'post': 'chargeitem_create',
'put': 'chargeitem_update', 'delete': 'chargeitem_delete'}
queryset = Chargeitem.objects
serializer_class = ChargeitemSerializer
search_fields = ['itemkind']
filterset_fields = ['bills']
ordering = ['-create_time']
def paginate_queryset(self, queryset):
if ((not self.request.query_params.get('page', None)) and (self.request.query_params.get('bills', None))) or (self.paginator is None):
return None
return self.paginator.paginate_queryset(queryset, self.request, view=self)

View File

View File

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

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

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

View File

View File

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

View File

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

View File

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

View File

View File

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

View File

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

View File

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

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

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

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

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

View File

@ -0,0 +1,14 @@
from django_filters import rest_framework as filters
from .models import *
class CertAppFilter(filters.FilterSet):
noproject = filters.BooleanFilter(field_name='project', lookup_expr='isnull')
class Meta:
model = CertApp
fields = ['status', 'noproject']
class ProjectFilter(filters.FilterSet):
planoff = filters.BooleanFilter(field_name='plan', lookup_expr='isnull')
class Meta:
model = Project
fields = ['plan', 'planoff']

View File

@ -0,0 +1,32 @@
# Generated by Django 3.0.7 on 2020-08-13 09:44
from django.db import migrations, models
import django.db.models.deletion
class Migration(migrations.Migration):
dependencies = [
('project', '0018_certapp_level'),
]
operations = [
migrations.RemoveField(
model_name='unit',
name='factory',
),
migrations.RemoveField(
model_name='unit',
name='factory_v',
),
migrations.RemoveField(
model_name='unit',
name='subapplication',
),
migrations.AddField(
model_name='unit',
name='certapp',
field=models.ForeignKey(default=1, on_delete=django.db.models.deletion.CASCADE, to='project.CertApp', verbose_name='所属业务'),
preserve_default=False,
),
]

View File

@ -0,0 +1,20 @@
# Generated by Django 3.0.7 on 2020-08-17 01:48
from django.db import migrations, models
import django.db.models.deletion
class Migration(migrations.Migration):
dependencies = [
('certset', '0016_auto_20200805_1435'),
('project', '0019_auto_20200813_1744'),
]
operations = [
migrations.AddField(
model_name='unit',
name='standard',
field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, to='certset.Standard', verbose_name='采用标准'),
),
]

View File

@ -0,0 +1,33 @@
# Generated by Django 3.0.7 on 2020-08-18 03:53
from django.db import migrations, models
import django.db.models.deletion
class Migration(migrations.Migration):
dependencies = [
('certset', '0016_auto_20200805_1435'),
('project', '0020_unit_standard'),
]
operations = [
migrations.AddField(
model_name='unit',
name='implementrule',
field=models.ForeignKey(default=6, on_delete=django.db.models.deletion.DO_NOTHING, to='certset.ImplementRule', verbose_name='采用规则'),
preserve_default=False,
),
migrations.AlterField(
model_name='unit',
name='standard',
field=models.ForeignKey(default=2, on_delete=django.db.models.deletion.DO_NOTHING, to='certset.Standard', verbose_name='采用标准'),
preserve_default=False,
),
migrations.AlterField(
model_name='unit',
name='unittype',
field=models.ForeignKey(default=4, on_delete=django.db.models.deletion.DO_NOTHING, to='certset.UnitType', verbose_name='单元类型'),
preserve_default=False,
),
]

View File

@ -0,0 +1,47 @@
# Generated by Django 3.0.7 on 2020-08-18 09:04
import django.contrib.postgres.fields.jsonb
from django.db import migrations, models
import django.db.models.deletion
class Migration(migrations.Migration):
dependencies = [
('crm', '0011_enterprise_parent'),
('project', '0021_auto_20200818_1153'),
]
operations = [
migrations.AddField(
model_name='certapp',
name='scope',
field=models.TextField(blank=True, null=True, verbose_name='认证范围'),
),
migrations.AddField(
model_name='project',
name='assign_date',
field=models.DateField(blank=True, null=True, verbose_name='下达日期'),
),
migrations.AddField(
model_name='project',
name='auditee',
field=models.ForeignKey(default=43, on_delete=django.db.models.deletion.DO_NOTHING, related_name='project_auditee', to='crm.Enterprise', verbose_name='受审核方'),
preserve_default=False,
),
migrations.AddField(
model_name='project',
name='auditee_v',
field=django.contrib.postgres.fields.jsonb.JSONField(default=dict, verbose_name='受审核方'),
),
migrations.AddField(
model_name='project',
name='number',
field=models.CharField(blank=True, max_length=100, null=True, verbose_name='项目编号'),
),
migrations.AddField(
model_name='project',
name='remark',
field=models.TextField(blank=True, null=True, verbose_name='备注'),
),
]

View File

@ -0,0 +1,22 @@
# Generated by Django 3.0.7 on 2020-08-21 01:57
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('project', '0022_auto_20200818_1704'),
]
operations = [
migrations.AlterModelOptions(
name='project',
options={'verbose_name': '认证项目', 'verbose_name_plural': '认证项目'},
),
migrations.AddField(
model_name='project',
name='status',
field=models.CharField(choices=[('待下达', '待下达'), ('待派差', '待派差'), ('进行中', '进行中'), ('已中止', '已中止'), ('已完成', '已完成')], default='待下达', max_length=50, verbose_name='项目状态'),
),
]

View File

@ -0,0 +1,21 @@
# Generated by Django 3.0.7 on 2020-08-21 02:04
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', '0023_auto_20200821_0957'),
]
operations = [
migrations.AddField(
model_name='project',
name='assign_by',
field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, to=settings.AUTH_USER_MODEL, verbose_name='下达人'),
),
]

View File

@ -0,0 +1,46 @@
# Generated by Django 3.0.7 on 2020-08-21 07:41
from django.conf import settings
from django.db import migrations, models
import django.db.models.deletion
import django.utils.timezone
class Migration(migrations.Migration):
dependencies = [
migrations.swappable_dependency(settings.AUTH_USER_MODEL),
('system', '0028_auto_20200807_1018'),
('project', '0024_project_assign_by'),
]
operations = [
migrations.AddField(
model_name='project',
name='can_paichai',
field=models.BooleanField(default=False, verbose_name='是否可派差'),
),
migrations.CreateModel(
name='Plan',
fields=[
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('create_time', models.DateTimeField(default=django.utils.timezone.now, help_text='创建时间', verbose_name='创建时间')),
('update_time', models.DateTimeField(auto_now=True, help_text='修改时间', verbose_name='修改时间')),
('is_deleted', models.BooleanField(default=False, help_text='删除标记', verbose_name='删除标记')),
('name', models.CharField(max_length=1000, verbose_name='计划名称')),
('month', models.DateField(blank=True, null=True, verbose_name='计划审核月份')),
('belong_dept', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='plan_belong_dept', to='system.Organization', verbose_name='所属部门')),
('create_by', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='plan_create_by', to=settings.AUTH_USER_MODEL, verbose_name='创建人')),
('update_by', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='plan_update_by', to=settings.AUTH_USER_MODEL, verbose_name='最后编辑人')),
],
options={
'verbose_name': '审核计划',
'verbose_name_plural': '审核计划',
},
),
migrations.AddField(
model_name='project',
name='plan',
field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, to='project.Plan', verbose_name='所属计划'),
),
]

View File

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

View File

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

View File

@ -0,0 +1,14 @@
# Generated by Django 3.0.5 on 2020-09-03 03:42
from django.db import migrations
class Migration(migrations.Migration):
dependencies = [
('project', '0031_auto_20200901_1525'),
('project', '0027_auto_20200825_1636'),
]
operations = [
]

View File

@ -4,9 +4,10 @@ from django.db import models
from rest_framework.exceptions import ParseError from rest_framework.exceptions import ParseError
from simple_history.models import HistoricalRecords from simple_history.models import HistoricalRecords
from apps.certset.models import ImplementRule, UnitType, Evaluations from apps.certset.models import ImplementRule, UnitType, Evaluations, Standard
from apps.crm.models import Enterprise from apps.crm.models import Enterprise
from apps.system.models import CommonAModel, CommonBModel, Dict, User from apps.system.models import CommonAModel, CommonBModel, Dict, User
# from apps.plan.models import Plan
# Create your models here. # Create your models here.
@ -14,7 +15,31 @@ class Project(CommonBModel):
""" """
认证项目 认证项目
""" """
pass status_choices = (
('待下达', '待下达'),
('待派差', '待派差'),
('进行中', '进行中'),
('已中止', '已中止'),
('已完成', '已完成')
)
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)
class Meta:
verbose_name = '认证项目'
verbose_name_plural = verbose_name
def __str__(self):
return self.number
class CertApp(CommonBModel): class CertApp(CommonBModel):
""" """
@ -37,7 +62,7 @@ class CertApp(CommonBModel):
number = models.CharField('受理编号', max_length = 100, null=True, blank=True) number = models.CharField('受理编号', max_length = 100, null=True, blank=True)
apply_date = models.DateField('申请日期', null=True, blank=True) apply_date = models.DateField('申请日期', null=True, blank=True)
accept_date = models.DateField('受理日期', null=True, blank=True) accept_date = models.DateField('受理日期', null=True, blank=True)
accept_by = models.ForeignKey(User, verbose_name='受理人', on_delete=models.SET_NULL, null=True, blank=True)
applicant_v = JSONField(verbose_name='申请方') applicant_v = JSONField(verbose_name='申请方')
applicant = models.ForeignKey(Enterprise, related_name='certapp_applicant', on_delete=models.DO_NOTHING) applicant = models.ForeignKey(Enterprise, related_name='certapp_applicant', on_delete=models.DO_NOTHING)
@ -65,6 +90,7 @@ class CertApp(CommonBModel):
manufacture_v = JSONField(verbose_name='制造商', null=True) manufacture_v = JSONField(verbose_name='制造商', null=True)
factory = models.ForeignKey(Enterprise, on_delete=models.CASCADE, related_name='certapp_factory', null=True, blank=True) factory = models.ForeignKey(Enterprise, on_delete=models.CASCADE, related_name='certapp_factory', null=True, blank=True)
factory_v = JSONField(verbose_name='生产厂', null=True) factory_v = JSONField(verbose_name='生产厂', null=True)
scope = models.TextField('认证范围', null=True, blank=True)
system_people = models.FloatField('体系相关员工数',null=True, blank=True, default=0) system_people = models.FloatField('体系相关员工数',null=True, blank=True, default=0)
initial_people = models.FloatField('初始人日数',null=True, blank=True, default=0) initial_people = models.FloatField('初始人日数',null=True, blank=True, default=0)
supervision_people = models.FloatField('监督人日数',null=True, blank=True, default=0) supervision_people = models.FloatField('监督人日数',null=True, blank=True, default=0)
@ -173,12 +199,12 @@ class Unit(CommonBModel):
""" """
认证单元,一个单元一张证书 认证单元,一个单元一张证书
""" """
factory = models.ForeignKey(Enterprise, on_delete=models.DO_NOTHING)
factory_v = JSONField(verbose_name='生产厂', blank=True)
name = models.CharField('单元名称', max_length=200) name = models.CharField('单元名称', max_length=200)
description = models.TextField('单元描述', blank=True) description = models.TextField('单元描述', blank=True)
unittype = models.ForeignKey(UnitType, verbose_name='单元类型', on_delete = models.SET_NULL, null=True, blank=True) implementrule = models.ForeignKey(ImplementRule, verbose_name='采用规则', on_delete=models.DO_NOTHING)
subapplication = models.ForeignKey(Application, verbose_name='所属子申请', on_delete = models.CASCADE) unittype = models.ForeignKey(UnitType, verbose_name='单元类型', on_delete = models.DO_NOTHING)
standard = models.ForeignKey(Standard, verbose_name='采用标准', on_delete = models.DO_NOTHING)
certapp = models.ForeignKey(CertApp, verbose_name='所属业务', on_delete = models.CASCADE)
class Meta: class Meta:
verbose_name = '认证单元' verbose_name = '认证单元'
@ -188,3 +214,10 @@ class Unit(CommonBModel):
return self.name return self.name
def save(self, *args, **kwargs):
super().save(*args, **kwargs)
obj = self.certapp
objs = Unit.objects.filter(certapp=obj, is_deleted=False).values_list('name', flat=True)
obj.scope = obj.factory_v['address'] + ':' + ';'.join(objs)
obj.save()

View File

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

View File

@ -6,7 +6,11 @@ router = routers.DefaultRouter()
router.register('application', ApplicationViewSet, basename="application") router.register('application', ApplicationViewSet, basename="application")
router.register('subapplication', SubApplicationViewSet, basename="subapplication") router.register('subapplication', SubApplicationViewSet, basename="subapplication")
router.register('certapp', CertappViewset, basename="certapp") router.register('certapp', CertappViewset, basename="certapp")
router.register('evaluationdetail', EvaluationDetailViewset, basename="evaluationdetail") router.register('evaluationdetail', EvaluationDetailViewset, basename="evaluationdetail")
router.register('unit', UnitViewSet, basename="unit")
router.register('project', ProjectViewSet, basename="project")
urlpatterns = [ urlpatterns = [
path('', include(router.urls)) path('', include(router.urls))

View File

@ -1,5 +1,7 @@
from rest_framework.views import APIView
from apps import project
from django.shortcuts import render from django.shortcuts import render
import rest_framework from rest_framework.serializers import ModelSerializer
from rest_framework.viewsets import ModelViewSet, GenericViewSet from rest_framework.viewsets import ModelViewSet, GenericViewSet
from rest_framework.response import Response from rest_framework.response import Response
from rest_framework import status from rest_framework import status
@ -9,9 +11,12 @@ from apps.system.models import Dict
from apps.system.permission_data import RbacFilterSet from apps.system.permission_data import RbacFilterSet
from apps.system.mixins import CreateUpdateCustomMixin, OptimizationMixin from apps.system.mixins import CreateUpdateCustomMixin, OptimizationMixin
import random import random
from rest_framework.decorators import action
from .filters import *
from utils.pagination import PageOrNot
from rest_framework.exceptions import ParseError, NotAuthenticated
# Create your views here. # Create your views here.
class ApplicationViewSet(CreateUpdateCustomMixin, ModelViewSet): class ApplicationViewSet(RbacFilterSet, ModelViewSet):
""" """
认证申请 认证申请
""" """
@ -29,7 +34,7 @@ class ApplicationViewSet(CreateUpdateCustomMixin, ModelViewSet):
def perform_create(self, serializer): def perform_create(self, serializer):
serializer.save(create_by = self.request.user, belong_dept=self.request.user.dept, number=random.randrange(1000,2000)) serializer.save(create_by = self.request.user, belong_dept=self.request.user.dept, number=random.randrange(1000,2000))
class SubApplicationViewSet(CreateUpdateCustomMixin, ModelViewSet): class SubApplicationViewSet(RbacFilterSet, ModelViewSet):
""" """
子认证申请 子认证申请
""" """
@ -60,7 +65,7 @@ class SubApplicationViewSet(CreateUpdateCustomMixin, ModelViewSet):
return None return None
return self.paginator.paginate_queryset(queryset, self.request, view=self) return self.paginator.paginate_queryset(queryset, self.request, view=self)
class CertappViewset(CreateUpdateCustomMixin, ModelViewSet): class CertappViewset(PageOrNot, RbacFilterSet, ModelViewSet):
""" """
申请受理 申请受理
""" """
@ -68,18 +73,21 @@ class CertappViewset(CreateUpdateCustomMixin, ModelViewSet):
queryset = CertApp.objects.all() queryset = CertApp.objects.all()
serializer_class = CertappSerializer serializer_class = CertappSerializer
ordering = ['-create_time'] ordering = ['-create_time']
filterset_fields = ['status', 'project']
# filterset_class = CertAppFilter
def create(self, request, *args, **kwargs): def create(self, request, *args, **kwargs):
postdata = request.data postdata = request.data
postdata['number'] = random.randrange(1000,2000) postdata['number'] = random.randrange(1000,2000)
if postdata.get('field_code', None): if postdata.get('field_code', None):
postdata['cert_field'] = Dict.objects.get(code=postdata['field_code']).id postdata['cert_field'] = Dict.objects.get(code=postdata['field_code']).id
print(postdata)
serializer = self.get_serializer(data=postdata) serializer = self.get_serializer(data=postdata)
serializer.is_valid(raise_exception=True) serializer.is_valid(raise_exception=True)
self.perform_create(serializer) self.perform_create(serializer)
headers = self.get_success_headers(serializer.data) headers = self.get_success_headers(serializer.data)
return Response(serializer.data, status=status.HTTP_201_CREATED, headers=headers) return Response(serializer.data, status=status.HTTP_201_CREATED, headers=headers)
class EvaluationDetailViewset(CreateUpdateCustomMixin, ModelViewSet): class EvaluationDetailViewset(CreateUpdateCustomMixin, ModelViewSet):
""" """
受理信息 受理信息
@ -96,3 +104,80 @@ class EvaluationDetailViewset(CreateUpdateCustomMixin, ModelViewSet):
return None return None
return self.paginator.paginate_queryset(queryset, self.request, view=self) return self.paginator.paginate_queryset(queryset, self.request, view=self)
@action(methods=['put'], detail=True, perms_map={'put':'complete_certapp'},
url_name='complete_certapp')
def complete(self, request, pk=None):
"""
完成受理
"""
obj = self.get_object()
obj.status = '已受理'
obj.save()
return Response(status=status.HTTP_200_OK)
class UnitViewSet(RbacFilterSet, ModelViewSet):
"""
产品单元
"""
perms_map = {'get': 'certapp_view', 'post':'certapp_create', 'put':'certapp_update','delete': 'certapp_delete'}
queryset = Unit.objects.all()
serializer_class = UnitSerializer
ordering = ['pk']
filterset_fields = ['certapp']
class ProjectViewSet(RbacFilterSet, ModelViewSet):
perms_map = {'get': 'project_view', 'post':'project_create', 'put':'project_update','delete': 'project_delete'}
queryset = Project.objects.all()
serializer_class = ProjectSerializer
ordering = ['pk']
filterset_class = ProjectFilter
def get_serializer_class(self):
if self.action == 'update':
return ProjectUpdateSerializer
return ProjectSerializer
def create(self, request, *args, **kwargs):
postdata = request.data
postdata['number'] = random.randrange(8000,9000)
serializer = self.get_serializer(data=postdata)
serializer.is_valid(raise_exception=True)
if self.request.user is not None:
instance = serializer.save(create_by = self.request.user, belong_dept=self.request.user.dept)
if 'certapps' in postdata and postdata['certapps']:
CertApp.objects.filter(pk__in = postdata['certapps']).update(project=instance, status='进行中')
headers = self.get_success_headers(serializer.data)
return Response(serializer.data, status=status.HTTP_201_CREATED, headers=headers)
else:
return NotAuthenticated()
@action(methods=['put'], detail=True, perms_map={'put':'project_assgin'},
url_name='project_assgin')
def assgin(self, request, pk=None):
"""
下达项目
"""
obj = self.get_object()
if obj.status == '待下达':
obj.status = '待派差'
obj.assgin_by = request.user
obj.save()
return Response(status=status.HTTP_200_OK)
else:
return Response('状态有误', status=status.HTTP_400_BAD_REQUEST)
@action(methods=['put'], detail=False, perms_map={'put':'project_plan'},
url_name='project_plan')
def plan(self, request, *args, **kwargs):
"""
项目计划
"""
projects = request.data['projects']
plan = request.data['plan']
if projects:
Project.objects.filter(pk__in=projects).update(plan=plan)
return Response(status=status.HTTP_200_OK)

View File

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

View File

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

View File

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

View File

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