diff --git a/hb_client/.env.development b/hb_client/.env.development index db8f2e7..ef83e12 100644 --- a/hb_client/.env.development +++ b/hb_client/.env.development @@ -2,8 +2,8 @@ ENV = 'development' # base api -#VUE_APP_BASE_API = 'http://localhost:8000/api' -VUE_APP_BASE_API = 'http://47.95.0.242:2222/api' +VUE_APP_BASE_API = 'http://127.0.0.1:8000/api' +#VUE_APP_BASE_API = 'http://47.95.0.242:2222/api' # vue-cli uses the VUE_CLI_BABEL_TRANSPILE_MODULES environment variable, diff --git a/hb_client/package.json b/hb_client/package.json index 499efce..4a4ab4c 100644 --- a/hb_client/package.json +++ b/hb_client/package.json @@ -30,6 +30,7 @@ "vue-json-editor": "^1.4.3", "vue-router": "^3.5.2", "vuex": "^3.6.2", + "webpack-dev-server": "^4.2.0", "xlsx": "^0.17.1" }, "devDependencies": { diff --git a/hb_client/src/api/sam.js b/hb_client/src/api/sam.js new file mode 100644 index 0000000..67998a3 --- /dev/null +++ b/hb_client/src/api/sam.js @@ -0,0 +1,59 @@ +import request from '@/utils/request' +//客户 +export function getCustomerList(query) { + return request({ + url: '/sam/customer/', + method: 'get', + params: query + }) +} +export function createCustomer(data) { + return request({ + url: '/sam/customer/', + method: 'post', + data + }) +} +export function updateCustomer(id, data) { + return request({ + url: `/sam/customer/${id}/`, + method: 'put', + data + }) +} +export function deleteCustomer(id, data) { + return request({ + url: `/sam/customer/${id}/`, + method: 'delete', + data + }) +} +//合同 +export function getContractList(query) { + return request({ + url: '/sam/contract/', + method: 'get', + params: query + }) +} +export function createContract(data) { + return request({ + url: '/sam/contract/', + method: 'post', + data + }) +} +export function updateContract(id, data) { + return request({ + url: `/sam/contract/${id}/`, + method: 'put', + data + }) +} +export function deleteContract(id, data) { + return request({ + url: `/sam/contract/${id}/`, + method: 'delete', + data + }) +} diff --git a/hb_client/src/router/index.js b/hb_client/src/router/index.js index c67910a..941fccc 100644 --- a/hb_client/src/router/index.js +++ b/hb_client/src/router/index.js @@ -80,6 +80,49 @@ export const constantRoutes = [ * the routes that need to be dynamically loaded based on user perms */ export const asyncRoutes = [ + + { + path: '/mtm', + component: Layout, + redirect: '/mtm/material/', + name: 'mtm', + meta: { title: '制造管理', icon: 'example', perms: ['procurement_set'] }, + children: [ + { + path: 'material', + name: 'material', + component: () => import('@/views/mtm/material'), + meta: { title: '物料清单', icon: 'example', perms: ['vendor_manage'] } + }, + { + path: 'process', + name: 'process', + component: () => import('@/views/mtm/process'), + meta: { title: '工序管理', icon: 'example', perms: ['vendor_manage'] } + }, + { + path: 'step/:id', + name: 'Step', + component: () => import('@/views/mtm/step.vue'), + meta: { title: '子工序', perms: ['vendor_manage'] }, + hidden: true + } + , + { + path: 'stepdo/:id', + name: 'StepDo', + component: () => import('@/views/mtm/stepdo.vue'), + meta: { title: '子工序查看', perms: ['vendor_manage'] }, + hidden: true + }, + { + path: '/mtm/productprocess/', + name: 'productprocess', + component: () => import('@/views/mtm/productprocess'), + meta: { title: '产品管理', icon: 'example', perms: ['vendor_manage'] } + }, + ] + }, { path: '/equipment', component: Layout, @@ -91,13 +134,34 @@ export const asyncRoutes = [ path: 'index', name: 'index', component: () => import('@/views/equipment/index'), - meta: { title: '设备台账', icon: 'example', perms: ['index_manage'] } + meta: { title: '生产设备', icon: 'example', perms: ['index_manage'] } }, { path: 'index', name: 'index', component: () => import('@/views/equipment/index'), - meta: { title: '运维记录', icon: 'example', perms: ['index_manage'] } + meta: { title: '监视和测量设备', icon: 'example', perms: ['index_manage'] } + } + ] + }, + { + path: '/sam', + component: Layout, + redirect: '/sam/index', + name: 'sam', + meta: { title: '合同管理', icon: 'example', perms: ['equipment_set'] }, + children: [ + { + path: 'customer', + name: 'customer', + component: () => import('@/views/sam/customer'), + meta: { title: '客户信息', icon: 'example', perms: ['index_manage'] } + }, + { + path: 'contract', + name: 'contract', + component: () => import('@/views/sam/contract'), + meta: { title: '合同信息', icon: 'example', perms: ['index_manage'] } } ] }, @@ -123,48 +187,6 @@ export const asyncRoutes = [ ] }, - { - path: '/mtm', - component: Layout, - redirect: '/mtm/material/', - name: 'mtm', - meta: { title: '制造管理', icon: 'example', perms: ['procurement_set'] }, - children: [ - { - path: 'material', - name: 'material', - component: () => import('@/views/mtm/material'), - meta: { title: '物料', icon: 'example', perms: ['vendor_manage'] } - }, - { - path: 'process', - name: 'process', - component: () => import('@/views/mtm/process'), - meta: { title: '工序', icon: 'example', perms: ['vendor_manage'] } - }, - { - path: 'step/:id', - name: 'Step', - component: () => import('@/views/mtm/step.vue'), - meta: { title: '子工序', perms: ['vendor_manage'] }, - hidden: true - } - , - { - path: 'stepdo/:id', - name: 'StepDo', - component: () => import('@/views/mtm/stepdo.vue'), - meta: { title: '子工序查看', perms: ['vendor_manage'] }, - hidden: true - }, - { - path: '/mtm/productprocess/', - name: 'productprocess', - component: () => import('@/views/mtm/productprocess'), - meta: { title: '产品工艺', icon: 'example', perms: ['vendor_manage'] } - }, - ] - }, { path: '/procurement', diff --git a/hb_client/src/views/equipment/index.vue b/hb_client/src/views/equipment/index.vue index 1826b5e..6feaa63 100644 --- a/hb_client/src/views/equipment/index.vue +++ b/hb_client/src/views/equipment/index.vue @@ -109,47 +109,39 @@ + + + + - - + + + + + + - - - - - - + + + + - - - - - - - - - - - - + + + + + + + + - - - + + + + + + + + + + + - + + + + + - + + + + + + + + + + +
取消 @@ -244,13 +264,7 @@ export default { '2':'检验工具', }, - typeoptions: [{ - value: 1, - label: '生产设备' - }, { - value: 2, - label: '检验工具' - }], + options: [{ value: 0, label: '运转正常' @@ -370,6 +384,7 @@ export default { } }); } else { + this.equipment.type=1; createEquipment(this.equipment).then((res) => { if (res.code >= 200) { this.getList(); diff --git a/hb_client/src/views/mtm/material.vue b/hb_client/src/views/mtm/material.vue index 8179d8a..950ff75 100644 --- a/hb_client/src/views/mtm/material.vue +++ b/hb_client/src/views/mtm/material.vue @@ -4,7 +4,7 @@
@@ -45,17 +47,20 @@ - - + + - - + + + @@ -109,6 +114,10 @@ + + + + { diff --git a/hb_client/src/views/sam/contract.vue b/hb_client/src/views/sam/contract.vue new file mode 100644 index 0000000..ad5f502 --- /dev/null +++ b/hb_client/src/views/sam/contract.vue @@ -0,0 +1,261 @@ + + diff --git a/hb_client/src/views/sam/customer.vue b/hb_client/src/views/sam/customer.vue new file mode 100644 index 0000000..bb6bea7 --- /dev/null +++ b/hb_client/src/views/sam/customer.vue @@ -0,0 +1,244 @@ + + diff --git a/hb_server/apps/em/migrations/0004_equipment_count.py b/hb_server/apps/em/migrations/0004_equipment_count.py new file mode 100644 index 0000000..427dc68 --- /dev/null +++ b/hb_server/apps/em/migrations/0004_equipment_count.py @@ -0,0 +1,18 @@ +# Generated by Django 3.2.6 on 2021-09-13 08:33 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('em', '0003_equipment_type'), + ] + + operations = [ + migrations.AddField( + model_name='equipment', + name='count', + field=models.IntegerField(default=0, verbose_name='数量'), + ), + ] diff --git a/hb_server/apps/em/models.py b/hb_server/apps/em/models.py index b55b489..d51e3e8 100644 --- a/hb_server/apps/em/models.py +++ b/hb_server/apps/em/models.py @@ -4,6 +4,7 @@ from django.db.models.base import Model import django.utils.timezone as timezone from django.db.models.query import QuerySet from apps.system.models import CommonAModel, CommonBModel, Organization, User, Dict, File +#from apps.mtm.models import Process from utils.model import SoftModel, BaseModel from simple_history.models import HistoricalRecords @@ -32,8 +33,10 @@ class Equipment(CommonBModel): state = models.CharField('设备状态', max_length=11, choices=state_choices, default=1) parameter = models.TextField('技术参数', null=True, blank=True) place = models.CharField('存放位置', max_length=50, null=True, blank=True) + count = models.IntegerField('数量', default=0) keeper = models.ForeignKey(User, verbose_name='保管人', on_delete=models.CASCADE, null=True, blank=True) description = models.CharField('描述', max_length=200, blank=True, null=True) + #process = models.ForeignKey(Process, verbose_name='工序', on_delete=models.CASCADE, null=True, blank=True) class Meta: verbose_name = '设备信息' diff --git a/hb_server/apps/inm/migrations/0002_fifo_inventory.py b/hb_server/apps/inm/migrations/0002_fifo_inventory.py new file mode 100644 index 0000000..20fb89c --- /dev/null +++ b/hb_server/apps/inm/migrations/0002_fifo_inventory.py @@ -0,0 +1,51 @@ +# Generated by Django 3.2.6 on 2021-09-13 01:54 + +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 = [ + ('mtm', '0011_alter_recordformfield_field_type'), + migrations.swappable_dependency(settings.AUTH_USER_MODEL), + ('inm', '0001_initial'), + ] + + operations = [ + migrations.CreateModel( + name='Inventory', + 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='删除标记')), + ('count', models.IntegerField(default=0, verbose_name='数量')), + ('create_by', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='inventory_create_by', to=settings.AUTH_USER_MODEL, verbose_name='创建人')), + ('material', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='mtm.material', verbose_name='物料信息')), + ('update_by', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='inventory_update_by', to=settings.AUTH_USER_MODEL, verbose_name='最后编辑人')), + ('warehouse', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='inm.warehouse', verbose_name='所在仓库')), + ], + options={ + 'verbose_name': '库存表', + 'verbose_name_plural': '库存表', + }, + ), + migrations.CreateModel( + name='FIFO', + 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.IntegerField(default=1, verbose_name='出入库类型')), + ('create_by', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='fifo_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='fifo_update_by', to=settings.AUTH_USER_MODEL, verbose_name='最后编辑人')), + ], + options={ + 'abstract': False, + }, + ), + ] diff --git a/hb_server/apps/mtm/migrations/0012_auto_20210913_1412.py b/hb_server/apps/mtm/migrations/0012_auto_20210913_1412.py new file mode 100644 index 0000000..853adac --- /dev/null +++ b/hb_server/apps/mtm/migrations/0012_auto_20210913_1412.py @@ -0,0 +1,23 @@ +# Generated by Django 3.2.6 on 2021-09-13 06:12 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('mtm', '0011_alter_recordformfield_field_type'), + ] + + operations = [ + migrations.AddField( + model_name='material', + name='specification', + field=models.CharField(blank=True, max_length=100, null=True, verbose_name='规格型号'), + ), + migrations.AlterField( + model_name='material', + name='type', + field=models.CharField(choices=[(1, '成品'), (2, '半成品'), (3, '主要原料'), (4, '辅助原料')], default=1, max_length=20, verbose_name='物料类型'), + ), + ] diff --git a/hb_server/apps/mtm/models.py b/hb_server/apps/mtm/models.py index 06f1672..f964756 100644 --- a/hb_server/apps/mtm/models.py +++ b/hb_server/apps/mtm/models.py @@ -15,7 +15,8 @@ class Material(CommonAModel): type_choices=( (1, '成品'), (2, '半成品'), - (3, '原材料') + (3, '主要原料'), + (4,'辅助原料') ) unit_choices =( ('块', '块'), @@ -23,6 +24,7 @@ class Material(CommonAModel): ) name = models.CharField('物料名称', max_length=100, unique=True) number = models.CharField('编号', max_length=100, unique=True) + specification = models.CharField('型号', max_length=100, null=True, blank=True) type = models.CharField('物料类型', choices= type_choices, max_length=20, default=1) sort_str = models.CharField('排序字符', max_length=100, null=True, blank=True) processes = models.JSONField('工艺流程', default=list, blank=True) diff --git a/hb_server/apps/mtm/serializers.py b/hb_server/apps/mtm/serializers.py index 68b214b..43e5bb8 100644 --- a/hb_server/apps/mtm/serializers.py +++ b/hb_server/apps/mtm/serializers.py @@ -50,7 +50,7 @@ class StepSimpleSerializer(serializers.ModelSerializer): fields = ['id', 'name', 'sort'] class StepDetailSerializer(serializers.ModelSerializer): - equipments_ = EquipmentSimpleSerializer(source='equipments', many=True) + class Meta: model = Step fields = '__all__' diff --git a/hb_server/apps/sam/migrations/0002_auto_20210913_0954.py b/hb_server/apps/sam/migrations/0002_auto_20210913_0954.py new file mode 100644 index 0000000..30d2680 --- /dev/null +++ b/hb_server/apps/sam/migrations/0002_auto_20210913_0954.py @@ -0,0 +1,77 @@ +# Generated by Django 3.2.6 on 2021-09-13 01:54 + +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), + ('sam', '0001_initial'), + ] + + operations = [ + migrations.CreateModel( + name='Contract', + 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='删除标记')), + ('name', models.CharField(max_length=100, verbose_name='合同名称')), + ('number', models.CharField(max_length=100, unique=True, verbose_name='合同编号')), + ('amount', models.IntegerField(default=0, verbose_name='合同金额')), + ('sign_date', models.DateField(verbose_name='签订日期')), + ('description', models.CharField(blank=True, max_length=200, null=True, verbose_name='描述')), + ('create_by', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='contract_create_by', to=settings.AUTH_USER_MODEL, verbose_name='创建人')), + ], + options={ + 'verbose_name': '合同信息', + 'verbose_name_plural': '合同信息', + }, + ), + migrations.RemoveField( + model_name='customer', + name='country', + ), + migrations.RemoveField( + model_name='customer', + name='phone', + ), + migrations.RemoveField( + model_name='order', + name='contact', + ), + migrations.AddField( + model_name='customer', + name='contact_phone', + field=models.CharField(max_length=11, null=True, unique=True, verbose_name='联系电话'), + ), + migrations.AlterField( + model_name='customer', + name='contact', + field=models.CharField(default=1, max_length=20, verbose_name='联系人'), + preserve_default=False, + ), + migrations.DeleteModel( + name='Contact', + ), + migrations.AddField( + model_name='contract', + name='customer', + field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='contact_customer', to='sam.customer', verbose_name='关联客户'), + ), + migrations.AddField( + model_name='contract', + name='update_by', + field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='contract_update_by', to=settings.AUTH_USER_MODEL, verbose_name='最后编辑人'), + ), + migrations.AddField( + model_name='order', + name='contract', + field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, to='sam.contract', verbose_name='所属合同'), + ), + ] diff --git a/hb_server/apps/sam/models.py b/hb_server/apps/sam/models.py index 1925c07..b03e471 100644 --- a/hb_server/apps/sam/models.py +++ b/hb_server/apps/sam/models.py @@ -17,7 +17,7 @@ class Customer(CommonAModel): name = models.CharField('客户名称', max_length=50, unique=True) address = models.CharField('详细地址', max_length=20, blank=True, null=True) contact = models.CharField('联系人', max_length=20) - contact_phone = models.CharField('联系电话', max_length=11, unique=True) + contact_phone = models.CharField('联系电话', max_length=11, unique=True,null=True) description = models.CharField('描述', max_length=200, blank=True, null=True) class Meta: diff --git a/hb_server/apps/sam/serializers.py b/hb_server/apps/sam/serializers.py index 3ecfd51..4d608b0 100644 --- a/hb_server/apps/sam/serializers.py +++ b/hb_server/apps/sam/serializers.py @@ -2,7 +2,6 @@ from rest_framework import serializers from .models import Contract, Customer, Order - class CustomerSerializer(serializers.ModelSerializer): class Meta: model = Customer @@ -44,4 +43,4 @@ class OrderSerializer(serializers.ModelSerializer): customer_ = CustomerSimpleSerializer(source='customer', read_only=True) class Meta: model = Order - fields = '__all__' \ No newline at end of file + fields = '__all__' diff --git a/hb_server/apps/sam/urls.py b/hb_server/apps/sam/urls.py new file mode 100644 index 0000000..fda60b5 --- /dev/null +++ b/hb_server/apps/sam/urls.py @@ -0,0 +1,14 @@ +from django.db.models import base +from rest_framework import urlpatterns +from apps.sam.views import CustomerViewSet,ContractViewSet +from django.urls import path, include +from rest_framework.routers import DefaultRouter + +router = DefaultRouter() +router.register('customer', CustomerViewSet, basename='customer') +router.register('contract', ContractViewSet, basename='contract') + +urlpatterns = [ + path('', include(router.urls)), +] + diff --git a/hb_server/apps/system/views.py b/hb_server/apps/system/views.py index a05fb3f..2ee96a6 100644 --- a/hb_server/apps/system/views.py +++ b/hb_server/apps/system/views.py @@ -353,7 +353,7 @@ class FileViewSet(CreateModelMixin, DestroyModelMixin, RetrieveModelMixin, ListM -import face_recognition +#import face_recognition import uuid import base64 import os @@ -381,13 +381,14 @@ class FaceLogin(CreateAPIView): with open(filepath, 'wb') as f: data = tran64(request.data.get('base64').replace(' ', '+')) f.write(base64.urlsafe_b64decode(data)) - picture_of_me = face_recognition.load_image_file(settings.BASE_DIR +'/temp/me.png') - my_face_encoding = face_recognition.face_encodings(picture_of_me)[0] - unknown_picture = face_recognition.load_image_file(filepath) - unknown_face_encoding = face_recognition.face_encodings(unknown_picture)[0] - results = face_recognition.compare_faces([my_face_encoding], unknown_face_encoding, tolerance=0.2) + # picture_of_me = face_recognition.load_image_file(settings.BASE_DIR +'/temp/me.png') + # my_face_encoding = face_recognition.face_encodings(picture_of_me)[0] + # unknown_picture = face_recognition.load_image_file(filepath) + # unknown_face_encoding = face_recognition.face_encodings(unknown_picture)[0] + #results = face_recognition.compare_faces([my_face_encoding], unknown_face_encoding, tolerance=0.2) os.remove(filepath) - if results[0] == True: - return Response('这是曹前明') - else: - return Response('这不是曹前明') \ No newline at end of file + # if results[0] == True: + # return Response('这是曹前明') + # else: + # return Response('这不是曹前明') + diff --git a/hb_server/server/urls.py b/hb_server/server/urls.py index 8fe9aa2..607412d 100644 --- a/hb_server/server/urls.py +++ b/hb_server/server/urls.py @@ -65,6 +65,7 @@ urlpatterns = [ path('api/wf/', include('apps.wf.urls')), path('api/mtm/', include('apps.mtm.urls')), path('api/inm/', include('apps.inm.urls')), + path('api/sam/', include('apps.sam.urls')), # 工具 path('api/utils/signature/', GenSignature.as_view()),