diff --git a/hb_client/package.json b/hb_client/package.json
index 1382831..0a17f55 100644
--- a/hb_client/package.json
+++ b/hb_client/package.json
@@ -31,6 +31,7 @@
"path-to-regexp": "^6.2.0",
"vue": "^2.6.14",
"vue-json-editor": "^1.4.3",
+ "vue-quill-editor": "^3.0.6",
"vue-router": "^3.5.2",
"vuex": "^3.6.2",
"webpack-dev-server": "^4.2.0",
diff --git a/hb_client/src/router/index.js b/hb_client/src/router/index.js
index 87508ea..9685b0e 100644
--- a/hb_client/src/router/index.js
+++ b/hb_client/src/router/index.js
@@ -176,6 +176,13 @@ export const asyncRoutes = [
meta: { title: '合同信息', icon: 'example', perms: ['index_manage'] }
}
,
+ {
+ path: 'review',
+ name: 'review',
+ component: () => import('@/views/sam/review'),
+ meta: { title: '合同评审', icon: 'example', perms: ['index_manage'] }
+ }
+ ,
{
path: 'order',
name: 'order',
diff --git a/hb_client/src/views/mtm/productprocess.vue b/hb_client/src/views/mtm/productprocess.vue
index e810968..29afc03 100644
--- a/hb_client/src/views/mtm/productprocess.vue
+++ b/hb_client/src/views/mtm/productprocess.vue
@@ -386,12 +386,15 @@
>
-
+
-
-
-
+
+
+
+
+
+
{
+ getMaterialList({pageoff:true}).then((response) => {
if (response.data) {
- this.materialoptions = genTree(response.data.results);
+ this.materialoptions = genTree(response.data);
}
this.listLoading = false;
});
@@ -546,6 +553,7 @@ export default {
{
this.process = id;
// alert(this.process)
+ this.getmaterialList();//物料列表
this.getInputmaterialLists();//输入物料
this.getOutputmaterialLists();//输出物料
@@ -564,7 +572,6 @@ export default {
this.listQueryinput.process=this.process;
this.listQueryinput.product=this.product
- //this.listQueryinput.page=0;
getInputmaterialList(this.listQueryinput).then((response) => {
if (response.data) {
diff --git a/hb_client/src/views/mtm/step.vue b/hb_client/src/views/mtm/step.vue
index d614d5d..48f3c4d 100644
--- a/hb_client/src/views/mtm/step.vue
+++ b/hb_client/src/views/mtm/step.vue
@@ -6,7 +6,7 @@
font-weight: 700;
">子工序列表
- 新增子工序
过程记录表
- 新增
{{ scope.row.number }}
-
+
{{ scope.row.amount }}
+
+ {{ scope.row.invoice }}
+
+
{{ scope.row.customer_.name }}
@@ -112,7 +116,9 @@
-
+
+
+
{{ scope.row.product_.name }}
+
+
+ {{ scope.row.product_.specification }}
{{ scope.row.count }}
@@ -117,6 +120,7 @@
+
diff --git a/hb_client/src/views/sam/review.vue b/hb_client/src/views/sam/review.vue
new file mode 100644
index 0000000..abd14b4
--- /dev/null
+++ b/hb_client/src/views/sam/review.vue
@@ -0,0 +1,284 @@
+
+
+
+
+
+ 搜索
+ 重置
+
+
+ 新增客户
+
+
+
+
+
+
+ {{ scope.row.name }}
+
+
+
+ {{ scope.row.number }}
+
+
+ {{ scope.row.amount }}
+
+
+ {{ scope.row.invoice }}
+
+
+
+ {{ scope.row.customer_.name }}
+
+
+ {{ scope.row.sign_date }}
+
+
+ {{ scope.row.description }}
+
+
+ {{ scope.row.create_time }}
+
+
+
+
+ 编辑
+ 删除
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 取消
+ 确认
+
+
+
+
+
diff --git a/hb_daq/.gitignore b/hb_daq/.gitignore
new file mode 100644
index 0000000..1f2de66
--- /dev/null
+++ b/hb_daq/.gitignore
@@ -0,0 +1,3 @@
+dist/
+config/*
+.build/
\ No newline at end of file
diff --git a/hb_daq/default.aproj b/hb_daq/default.aproj
new file mode 100644
index 0000000..c3e936d
--- /dev/null
+++ b/hb_daq/default.aproj
@@ -0,0 +1,8 @@
+
+
+
+
+
+
+
+
diff --git a/hb_daq/dlg/add.aardio b/hb_daq/dlg/add.aardio
new file mode 100644
index 0000000..463f520
--- /dev/null
+++ b/hb_daq/dlg/add.aardio
@@ -0,0 +1,24 @@
+import win.ui;
+/*DSG{{*/
+var winform = win.form(text="新建采集内容";right=299;bottom=179;border="dialog frame";max=false;min=false)
+winform.add(
+button={cls="button";text="确定";left=90;top=119;right=196;bottom=154;z=5};
+edit={cls="edit";left=84;top=26;right=281;bottom=50;dl=1;dr=1;dt=1;edge=1;z=2};
+edit2={cls="edit";left=84;top=69;right=281;bottom=93;dl=1;dr=1;dt=1;edge=1;z=4};
+static={cls="static";text="设备编号";left=8;top=29;right=78;bottom=54;dl=1;dt=1;notify=1;transparent=1;z=1};
+static2={cls="static";text="文件夹地址";left=8;top=74;right=78;bottom=99;dl=1;dt=1;notify=1;transparent=1;z=3}
+)
+/*}}*/
+
+winform.button.oncommand = function(id,event){
+ if(winform.edit.text!="" && winform.edit2.text!=""){
+ winform.parent.listview.addItem({winform.edit.text;winform.edit2.text})
+ winform.close()
+ }else{
+ winform.msgbox("请输入信息!")}
+
+}
+
+winform.show();
+win.loopMessage();
+return winform;
\ No newline at end of file
diff --git a/hb_daq/lib/config.aardio b/hb_daq/lib/config.aardio
new file mode 100644
index 0000000..a1cbfc5
--- /dev/null
+++ b/hb_daq/lib/config.aardio
@@ -0,0 +1,20 @@
+//config 配置文件
+import fsys.config;
+config = fsys.config("/config/");
+//config = fsys.config( io.appData("/软件作者/应用程序名/") );
+
+//不需要序列化的配置名字前请添加下划线
+namespace config {
+ __appName = "应用程序名";
+ __appVersion = "1.0.0.01";
+ __appDescription = "这是一个测试程序";
+ __website = "http://www.aardio.com/";
+}
+
+/**intellisense(config)
+__appName = 应用程序名
+__appVersion = 应用程序内部版本号
+__appDescription = 程序说明
+__website = 官方网站
+? = 配置文件名,\n读写配置并序列化为一个表对象,\n表的成员值可以是支持序列化的普通变量,支持table对象\n配置文件在首次使用时自动加载,退出程序时自动保存\n!fsys_table.
+end intellisense**/
\ No newline at end of file
diff --git a/hb_daq/main.aardio b/hb_daq/main.aardio
new file mode 100644
index 0000000..ab39ff1
--- /dev/null
+++ b/hb_daq/main.aardio
@@ -0,0 +1,208 @@
+import win.ui;
+import win.inputBox;
+import win.ui.menu;
+import win.util.tray;
+import win.ui.atom;
+import win.timer;
+import console;
+import win.timer;
+import fsys;
+import web.multipartFormData;
+import inet.http;
+import fsys.config;
+/*DSG{{*/
+mainForm = win.form(text="数据采集";right=799;bottom=399;border="dialog frame";max=false)
+mainForm.add(
+add={cls="button";text="新建";left=27;top=130;right=98;bottom=154;font=LOGFONT(h=-14;name='微软雅黑');z=6};
+backupPath={cls="edit";left=107;top=58;right=337;bottom=84;edge=1;font=LOGFONT(h=-14;name='微软雅黑');z=11};
+backupPathLabel={cls="static";text="备份文件夹";left=31;top=60;right=118;bottom=81;font=LOGFONT(h=-14;name='微软雅黑');notify=1;transparent=1;z=10};
+groupbox={cls="groupbox";text="采集内容";left=18;top=110;right=346;bottom=390;edge=1;z=5};
+groupbox2={cls="groupbox";text="采集日志";left=353;top=7;right=792;bottom=390;ah=1;aw=1;db=1;dr=1;edge=1;z=1};
+groupbox3={cls="groupbox";text="基础配置";left=18;top=7;right=346;bottom=102;edge=1;z=2};
+listbox={cls="listbox";left=360;top=24;right=785;bottom=387;edge=1;hscroll=1;items={};vscroll=1;z=12};
+listview={cls="listview";left=27;top=161;right=337;bottom=384;edge=1;fullRow=1;items={};msel=false;z=7};
+serverUrl={cls="edit";left=107;top=25;right=337;bottom=51;edge=1;font=LOGFONT(h=-14;name='微软雅黑');z=4};
+serverUrlLabel={cls="static";text="服务器地址";left=31;top=28;right=118;bottom=49;font=LOGFONT(h=-14;name='微软雅黑');notify=1;transparent=1;z=3};
+start={cls="button";text="开始采集";left=266;top=130;right=337;bottom=154;font=LOGFONT(h=-14;name='微软雅黑');z=8};
+statusLabel={cls="static";left=143;top=130;right=221;bottom=154;align="center";color=32768;font=LOGFONT(h=-16;name='微软雅黑';weight=700);transparent=1;z=9}
+)
+/*}}*/
+
+/*
+inputbox = win.inputBox(mainForm.hwnd)
+inputbox.text = "输入框标题"
+inputbox.info.text = "请在下面输入您的名字"
+inputbox.input.text = "在这里输入您的名字"
+name = inputbox.doModal();
+
+if(name)
+ win.msgbox("您的名字是:"+name )
+else
+ win.msgbox("你拒绝输入名字")
+*/
+mainForm.listview.adjust = function(cx,cy){
+ mainForm.listview.fillParent(/*列序号*/);
+}
+
+mainForm.listview.insertColumn("设备编号",100,,0x0/*_LVCFMT_LEFT*/)
+mainForm.listview.insertColumn("文件夹地址",100,,0x0/*_LVCFMT_LEFT*/) //第二列开始可以使用_LVCFMT_CENTER居中
+
+config = fsys.config("/config/")
+mainForm.bindConfig( config.winform,{
+ serverUrl = "text";
+ backupPath = "text";
+ listview = "items";
+} );
+if(mainForm.serverUrl.text==""){
+ mainForm.serverUrl.text='http://127.0.0.1:8000'
+}
+if(mainForm.backupPath.text==""){
+ mainForm.backupPath.text="D:\Daq\Backup"
+}
+/*
+if(table.count(mainForm.listview.items)==0){
+ mainForm.listview.items = {{"JN102";"D:\tmp"}};
+}
+*/
+
+var isWorking = false;
+var atom,hwnd/*冲突窗口的句柄,该函数会自动激活此窗口*/ = mainForm.atom("33D501DF-BFC2-4283-8BBE-AF17AADB1C27");
+if(!atom){
+ /*为窗口设置原子值可以避免一个程序重复运行多个实例*/
+ win.quitMessage(); return;
+}
+
+
+mainForm.onMinimize = function(lParam){
+ var tray = win.util.tray(mainForm) //创建托盘图标
+ tray.tip = "数据采集";
+ mainForm.show(false); //隐藏窗口
+ return true;//阻击默认消息传递,取消最小化过程
+}
+mainForm.wndproc = {
+ [0xACCF/*_WM_TRAYMESSAGE*/ ] = function(hwnd,message,wParam,lParam){
+ if( lParam = 0x205/*_WM_RBUTTONUP*/ ){
+ var pt = ::POINT();
+ ::User32.GetCursorPos(pt);
+ //弹出托盘菜单以前,一定要前置主窗口中,不然不点击菜单不会消失
+ win.setForeground(mainForm.hwnd)
+ mainForm.popmenu.popup(pt.x,pt.y,true )
+ }elseif(lParam = 0x203/*_WM_LBUTTONDBLCLK*/){
+ mainForm.show()
+ }
+
+
+ }
+}
+
+mainForm.popmenu = win.ui.popmenu(mainForm);//创建弹出菜单
+mainForm.popmenu.add('&打开',function(id){
+ //在下面输入菜单响应代码
+ mainForm.show()
+});
+mainForm.popmenu.add();//分隔线
+mainForm.popmenu.add('&退出',function(id){ mainForm.close() })
+
+mainForm.start.oncommand = function(id,event){
+ toggleWorking();
+
+}
+var timer = win.timer( mainForm );
+timer.setInterval(5000)
+function toggleWorking(){
+ if(isWorking == false){
+ mainForm.serverUrl.disabled = true
+ mainForm.backupPath.disabled = true
+ mainForm.add.disabled = true
+ mainForm.statusLabel.text="采集中..."
+ mainForm.start.text="停止采集"
+ isWorking = true
+ timer.enable()
+ }else{
+ mainForm.serverUrl.disabled = false
+ mainForm.backupPath.disabled = false
+ mainForm.add.disabled = false
+ mainForm.statusLabel.text=""
+ mainForm.start.text="开始采集"
+ isWorking=false
+ timer.disable()
+ }
+}
+if(mainForm.serverUrl && table.count(mainForm.listview.items)>0){
+toggleWorking();
+}
+
+timer.onTimer = function(hwnd,msg,id,tick){
+ for itemIndex in mainForm.listview.each(){
+ var number, dir = mainForm.listview.items[itemIndex][1], mainForm.listview.items[itemIndex][2]
+ //批量处理文件
+ fsys.enum( dir, //指定要遍历的目录
+ "*.*", //指定查询文件名,支持windows掩码
+ function(dir,filename,fullpath,findData){ //指定触发器
+ if(filename){
+ mainForm.listbox.add(tostring(time.now(),"%Y-%m-%d %H:%M:%S","chs") + ":新文件-"+filename, -1)
+ mainForm.listbox.add("正在上传并解析...")
+ var webData = web.multipartFormData();
+ webData.add("equip_num", number)
+ webData.add("file", "@"+fullpath)
+ webData.contentHeader()
+ var http = inet.http();
+ /*
+http.beginRequest( mainForm.serverUrl.text + "/api/em/daq/", "POST" );
+ //小数据一次性上传
+ http.beginSendData(webData.size());
+ http.writeData(webData.readAll())
+ http.endSendData();
+*/
+ var html,err,errCode = http.post( mainForm.serverUrl.text + "/api/em/daq/",webData.readAll(),webData.contentHeader());
+ if(html){
+ var res = web.json.parse(html)
+ if(res['code']==200){
+ import fsys
+ var theDir = fsys.createDir(mainForm.backupPath.text+"\"+number, false)
+ fsys.move(fullpath, theDir) //移动到备份文件库
+ mainForm.listbox.add("采集成功!")
+ }else{
+ mainForm.listbox.add("失败:"+res['msg'])
+ }
+ }else{
+ mainForm.listbox.add("失败:请求错误")
+ }
+
+
+
+ }
+ }, false
+ );
+ }
+}
+
+mainForm.listview.onnotify = function(id,code,ptr){
+
+ select(code) {
+ case 0xFFFFFFFB/*_NM_RCLICK*/ {
+ var x,y = win.getCursorPos();
+ var popmenu = win.ui.popmenu(mainForm);//创建弹出菜单
+ popmenu.add('删除',function(id){
+ //在下面输入菜单响应代码
+ mainForm.listview.delItem( mainForm.listview.selIndex )
+ });
+ popmenu.popup(x,y,true);//弹出菜单
+ }
+ }
+
+}
+
+mainForm.add.oncommand = function(id,event){
+
+var frmChild = mainForm.loadForm("\dlg\add.aardio");
+frmChild.doModal();
+
+}
+
+
+
+
+
+mainForm.show();
+return win.loopMessage();
\ No newline at end of file
diff --git a/hb_server/apps/em/serializers.py b/hb_server/apps/em/serializers.py
index b17e860..a200114 100644
--- a/hb_server/apps/em/serializers.py
+++ b/hb_server/apps/em/serializers.py
@@ -1,3 +1,4 @@
+from rest_framework import serializers
from rest_framework.serializers import ModelSerializer
from .models import Equipment,Equipmentrecord
@@ -34,4 +35,8 @@ class EquipmentrecordSerializer(ModelSerializer):
def setup_eager_loading(queryset):
""" Perform necessary eager loading of data. """
queryset = queryset.select_related('equipment')
- return queryset
\ No newline at end of file
+ return queryset
+
+class DaqCreateSerializer(serializers.Serializer):
+ number = serializers.CharField()
+ file = serializers.FileField()
\ No newline at end of file
diff --git a/hb_server/apps/em/urls.py b/hb_server/apps/em/urls.py
index a2f58d8..e2f7e91 100644
--- a/hb_server/apps/em/urls.py
+++ b/hb_server/apps/em/urls.py
@@ -1,6 +1,6 @@
from django.db.models import base
from rest_framework import urlpatterns
-from apps.em.views import EquipmentViewSet,EquipmentrecordViewSet
+from apps.em.views import DaqView, EquipmentViewSet,EquipmentrecordViewSet
from django.urls import path, include
from rest_framework.routers import DefaultRouter
@@ -8,6 +8,7 @@ router = DefaultRouter()
router.register('equipment', EquipmentViewSet, basename='equipment')
router.register('equipmentrecord', EquipmentrecordViewSet, basename='equipmentrecord')
urlpatterns = [
+ path('daq/', DaqView.as_view()),
path('', include(router.urls)),
]
diff --git a/hb_server/apps/em/views.py b/hb_server/apps/em/views.py
index 64ad57d..00ae4b9 100644
--- a/hb_server/apps/em/views.py
+++ b/hb_server/apps/em/views.py
@@ -1,10 +1,12 @@
from django.shortcuts import render
+from rest_framework.exceptions import APIException
+from rest_framework.views import APIView
from rest_framework.viewsets import ModelViewSet
from rest_framework import serializers, status
from rest_framework.response import Response
from apps.em.models import Equipment,Equipmentrecord
-from apps.em.serializers import EquipmentSerializer,EquipmentrecordSerializer
+from apps.em.serializers import DaqCreateSerializer, EquipmentSerializer,EquipmentrecordSerializer
from apps.system.mixins import CreateUpdateModelAMixin, OptimizationMixin
@@ -57,4 +59,28 @@ class EquipmentrecordViewSet(CreateUpdateModelAMixin, OptimizationMixin, ModelVi
serializer = self.get_serializer(id, data=data)
serializer.is_valid(raise_exception=True)
serializer.save()
- return Response(status=status.HTTP_200_OK)
\ No newline at end of file
+ return Response(status=status.HTTP_200_OK)
+
+import uuid
+import os
+from django.conf import settings
+from rest_framework.parsers import MultiPartParser
+class DaqView(APIView):
+ """
+ 数据采集
+ """
+ authentication_classes = []
+ permission_classes = []
+ parser_classes = [MultiPartParser]
+
+ def post(self, request, format=None):
+ data = request.data
+ file = data.get('file', None)
+ equip_num = data.get('equip_num', None)
+ filename = str(uuid.uuid4())
+ filepath = settings.BASE_DIR +'/temp/' + filename + os.path.splitext(file.name)[-1]
+ with open(filepath, 'wb') as f:
+ for chunk in file.chunks():
+ f.write(chunk)
+ return Response()
+ # raise APIException('解析失败')
\ No newline at end of file
diff --git a/hb_server/apps/mtm/serializers.py b/hb_server/apps/mtm/serializers.py
index 68b214b..004d3d3 100644
--- a/hb_server/apps/mtm/serializers.py
+++ b/hb_server/apps/mtm/serializers.py
@@ -25,7 +25,7 @@ class MaterialDetailSerializer(serializers.ModelSerializer):
class MaterialSimpleSerializer(serializers.ModelSerializer):
class Meta:
model = Material
- fields = ['id', 'name', 'number', 'unit']
+ fields = ['id', 'name', 'number', 'unit','specification']
class ProcessSerializer(serializers.ModelSerializer):
instruction_ = FileSimpleSerializer(source='instruction', read_only=True)
diff --git a/hb_server/apps/mtm/views.py b/hb_server/apps/mtm/views.py
index c58ed9f..317575c 100644
--- a/hb_server/apps/mtm/views.py
+++ b/hb_server/apps/mtm/views.py
@@ -100,7 +100,7 @@ class InputMaterialViewSet(CreateUpdateModelAMixin, ModelViewSet):
perms_map = {'*':'*'}
queryset = InputMaterial.objects.select_related('material').all()
serializer_class = InputMaterialSerializer
- filterset_fields = ['process', 'material']
+ filterset_fields = ['process', 'product']
ordering = ['sort', '-create_time']
def get_serializer_class(self):
@@ -117,7 +117,7 @@ class OutputMaterialViewSet(CreateUpdateModelAMixin, ModelViewSet):
perms_map = {'*':'*'}
queryset = OutputMaterial.objects.select_related('material').all()
serializer_class = OutputMaterialSerializer
- filterset_fields = ['process', 'material']
+ filterset_fields = ['process', 'product']
ordering = ['sort', '-create_time']
def get_serializer_class(self):
diff --git a/hb_server/apps/sam/migrations/0003_contract_invoice.py b/hb_server/apps/sam/migrations/0003_contract_invoice.py
new file mode 100644
index 0000000..d4031f3
--- /dev/null
+++ b/hb_server/apps/sam/migrations/0003_contract_invoice.py
@@ -0,0 +1,18 @@
+# Generated by Django 3.2.6 on 2021-09-22 01:42
+
+from django.db import migrations, models
+
+
+class Migration(migrations.Migration):
+
+ dependencies = [
+ ('sam', '0002_auto_20210913_0954'),
+ ]
+
+ operations = [
+ migrations.AddField(
+ model_name='contract',
+ name='invoice',
+ field=models.IntegerField(default=0, verbose_name='开票金额'),
+ ),
+ ]
diff --git a/hb_server/apps/sam/models.py b/hb_server/apps/sam/models.py
index b03e471..4683844 100644
--- a/hb_server/apps/sam/models.py
+++ b/hb_server/apps/sam/models.py
@@ -31,9 +31,17 @@ class Contract(CommonAModel):
"""
合同信息
"""
+ state_choices = (
+ (0, '完好'),
+ (1, '限用'),
+ (2, '在修'),
+ (3, '禁用')
+ )
name = models.CharField('合同名称', max_length=100)
number = models.CharField('合同编号', max_length=100, unique=True)
amount = models.IntegerField('合同金额', default=0)
+ invoice = models.IntegerField('开票金额', default=0)
+ #state = models.CharField('合同状态', choices= state_choices, max_length=20, default=1)
customer = models.ForeignKey(Customer, verbose_name='关联客户', on_delete=models.CASCADE, related_name='contact_customer')
sign_date = models.DateField('签订日期')
description = models.CharField('描述', max_length=200, blank=True, null=True)