Merge branch 'develop' of https://e.coding.net/ctcdevteam/hberp/hberp into develop
This commit is contained in:
commit
400173c0cf
|
@ -36,34 +36,34 @@ export function deleteEquipment(id, data) {
|
||||||
}
|
}
|
||||||
export function getEquipmentrecordList(query) {
|
export function getEquipmentrecordList(query) {
|
||||||
return request({
|
return request({
|
||||||
url: '/em/equipmentrecord/',
|
url: '/em/echeck_record/',
|
||||||
method: 'get',
|
method: 'get',
|
||||||
params: query
|
params: query
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
export function getEquipmentrecordAll() {
|
export function getEquipmentrecordAll() {
|
||||||
return request({
|
return request({
|
||||||
url: '/em/equipmentrecord/',
|
url: '/em/echeck_record/',
|
||||||
method: 'get'
|
method: 'get'
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
export function createEquipmentrecord(data) {
|
export function createEquipmentrecord(data) {
|
||||||
return request({
|
return request({
|
||||||
url: '/em/equipmentrecord/',
|
url: '/em/echeck_record/',
|
||||||
method: 'post',
|
method: 'post',
|
||||||
data
|
data
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
export function updateEquipmentrecord(id, data) {
|
export function updateEquipmentrecord(id, data) {
|
||||||
return request({
|
return request({
|
||||||
url: `/em/equipmentrecord/${id}/`,
|
url: `/em/echeck_record/${id}/`,
|
||||||
method: 'put',
|
method: 'put',
|
||||||
data
|
data
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
export function deleteEquipmentrecord(id, data) {
|
export function deleteEquipmentrecord(id, data) {
|
||||||
return request({
|
return request({
|
||||||
url: `/em/equipmentrecord/${id}/`,
|
url: `/em/echeck_record/${id}/`,
|
||||||
method: 'delete',
|
method: 'delete',
|
||||||
data
|
data
|
||||||
})
|
})
|
||||||
|
|
|
@ -357,4 +357,14 @@ export function getCard(id) {
|
||||||
url: `/wpm/wproduct/${id}/card/`,
|
url: `/wpm/wproduct/${id}/card/`,
|
||||||
method: 'GET',
|
method: 'GET',
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//指派发货订单
|
||||||
|
|
||||||
|
export function toorder(data) {
|
||||||
|
return request({
|
||||||
|
url: '/wpm/wproduct/to_order/',
|
||||||
|
method: 'post',
|
||||||
|
data
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
|
@ -273,12 +273,6 @@ export const asyncRoutes = [
|
||||||
name: 'record',
|
name: 'record',
|
||||||
component: () => import('@/views/em/record'),
|
component: () => import('@/views/em/record'),
|
||||||
meta: { title: '校准检定记录', icon: 'example', perms: ['em_record'] }
|
meta: { title: '校准检定记录', icon: 'example', perms: ['em_record'] }
|
||||||
},
|
|
||||||
{
|
|
||||||
path: 'detection ',
|
|
||||||
name: 'detection ',
|
|
||||||
component: () => import('@/views/em/detection'),
|
|
||||||
meta: { title: '运维记录', icon: 'example', perms: ['em_detection'] }
|
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
|
@ -399,6 +393,12 @@ export const asyncRoutes = [
|
||||||
name: 'producttest',
|
name: 'producttest',
|
||||||
component: () => import('@/views/qm/producttest'),
|
component: () => import('@/views/qm/producttest'),
|
||||||
meta: { title: '成品检验', icon: 'example', perms: ['index_manage'] }
|
meta: { title: '成品检验', icon: 'example', perms: ['index_manage'] }
|
||||||
|
},
|
||||||
|
{
|
||||||
|
path: 'unproduct',
|
||||||
|
name: 'unproduct',
|
||||||
|
component: () => import('@/views/qm/unproduct'),
|
||||||
|
meta: { title: '不合格品', icon: 'example', perms: ['index_manage'] }
|
||||||
}
|
}
|
||||||
|
|
||||||
]
|
]
|
||||||
|
|
|
@ -2,109 +2,116 @@
|
||||||
<div class="app-container">
|
<div class="app-container">
|
||||||
<el-card>
|
<el-card>
|
||||||
<div>
|
<div>
|
||||||
<el-button type="primary" icon="el-icon-plus" @click="handleCreate"
|
<el-button type="primary" icon="el-icon-plus" @click="handleCreate"
|
||||||
>新增设备</el-button
|
>新增设备</el-button
|
||||||
>
|
>
|
||||||
<el-input
|
<el-input
|
||||||
v-model="listQuery.search"
|
v-model="listQuery.search"
|
||||||
placeholder="设备名称/设备编号/备注"
|
placeholder="设备名称/设备编号/备注"
|
||||||
style="width: 300px"
|
style="width: 300px"
|
||||||
class="filter-item"
|
class="filter-item"
|
||||||
@keyup.enter.native="handleFilter"
|
@keyup.enter.native="handleFilter"
|
||||||
/>
|
/>
|
||||||
<el-button
|
<el-button
|
||||||
class="filter-item"
|
class="filter-item"
|
||||||
type="primary"
|
type="primary"
|
||||||
icon="el-icon-search"
|
icon="el-icon-search"
|
||||||
@click="handleFilter"
|
@click="handleFilter"
|
||||||
>搜索</el-button
|
>搜索</el-button
|
||||||
>
|
>
|
||||||
<el-button
|
<el-button
|
||||||
class="filter-item"
|
class="filter-item"
|
||||||
type="primary"
|
type="primary"
|
||||||
icon="el-icon-refresh-left"
|
icon="el-icon-refresh-left"
|
||||||
@click="resetFilter"
|
@click="resetFilter"
|
||||||
>重置</el-button
|
>重置</el-button
|
||||||
>
|
>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
</el-card>
|
</el-card>
|
||||||
<el-card >
|
<el-card>
|
||||||
<el-table
|
<el-table
|
||||||
v-loading="listLoading"
|
v-loading="listLoading"
|
||||||
:data="equipmentList.results"
|
:data="equipmentList.results"
|
||||||
border
|
:cell-style="tableRowClassName"
|
||||||
|
border
|
||||||
fit
|
fit
|
||||||
stripe
|
stripe
|
||||||
highlight-current-row
|
height="100"
|
||||||
height="100"
|
v-el-height-adaptive-table="{ bottomOffset: 42 }"
|
||||||
v-el-height-adaptive-table="{bottomOffset: 42}"
|
|
||||||
>
|
>
|
||||||
<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">{{ scope.row.number }}</template>
|
<template slot-scope="scope">{{ scope.row.number }}</template>
|
||||||
</el-table-column>
|
</el-table-column>
|
||||||
|
|
||||||
<el-table-column label="管理类别">
|
<el-table-column label="管理类别">
|
||||||
<template slot-scope="scope">{{ mgmtype_[scope.row.mgmtype] }}</template>
|
<template slot-scope="scope">{{
|
||||||
|
mgmtype_[scope.row.mgmtype]
|
||||||
|
}}</template>
|
||||||
</el-table-column>
|
</el-table-column>
|
||||||
<el-table-column label="校/检方式">
|
<el-table-column label="校/检方式" width="100">
|
||||||
<template slot-scope="scope">{{ waytype_[scope.row.way] }}</template>
|
<template slot-scope="scope">{{ waytype_[scope.row.way] }}</template>
|
||||||
</el-table-column>
|
</el-table-column>
|
||||||
<el-table-column label="标准/依据">
|
<el-table-column label="标准/依据" width="100">
|
||||||
<template slot-scope="scope">{{ scope.row.standard }}</template>
|
<template slot-scope="scope">{{ scope.row.standard }}</template>
|
||||||
</el-table-column>
|
</el-table-column>
|
||||||
<el-table-column label="校/检周期">
|
<el-table-column label="校/检周期" width="100">
|
||||||
<template slot-scope="scope">{{ scope.row.cycle }}</template>
|
<template slot-scope="scope">{{ scope.row.cycle }}</template>
|
||||||
</el-table-column>
|
</el-table-column>
|
||||||
<el-table-column label="设备名称">
|
<el-table-column label="最近一次校准日期" width="140">
|
||||||
|
<template slot-scope="scope">{{ scope.row.check_date }}</template>
|
||||||
|
</el-table-column>
|
||||||
|
<el-table-column label="下次校准日期" width="130">
|
||||||
|
<template slot-scope="scope">
|
||||||
|
{{ scope.row.next_check_date }}</template
|
||||||
|
>
|
||||||
|
</el-table-column>
|
||||||
|
|
||||||
|
<el-table-column label="设备名称">
|
||||||
<template slot-scope="scope">{{ scope.row.name }}</template>
|
<template slot-scope="scope">{{ scope.row.name }}</template>
|
||||||
</el-table-column>
|
</el-table-column>
|
||||||
<el-table-column label="型号规格">
|
<el-table-column label="型号规格">
|
||||||
<template slot-scope="scope">{{ scope.row.model }}</template>
|
<template slot-scope="scope">{{ scope.row.model }}</template>
|
||||||
</el-table-column>
|
</el-table-column>
|
||||||
|
|
||||||
<el-table-column label="生产厂家">
|
<el-table-column label="生产厂家">
|
||||||
<template slot-scope="scope">{{ scope.row.factory }}</template>
|
<template slot-scope="scope">{{ scope.row.factory }}</template>
|
||||||
</el-table-column>
|
</el-table-column>
|
||||||
<el-table-column label="使用类别">
|
<el-table-column label="使用类别">
|
||||||
<template slot-scope="scope">{{ usetype_[scope.row.way] }}</template>
|
<template slot-scope="scope">{{ usetype_[scope.row.way] }}</template>
|
||||||
</el-table-column>
|
</el-table-column>
|
||||||
<el-table-column label="校/检状态">
|
<el-table-column label="校/检状态" width="100">
|
||||||
<template slot-scope="scope">{{ state_[scope.row.statedm] }}</template>
|
<template slot-scope="scope">{{ state_[scope.row.state] }}</template>
|
||||||
</el-table-column>
|
</el-table-column>
|
||||||
|
|
||||||
<el-table-column label="保管人">
|
<el-table-column label="保管人">
|
||||||
<template slot-scope="scope" v-if="scope.row.keeper_">{{ scope.row.keeper_.username }}</template>
|
<template slot-scope="scope" v-if="scope.row.keeper_">{{
|
||||||
|
scope.row.keeper_.username
|
||||||
|
}}</template>
|
||||||
</el-table-column>
|
</el-table-column>
|
||||||
<el-table-column label="存放位置">
|
<el-table-column label="存放位置">
|
||||||
<template slot-scope="scope">{{ scope.row.place }}</template>
|
<template slot-scope="scope">{{ scope.row.place }}</template>
|
||||||
</el-table-column>
|
</el-table-column>
|
||||||
<el-table-column label="绑定工序">
|
<el-table-column label="绑定工序">
|
||||||
<template slot-scope="scope" v-if="scope.row.step_">
|
<template slot-scope="scope" v-if="scope.row.step_">
|
||||||
<el-tag v-for="item in scope.row.step_"
|
<el-tag
|
||||||
:key="item.number"
|
v-for="item in scope.row.step_"
|
||||||
:label="item.name"
|
:key="item.number"
|
||||||
:value="item.number">{{item.name}}</el-tag>
|
:label="item.name"
|
||||||
|
:value="item.number"
|
||||||
|
>{{ item.name }}</el-tag
|
||||||
|
>
|
||||||
</template>
|
</template>
|
||||||
</el-table-column>
|
</el-table-column>
|
||||||
<el-table-column label="备注">
|
<el-table-column label="备注">
|
||||||
<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
|
<el-table-column align="center" label="操作" fixed="right" width="120px">
|
||||||
align="center"
|
|
||||||
label="操作"
|
|
||||||
width="120px"
|
|
||||||
>
|
|
||||||
<template slot-scope="scope">
|
<template slot-scope="scope">
|
||||||
|
|
||||||
<el-link
|
<el-link
|
||||||
v-if="checkPermission(['equipment_update'])"
|
v-if="checkPermission(['equipment_update'])"
|
||||||
type="primary"
|
type="primary"
|
||||||
@click="handleEdit(scope)"
|
@click="handleEdit(scope)"
|
||||||
>编辑</el-link
|
>编辑</el-link
|
||||||
>
|
>
|
||||||
|
@ -137,130 +144,153 @@
|
||||||
label-position="right"
|
label-position="right"
|
||||||
:rules="rule1"
|
:rules="rule1"
|
||||||
>
|
>
|
||||||
<el-row>
|
<el-row>
|
||||||
<el-col :span="12">
|
<el-col :span="12">
|
||||||
<el-form-item label="设备名称" prop="name">
|
<el-form-item label="设备名称" prop="name">
|
||||||
<el-input v-model="equipment.name" placeholder="设备名称" />
|
<el-input v-model="equipment.name" placeholder="设备名称" />
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
</el-col>
|
|
||||||
<el-col :span="12">
|
|
||||||
<el-form-item label="设备编号" prop="number">
|
|
||||||
<el-input v-model="equipment.number" placeholder="设备编号" />
|
|
||||||
</el-form-item>
|
|
||||||
</el-col>
|
|
||||||
</el-row>
|
|
||||||
<el-row>
|
|
||||||
<el-col :span="12">
|
|
||||||
<el-form-item label="型号规格" prop="model">
|
|
||||||
<el-input v-model="equipment.model" placeholder="规格型号规格" />
|
|
||||||
</el-form-item>
|
|
||||||
</el-col>
|
|
||||||
<el-col :span="12">
|
|
||||||
<el-form-item label="标准/依据" prop="standard">
|
|
||||||
<el-input v-model="equipment.standard" placeholder="溯源标准或依据" />
|
|
||||||
</el-form-item>
|
|
||||||
</el-col>
|
|
||||||
</el-row>
|
|
||||||
|
|
||||||
<el-row>
|
|
||||||
<el-col :span="12">
|
|
||||||
<el-form-item label="校/检状态" prop="statedm">
|
|
||||||
|
|
||||||
<el-select style="width: 100%" v-model="equipment.statedm" placeholder="请选择">
|
|
||||||
<el-option
|
|
||||||
v-for="item in options"
|
|
||||||
:key="item.value"
|
|
||||||
:label="item.label"
|
|
||||||
:value="item.value">
|
|
||||||
</el-option>
|
|
||||||
</el-select>
|
|
||||||
</el-form-item>
|
|
||||||
</el-col>
|
|
||||||
<el-col :span="12">
|
|
||||||
<el-form-item label="管理类别" prop="mgmtype">
|
|
||||||
<el-select style="width: 100%" v-model="equipment.mgmtype" placeholder="请选择">
|
|
||||||
<el-option
|
|
||||||
v-for="item in mgmoptions"
|
|
||||||
:key="item.value"
|
|
||||||
:label="item.label"
|
|
||||||
:value="item.value">
|
|
||||||
</el-option>
|
|
||||||
</el-select>
|
|
||||||
</el-form-item>
|
|
||||||
</el-col>
|
|
||||||
</el-row>
|
|
||||||
<el-row>
|
|
||||||
<el-col :span="12">
|
|
||||||
<el-form-item label="存放位置" prop="place">
|
|
||||||
<el-input v-model="equipment.place" placeholder="存放位置" />
|
|
||||||
</el-form-item>
|
|
||||||
</el-col>
|
</el-col>
|
||||||
<el-col :span="12">
|
<el-col :span="12">
|
||||||
<el-form-item label="责任人" prop="keeper">
|
<el-form-item label="设备编号" prop="number">
|
||||||
|
<el-input v-model="equipment.number" placeholder="设备编号" />
|
||||||
<el-select
|
</el-form-item>
|
||||||
v-model="equipment.keeper"
|
</el-col>
|
||||||
filterable
|
</el-row>
|
||||||
style="width: 100%"
|
<el-row>
|
||||||
allow-create
|
<el-col :span="12">
|
||||||
default-first-option
|
<el-form-item label="型号规格" prop="model">
|
||||||
placeholder="请选择">
|
<el-input v-model="equipment.model" placeholder="规格型号规格" />
|
||||||
<el-option
|
</el-form-item>
|
||||||
v-for="item in keeperOptions"
|
</el-col>
|
||||||
|
<el-col :span="12">
|
||||||
|
<el-form-item label="标准/依据" prop="standard">
|
||||||
|
<el-input
|
||||||
|
v-model="equipment.standard"
|
||||||
|
placeholder="溯源标准或依据"
|
||||||
|
/>
|
||||||
|
</el-form-item>
|
||||||
|
</el-col>
|
||||||
|
</el-row>
|
||||||
|
|
||||||
|
<el-row>
|
||||||
|
<el-col :span="12">
|
||||||
|
<el-form-item label="校/检状态" prop="state">
|
||||||
|
<el-select
|
||||||
|
style="width: 100%"
|
||||||
|
v-model="equipment.state"
|
||||||
|
placeholder="请选择"
|
||||||
|
>
|
||||||
|
<el-option
|
||||||
|
v-for="item in options"
|
||||||
:key="item.value"
|
:key="item.value"
|
||||||
:label="item.label"
|
:label="item.label"
|
||||||
:value="item.value">
|
:value="item.value"
|
||||||
</el-option>
|
>
|
||||||
</el-select>
|
</el-option>
|
||||||
|
</el-select>
|
||||||
|
</el-form-item>
|
||||||
</el-form-item>
|
</el-col>
|
||||||
</el-col>
|
<el-col :span="12">
|
||||||
</el-row>
|
<el-form-item label="管理类别" prop="mgmtype">
|
||||||
<el-row>
|
<el-select
|
||||||
<el-col :span="12">
|
style="width: 100%"
|
||||||
<el-form-item label="校/检方式" prop="way">
|
v-model="equipment.mgmtype"
|
||||||
<el-select style="width: 100%" v-model="equipment.way" placeholder="请选择">
|
placeholder="请选择"
|
||||||
<el-option
|
>
|
||||||
v-for="item in wayoptions"
|
<el-option
|
||||||
:key="item.value"
|
v-for="item in mgmoptions"
|
||||||
:label="item.label"
|
:key="item.value"
|
||||||
:value="item.value">
|
:label="item.label"
|
||||||
</el-option>
|
:value="item.value"
|
||||||
</el-select>
|
>
|
||||||
</el-form-item>
|
</el-option>
|
||||||
</el-col>
|
</el-select>
|
||||||
<el-col :span="12">
|
</el-form-item>
|
||||||
<el-form-item label="存放位置" prop="place">
|
</el-col>
|
||||||
<el-input v-model="equipment.place" placeholder="存放位置" />
|
</el-row>
|
||||||
</el-form-item>
|
<el-row>
|
||||||
</el-col>
|
<el-col :span="12">
|
||||||
</el-row>
|
<el-form-item label="存放位置" prop="place">
|
||||||
<el-row>
|
<el-input v-model="equipment.place" placeholder="存放位置" />
|
||||||
<el-col :span="12">
|
</el-form-item>
|
||||||
<el-form-item label="使用类别" prop="usetype">
|
</el-col>
|
||||||
<el-select style="width: 100%" v-model="equipment.usetype" placeholder="请选择">
|
<el-col :span="12">
|
||||||
<el-option
|
<el-form-item label="责任人" prop="keeper">
|
||||||
v-for="item in useoptions"
|
<el-select
|
||||||
:key="item.value"
|
v-model="equipment.keeper"
|
||||||
:label="item.label"
|
filterable
|
||||||
:value="item.value">
|
style="width: 100%"
|
||||||
</el-option>
|
allow-create
|
||||||
</el-select>
|
default-first-option
|
||||||
</el-form-item>
|
placeholder="请选择"
|
||||||
|
>
|
||||||
</el-col>
|
<el-option
|
||||||
<el-col :span="12">
|
v-for="item in keeperOptions"
|
||||||
<el-form-item label="校/检周期" prop="cycle">
|
:key="item.value"
|
||||||
<el-input v-model="equipment.cycle" placeholder="校准或检定周期" />
|
:label="item.label"
|
||||||
</el-form-item>
|
:value="item.value"
|
||||||
</el-col>
|
>
|
||||||
</el-row>
|
</el-option>
|
||||||
|
</el-select>
|
||||||
<el-form-item label="生产厂家" prop="factory">
|
</el-form-item>
|
||||||
|
</el-col>
|
||||||
|
</el-row>
|
||||||
|
<el-row>
|
||||||
|
<el-col :span="12">
|
||||||
|
<el-form-item label="校/检方式" prop="way">
|
||||||
|
<el-select
|
||||||
|
style="width: 100%"
|
||||||
|
v-model="equipment.way"
|
||||||
|
placeholder="请选择"
|
||||||
|
>
|
||||||
|
<el-option
|
||||||
|
v-for="item in wayoptions"
|
||||||
|
:key="item.value"
|
||||||
|
:label="item.label"
|
||||||
|
:value="item.value"
|
||||||
|
>
|
||||||
|
</el-option>
|
||||||
|
</el-select>
|
||||||
|
</el-form-item>
|
||||||
|
</el-col>
|
||||||
|
<el-col :span="12">
|
||||||
|
<el-form-item label="存放位置" prop="place">
|
||||||
|
<el-input v-model="equipment.place" placeholder="存放位置" />
|
||||||
|
</el-form-item>
|
||||||
|
</el-col>
|
||||||
|
</el-row>
|
||||||
|
<el-row>
|
||||||
|
<el-col :span="12">
|
||||||
|
<el-form-item label="使用类别" prop="usetype">
|
||||||
|
<el-select
|
||||||
|
style="width: 100%"
|
||||||
|
v-model="equipment.usetype"
|
||||||
|
placeholder="请选择"
|
||||||
|
>
|
||||||
|
<el-option
|
||||||
|
v-for="item in useoptions"
|
||||||
|
:key="item.value"
|
||||||
|
:label="item.label"
|
||||||
|
:value="item.value"
|
||||||
|
>
|
||||||
|
</el-option>
|
||||||
|
</el-select>
|
||||||
|
</el-form-item>
|
||||||
|
</el-col>
|
||||||
|
<el-col :span="12">
|
||||||
|
<el-form-item label="校/检周期" prop="cycle">
|
||||||
|
<el-input
|
||||||
|
v-model="equipment.cycle"
|
||||||
|
placeholder="校准或检定周期"
|
||||||
|
/>
|
||||||
|
</el-form-item>
|
||||||
|
</el-col>
|
||||||
|
</el-row>
|
||||||
|
|
||||||
|
<el-form-item label="生产厂家" prop="factory">
|
||||||
<el-input v-model="equipment.factory" placeholder="生产厂商及国别" />
|
<el-input v-model="equipment.factory" placeholder="生产厂商及国别" />
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
|
|
||||||
<el-form-item label="备注" prop="description">
|
<el-form-item label="备注" prop="description">
|
||||||
<el-input
|
<el-input
|
||||||
type="textarea"
|
type="textarea"
|
||||||
|
@ -269,14 +299,6 @@
|
||||||
placeholder="备注"
|
placeholder="备注"
|
||||||
/>
|
/>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
</el-form>
|
</el-form>
|
||||||
<div style="text-align: right">
|
<div style="text-align: right">
|
||||||
<el-button type="danger" @click="dialogVisible = false">取消</el-button>
|
<el-button type="danger" @click="dialogVisible = false">取消</el-button>
|
||||||
|
@ -285,13 +307,19 @@
|
||||||
</el-dialog>
|
</el-dialog>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
<style>
|
||||||
|
</style>
|
||||||
<script>
|
<script>
|
||||||
import { getpEquipmentList, createEquipment,updateEquipment,deleteEquipment } from "@/api/equipment";
|
import {
|
||||||
|
getpEquipmentList,
|
||||||
|
createEquipment,
|
||||||
|
updateEquipment,
|
||||||
|
deleteEquipment,
|
||||||
|
} from "@/api/equipment";
|
||||||
import { getUserList } from "@/api/user";
|
import { getUserList } from "@/api/user";
|
||||||
import { getOrgList } from "@/api/org";
|
import { getOrgList } from "@/api/org";
|
||||||
import checkPermission from "@/utils/permission";
|
import checkPermission from "@/utils/permission";
|
||||||
|
|
||||||
|
|
||||||
import { genTree } from "@/utils";
|
import { genTree } from "@/utils";
|
||||||
import Pagination from "@/components/Pagination"; // secondary package based on el-pagination
|
import Pagination from "@/components/Pagination"; // secondary package based on el-pagination
|
||||||
const defaultequipment = {
|
const defaultequipment = {
|
||||||
|
@ -306,105 +334,103 @@ export default {
|
||||||
equipmentList: {
|
equipmentList: {
|
||||||
count: 0,
|
count: 0,
|
||||||
},
|
},
|
||||||
mgmtype_: {
|
mgmtype_: {
|
||||||
'1':'A',
|
1: "A",
|
||||||
'2':'B',
|
2: "B",
|
||||||
'3':'C',
|
3: "C",
|
||||||
},
|
},
|
||||||
mgmoptions: [{
|
mgmoptions: [
|
||||||
|
{
|
||||||
value: 1,
|
value: 1,
|
||||||
label: 'A'
|
label: "A",
|
||||||
}, {
|
},
|
||||||
|
{
|
||||||
value: 2,
|
value: 2,
|
||||||
label: 'B'
|
label: "B",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
value: 3,
|
value: 3,
|
||||||
label: 'C'
|
label: "C",
|
||||||
}],
|
|
||||||
waytype_: {
|
|
||||||
'1':'外检',
|
|
||||||
'2':'自检',
|
|
||||||
|
|
||||||
},
|
},
|
||||||
wayoptions: [{
|
],
|
||||||
|
waytype_: {
|
||||||
|
1: "外检",
|
||||||
|
2: "自检",
|
||||||
|
},
|
||||||
|
wayoptions: [
|
||||||
|
{
|
||||||
value: 1,
|
value: 1,
|
||||||
label: '外检'
|
label: "外检",
|
||||||
}, {
|
|
||||||
value: 2,
|
|
||||||
label: '自检'
|
|
||||||
}],
|
|
||||||
usetype_:{
|
|
||||||
'1':'专用',
|
|
||||||
'2':'公用',
|
|
||||||
},
|
|
||||||
useoptions: [{
|
|
||||||
value: 1,
|
|
||||||
label: '专用'
|
|
||||||
}, {
|
|
||||||
value: 2,
|
|
||||||
label: '公用'
|
|
||||||
}],
|
|
||||||
state_:{
|
|
||||||
0:'合格',
|
|
||||||
1:'准用',
|
|
||||||
2:'限用',
|
|
||||||
3:'禁用',
|
|
||||||
4:'停用',
|
|
||||||
5:'封存',
|
|
||||||
},
|
|
||||||
options: [{
|
|
||||||
value: 0,
|
|
||||||
label: '合格'
|
|
||||||
}, {
|
|
||||||
value: 1,
|
|
||||||
label: '准用'
|
|
||||||
}, {
|
|
||||||
value: 2,
|
|
||||||
label: '限用'
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
value: 3,
|
value: 2,
|
||||||
label: '禁用'
|
label: "自检",
|
||||||
}, {
|
},
|
||||||
value: 4,
|
],
|
||||||
label: '停用'
|
usetype_: {
|
||||||
}, {
|
1: "专用",
|
||||||
value: 5,
|
2: "公用",
|
||||||
label: '封存'
|
},
|
||||||
}],
|
useoptions: [
|
||||||
|
{
|
||||||
|
value: 1,
|
||||||
|
label: "专用",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
value: 2,
|
||||||
|
label: "公用",
|
||||||
|
},
|
||||||
|
],
|
||||||
|
state_: {
|
||||||
|
10: "合格",
|
||||||
|
|
||||||
|
40: "禁用",
|
||||||
|
},
|
||||||
|
options: [
|
||||||
|
{
|
||||||
|
value: 10,
|
||||||
|
label: "合格",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
value: 40,
|
||||||
|
label: "禁用",
|
||||||
|
},
|
||||||
|
],
|
||||||
listQuery: {
|
listQuery: {
|
||||||
page: 1,
|
page: 1,
|
||||||
page_size: 20,
|
page_size: 20,
|
||||||
},
|
},
|
||||||
keeperOptions:[],
|
keeperOptions: [],
|
||||||
depOptions:[],
|
depOptions: [],
|
||||||
listLoading: true,
|
listLoading: true,
|
||||||
dialogVisible: false,
|
dialogVisible: false,
|
||||||
dialogType: "new",
|
dialogType: "new",
|
||||||
rule1: {
|
rule1: {
|
||||||
name: [{ required: true, message: "请输入", trigger: "blur" }],
|
name: [{ required: true, message: "请输入", trigger: "blur" }],
|
||||||
number: [{ required: true, message: "请输入", trigger: "blur" }],
|
number: [{ required: true, message: "请输入", trigger: "blur" }],
|
||||||
type: [{ required: true, message: "请输入", trigger: "blur" }],
|
type: [{ required: true, message: "请输入", trigger: "blur" }],
|
||||||
model: [{ required: true, message: "请输入", trigger: "blur" }],
|
model: [{ required: true, message: "请输入", trigger: "blur" }],
|
||||||
state: [{ required: true, message: "请选择", trigger: "blur" }],
|
state: [{ required: true, message: "请选择", trigger: "blur" }],
|
||||||
belong_dept:[{ required: true, message: "请选择", trigger: "blur" }]
|
belong_dept: [{ required: true, message: "请选择", trigger: "blur" }],
|
||||||
},
|
},
|
||||||
|
datatime: null,
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
computed: {},
|
computed: {},
|
||||||
watch: {},
|
watch: {},
|
||||||
created() {
|
created() {
|
||||||
this.getList();
|
this.getList();
|
||||||
this.getUserList();
|
|
||||||
this.getOrgList();
|
this.getUserList();
|
||||||
|
this.getOrgList();
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
checkPermission,
|
checkPermission,
|
||||||
|
|
||||||
//设备列表
|
//设备列表
|
||||||
getList() {
|
getList() {
|
||||||
this.listLoading = true;
|
this.listLoading = true;
|
||||||
this.listQuery.type=2;
|
this.listQuery.type = 2;
|
||||||
getpEquipmentList(this.listQuery).then((response) => {
|
getpEquipmentList(this.listQuery).then((response) => {
|
||||||
if (response.data) {
|
if (response.data) {
|
||||||
this.equipmentList = response.data;
|
this.equipmentList = response.data;
|
||||||
|
@ -412,20 +438,51 @@ export default {
|
||||||
this.listLoading = false;
|
this.listLoading = false;
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
//组员列表
|
|
||||||
|
//校准时间提醒
|
||||||
|
tableRowClassName(row, column, rowIndex, columnIndex) {
|
||||||
|
if(row.row.next_check_date!=null)
|
||||||
|
{
|
||||||
|
var adata = new Date(); //获取当前时间
|
||||||
|
const date = {
|
||||||
|
year: adata.getFullYear(),
|
||||||
|
month: adata.getMonth() + 1,
|
||||||
|
date: adata.getDate(),
|
||||||
|
};
|
||||||
|
const newmonth = date.month > 10 ? date.month : "0" + date.month;
|
||||||
|
const day = date.date > 10 ? date.date : "0" + date.date;
|
||||||
|
var updateTime = date.year + "-" + newmonth + "-" + day;
|
||||||
|
var dateBegin = row.row.next_check_date;
|
||||||
|
|
||||||
|
var a =
|
||||||
|
(new Date(dateBegin).getTime() - new Date(updateTime).getTime()) /1000/60/60/24; //计算出相差的毫秒数
|
||||||
|
console.log(a);
|
||||||
|
if (4>a&&a>0 && row.column.label==='下次校准日期') {
|
||||||
|
|
||||||
|
return "background:yellow";
|
||||||
|
}
|
||||||
|
else if (a<0 && row.column.label==='下次校准日期') {
|
||||||
|
|
||||||
|
return "background:red";
|
||||||
|
}
|
||||||
|
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
|
||||||
|
},
|
||||||
|
//组员列表
|
||||||
getUserList() {
|
getUserList() {
|
||||||
getUserList({pageoff:true}).then((res) => {
|
getUserList({ page: 0 }).then((res) => {
|
||||||
this.keeperOptions = genTree(res.data);
|
this.keeperOptions = genTree(res.data);
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
//部门列表
|
//部门列表
|
||||||
getOrgList() {
|
getOrgList() {
|
||||||
getOrgList({pageoff:true}).then((res) => {
|
getOrgList({ page: 0 }).then((res) => {
|
||||||
this.depOptions = genTree(res.data);
|
this.depOptions = genTree(res.data);
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
|
||||||
|
|
||||||
handleFilter() {
|
handleFilter() {
|
||||||
this.listQuery.page = 1;
|
this.listQuery.page = 1;
|
||||||
this.getList();
|
this.getList();
|
||||||
|
@ -434,7 +491,7 @@ export default {
|
||||||
this.listQuery = {
|
this.listQuery = {
|
||||||
page: 1,
|
page: 1,
|
||||||
page_size: 20,
|
page_size: 20,
|
||||||
}
|
};
|
||||||
this.getList();
|
this.getList();
|
||||||
},
|
},
|
||||||
handleCreate() {
|
handleCreate() {
|
||||||
|
@ -445,7 +502,7 @@ export default {
|
||||||
this.$refs["Form"].clearValidate();
|
this.$refs["Form"].clearValidate();
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
|
||||||
handleEdit(scope) {
|
handleEdit(scope) {
|
||||||
this.equipment = Object.assign({}, scope.row); // copy obj
|
this.equipment = Object.assign({}, scope.row); // copy obj
|
||||||
this.dialogType = "edit";
|
this.dialogType = "edit";
|
||||||
|
@ -469,7 +526,7 @@ export default {
|
||||||
console.error(err);
|
console.error(err);
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
|
||||||
async confirm(form) {
|
async confirm(form) {
|
||||||
this.$refs[form].validate((valid) => {
|
this.$refs[form].validate((valid) => {
|
||||||
if (valid) {
|
if (valid) {
|
||||||
|
@ -483,11 +540,11 @@ export default {
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
this.equipment.type=2;
|
this.equipment.type = 2;
|
||||||
createEquipment(this.equipment).then((res) => {
|
createEquipment(this.equipment).then((res) => {
|
||||||
if (res.code >= 200) {
|
if (res.code >= 200) {
|
||||||
this.getList();
|
this.getList();
|
||||||
this.dialogVisible = false;
|
this.dialogVisible = false;
|
||||||
this.$message.success("成功");
|
this.$message.success("成功");
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
|
@ -298,22 +298,22 @@ export default {
|
||||||
count: 0,
|
count: 0,
|
||||||
},
|
},
|
||||||
state_:{
|
state_:{
|
||||||
0:'完好',
|
10:'完好',
|
||||||
1:'限用',
|
20:'限用',
|
||||||
2:'在修',
|
30:'在修',
|
||||||
3:'禁用',
|
40:'禁用',
|
||||||
},
|
},
|
||||||
options: [{
|
options: [{
|
||||||
value: 0,
|
value: 10,
|
||||||
label: '完好'
|
label: '完好'
|
||||||
}, {
|
}, {
|
||||||
value: 1,
|
value: 20,
|
||||||
label: '限用'
|
label: '限用'
|
||||||
}, {
|
}, {
|
||||||
value: 2,
|
value: 30,
|
||||||
label: '在修'
|
label: '在修'
|
||||||
}, {
|
}, {
|
||||||
value: 3,
|
value: 40,
|
||||||
label: '禁用'
|
label: '禁用'
|
||||||
}],
|
}],
|
||||||
listQuery: {
|
listQuery: {
|
||||||
|
|
|
@ -52,13 +52,10 @@
|
||||||
<template slot-scope="scope">{{ scope.row.equipment_.model }}</template>
|
<template slot-scope="scope">{{ scope.row.equipment_.model }}</template>
|
||||||
</el-table-column>
|
</el-table-column>
|
||||||
<el-table-column label="设备状态">
|
<el-table-column label="设备状态">
|
||||||
<template slot-scope="scope">{{ state_[scope.row.equipment_.statedm] }}</template>
|
<template slot-scope="scope">{{ state_[scope.row.equipment_.state] }}</template>
|
||||||
</el-table-column>
|
</el-table-column>
|
||||||
<el-table-column label="最近一次校准/检定日期">
|
<el-table-column label="校准检查日期">
|
||||||
<template slot-scope="scope">{{ scope.row.recentlydate }}</template>
|
<template slot-scope="scope">{{ scope.row.check_date }}</template>
|
||||||
</el-table-column>
|
|
||||||
<el-table-column label="下次应校准或检定日期">
|
|
||||||
<template slot-scope="scope">{{ scope.row.nextdate }}</template>
|
|
||||||
</el-table-column>
|
</el-table-column>
|
||||||
<el-table-column label="备注">
|
<el-table-column label="备注">
|
||||||
<template slot-scope="scope">{{ scope.row.description }}</template>
|
<template slot-scope="scope">{{ scope.row.description }}</template>
|
||||||
|
@ -107,7 +104,7 @@
|
||||||
:rules="rule1"
|
:rules="rule1"
|
||||||
>
|
>
|
||||||
|
|
||||||
<el-form-item label="校准或检定设备" prop="equipment">
|
<el-form-item label="校准检定设备" prop="equipment">
|
||||||
<el-select style="width: 100%" v-model="equipmentrecord.equipment" placeholder="请选择">
|
<el-select style="width: 100%" v-model="equipmentrecord.equipment" placeholder="请选择">
|
||||||
<el-option
|
<el-option
|
||||||
v-for="item in equipmentoptions"
|
v-for="item in equipmentoptions"
|
||||||
|
@ -117,22 +114,11 @@
|
||||||
</el-option>
|
</el-option>
|
||||||
</el-select>
|
</el-select>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<el-form-item label="校准或检定状态" prop="state">
|
|
||||||
|
|
||||||
<el-select style="width: 100%" v-model="equipmentrecord.state" placeholder="请选择">
|
<el-form-item label="校准检查日期" prop="check_date">
|
||||||
<el-option
|
|
||||||
v-for="item in options"
|
|
||||||
:key="item.value"
|
|
||||||
:label="item.label"
|
|
||||||
:value="item.value">
|
|
||||||
</el-option>
|
|
||||||
</el-select>
|
|
||||||
</el-form-item>
|
|
||||||
<el-row>
|
|
||||||
<el-col :span="12">
|
|
||||||
<el-form-item label="最近一次校准或检定日期" prop="recentlydate">
|
|
||||||
<el-date-picker
|
<el-date-picker
|
||||||
v-model="equipmentrecord.recentlydate"
|
v-model="equipmentrecord.check_date"
|
||||||
type="date"
|
type="date"
|
||||||
placeholder="选择日期"
|
placeholder="选择日期"
|
||||||
value-format="yyyy-MM-dd"
|
value-format="yyyy-MM-dd"
|
||||||
|
@ -141,21 +127,7 @@
|
||||||
</el-date-picker>
|
</el-date-picker>
|
||||||
|
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
</el-col>
|
|
||||||
<el-col :span="12">
|
|
||||||
<el-form-item label="下次应校准或检定日期" prop="nextdate">
|
|
||||||
<el-date-picker
|
|
||||||
v-model="equipmentrecord.nextdate"
|
|
||||||
type="date"
|
|
||||||
placeholder="选择日期"
|
|
||||||
value-format="yyyy-MM-dd"
|
|
||||||
style="width: 100%"
|
|
||||||
>
|
|
||||||
</el-date-picker>
|
|
||||||
|
|
||||||
</el-form-item>
|
|
||||||
</el-col>
|
|
||||||
</el-row>
|
|
||||||
<el-form-item label="备注" prop="description">
|
<el-form-item label="备注" prop="description">
|
||||||
<el-input
|
<el-input
|
||||||
type="textarea"
|
type="textarea"
|
||||||
|
@ -176,7 +148,7 @@
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
<script>
|
<script>
|
||||||
import { getpEquipmentList, createEquipment,updateEquipment,deleteEquipment,
|
import { getpEquipmentList,
|
||||||
getEquipmentrecordList, createEquipmentrecord,updateEquipmentrecord,deleteEquipmentrecord } from "@/api/equipment";
|
getEquipmentrecordList, createEquipmentrecord,updateEquipmentrecord,deleteEquipmentrecord } from "@/api/equipment";
|
||||||
import { getUserList } from "@/api/user";
|
import { getUserList } from "@/api/user";
|
||||||
import { getOrgList } from "@/api/org";
|
import { getOrgList } from "@/api/org";
|
||||||
|
@ -202,39 +174,18 @@ export default {
|
||||||
},
|
},
|
||||||
equipmentoptions:[],
|
equipmentoptions:[],
|
||||||
state_:{
|
state_:{
|
||||||
0:'合格',
|
10:'合格',
|
||||||
1:'准用',
|
|
||||||
2:'限用',
|
40:'禁用',
|
||||||
3:'禁用',
|
|
||||||
4:'停用',
|
|
||||||
5:'封存',
|
|
||||||
},
|
},
|
||||||
options: [{
|
|
||||||
value: 0,
|
|
||||||
label: '合格'
|
|
||||||
}, {
|
|
||||||
value: 1,
|
|
||||||
label: '准用'
|
|
||||||
}, {
|
|
||||||
value: 2,
|
|
||||||
label: '限用'
|
|
||||||
},
|
|
||||||
{
|
|
||||||
value: 3,
|
|
||||||
label: '禁用'
|
|
||||||
}, {
|
|
||||||
value: 4,
|
|
||||||
label: '停用'
|
|
||||||
}, {
|
|
||||||
value: 5,
|
|
||||||
label: '封存'
|
|
||||||
}],
|
|
||||||
listLoading: true,
|
listLoading: true,
|
||||||
dialogVisible: false,
|
dialogVisible: false,
|
||||||
dialogType: "new",
|
dialogType: "new",
|
||||||
rule1: {
|
rule1: {
|
||||||
equipment: [{ required: true, message: "请输入", trigger: "blur" }],
|
equipment: [{ required: true, message: "请输入", trigger: "blur" }],
|
||||||
state: [{ required: true, message: "请输入", trigger: "blur" }],
|
|
||||||
|
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
|
@ -77,6 +77,12 @@
|
||||||
</el-table-column>
|
</el-table-column>
|
||||||
<el-table-column label="工序">
|
<el-table-column label="工序">
|
||||||
<template slot-scope="scope">{{ scope.row.process_.name }}</template>
|
<template slot-scope="scope">{{ scope.row.process_.name }}</template>
|
||||||
|
</el-table-column>
|
||||||
|
<el-table-column label="是否质检">
|
||||||
|
<template slot-scope="scope">
|
||||||
|
<el-tag v-if="scope.row.need_combtest==true"> 是</el-tag>
|
||||||
|
<el-tag v-else>否</el-tag>
|
||||||
|
</template>
|
||||||
</el-table-column>
|
</el-table-column>
|
||||||
<el-table-column label="排序">
|
<el-table-column label="排序">
|
||||||
<template slot-scope="scope">{{ scope.row.sort }}</template>
|
<template slot-scope="scope">{{ scope.row.sort }}</template>
|
||||||
|
@ -132,6 +138,9 @@
|
||||||
</el-select>
|
</el-select>
|
||||||
|
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
|
<el-form-item label="是否质检" prop="need_combtest">
|
||||||
|
<el-switch v-model="subproducation.need_combtest"></el-switch>
|
||||||
|
</el-form-item>
|
||||||
<el-form-item label="排序" prop="sort">
|
<el-form-item label="排序" prop="sort">
|
||||||
<el-input-number
|
<el-input-number
|
||||||
v-model="subproducation.sort"
|
v-model="subproducation.sort"
|
||||||
|
@ -554,7 +563,7 @@
|
||||||
|
|
||||||
<el-table-column align="center" label="文件">
|
<el-table-column align="center" label="文件">
|
||||||
<template slot-scope="scope" v-if="scope.row.file_">
|
<template slot-scope="scope" v-if="scope.row.file_">
|
||||||
<el-link :href="scope.row.file_.path" >{{scope.row.file_.name}}</el-link>
|
<el-link :href="scope.row.file_.file" >{{scope.row.file_.name}}</el-link>
|
||||||
</template>
|
</template>
|
||||||
</el-table-column>
|
</el-table-column>
|
||||||
<el-table-column
|
<el-table-column
|
||||||
|
@ -659,7 +668,7 @@ const defaultusedstep = {
|
||||||
};
|
};
|
||||||
const defaulttechdoc = {enabled:false};
|
const defaulttechdoc = {enabled:false};
|
||||||
const defaultsubproducation = {
|
const defaultsubproducation = {
|
||||||
|
need_combtest:false,
|
||||||
};
|
};
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
|
|
|
@ -149,86 +149,7 @@
|
||||||
:limit.sync="listQuery2.page_size"
|
:limit.sync="listQuery2.page_size"
|
||||||
@pagination="getList2"
|
@pagination="getList2"
|
||||||
/>
|
/>
|
||||||
<!--不合格半成品重审-->
|
|
||||||
<el-dialog title="不合格半成品重审" :close-on-click-modal="false" :visible.sync="limitedRetrial">
|
|
||||||
<el-form label-width="130px" label-position="right">
|
|
||||||
<el-form-item :label="item.field_name" v-for="item in customfieldList.ticket_data_" :key="item.id" v-show="!item.is_hidden">
|
|
||||||
<template v-if="item.field_type=='string'">
|
|
||||||
<el-input v-model="item.default_value" :placeholder="item.description" />
|
|
||||||
</template>
|
|
||||||
<template v-if="item.field_type==='int'">
|
|
||||||
<el-input v-model="item.default_value" type="number" :placeholder="item.description" oninput="value=value.replace(/[^\d]/g,'')" />
|
|
||||||
</template>
|
|
||||||
<template v-if="item.field_type==='float'">
|
|
||||||
<el-input v-model="item.default_value" type="number" :placeholder="item.description" />
|
|
||||||
</template>
|
|
||||||
<template v-if="item.field_type==='date'">
|
|
||||||
<el-date-picker
|
|
||||||
v-model="item.default_value"
|
|
||||||
type="date"
|
|
||||||
placeholder="选择日期"
|
|
||||||
value-format="yyyy-MM-dd"
|
|
||||||
style="width: 100%"
|
|
||||||
>
|
|
||||||
</el-date-picker>
|
|
||||||
</template>
|
|
||||||
<template v-if="item.field_type==='datetime'">
|
|
||||||
<el-date-picker
|
|
||||||
v-model="item.default_value"
|
|
||||||
type="datetime"
|
|
||||||
placeholder="选择日期"
|
|
||||||
value-format="yyyy-MM-dd HH:mm:ss"
|
|
||||||
style="width: 100%"
|
|
||||||
>
|
|
||||||
</el-date-picker>
|
|
||||||
</template>
|
|
||||||
<template v-if="item.field_type==='select'">
|
|
||||||
<el-select style="width: 100%" v-model="item.default_value" placeholder="请选择">
|
|
||||||
<el-option
|
|
||||||
v-for="item1 in item.field_choice"
|
|
||||||
:key="item1.id"
|
|
||||||
:label="item1.name"
|
|
||||||
:value="item1.id"
|
|
||||||
>
|
|
||||||
</el-option>
|
|
||||||
</el-select>
|
|
||||||
</template>
|
|
||||||
<template v-if="item.field_type==='selects'">
|
|
||||||
<el-select style="width: 100%" multiple v-model="item.default_value" placeholder="请选择">
|
|
||||||
<el-option
|
|
||||||
v-for="item1 in item.field_choice"
|
|
||||||
:key="item1.id"
|
|
||||||
:label="item1.name"
|
|
||||||
:value="item1.id"
|
|
||||||
>
|
|
||||||
</el-option>
|
|
||||||
</el-select>
|
|
||||||
</template>
|
|
||||||
<template v-if="item.field_type==='textarea'">
|
|
||||||
<el-input type="textarea" :rows="3" v-model="item.default_value" placeholder="内容" />
|
|
||||||
</template>
|
|
||||||
<template v-if="item.field_type==='file'">
|
|
||||||
<el-upload
|
|
||||||
ref="upload"
|
|
||||||
:action="upUrl"
|
|
||||||
:on-preview="handlePreview"
|
|
||||||
:on-success="handleUpSuccess"
|
|
||||||
:on-remove="handleRemove"
|
|
||||||
:headers="upHeaders"
|
|
||||||
:file-list="fileList"
|
|
||||||
:limit="1"
|
|
||||||
accept=".doc,.docx,.xls,.xlsx,.ppt,.pptx"
|
|
||||||
>
|
|
||||||
<el-button size="small" type="primary">上传文件</el-button>
|
|
||||||
</el-upload>
|
|
||||||
</template>
|
|
||||||
</el-form-item>
|
|
||||||
</el-form>
|
|
||||||
<div slot="footer" class="dialog-footer">
|
|
||||||
<el-button @click="limitedRetrial = false">取 消</el-button>
|
|
||||||
|
|
||||||
</div>
|
|
||||||
</el-dialog>
|
|
||||||
</el-tab-pane>
|
</el-tab-pane>
|
||||||
</el-tabs>
|
</el-tabs>
|
||||||
</el-card>
|
</el-card>
|
||||||
|
|
|
@ -136,7 +136,7 @@ export default {
|
||||||
//半成品列表
|
//半成品列表
|
||||||
getList() {
|
getList() {
|
||||||
this.listLoading = true;
|
this.listLoading = true;
|
||||||
this.listQuery.type=1;
|
this.listQuery.material__type=1;
|
||||||
getiproductList(this.listQuery).then((response) => {
|
getiproductList(this.listQuery).then((response) => {
|
||||||
if (response.data) {
|
if (response.data) {
|
||||||
this.iproductData= response.data;
|
this.iproductData= response.data;
|
||||||
|
|
|
@ -0,0 +1,294 @@
|
||||||
|
<template>
|
||||||
|
<div class="app-container">
|
||||||
|
<el-card style="margin-top: 2px">
|
||||||
|
<el-tabs v-model="activeName" type="card">
|
||||||
|
<el-tab-pane label="成品不合格" name="1">
|
||||||
|
<el-table
|
||||||
|
:data="wproductList.results"
|
||||||
|
border
|
||||||
|
fit
|
||||||
|
stripe
|
||||||
|
highlight-current-row
|
||||||
|
max-height="600"
|
||||||
|
>
|
||||||
|
<el-table-column type="index" label="序号" width="50"/>
|
||||||
|
<el-table-column label="产品编号">
|
||||||
|
<template slot-scope="scope">{{ scope.row.number }}</template>
|
||||||
|
</el-table-column>
|
||||||
|
<el-table-column label="任务编号">
|
||||||
|
<template slot-scope="scope" v-if="scope.row.subproduction_plan_">{{ scope.row.subproduction_plan_.number }}
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
<el-table-column label="产品名称">
|
||||||
|
<template slot-scope="scope" v-if="scope.row.material_">{{ scope.row.material_.name }}</template>
|
||||||
|
</el-table-column>
|
||||||
|
<el-table-column label="型号规格">
|
||||||
|
<template slot-scope="scope" v-if="scope.row.material_">{{ scope.row.material_.specification }}</template>
|
||||||
|
</el-table-column>
|
||||||
|
<el-table-column label="军检状态">
|
||||||
|
<template slot-scope="scope">
|
||||||
|
<el-tag v-if="scope.row.is_mtested==false">未军检</el-tag>
|
||||||
|
<el-tag v-if="scope.row.is_mtested==true">已军检</el-tag>
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
<el-table-column label="军检结论">
|
||||||
|
<template slot-scope="scope">
|
||||||
|
<el-tag v-if="scope.row.is_mtestok==false">不合格</el-tag>
|
||||||
|
<el-tag v-if="scope.row.is_mtestok==true">合格</el-tag>
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
<el-table-column label="仓库">
|
||||||
|
<template slot-scope="scope" v-if="scope.row.warehouse_">{{ scope.row.warehouse_.name }}</template>
|
||||||
|
</el-table-column>
|
||||||
|
<el-table-column label="检查表">
|
||||||
|
<template slot-scope="scope">{{ scope.row.number }}</template>
|
||||||
|
</el-table-column>
|
||||||
|
<el-table-column label="检查状态">
|
||||||
|
<template slot-scope="scope">{{ actstate_[scope.row.act_state]}}</template>
|
||||||
|
</el-table-column>
|
||||||
|
<el-table-column align="center" label="操作" width="220px">
|
||||||
|
<template slot-scope="scope">
|
||||||
|
<el-link
|
||||||
|
v-if="checkPermission(['warehouse_update'])&&scope.row.act_state==30&&scope.row.is_mtested==false"
|
||||||
|
@click="handleMtest(scope)"
|
||||||
|
>军检
|
||||||
|
</el-link>
|
||||||
|
<el-link
|
||||||
|
@click="checkRecord(scope)"
|
||||||
|
>检验记录
|
||||||
|
</el-link>
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
</el-table>
|
||||||
|
<pagination
|
||||||
|
v-show="wproductList.count > 0"
|
||||||
|
:total="wproductList.count"
|
||||||
|
:page.sync="listQuery.page"
|
||||||
|
:limit.sync="listQuery.page_size"
|
||||||
|
@pagination="getList"
|
||||||
|
/>
|
||||||
|
</el-tab-pane>
|
||||||
|
<el-tab-pane label="过程不合格品" name="2">
|
||||||
|
<el-table
|
||||||
|
:data="wproductticket.results"
|
||||||
|
border
|
||||||
|
fit
|
||||||
|
stripe
|
||||||
|
highlight-current-row
|
||||||
|
height="620"
|
||||||
|
v-el-height-adaptive-table="{ bottomOffset: 40 }"
|
||||||
|
>
|
||||||
|
<el-table-column type="index" width="50" />
|
||||||
|
<el-table-column label="玻璃编号">
|
||||||
|
<template slot-scope="scope">{{ scope.row.number }}</template>
|
||||||
|
</el-table-column>
|
||||||
|
<el-table-column label="订单编号">
|
||||||
|
<template slot-scope="scope" v-if="scope.row.order_">{{
|
||||||
|
scope.row.order_.number
|
||||||
|
}}</template>
|
||||||
|
</el-table-column>
|
||||||
|
<el-table-column label="产品名称">
|
||||||
|
<template slot-scope="scope" v-if="scope.row.product_">{{
|
||||||
|
scope.row.product_.name
|
||||||
|
}}</template>
|
||||||
|
</el-table-column>
|
||||||
|
<el-table-column label="规格型号">
|
||||||
|
<template slot-scope="scope" v-if="scope.row.product_">{{
|
||||||
|
scope.row.product_.specification
|
||||||
|
}}</template>
|
||||||
|
</el-table-column>
|
||||||
|
<el-table-column label="责任工序">
|
||||||
|
<template slot-scope="scope" v-if="scope.row.resp_process_">{{
|
||||||
|
scope.row.resp_process_.name
|
||||||
|
}}</template>
|
||||||
|
</el-table-column>
|
||||||
|
<el-table-column label="处理结果">
|
||||||
|
<template slot-scope="scope">{{
|
||||||
|
decision_[scope.row.decision]
|
||||||
|
}}</template>
|
||||||
|
</el-table-column>
|
||||||
|
<el-table-column label="创建时间">
|
||||||
|
<template slot-scope="scope">{{
|
||||||
|
scope.row.create_time
|
||||||
|
}}</template>
|
||||||
|
</el-table-column>
|
||||||
|
<el-table-column label="操作">
|
||||||
|
<template slot-scope="scope">
|
||||||
|
<el-link
|
||||||
|
v-if="checkPermission(['material_update'])"
|
||||||
|
type="primary"
|
||||||
|
@click="handledetailbhg(scope)"
|
||||||
|
>查看</el-link
|
||||||
|
>
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
</el-table>
|
||||||
|
<pagination
|
||||||
|
v-show="wproductticket.count > 0"
|
||||||
|
:total="wproductticket.count"
|
||||||
|
:page.sync="listQuery2.page"
|
||||||
|
:limit.sync="listQuery2.page_size"
|
||||||
|
@pagination="getList2"
|
||||||
|
/>
|
||||||
|
|
||||||
|
</el-tab-pane>
|
||||||
|
<el-tab-pane label="入场不合格" name="4">
|
||||||
|
<el-table
|
||||||
|
v-loading="listLoading"
|
||||||
|
:data="fifodetailList4.results"
|
||||||
|
border
|
||||||
|
fit
|
||||||
|
stripe
|
||||||
|
highlight-current-row
|
||||||
|
height="620"
|
||||||
|
v-el-height-adaptive-table="{bottomOffset: 40}"
|
||||||
|
>
|
||||||
|
<el-table-column type="index" width="50" />
|
||||||
|
<el-table-column label="物料批次">
|
||||||
|
<template slot-scope="scope">{{ scope.row.batch }}</template>
|
||||||
|
</el-table-column>
|
||||||
|
<el-table-column label="物料名称">
|
||||||
|
<template slot-scope="scope">{{ scope.row.material_.name }}</template>
|
||||||
|
</el-table-column>
|
||||||
|
<el-table-column label="规格型号">
|
||||||
|
<template slot-scope="scope">{{
|
||||||
|
scope.row.material_.specification
|
||||||
|
}}</template>
|
||||||
|
</el-table-column>
|
||||||
|
<el-table-column label="物料单位">
|
||||||
|
<template slot-scope="scope">{{ scope.row.material_.unit }}</template>
|
||||||
|
</el-table-column>
|
||||||
|
|
||||||
|
<el-table-column label="创建时间">
|
||||||
|
<template slot-scope="scope">{{ scope.row.create_time }}</template>
|
||||||
|
</el-table-column>
|
||||||
|
|
||||||
|
</el-table>
|
||||||
|
<pagination
|
||||||
|
v-show="fifodetailList4.count > 0"
|
||||||
|
:total="fifodetailList4.count"
|
||||||
|
:page.sync="listQuery4.page"
|
||||||
|
:limit.sync="listQuery4.page_size"
|
||||||
|
@pagination="getList4"
|
||||||
|
/>
|
||||||
|
</el-tab-pane>
|
||||||
|
</el-tabs>
|
||||||
|
</el-card>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
<script>
|
||||||
|
import { getProductionplanList } from "@/api/pm";
|
||||||
|
import { getwproductticketList,getwproductList } from "@/api/wpm";
|
||||||
|
import { ticketread } from "@/api/workflow";
|
||||||
|
import { getfifodetailList} from "@/api/inm";
|
||||||
|
import checkPermission from "@/utils/permission";
|
||||||
|
import Pagination from "@/components/Pagination"; // secondary package based on el-pagination
|
||||||
|
|
||||||
|
export default {
|
||||||
|
components: { Pagination },
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
wproductList: {
|
||||||
|
count: 0,
|
||||||
|
},
|
||||||
|
actstate_: {
|
||||||
|
6: "待复检",
|
||||||
|
10: "操作进行中",
|
||||||
|
20: "待检验",
|
||||||
|
30: "已合格",
|
||||||
|
40: "库存中",
|
||||||
|
50: "不合格",
|
||||||
|
60: "待成品检验",
|
||||||
|
8: "操作准备中",
|
||||||
|
26: "待夹层检验",
|
||||||
|
70: "报废",
|
||||||
|
},
|
||||||
|
listQuery: {
|
||||||
|
page: 1,
|
||||||
|
page_size: 20,
|
||||||
|
},
|
||||||
|
wproductticket: {
|
||||||
|
count: 0,
|
||||||
|
},
|
||||||
|
|
||||||
|
listQuery2: {
|
||||||
|
page: 1,
|
||||||
|
page_size: 20,
|
||||||
|
},
|
||||||
|
customfieldList: [],
|
||||||
|
activeName: "1",
|
||||||
|
decision_: {
|
||||||
|
10: "返工",
|
||||||
|
20: "返修",
|
||||||
|
30: "报废",
|
||||||
|
40: "让步接受",
|
||||||
|
50: "偏离许可",
|
||||||
|
60: "降级使用",
|
||||||
|
70: "退回供方",
|
||||||
|
80: "召回",
|
||||||
|
},
|
||||||
|
listQuery4: {
|
||||||
|
page: 1,
|
||||||
|
page_size: 20,
|
||||||
|
},
|
||||||
|
fifodetailList4:{
|
||||||
|
count: 0,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
},
|
||||||
|
computed: {},
|
||||||
|
watch: {},
|
||||||
|
created() {
|
||||||
|
this.getList(); //成品不合格
|
||||||
|
this.getList2(); //过程
|
||||||
|
this.getList4();//入场不合格
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
checkPermission,
|
||||||
|
//不合格成品
|
||||||
|
|
||||||
|
getList() {
|
||||||
|
this.listLoading = true;
|
||||||
|
|
||||||
|
|
||||||
|
this.listQuery.material__type = 1;
|
||||||
|
this.listQuery.tag='ok';
|
||||||
|
getwproductList(this.listQuery).then((response) => {
|
||||||
|
if (response.data) {
|
||||||
|
this.wproductList = response.data;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
},
|
||||||
|
|
||||||
|
//不合格玻璃审批工单列表
|
||||||
|
getList2() {
|
||||||
|
getwproductticketList(this.listQuery2).then((response) => {
|
||||||
|
if (response.data) {
|
||||||
|
this.wproductticket = response.data;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
},
|
||||||
|
//不合格玻璃审理单查看
|
||||||
|
handledetailbhg(scope)
|
||||||
|
{
|
||||||
|
|
||||||
|
this.$router.push({name:"ticketDetail",params:{ticketId:scope.row.ticket}})
|
||||||
|
},
|
||||||
|
//入场检验不合格
|
||||||
|
//不合格物料
|
||||||
|
getList4() {
|
||||||
|
this.listLoading = true;
|
||||||
|
this.listQuery4.fifo__type = 3;
|
||||||
|
this.listQuery4.is_testok = false;
|
||||||
|
this.listQuery4.is_tested = true;
|
||||||
|
getfifodetailList(this.listQuery4).then((response) => {
|
||||||
|
if (response.data) {
|
||||||
|
this.fifodetailList4 = response.data;
|
||||||
|
}
|
||||||
|
this.listLoading = false;
|
||||||
|
});
|
||||||
|
},
|
||||||
|
},
|
||||||
|
};
|
||||||
|
</script>
|
|
@ -206,8 +206,8 @@ export default {
|
||||||
dialogVisible: false,
|
dialogVisible: false,
|
||||||
dialogType: "new",
|
dialogType: "new",
|
||||||
rule1: {
|
rule1: {
|
||||||
number: [{ required: true, message: "请输入", trigger: "blur" }],
|
|
||||||
customer: [{ required: true, message: "请输入", trigger: "blur" }],
|
|
||||||
product: [{ required: true, message: "请输入", trigger: "blur" }],
|
product: [{ required: true, message: "请输入", trigger: "blur" }],
|
||||||
delivery_date: [{ required: true, message: "请输入", trigger: "blur" }],
|
delivery_date: [{ required: true, message: "请输入", trigger: "blur" }],
|
||||||
},
|
},
|
||||||
|
|
|
@ -262,7 +262,7 @@ export default {
|
||||||
if (response.data) {
|
if (response.data) {
|
||||||
this.sale.customer = response.data.customer;
|
this.sale.customer = response.data.customer;
|
||||||
this.sale.product = response.data.product;
|
this.sale.product = response.data.product;
|
||||||
getiproductList({page:0,material__type:1,material:this.sale.product}).then((response) => {
|
getiproductList({page:0,to_order:response.data.id}).then((response) => {
|
||||||
if (response.data) {
|
if (response.data) {
|
||||||
this.iproductoptions=response.data;
|
this.iproductoptions=response.data;
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,8 +3,10 @@
|
||||||
<el-card>
|
<el-card>
|
||||||
<div slot="header" class="clearfix">
|
<div slot="header" class="clearfix">
|
||||||
<span>基本信息</span>
|
<span>基本信息</span>
|
||||||
|
|
||||||
|
|
||||||
<el-button style="float: right; padding: 3px 0" @click="readbook()" type="text">查看作业指导书</el-button>
|
|
||||||
|
<el-button style="float: right; padding: 3px 0" @click="getWordText()" type="text">查看作业指导书</el-button>
|
||||||
</div>
|
</div>
|
||||||
<el-form
|
<el-form
|
||||||
ref="form"
|
ref="form"
|
||||||
|
@ -57,18 +59,13 @@
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
</el-form>
|
</el-form>
|
||||||
<el-drawer
|
<el-drawer
|
||||||
title="作业指导书点击下载查看!"
|
title="作业指导书查看!"
|
||||||
:visible.sync="drawer"
|
:visible.sync="drawer"
|
||||||
direction="rtl"
|
direction="rtl"
|
||||||
size="10%">
|
size="70%">
|
||||||
<el-table :data="techdocList">
|
<div class="word-wrap">
|
||||||
<el-table-column label="表名称" width="150">
|
<div id="wordView" v-html="wordText" />
|
||||||
|
</div>
|
||||||
<template slot-scope="scope">
|
|
||||||
<el-link type="primary" :href="scope.row.file_.file" target="_blank">{{ scope.row.file_.name }}</el-link>
|
|
||||||
</template>
|
|
||||||
</el-table-column>
|
|
||||||
</el-table>
|
|
||||||
</el-drawer>
|
</el-drawer>
|
||||||
</el-card>
|
</el-card>
|
||||||
<el-row gutter="2">
|
<el-row gutter="2">
|
||||||
|
@ -602,7 +599,7 @@ import {
|
||||||
createOutputs,
|
createOutputs,
|
||||||
deleteOperationeinput
|
deleteOperationeinput
|
||||||
} from "@/api/wpm";
|
} from "@/api/wpm";
|
||||||
|
import mammoth from "mammoth";
|
||||||
import { getrffieldList,gettechdocList } from "@/api/mtm";
|
import { getrffieldList,gettechdocList } from "@/api/mtm";
|
||||||
import checkPermission from "@/utils/permission";
|
import checkPermission from "@/utils/permission";
|
||||||
import { getprogressList } from "@/api/pm";
|
import { getprogressList } from "@/api/pm";
|
||||||
|
@ -731,13 +728,15 @@ export default {
|
||||||
outputData: [],
|
outputData: [],
|
||||||
tprogressData: [],
|
tprogressData: [],
|
||||||
tool:"",
|
tool:"",
|
||||||
|
wordText: "",
|
||||||
|
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
computed: {},
|
computed: {},
|
||||||
watch: {},
|
watch: {},
|
||||||
created() {
|
created() {
|
||||||
this.id = this.$route.params.id; //操作ID
|
this.id = this.$route.params.id; //操作ID
|
||||||
|
this.readbook();
|
||||||
this.getList(); //边角料
|
this.getList(); //边角料
|
||||||
this.getpwpList(); //半成品
|
this.getpwpList(); //半成品
|
||||||
this.getequList(); //设备
|
this.getequList(); //设备
|
||||||
|
@ -752,11 +751,35 @@ export default {
|
||||||
checkPermission,
|
checkPermission,
|
||||||
|
|
||||||
//作业指导书
|
//作业指导书
|
||||||
|
|
||||||
|
getWordText() {
|
||||||
|
this.drawer=true;
|
||||||
|
const xhr = new XMLHttpRequest();
|
||||||
|
|
||||||
|
xhr.open("get", this.techdocList, true);
|
||||||
|
|
||||||
|
xhr.responseType = "arraybuffer";
|
||||||
|
|
||||||
|
xhr.onload = () => {
|
||||||
|
if (xhr.status == 200) {
|
||||||
|
|
||||||
|
mammoth.convertToHtml({ arrayBuffer: new Uint8Array(xhr.response) }).then((resultObject) => {
|
||||||
|
this.$nextTick(() => {
|
||||||
|
|
||||||
|
this.wordText = resultObject.value;
|
||||||
|
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
};
|
||||||
|
xhr.send();
|
||||||
|
},
|
||||||
readbook(){
|
readbook(){
|
||||||
this.drawer=true;
|
|
||||||
gettechdocList({operation:this.id,page:0}).then((response) => {
|
gettechdocList({operation:this.id,page:0}).then((response) => {
|
||||||
if (response.data) {
|
if (response.data) {
|
||||||
this.techdocList= response.data;
|
this.techdocList= response.data[0].file_.file;
|
||||||
|
console.log( this.techdocList);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,9 @@
|
||||||
|
from django_filters import rest_framework as filters
|
||||||
|
from apps.hrm.models import ClockRecord
|
||||||
|
|
||||||
|
class ClockRecordFilterSet(filters.FilterSet):
|
||||||
|
create_time_start = filters.DateFilter(field_name="create_time", lookup_expr='gte')
|
||||||
|
create_time_end = filters.DateFilter(field_name="create_time", lookup_expr='lte')
|
||||||
|
class Meta:
|
||||||
|
model = ClockRecord
|
||||||
|
fields = ['create_by', 'create_time_start', 'create_time_end']
|
|
@ -0,0 +1,32 @@
|
||||||
|
# Generated by Django 3.2.9 on 2022-01-21 06:45
|
||||||
|
|
||||||
|
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),
|
||||||
|
('hrm', '0003_employee_face_data'),
|
||||||
|
]
|
||||||
|
|
||||||
|
operations = [
|
||||||
|
migrations.CreateModel(
|
||||||
|
name='ClockRecord',
|
||||||
|
fields=[
|
||||||
|
('id', models.BigAutoField(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='删除标记')),
|
||||||
|
('type', models.PositiveSmallIntegerField(choices=[(10, '上班打卡')], default=10, verbose_name='打卡类型')),
|
||||||
|
('create_by', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='clockrecord_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='clockrecord_update_by', to=settings.AUTH_USER_MODEL, verbose_name='最后编辑人')),
|
||||||
|
],
|
||||||
|
options={
|
||||||
|
'abstract': False,
|
||||||
|
},
|
||||||
|
),
|
||||||
|
]
|
|
@ -36,8 +36,12 @@ class Employee(CommonAModel):
|
||||||
def __str__(self):
|
def __str__(self):
|
||||||
return self.name
|
return self.name
|
||||||
|
|
||||||
# class Attendance(CommonADModel):
|
class ClockRecord(CommonADModel):
|
||||||
# """
|
"""
|
||||||
# 出勤记录
|
打卡记录
|
||||||
# """
|
"""
|
||||||
|
ClOCK_WORK1 = 10
|
||||||
|
type_choice = (
|
||||||
|
(ClOCK_WORK1, '上班打卡'),
|
||||||
|
)
|
||||||
|
type = models.PositiveSmallIntegerField('打卡类型', choices=type_choice, default=ClOCK_WORK1)
|
|
@ -1,25 +1,24 @@
|
||||||
from apps.system.models import User
|
from apps.system.models import User
|
||||||
from rest_framework.serializers import ModelSerializer
|
from rest_framework.serializers import ModelSerializer
|
||||||
from rest_framework import serializers
|
from rest_framework import serializers
|
||||||
from .models import Employee
|
from .models import ClockRecord, Employee
|
||||||
from apps.system.serializers import UserListSerializer, UserSimpleSerializer
|
from apps.system.serializers import UserListSerializer, UserSimpleSerializer
|
||||||
from django.db.models.query import Prefetch
|
from django.db.models.query import Prefetch
|
||||||
|
|
||||||
class EmployeeSerializer(ModelSerializer):
|
class EmployeeSerializer(ModelSerializer):
|
||||||
# user_ = UserListSerializer(source='user', read_only=True)
|
|
||||||
class Meta:
|
class Meta:
|
||||||
model = Employee
|
model = Employee
|
||||||
fields = '__all__'
|
exclude = ['face_data']
|
||||||
# @staticmethod
|
|
||||||
# def setup_eager_loading(queryset):
|
|
||||||
# """ Perform necessary eager loading of data. """
|
|
||||||
# queryset = queryset.select_related('user', 'user__dept')
|
|
||||||
# # queryset = queryset.prefetch_related('user','user__dept')
|
|
||||||
# queryset = queryset.prefetch_related(
|
|
||||||
# Prefetch('user_',
|
|
||||||
# queryset=User.objects.filter(employee_user__isnull=True))
|
|
||||||
# )
|
|
||||||
# return queryset
|
|
||||||
|
|
||||||
class FaceLoginSerializer(serializers.Serializer):
|
class FaceLoginSerializer(serializers.Serializer):
|
||||||
base64 = serializers.CharField()
|
base64 = serializers.CharField()
|
||||||
|
|
||||||
|
|
||||||
|
class FaceClockCreateSerializer(serializers.Serializer):
|
||||||
|
base64 = serializers.CharField()
|
||||||
|
|
||||||
|
class ClockRecordListSerializer(serializers.ModelSerializer):
|
||||||
|
create_by_ = UserSimpleSerializer(source='create_by', read_only=True)
|
||||||
|
class Meta:
|
||||||
|
model = ClockRecord
|
||||||
|
fields = '__all__'
|
||||||
|
|
|
@ -0,0 +1,48 @@
|
||||||
|
from django.conf import settings
|
||||||
|
import uuid
|
||||||
|
import face_recognition
|
||||||
|
import os
|
||||||
|
from apps.hrm.models import Employee
|
||||||
|
from apps.hrm.tasks import update_all_user_facedata_cache
|
||||||
|
from apps.system.models import User
|
||||||
|
from django.core.cache import cache
|
||||||
|
|
||||||
|
class HRMService:
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def face_compare_from_base64(cls, base64_data):
|
||||||
|
filename = str(uuid.uuid4())
|
||||||
|
filepath = settings.BASE_DIR +'/temp/' + filename +'.png'
|
||||||
|
with open(filepath, 'wb') as f:
|
||||||
|
f.write(base64_data)
|
||||||
|
try:
|
||||||
|
unknown_picture = face_recognition.load_image_file(filepath)
|
||||||
|
unknown_face_encoding = face_recognition.face_encodings(unknown_picture)[0]
|
||||||
|
os.remove(filepath)
|
||||||
|
except:
|
||||||
|
os.remove(filepath)
|
||||||
|
return None, '头像解码失败'
|
||||||
|
|
||||||
|
# 匹配人脸库
|
||||||
|
face_datas = cache.get('face_datas')
|
||||||
|
face_users = cache.get('face_users')
|
||||||
|
if face_datas is None:
|
||||||
|
update_all_user_facedata_cache()
|
||||||
|
|
||||||
|
results = face_recognition.compare_faces(face_datas, unknown_face_encoding, tolerance=0.5)
|
||||||
|
for index, value in enumerate(results):
|
||||||
|
if value:
|
||||||
|
# 识别成功
|
||||||
|
user = User.objects.get(id=face_users[index])
|
||||||
|
return user, ''
|
||||||
|
return None, '识别失败'
|
||||||
|
|
||||||
|
def get_facedata_from_img(cls, img_rpath):
|
||||||
|
try:
|
||||||
|
photo_path = settings.BASE_DIR + img_rpath
|
||||||
|
picture_of_me = face_recognition.load_image_file(photo_path)
|
||||||
|
my_face_encoding = face_recognition.face_encodings(picture_of_me)[0]
|
||||||
|
face_data_list = my_face_encoding.tolist()
|
||||||
|
return face_data_list
|
||||||
|
except:
|
||||||
|
return None
|
|
@ -2,8 +2,12 @@ from django.db.models.signals import post_save
|
||||||
from apps.system.models import User
|
from apps.system.models import User
|
||||||
from django.dispatch import receiver
|
from django.dispatch import receiver
|
||||||
from apps.hrm.models import Employee
|
from apps.hrm.models import Employee
|
||||||
|
from django.conf import settings
|
||||||
|
import face_recognition
|
||||||
|
import logging
|
||||||
|
logger = logging.getLogger('log')
|
||||||
|
|
||||||
@receiver(post_save, sender=User)
|
@receiver(post_save, sender=User)
|
||||||
def createEmployee(sender, instance, created, **kwargs):
|
def createEmployee(sender, instance, created, **kwargs):
|
||||||
if created:
|
if created:
|
||||||
Employee.objects.get_or_create(user=instance)
|
Employee.objects.get_or_create(user=instance)
|
||||||
|
|
|
@ -0,0 +1,31 @@
|
||||||
|
from __future__ import absolute_import, unicode_literals
|
||||||
|
|
||||||
|
from celery import shared_task
|
||||||
|
from apps.hrm.models import Employee
|
||||||
|
from apps.system.models import User
|
||||||
|
from django.core.cache import cache
|
||||||
|
|
||||||
|
|
||||||
|
@shared_task
|
||||||
|
def update_all_user_not_atwork():
|
||||||
|
"""
|
||||||
|
将所有员工设为非在岗状态
|
||||||
|
"""
|
||||||
|
User.objects.all().update(is_atwork=False)
|
||||||
|
|
||||||
|
@shared_task
|
||||||
|
def update_all_user_facedata_cache():
|
||||||
|
"""
|
||||||
|
更新人脸数据缓存
|
||||||
|
"""
|
||||||
|
facedata_queyset = Employee.objects.filter(face_data__isnull=False,
|
||||||
|
user__is_active=True).values('user', 'face_data')
|
||||||
|
face_users = []
|
||||||
|
face_datas = []
|
||||||
|
for i in facedata_queyset:
|
||||||
|
face_users.append(i['user'])
|
||||||
|
face_datas.append(i['face_data'])
|
||||||
|
cache.set('face_users', face_users, timeout=None)
|
||||||
|
cache.set('face_datas', face_datas, timeout=None)
|
||||||
|
|
||||||
|
|
|
@ -1,11 +1,12 @@
|
||||||
from django.db.models import base
|
from django.db.models import base
|
||||||
from rest_framework import urlpatterns
|
from rest_framework import urlpatterns
|
||||||
from apps.hrm.views import EmployeeViewSet, FaceLogin
|
from apps.hrm.views import ClockRecordViewSet, EmployeeViewSet, FaceLogin
|
||||||
from django.urls import path, include
|
from django.urls import path, include
|
||||||
from rest_framework.routers import DefaultRouter
|
from rest_framework.routers import DefaultRouter
|
||||||
|
|
||||||
router = DefaultRouter()
|
router = DefaultRouter()
|
||||||
router.register('employee', EmployeeViewSet, basename='employee')
|
router.register('employee', EmployeeViewSet, basename='employee')
|
||||||
|
router.register('clock_record', ClockRecordViewSet, basename='clock_record')
|
||||||
urlpatterns = [
|
urlpatterns = [
|
||||||
path('facelogin/', FaceLogin.as_view()),
|
path('facelogin/', FaceLogin.as_view()),
|
||||||
path('', include(router.urls)),
|
path('', include(router.urls)),
|
||||||
|
|
|
@ -1,33 +1,27 @@
|
||||||
|
from functools import update_wrapper
|
||||||
from django.shortcuts import render
|
from django.shortcuts import render
|
||||||
|
from django.utils import timezone
|
||||||
from rest_framework.response import Response
|
from rest_framework.response import Response
|
||||||
from rest_framework.viewsets import ModelViewSet, GenericViewSet
|
from rest_framework.viewsets import ModelViewSet, GenericViewSet
|
||||||
from rest_framework.mixins import UpdateModelMixin, RetrieveModelMixin
|
from rest_framework.mixins import UpdateModelMixin, RetrieveModelMixin, CreateModelMixin, ListModelMixin
|
||||||
|
from apps.hrm.filters import ClockRecordFilterSet
|
||||||
|
from apps.hrm.services import HRMService
|
||||||
|
from apps.hrm.tasks import update_all_user_facedata_cache
|
||||||
from apps.system.mixins import CreateUpdateModelAMixin, OptimizationMixin
|
from apps.system.mixins import CreateUpdateModelAMixin, OptimizationMixin
|
||||||
from apps.hrm.models import Employee
|
from apps.hrm.models import ClockRecord, Employee
|
||||||
from apps.hrm.serializers import EmployeeSerializer, FaceLoginSerializer
|
from apps.hrm.serializers import ClockRecordListSerializer, EmployeeSerializer, FaceClockCreateSerializer, FaceLoginSerializer
|
||||||
import face_recognition
|
|
||||||
from django.conf import settings
|
|
||||||
from django.core.cache import cache
|
|
||||||
import logging
|
|
||||||
from rest_framework.generics import CreateAPIView
|
from rest_framework.generics import CreateAPIView
|
||||||
from rest_framework import status
|
from rest_framework import status
|
||||||
from rest_framework_simplejwt.tokens import RefreshToken
|
from rest_framework_simplejwt.tokens import RefreshToken
|
||||||
|
from rest_framework import exceptions
|
||||||
from apps.system.models import User
|
from apps.system.models import User
|
||||||
logger = logging.getLogger('log')
|
from apps.system.serializers import UserSimpleSerializer
|
||||||
|
from rest_framework.permissions import AllowAny
|
||||||
|
|
||||||
|
|
||||||
def load_face_data(username:int, path:str):
|
|
||||||
"""
|
|
||||||
将某用户face_encoding加载进缓存
|
|
||||||
"""
|
|
||||||
face_datas = cache.get_or_set('face_datas', {}, timeout=None)
|
|
||||||
photo_path = settings.BASE_DIR + path
|
|
||||||
picture_of_me = face_recognition.load_image_file(photo_path)
|
|
||||||
my_face_encoding = face_recognition.face_encodings(picture_of_me)[0]
|
|
||||||
face_datas[username] = my_face_encoding
|
|
||||||
cache.set('face_datas', face_datas, timeout=None)
|
|
||||||
return my_face_encoding
|
|
||||||
|
|
||||||
# Create your views here.
|
# Create your views here.
|
||||||
class EmployeeViewSet(CreateUpdateModelAMixin, OptimizationMixin, UpdateModelMixin, RetrieveModelMixin, GenericViewSet):
|
class EmployeeViewSet(CreateUpdateModelAMixin, OptimizationMixin, UpdateModelMixin, RetrieveModelMixin, GenericViewSet):
|
||||||
|
@ -39,20 +33,74 @@ class EmployeeViewSet(CreateUpdateModelAMixin, OptimizationMixin, UpdateModelMix
|
||||||
serializer_class = EmployeeSerializer
|
serializer_class = EmployeeSerializer
|
||||||
ordering = ['-pk']
|
ordering = ['-pk']
|
||||||
|
|
||||||
def perform_update(self, serializer):
|
def update(self, request, *args, **kwargs):
|
||||||
instance = serializer.save(update_by = self.request.user)
|
partial = kwargs.pop('partial', False)
|
||||||
try:
|
instance = self.get_object()
|
||||||
photo_path = settings.BASE_DIR + instance.photo
|
data = request.data
|
||||||
picture_of_me = face_recognition.load_image_file(photo_path)
|
serializer = self.get_serializer(instance, data=data, partial=partial)
|
||||||
my_face_encoding = face_recognition.face_encodings(picture_of_me)[0]
|
serializer.is_valid(raise_exception=True)
|
||||||
instance.face_data = my_face_encoding.tolist()
|
photo = data.get('photo', None)
|
||||||
instance.save()
|
if instance.photo != photo:
|
||||||
except:
|
f_l = HRMService.get_facedata_from_img(photo)
|
||||||
logger.error('人脸识别出错')
|
if f_l:
|
||||||
|
serializer.save(update_by=request.user, face_data = f_l)
|
||||||
|
# 更新人脸缓存
|
||||||
|
update_all_user_facedata_cache.delay()
|
||||||
|
return Response()
|
||||||
|
return Response('头像识别失败', status=status.HTTP_400_BAD_REQUEST)
|
||||||
|
serializer.save(update_by=request.user)
|
||||||
|
return Response()
|
||||||
|
|
||||||
|
|
||||||
|
class ClockRecordViewSet(CreateModelMixin, ListModelMixin, GenericViewSet):
|
||||||
|
"""
|
||||||
|
打卡记录
|
||||||
|
"""
|
||||||
|
perms_map = {'get':'*', 'post':'*'}
|
||||||
|
authentication_classes = []
|
||||||
|
permission_classes = [AllowAny]
|
||||||
|
queryset = ClockRecord.objects.select_related('create_by').all()
|
||||||
|
serializer_class = ClockRecordListSerializer
|
||||||
|
filterset_class = ClockRecordFilterSet
|
||||||
|
ordering = ['-pk']
|
||||||
|
|
||||||
|
def get_serializer_class(self):
|
||||||
|
if self.action == 'create':
|
||||||
|
return FaceClockCreateSerializer
|
||||||
|
return super().get_serializer_class()
|
||||||
|
|
||||||
|
def create(self, request, *args, **kwargs):
|
||||||
|
now = timezone.now()
|
||||||
|
now_local = timezone.localtime()
|
||||||
|
if 8<=now_local.hour<=17:
|
||||||
|
base64_data = base64.urlsafe_b64decode(tran64(
|
||||||
|
request.data.get('base64').replace(' ', '+')))
|
||||||
|
user, msg = HRMService.face_compare_from_base64(base64_data)
|
||||||
|
if user:
|
||||||
|
ins, created = ClockRecord.objects.get_or_create(
|
||||||
|
create_by=request.user, create_time__hour__range = [8,18],
|
||||||
|
create_time__year=now.year, create_time__month=now.month,
|
||||||
|
create_time__day=now.day,
|
||||||
|
defaults={
|
||||||
|
'type':ClockRecord.ClOCK_WORK1,
|
||||||
|
'create_by':user,
|
||||||
|
'create_time':now
|
||||||
|
})
|
||||||
|
if not created:
|
||||||
|
ins.create_time = now
|
||||||
|
ins.save()
|
||||||
|
# 设为在岗
|
||||||
|
user.is_atwork = True
|
||||||
|
user.save()
|
||||||
|
return Response(UserSimpleSerializer(instance=user).data)
|
||||||
|
return Response(msg, status=status.HTTP_400_BAD_REQUEST)
|
||||||
|
return Response('非打卡时间范围', status=status.HTTP_400_BAD_REQUEST)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
import uuid
|
|
||||||
import base64
|
import base64
|
||||||
import os
|
|
||||||
|
|
||||||
def tran64(s):
|
def tran64(s):
|
||||||
missing_padding = len(s) % 4
|
missing_padding = len(s) % 4
|
||||||
|
@ -70,41 +118,13 @@ class FaceLogin(CreateAPIView):
|
||||||
"""
|
"""
|
||||||
人脸识别登录
|
人脸识别登录
|
||||||
"""
|
"""
|
||||||
# serializer = FaceLoginSerializer(data=request.data)
|
base64_data = base64.urlsafe_b64decode(tran64(request.data.get('base64').replace(' ', '+')))
|
||||||
# serializer.is_valid(raise_exception=True)
|
user, msg = HRMService.face_compare_from_base64(base64_data)
|
||||||
filename = str(uuid.uuid4())
|
if user:
|
||||||
filepath = settings.BASE_DIR +'/temp/' + filename +'.png'
|
refresh = RefreshToken.for_user(user)
|
||||||
with open(filepath, 'wb') as f:
|
return Response({
|
||||||
data = tran64(request.data.get('base64').replace(' ', '+'))
|
'refresh': str(refresh),
|
||||||
f.write(base64.urlsafe_b64decode(data))
|
'access': str(refresh.access_token),
|
||||||
# picture_of_me = face_recognition.load_image_file(settings.BASE_DIR +'/temp/me.png')
|
'username':user.username
|
||||||
# my_face_encoding = face_recognition.face_encodings(picture_of_me)[0]
|
})
|
||||||
#results = face_recognition.compare_faces([my_face_encoding], unknown_face_encoding, tolerance=0.2)
|
return Response(msg, status=status.HTTP_400_BAD_REQUEST)
|
||||||
try:
|
|
||||||
unknown_picture = face_recognition.load_image_file(filepath)
|
|
||||||
unknown_face_encoding = face_recognition.face_encodings(unknown_picture)[0]
|
|
||||||
os.remove(filepath)
|
|
||||||
except:
|
|
||||||
os.remove(filepath)
|
|
||||||
return Response('头像解码失败', status=status.HTTP_400_BAD_REQUEST)
|
|
||||||
|
|
||||||
# 匹配人脸库
|
|
||||||
user_faces = Employee.objects.filter(face_data__isnull=False, user__is_active=True).values('user', 'face_data')
|
|
||||||
user_l = []
|
|
||||||
face_l = []
|
|
||||||
for i in user_faces:
|
|
||||||
user_l.append(i['user'])
|
|
||||||
face_l.append(i['face_data'])
|
|
||||||
|
|
||||||
results = face_recognition.compare_faces(face_l, unknown_face_encoding, tolerance=0.5)
|
|
||||||
for index, value in enumerate(results):
|
|
||||||
if value:
|
|
||||||
# 识别成功
|
|
||||||
user = User.objects.get(id=user_l[index])
|
|
||||||
refresh = RefreshToken.for_user(user)
|
|
||||||
return Response({
|
|
||||||
'refresh': str(refresh),
|
|
||||||
'access': str(refresh.access_token),
|
|
||||||
'username':user.username
|
|
||||||
})
|
|
||||||
return Response('未找到对应用户', status=status.HTTP_400_BAD_REQUEST)
|
|
|
@ -9,6 +9,7 @@ from apps.mtm.serializers import MaterialSimpleSerializer
|
||||||
from django.db import transaction
|
from django.db import transaction
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
class WareHouseSerializer(serializers.ModelSerializer):
|
class WareHouseSerializer(serializers.ModelSerializer):
|
||||||
create_by_ = UserSimpleSerializer('create_by', read_only=True)
|
create_by_ = UserSimpleSerializer('create_by', read_only=True)
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,18 @@
|
||||||
|
# Generated by Django 3.2.9 on 2022-01-21 05:41
|
||||||
|
|
||||||
|
from django.db import migrations, models
|
||||||
|
|
||||||
|
|
||||||
|
class Migration(migrations.Migration):
|
||||||
|
|
||||||
|
dependencies = [
|
||||||
|
('system', '0003_auto_20210812_0909'),
|
||||||
|
]
|
||||||
|
|
||||||
|
operations = [
|
||||||
|
migrations.AddField(
|
||||||
|
model_name='user',
|
||||||
|
name='is_atwork',
|
||||||
|
field=models.BooleanField(default=False, verbose_name='当前在岗'),
|
||||||
|
),
|
||||||
|
]
|
|
@ -116,6 +116,7 @@ class User(AbstractUser):
|
||||||
superior = models.ForeignKey(
|
superior = models.ForeignKey(
|
||||||
'self', null=True, blank=True, on_delete=models.SET_NULL, verbose_name='上级主管')
|
'self', null=True, blank=True, on_delete=models.SET_NULL, verbose_name='上级主管')
|
||||||
roles = models.ManyToManyField(Role, blank=True, verbose_name='角色')
|
roles = models.ManyToManyField(Role, blank=True, verbose_name='角色')
|
||||||
|
is_atwork = models.BooleanField('当前在岗', default=False)
|
||||||
|
|
||||||
class Meta:
|
class Meta:
|
||||||
verbose_name = '用户信息'
|
verbose_name = '用户信息'
|
||||||
|
|
|
@ -141,7 +141,9 @@ class UserListSerializer(serializers.ModelSerializer):
|
||||||
class Meta:
|
class Meta:
|
||||||
model = User
|
model = User
|
||||||
fields = ['id', 'name', 'phone', 'email', 'position',
|
fields = ['id', 'name', 'phone', 'email', 'position',
|
||||||
'username', 'is_active', 'date_joined', 'dept_name', 'dept', 'roles', 'avatar', 'roles_name']
|
'username', 'is_active', 'date_joined',
|
||||||
|
'dept_name', 'dept', 'roles', 'avatar',
|
||||||
|
'roles_name', 'is_atwork']
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def setup_eager_loading(queryset):
|
def setup_eager_loading(queryset):
|
||||||
|
|
|
@ -194,7 +194,7 @@ AUTHENTICATION_BACKENDS = (
|
||||||
# CACHES = {
|
# CACHES = {
|
||||||
# "default": {
|
# "default": {
|
||||||
# "BACKEND": "django_redis.cache.RedisCache",
|
# "BACKEND": "django_redis.cache.RedisCache",
|
||||||
# "LOCATION": "redis://redis:6379/1",
|
# "LOCATION": "redis://127.0.0.1:6379/0",
|
||||||
# "OPTIONS": {
|
# "OPTIONS": {
|
||||||
# "CLIENT_CLASS": "django_redis.client.DefaultClient",
|
# "CLIENT_CLASS": "django_redis.client.DefaultClient",
|
||||||
# "PICKLE_VERSION": -1
|
# "PICKLE_VERSION": -1
|
||||||
|
@ -203,7 +203,7 @@ AUTHENTICATION_BACKENDS = (
|
||||||
# }
|
# }
|
||||||
|
|
||||||
# celery配置,celery正常运行必须安装redis
|
# celery配置,celery正常运行必须安装redis
|
||||||
CELERY_BROKER_URL = "redis://redis:6379/0" # 任务存储
|
CELERY_BROKER_URL = "redis://127.0.0.1:6379/1" # 任务存储
|
||||||
CELERYD_MAX_TASKS_PER_CHILD = 100 # 每个worker最多执行300个任务就会被销毁,可防止内存泄露
|
CELERYD_MAX_TASKS_PER_CHILD = 100 # 每个worker最多执行300个任务就会被销毁,可防止内存泄露
|
||||||
CELERY_TIMEZONE = 'Asia/Shanghai' # 设置时区
|
CELERY_TIMEZONE = 'Asia/Shanghai' # 设置时区
|
||||||
CELERY_ENABLE_UTC = True # 启动时区设置
|
CELERY_ENABLE_UTC = True # 启动时区设置
|
||||||
|
|
Loading…
Reference in New Issue