Merge branch 'develop' of https://e.coding.net/ctcdevteam/hberp/hberp into develop

This commit is contained in:
shilixia 2022-02-17 14:34:04 +08:00
commit 3008f1e2ce
15 changed files with 155 additions and 138 deletions

View File

@ -66,4 +66,7 @@ export default {
#warningTabs .el-tabs__item{
padding: 0 10px!important;
}
#loginFaceWrap .el-dialog{
width: 780px!important;height: 720px!important;
}
</style>

View File

@ -1,11 +1,11 @@
<template>
<div style="width: 100%;height: 100%;">
<div style="width: 100%;height: 620px;">
<div>
<div class="video-box">
<video id="video" width="749" height="640" preload autoplay loop muted></video>
<canvas id="canvas" width="749" height="640"></canvas>
<video id="video" width="749" height="620" preload autoplay loop muted></video>
<canvas id="canvas" width="749" height="620"></canvas>
</div>
<canvas id="screenshotCanvas" width="749" height="640"></canvas>
<canvas id="screenshotCanvas" width="749" height="620"></canvas>
</div>
</div>
</template>

View File

@ -0,0 +1 @@
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg t="1644973249496" class="icon" viewBox="0 0 1061 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="3412" xmlns:xlink="http://www.w3.org/1999/xlink" width="33.15625" height="32"><defs><style type="text/css"></style></defs><path d="M939.425185 796.444444H122.500741C57.230222 796.444444 0 745.775407 0 687.824593V108.619852C0 50.669037 57.192296 0 122.500741 0h816.924444C1004.695704 0 1061.925926 50.669037 1061.925926 108.619852v579.204741C1061.925926 745.775407 1004.73363 796.444444 939.425185 796.444444z m-519.888592-137.102222c16.308148 0 40.808296-16.346074 40.808296-40.846222V373.418667c0-24.500148-16.308148-40.846222-40.808296-40.846223-24.538074 0-40.846222 16.346074-40.846223 40.846223v245.077333c0 24.500148 16.308148 40.846222 40.846223 40.846222z m179.693037 0c24.500148 0 40.846222-16.346074 40.846222-40.846222v-122.538667c0-24.500148-16.308148-40.846222-40.846222-40.846222-24.500148 0-40.846222 16.308148-40.846223 40.846222v122.500741c0 24.538074 16.308148 40.884148 40.846223 40.884148z m179.693037 0c24.538074 0 40.846222-16.346074 40.846222-40.846222V577.611852c0-24.500148-16.308148-40.846222-40.846222-40.846222-24.500148 0-40.808296 16.308148-40.808297 40.846222v40.846222c0 24.500148 16.308148 40.846222 40.808297 40.846222z m-539.117037 0c16.308148 0 40.846222-16.346074 40.846222-40.846222V250.88c0-24.500148-16.308148-40.846222-40.846222-40.846222-24.500148 0-40.846222 16.346074-40.846223 40.846222v367.616c0 24.500148 16.308148 40.846222 40.846223 40.846222zM265.481481 872.296296h530.962963a75.851852 75.851852 0 1 1 0 151.703704H265.481481a75.851852 75.851852 0 1 1 0-151.703704z" p-id="3413" fill="#ffffff"></path></svg>

After

Width:  |  Height:  |  Size: 1.8 KiB

View File

@ -55,7 +55,7 @@ export const constantRoutes = [
{
path: '/index',
component: () => import('@/views/bigScreen/index'),
meta: { title: '大屏', icon: 'home', affix: true,keepAlive: false }
meta: { title: '大屏', icon: 'bigScreen', affix: true,keepAlive: false }
},
{
path: '/changepassword',

View File

@ -7,11 +7,8 @@
<div style="padding: 20px;overflow: hidden;">
<div class="cardsWrap" @click="toDetail('1')">
<div class="svgIconWrap">
<svg-icon
class="svgIcon"
icon-class="contract"
:className="'svgIcon'"
/>
<el-icon class="el-icon-s-order svgIcon"></el-icon>
<!--<svg-icon class="svgIcon" icon-class="contract" :className="'svgIcon'"/>-->
</div>
<div class="totalCountWrap">
<span class="totalCountText">本月合同数</span>
@ -23,6 +20,7 @@
</div>
<div class="cardsWrap" @click="toDetail('2')">
<div class="svgIconWrap">
<el-icon class="el-icon-menu svgIcon"></el-icon>
<svg-icon
class="svgIcon"
icon-class="order"
@ -39,11 +37,8 @@
</div>
<div class="cardsWrap" @click="toDetail('3')">
<div class="svgIconWrap">
<svg-icon
class="svgIcon"
icon-class="productionTask"
:className="'svgIcon'"
/>
<el-icon class="el-icon-s-operation svgIcon"></el-icon>
<!--<svg-icon class="svgIcon" icon-class="productionTask" :className="'svgIcon'"/>-->
</div>
<div class="totalCountWrap">
<span class="totalCountText">本月在制任务</span>
@ -55,11 +50,8 @@
</div>
<div class="cardsWrap" @click="toDetail('4')">
<div class="svgIconWrap">
<svg-icon
icon-class="product"
class="svgIcon"
:className="'svgIcon'"
/>
<el-icon class="el-icon-s-claim svgIcon"></el-icon>
<!--<svg-icon icon-class="product" class="svgIcon" :className="'svgIcon'"/>-->
</div>
<div class="totalCountWrap">
<span class="totalCountText">本月交付产品</span>
@ -71,11 +63,8 @@
</div>
<div class="cardsWrap" @click="toDetail('5')">
<div class="svgIconWrap">
<svg-icon
icon-class="unqualified"
class="svgIcon"
:className="'svgIcon'"
/>
<el-icon class="el-icon-error svgIcon"></el-icon>
<!--<svg-icon icon-class="unqualified" class="svgIcon" :className="'svgIcon'"/>-->
</div>
<div class="totalCountWrap">
<span class="totalCountText">本月不合格产品</span>
@ -695,7 +684,8 @@
show: false//Y轴刻度线
},
axisLabel: {
color: '#333333'//Y轴文本颜色
color: '#333333',//Y轴文本颜色
fontSize: 10,//字体大小
},
splitLine: {
show: true, //Y轴分割线

View File

@ -64,8 +64,8 @@
</el-tabs>
</div>
</div>
<el-dialog :visible.sync="limitedPhoto" @close="closeCamera">
<div style="font-size: 28px;color: #333333;text-align: center;font-weight: bold;margin-bottom: 15px;">打卡</div>
<el-dialog :visible.sync="limitedPhoto" @close="closeCamera" id="loginFaceWrap">
<div style="font-size: 28px;color: #333333;text-align: center;font-weight: bold;">打卡</div>
<div class="testTracking">
<faceLogin ref="faceTracking" name="faceLogin" @func="getMsgFormSon"></faceLogin>
</div>
@ -309,6 +309,6 @@
}
.testTracking{
width:100%;
height: 700px;
height: 620px;
}
</style>

View File

@ -3,7 +3,7 @@
<el-card>
<el-row :gutter="2">
<!--表格-->
<el-col :span="6">
<el-col :span="10">
<el-card>
<div
slot="header"
@ -30,8 +30,12 @@
@current-change="handleCurrentChange"
>
<el-table-column type="index" width="50"/>
<el-table-column label="表名称">
<template slot-scope="scope">{{ scope.row.name }}</template>
<el-table-column label="表名称" prop="name">
</el-table-column>
<el-table-column label="表类型">
<template slot-scope="scope">
{{typeOptions_[scope.row.type]}}
</template>
</el-table-column>
<el-table-column label="是否启用">
<template slot-scope="scope">
@ -75,6 +79,36 @@
<el-form-item label="表格名称" prop="name">
<el-input v-model="recordform.name" placeholder="表格名称"/>
</el-form-item>
<!--<el-form-item label="引用表单" prop="field_type">
<el-select
style="width: 100%"
v-model="recordform.number"
placeholder="请选择"
>
<el-option
v-for="item in fieldtypeoptions"
:key="item.value"
:label="item.label"
:value="item.value"
>
</el-option>
</el-select>
</el-form-item>-->
<el-form-item label="表格类型" prop="formUsed">
<el-select
style="width: 100%"
v-model="recordform.type"
placeholder="请选择"
>
<el-option
v-for="item in typeOptions"
:key="item.value"
:label="item.label"
:value="item.value"
>
</el-option>
</el-select>
</el-form-item>
<el-form-item label="是否启用" prop="name">
<el-switch v-model="recordform.enabled"></el-switch>
</el-form-item>
@ -239,7 +273,7 @@
</el-card>
</el-col>
<!--表格字段-->
<el-col :span="18">
<el-col :span="14">
<el-card>
<div slot="header" class="clearfix">
<span style="font-size: 16px; font-weight: 300">记录字段</span>
@ -406,69 +440,6 @@
<el-form-item label="是否需要判定" prop="need_judge">
<el-switch v-model="field.need_judge"></el-switch>
</el-form-item>
<!--
<el-form-item
label="上限值"
v-if="field.need_judge == true"
prop="high_limit"
>
<el-input-number
v-model="field.high_limit"
:precision="2"
:min="0"
></el-input-number>
</el-form-item>
<el-form-item
label="上限规则"
v-if="field.need_judge == true"
prop="high_rule"
>
<el-select
style="width: 100%"
v-model="field.high_rule"
placeholder="请选择"
>
<el-option
v-for="item in highoptions"
:key="item.value"
:label="item.label"
:value="item.value"
>
</el-option>
</el-select>
</el-form-item>
<el-form-item
label="下限值"
v-if="field.need_judge == true"
prop="low_limit"
>
<el-input-number
v-model="field.low_limit"
:precision="2"
:min="0"
></el-input-number>
</el-form-item>
<el-form-item
label="下限规则"
v-if="field.need_judge == true"
prop="low_rule"
>
<el-select
style="width: 100%"
v-model="field.low_rule"
placeholder="请选择"
>
<el-option
v-for="item in lowoptions"
:key="item.value"
:label="item.label"
:value="item.value"
>
</el-option>
</el-select>
</el-form-item>
!-->
<el-form-item label="判定式" v-if="field.need_judge === true">
<el-input v-model="field.rule_expression" type="textarea"/>
</el-form-item>
@ -556,7 +527,7 @@
const defaultfield = {};
let preDrawAry = [];
export default {
components: {Pagination, vueJsonEditor, Treeselect, customForm,faceLogin},
components: {Pagination, vueJsonEditor, Treeselect, customForm, faceLogin},
data() {
return {
step: defaultstep,
@ -677,12 +648,31 @@
label: "绘图模板",
},
],
typeoptions: [
typeOptions: [
{
value: 1,
label: "生产记录",
value: 10,
label: "生产记录表",
}, {
value: 20,
label: "工序检查表",
}, {
value: 30,
label: "入场检验表",
}, {
value: 40,
label: "成品检验表",
}, {
value: 50,
label: "首件检查表",
},
],
typeOptions_:{
10 : "生产记录表",
20 : "工序检查表",
30 : "入场检验表",
40 : "成品检验表",
50 : "首件检查表",
},
canvas: null,
ctx: null,
myCanvas_rect: null,
@ -696,8 +686,8 @@
imgData: '',
canvasImg: '',
judgeList: [],
limitedPhoto:false,
isDisabled:true,
limitedPhoto: false,
isDisabled: true,
};
},
computed: {},
@ -850,7 +840,7 @@
},
recordformLists() {
this.listQueryrecordform.material = this.material;
this.listQueryrecordform.type = 2;
// this.listQueryrecordform.type = 2;
getrecordformList(this.listQueryrecordform).then((response) => {
if (response.data) {
this.recordformList = response.data;
@ -895,21 +885,20 @@
//新增字段
handlefieldCreate() {
this.field_choice = [""];
// this.field = Object.assign({}, defaultfield);
this.dialogType1 = "new";
this.dialogVisible1 = true;
// this.$refs["Form"].resetFields();
this.$nextTick(() => {
this.field.field_type= null;
this.field.field_key= null;
this.field.field_name= null;
this.field.sort= null;
this.field.parent= null;
this.field.help_text= null;
this.field.draw_template= null;
this.field.field_choice= null;
this.field.rule_expression= null;
this.field.display_expression= null;
this.field.field_type = null;
this.field.field_key = null;
this.field.field_name = null;
this.field.sort = null;
this.field.parent = null;
this.field.help_text = null;
this.field.draw_template = null;
this.field.field_choice = null;
this.field.rule_expression = null;
this.field.display_expression = null;
this.$refs["Form"].clearValidate();
});
},
@ -965,10 +954,12 @@
this.$refs[form].validate((valid) => {
if (valid) {
const isEdit = this.dialogType === "edit";
let obj = new Object();
obj.name=this.recordform.name;
obj.type=this.recordform.type;
obj.enabled=this.recordform.enabled;
if (isEdit) {
this.recordform.material = this.material;
this.recordform.type = 2;
updaterecordform(this.recordform.id, this.recordform).then(
updaterecordform(this.recordform.id, obj).then(
(res) => {
if (res.code >= 200) {
this.recordformLists();
@ -978,9 +969,8 @@
}
);
} else {
this.recordform.material = this.material;
this.recordform.type = 2;
createrecordform(this.recordform).then((res) => {
obj.material=parseInt(this.material);
createrecordform(obj).then((res) => {
if (res.code >= 200) {
this.recordformLists();
this.dialogVisible = false;
@ -1011,8 +1001,6 @@
} else {
this.field.form = this.formID;
this.field.field_choice = this.field_choice;
debugger;
console.log(this.field);
createrffield(this.field).then((res) => {
if (res.code >= 200) {
this.fieldLists();
@ -1027,12 +1015,12 @@
}
});
},
recordformcon(){
recordformcon() {
this.recordform.material = this.material;
this.recordform.type = 2;
this.limitedPhoto = true;
},
getMsgFormSon(data){
getMsgFormSon(data) {
this.limitedPhoto = data;
this.recordformLists();
this.dialogVisible = false;

View File

@ -0,0 +1,18 @@
# Generated by Django 3.2.9 on 2022-02-16 07:15
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('mtm', '0045_usedstep_need_test'),
]
operations = [
migrations.AlterField(
model_name='recordform',
name='type',
field=models.IntegerField(choices=[(10, '生产记录表'), (20, '工序检查表'), (30, '入厂检查表'), (40, '成品检查表'), (50, '首件检查表')], default=1, verbose_name='表格类型'),
),
]

View File

@ -107,11 +107,17 @@ class RecordForm(CommonAModel):
"""
记录表格
"""
RF_TYPE_DO = 1
RF_TYPE_TEST = 2
RF_TYPE_DO = 10
RF_TYPE_TEST = 20
RF_TYPE_TEST_IN = 30
RF_TYPE_TEST_GOOD = 40
RF_TYPE_TEST_FIRST = 50
type_choices=(
(RF_TYPE_DO, '生产记录模板'),
(RF_TYPE_TEST, '检验记录模板')
(RF_TYPE_DO, '生产记录表'),
(RF_TYPE_TEST, '工序检查表'),
(RF_TYPE_TEST_IN, '入厂检查表'),
(RF_TYPE_TEST_GOOD, '成品检查表'),
(RF_TYPE_TEST_FIRST, '首件检查表'),
)
name = models.CharField('表格名称', max_length=100)
type = models.IntegerField('表格类型', choices=type_choices, default=1)

View File

@ -190,6 +190,7 @@ class RecordFormCreateSerializer(serializers.ModelSerializer):
model = RecordForm
fields = ['name', 'type', 'step', 'material', 'number', 'enabled']
class RecordFormUpdateSerializer(serializers.ModelSerializer):
class Meta:
model = RecordForm

View File

@ -7,7 +7,7 @@ import django.utils.timezone as timezone
from django.db.models.query import QuerySet
from utils.model import SoftModel, BaseModel
from apps.mtm.models import Material, Process, SubProduction, SubprodctionMaterial
from apps.mtm.models import Material, Process, RecordFormField, SubProduction, SubprodctionMaterial
from apps.sam.models import Order
class ProductionPlan(CommonAModel):
@ -91,6 +91,16 @@ class SubProductionPlan(CommonAModel):
verbose_name = '子生产计划'
verbose_name_plural = verbose_name
class FirstItem(BaseModel):
"""
首件确认表记录条目
"""
form_field = models.ForeignKey(RecordFormField, verbose_name='关联自定义表格字段', on_delete=models.CASCADE)
field_value = models.JSONField('录入值', null=True, blank=True)
is_hidden = models.BooleanField('是否隐藏', default=False)
is_testok = models.BooleanField('是否合格', null=True, blank=True)
subproduction_plan = models.ForeignKey(SubProductionPlan, verbose_name='关联的子计划', on_delete=models.CASCADE, related_name='item_test_record')
class SubProductionProgress(BaseModel):
"""
子计划生产进度统计表/物料消耗
@ -104,3 +114,4 @@ class SubProductionProgress(BaseModel):
count_real = models.PositiveIntegerField('实际消耗/产出数', default=0)
count_ok = models.PositiveIntegerField('合格数量', default=0)
count_notok = models.PositiveIntegerField('不合格数量', default=0)

View File

@ -9,15 +9,11 @@ class CustomBackend(ModelBackend):
def authenticate(self, request, username=None, password=None, **kwargs):
if username is None:
username = kwargs.get(UserModel.USERNAME_FIELD)
if username is None or password is None:
return
try:
user = UserModel._default_manager.get(
Q(username=username) | Q(phone=username) | Q(email=username))
except UserModel.DoesNotExist:
# Run the default password hasher once to reduce the timing
# difference between an existing and a nonexistent user (#20760).
UserModel().set_password(password)
return None
else:
if user.check_password(password) and self.user_can_authenticate(user):
return user

View File

@ -35,7 +35,10 @@ class RbacPermission(BasePermission):
:return:
"""
if not request.user:
perms = ['visitor'] # 如果没有经过认证,视为游客
if request.META.get('HTTP_AUTHORIZATION', None) == 'big_screen':
perms = ['visitor']
else:
return False
else:
perms = cache.get(request.user.username + '__perms')
if not perms:

View File

@ -158,7 +158,7 @@ REST_FRAMEWORK = {
'rest_framework.authentication.SessionAuthentication',
],
'DEFAULT_PERMISSION_CLASSES': [
'rest_framework.permissions.IsAuthenticated',
# 'rest_framework.permissions.IsAuthenticated',
'apps.system.permission.RbacPermission'
],
'DEFAULT_RENDERER_CLASSES': [

View File

@ -48,9 +48,9 @@ class FitJSONRenderer(JSONRenderer):
response_body = BaseResponse()
response = renderer_context.get("response")
status_code = response.status_code # Http状态异常码
print(status_code)
if status_code >= 400: # 如果http响应异常
if isinstance(data, dict) and 'code' in data: # 如果自定义了异常码
if isinstance(data, dict) \
and 'code' in data and 'msg' in data: # 如果自定义了异常码
response_body = data
else:
response_body.data = data # data里是详细异常信息