Jelajahi Sumber

开始编写出库

flower_mr 1 bulan lalu
induk
melakukan
52398b175c

TEMPAT SAMPAH
bin/__pycache__/models.cpython-38.pyc


TEMPAT SAMPAH
bin/__pycache__/views.cpython-38.pyc


+ 1 - 0
bin/models.py

@@ -117,6 +117,7 @@ class LocationModel(models.Model):
                     # 创建库位
                     cls.objects.update_or_create(
                         warehouse_code=warehouse_code,
+                        warehouse_name="立体仓库",
                         row=row,
                         col=col,
                         layer=layer,

+ 0 - 1
bin/views.py

@@ -297,7 +297,6 @@ class LocationAllocation:
             print(f"获取库位组剩余数量失败:{str(e)}")
             return None
 
-
     @transaction.atomic
     def update_location_container_link(self,location_code,container_code):
         """

TEMPAT SAMPAH
bound/__pycache__/models.cpython-38.pyc


+ 18 - 0
bound/migrations/0004_boundbatchmodel_goods_unit.py

@@ -0,0 +1,18 @@
+# Generated by Django 4.1.2 on 2025-04-22 10:24
+
+from django.db import migrations, models
+
+
+class Migration(migrations.Migration):
+
+    dependencies = [
+        ('bound', '0003_boundbatchmodel_container_number'),
+    ]
+
+    operations = [
+        migrations.AddField(
+            model_name='boundbatchmodel',
+            name='goods_unit',
+            field=models.CharField(default='待填写', max_length=255, verbose_name='商品单位'),
+        ),
+    ]

TEMPAT SAMPAH
bound/migrations/__pycache__/0004_boundbatchmodel_goods_unit.cpython-38.pyc


+ 1 - 0
bound/models.py

@@ -48,6 +48,7 @@ class BoundBatchModel(models.Model):
     goods_code = models.CharField(max_length=255, verbose_name="商品编码")
     goods_desc = models.CharField(max_length=255, verbose_name="商品描述")
     goods_std = models.CharField(default='待填写', max_length=255, verbose_name="商品标准")
+    goods_unit = models.CharField(default='待填写', max_length=255, verbose_name="商品单位")
     goods_qty = models.BigIntegerField(default=0, verbose_name="商品数量")
     goods_in_qty = models.BigIntegerField(default=0, verbose_name="入库数量")
     goods_out_qty = models.BigIntegerField(default=0, verbose_name="出库数量")

TEMPAT SAMPAH
container/__pycache__/views.cpython-38.pyc


+ 36 - 11
container/views.py

@@ -14,6 +14,7 @@ from rest_framework import status
 from .models import ContainerListModel,ContainerDetailModel,ContainerOperationModel,ContainerWCSModel,TaskModel
 from bound.models import BoundBatchModel,BoundDetailModel,BoundListModel
 from bin.views import LocationAllocation
+from bin.models import LocationModel
 # from .files import FileListRenderCN, FileDetailRenderCN
 
 from .serializers import ContainerDetailGetSerializer,ContainerDetailPostSerializer
@@ -257,18 +258,14 @@ class ContainerWCSViewSet(viewsets.ModelViewSet):
                         print("❌ 库位组批次更新失败,请检查托盘编码")
                         return
                     print(f"[5]库位组批次更新成功!")
+
+                    update_location_container_link = allocator.update_location_container_link(location_list_cnumber.location_code, container_code)  # 更新库位和托盘的关联关系
+                    if not update_location_container_link:
+                        print("❌ 库位和托盘的关联关系更新失败,请检查托盘编码")
+                        return
+                    print(f"[7]库位和托盘的关联关系更新成功!")
                     
-                    # update_location_status = allocator.update_location_status(location_list_cnumber.location_code, 'occupied')  # 更新库位状态
-                    # if not update_location_status:
-                    #     print("❌ 库位状态更新失败,请检查托盘编码")
-                    #     return
-                    # print(f"[6]WCS到位,库位状态更新成功!")
 
-                    # update_location_container_link = allocator.update_location_container_link(location_list_cnumber.location_code, container_code)  # 更新库位和托盘的关联关系
-                    # if not update_location_container_link:
-                    #     print("❌ 库位和托盘的关联关系更新失败,请检查托盘编码")
-                    #     return
-                    # print(f"[7]库位和托盘的关联关系更新成功!")
                     allocation_target_location = (
                             location_list_cnumber.warehouse_code + '-' 
                             + f"{int(location_list_cnumber.row):02d}" + '-'  
@@ -369,6 +366,27 @@ class ContainerWCSViewSet(viewsets.ModelViewSet):
                     'message': '当前位置已是目标位置',
                     'data': data
                 }
+
+                allocator = LocationAllocation()  # 创建实例
+                location_row = int(container_obj.target_location.split('-')[1])
+                location_col = int(container_obj.target_location.split('-')[2])
+                location_layer = int(container_obj.target_location.split('-')[3])
+                coordinate = f"{location_row}-{location_col}-{location_layer}"
+                print(f"坐标:{coordinate}")
+                location_code = LocationModel.objects.filter(coordinate=coordinate).first().location_code
+                container_code = container
+                update_location_status = allocator.update_location_status(location_code, 'occupied')  # 更新库位状态
+                if not update_location_status:
+                    print("❌ 库位状态更新失败,请检查托盘编码")
+                    return
+                print(f"[6]WCS到位,库位状态更新成功!")
+
+                update_location_container_link = allocator.update_location_container_link(location_code, container_code)  # 更新库位和托盘的关联关系
+                if not update_location_container_link:
+                    print("❌ 库位和托盘的关联关系更新失败,请检查托盘编码")
+                    return
+                print(f"[7]库位和托盘的关联关系更新成功!")
+
             else:
                 current_task = ContainerWCSModel.objects.filter(
                     container=container, 
@@ -394,7 +412,7 @@ class ContainerWCSViewSet(viewsets.ModelViewSet):
                         return
                     print(f"[1]库位:{location_list_cnumber}")
                     
-                    update_location_status = allocator.update_location_status(location_list_cnumber.location_code, 'reserverd')  # 更新库位状态
+                    update_location_status = allocator.update_location_status(location_list_cnumber.location_code, 'reserved')  # 更新库位状态
                     if not update_location_status:
                         print("❌ 库位状态更新失败,请检查托盘编码")
                         return
@@ -417,6 +435,13 @@ class ContainerWCSViewSet(viewsets.ModelViewSet):
                         return
                     print(f"[5]库位组批次更新成功!")
                     
+                    
+                    update_location_container_link = allocator.update_location_container_link(location_list_cnumber.location_code, container_code)  # 更新库位和托盘的关联关系
+                    if not update_location_container_link:
+                        print("❌ 库位和托盘的关联关系更新失败,请检查托盘编码")
+                        return
+                    print(f"[7]库位和托盘的关联关系更新成功!")
+
                     # update_location_status = allocator.update_location_status(location_list_cnumber.location_code, 'occupied')  # 更新库位状态
                     # if not update_location_status:
                     #     print("❌ 库位状态更新失败,请检查托盘编码")  

+ 0 - 0
data_base/__init__.py


TEMPAT SAMPAH
data_base/__pycache__/generate_location.cpython-38.pyc


data_base/generate_location group.py → data_base/generate_location_group.py


+ 93 - 0
data_base/generate_warehouse.py

@@ -0,0 +1,93 @@
+# generate_locations.py
+import os
+import django
+import sys
+
+
+def setup_django():
+    # 使用原始字符串处理Windows路径
+    project_path = "D:/Document/code/vue/greater_wms"
+    sys.path.append(project_path)
+    
+    # 根据实际目录名设置(注意下划线)
+    os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'greaterwms.settings')
+    django.setup()
+
+def main():
+    try:
+        # 从正确的应用导入模型
+        from warehouse.models import ListModel,DepartmentListModel,BoundTypeListModel,BoundBSListModel,BoundCodeTypeListModel,BoundStatusListModel,ProductListModel
+
+        warehouse_code = "W01"
+        ListModel.objects.filter(openid="PDA1").delete()
+        warehouse_obj =ListModel.objects.create(
+            warehouse_code=warehouse_code,
+            warehouse_name="立体仓库",
+            warehouse_city="测试城市",
+            warehouse_address="测试地址",
+            warehouse_contact="测试联系人",
+            warehouse_manager="测试经理",
+            creater="测试创建人",
+            openid="PDA1",
+            is_delete=False,
+
+        )
+        print(f"开始生成库位,仓库编码:{warehouse_code}")
+        DepartmentListModel.objects.filter(openid="PDA1").delete()
+        DepartmentListModel.objects.create(
+            department_code="D01",
+            department_name="测试部门",
+            department_contact="测试联系人",
+            department_manager="测试经理",
+            openid="PDA1",
+            creater="测试创建人",
+            is_delete=False,
+        )
+        BoundTypeListModel.objects.filter(openid="PDA1").delete()
+        BoundTypeListModel.objects.create(
+            bound_type_code="B01",
+            bound_type_name="立体包装",
+            creater="测试创建人",
+            openid="PDA1",
+            is_delete=False,
+        )
+        BoundBSListModel.objects.filter(openid="PDA1").delete()
+        BoundBSListModel.objects.create(
+            bound_bs_code="B01",
+            bound_bs_name="测试业务",
+            creater="测试创建人",
+            openid="PDA1",
+            is_delete=False,
+        )
+        BoundCodeTypeListModel.objects.filter(openid="PDA1").delete()
+        BoundCodeTypeListModel.objects.create(
+            bound_code_type_code="BC01",
+            bound_code_type_name="测试编码类型",
+            creater="测试创建人",
+            openid="PDA1",
+            is_delete=False,
+        )
+        code = [100,101,102]
+        name = ["入库申请","入库同意","组盘中"]
+        index = 0
+        BoundStatusListModel.objects.filter(openid="PDA1").delete()
+        for i in code:
+            BoundStatusListModel.objects.create(
+                bound_status_code=i,
+                bound_status_name=name[index],
+                creater="测试创建人",
+                openid="PDA1",
+            )
+            index += 1
+
+        print("✅ 库位生成成功!")
+  
+        
+    except Exception as e:
+        print(f"❌ 生成失败:{str(e)}")
+        import traceback
+        traceback.print_exc()
+
+if __name__ == "__main__":
+    setup_django()
+    main()

+ 0 - 2
data_base/import requests.py

@@ -1,2 +0,0 @@
-import requests
-print(requests.utils.get_environ_proxies('https://example.com'))

+ 6 - 0
data_base/init.ps1

@@ -0,0 +1,6 @@
+python generate_warehouse.py
+# python generate_location.py
+python generate_location_group.py
+# python import_data.py
+# python import_product.py
+

+ 8 - 4
data_base/test_allocation.py

@@ -28,19 +28,23 @@ def main():
         from bin.views import LocationAllocation
         
         # container_code =["12346", "12345", "1", "2", "7"]
-        container_code =["12345"]
+        container_code =["11111"]
         allocator = LocationAllocation()  # 创建实例
 
         for code in container_code:  # Iterate through each container code
             print(f"开始生成库位,托盘编码:{code}")
-            allocator.get_location_type(code) 
+            # allocator.get_location_type(code) 
             # location_type = allocator.get_location_by_status(code,'in2')  # 获取库位类型
             # if not location_type:
             #     print("❌ 库位类型获取失败,请检查托盘数量")
             #     return
             # print(f"库位类型:{location_type}")
-      
-        
+            number=allocator.get_pallet_count_by_batch(code) 
+            if number is None:
+                print("❌ 该批次下无托盘,请检查托盘编码")
+                return
+            print(f"该批次下托盘总数:{number}")
+            
         # # 调用生成方法
         # # 修改调用部分的代码
         # number=allocator.get_pallet_count_by_batch(container_code)  # 通过实例调用)

TEMPAT SAMPAH
db.sqlite3


+ 181 - 0
logs/error.log

@@ -2498,3 +2498,184 @@ Traceback (most recent call last):
 AttributeError: 'NoneType' object has no attribute 'openid'
 [2025-04-21 10:03:23,692][django.request.log_response():241] [ERROR] Internal Server Error: /container/container_wcs/update/
 [2025-04-21 10:03:41,561][django.request.log_response():241] [ERROR] Internal Server Error: /container/container_wcs/
+[2025-04-21 23:32:28,153][django.request.log_response():241] [ERROR] Internal Server Error: /container/container_wcs/
+[2025-04-21 23:33:12,590][django.request.log_response():241] [ERROR] Internal Server Error: /container/container_wcs/
+[2025-04-21 23:33:43,300][django.request.log_response():241] [ERROR] Internal Server Error: /container/container_wcs/
+[2025-04-21 23:34:29,925][django.request.log_response():241] [ERROR] Internal Server Error: /container/container_wcs/
+[2025-04-21 23:35:04,166][django.request.log_response():241] [ERROR] Internal Server Error: /container/container_wcs/
+[2025-04-22 09:53:30,598][django.request.log_response():241] [ERROR] Internal Server Error: /bound/detail/
+Traceback (most recent call last):
+  File "d:\language\python38\lib\site-packages\asgiref\sync.py", line 472, in thread_handler
+    raise exc_info[1]
+  File "d:\language\python38\lib\site-packages\django\core\handlers\exception.py", line 42, in inner
+    response = await get_response(request)
+  File "d:\language\python38\lib\site-packages\django\core\handlers\base.py", line 253, in _get_response_async
+    response = await wrapped_callback(
+  File "d:\language\python38\lib\site-packages\asgiref\sync.py", line 435, in __call__
+    ret = await asyncio.wait_for(future, timeout=None)
+  File "d:\language\python38\lib\asyncio\tasks.py", line 455, in wait_for
+    return await fut
+  File "d:\language\python38\lib\concurrent\futures\thread.py", line 57, in run
+    result = self.fn(*self.args, **self.kwargs)
+  File "d:\language\python38\lib\site-packages\asgiref\sync.py", line 476, in thread_handler
+    return func(*args, **kwargs)
+  File "d:\language\python38\lib\site-packages\django\views\decorators\csrf.py", line 54, in wrapped_view
+    return view_func(*args, **kwargs)
+  File "d:\language\python38\lib\site-packages\rest_framework\viewsets.py", line 125, in view
+    return self.dispatch(request, *args, **kwargs)
+  File "d:\language\python38\lib\site-packages\rest_framework\views.py", line 509, in dispatch
+    response = self.handle_exception(exc)
+  File "d:\language\python38\lib\site-packages\rest_framework\views.py", line 469, in handle_exception
+    self.raise_uncaught_exception(exc)
+  File "d:\language\python38\lib\site-packages\rest_framework\views.py", line 480, in raise_uncaught_exception
+    raise exc
+  File "d:\language\python38\lib\site-packages\rest_framework\views.py", line 506, in dispatch
+    response = handler(request, *args, **kwargs)
+  File "D:\Document\code\vue\greater_wms\.\bound\views.py", line 263, in create
+    data['detail_code'] = f"DC-{data['bound_list']:02}{data['bound_batch']:02}"
+KeyError: 'bound_batch'
+[2025-04-22 09:53:48,855][django.request.log_response():241] [ERROR] Internal Server Error: /bound/detail/
+Traceback (most recent call last):
+  File "d:\language\python38\lib\site-packages\asgiref\sync.py", line 472, in thread_handler
+    raise exc_info[1]
+  File "d:\language\python38\lib\site-packages\django\core\handlers\exception.py", line 42, in inner
+    response = await get_response(request)
+  File "d:\language\python38\lib\site-packages\django\core\handlers\base.py", line 253, in _get_response_async
+    response = await wrapped_callback(
+  File "d:\language\python38\lib\site-packages\asgiref\sync.py", line 435, in __call__
+    ret = await asyncio.wait_for(future, timeout=None)
+  File "d:\language\python38\lib\asyncio\tasks.py", line 455, in wait_for
+    return await fut
+  File "d:\language\python38\lib\concurrent\futures\thread.py", line 57, in run
+    result = self.fn(*self.args, **self.kwargs)
+  File "d:\language\python38\lib\site-packages\asgiref\sync.py", line 476, in thread_handler
+    return func(*args, **kwargs)
+  File "d:\language\python38\lib\site-packages\django\views\decorators\csrf.py", line 54, in wrapped_view
+    return view_func(*args, **kwargs)
+  File "d:\language\python38\lib\site-packages\rest_framework\viewsets.py", line 125, in view
+    return self.dispatch(request, *args, **kwargs)
+  File "d:\language\python38\lib\site-packages\rest_framework\views.py", line 509, in dispatch
+    response = self.handle_exception(exc)
+  File "d:\language\python38\lib\site-packages\rest_framework\views.py", line 469, in handle_exception
+    self.raise_uncaught_exception(exc)
+  File "d:\language\python38\lib\site-packages\rest_framework\views.py", line 480, in raise_uncaught_exception
+    raise exc
+  File "d:\language\python38\lib\site-packages\rest_framework\views.py", line 506, in dispatch
+    response = handler(request, *args, **kwargs)
+  File "D:\Document\code\vue\greater_wms\.\bound\views.py", line 263, in create
+    data['detail_code'] = f"DC-{data['bound_list']:02}{data['bound_batch']:02}"
+KeyError: 'bound_batch'
+[2025-04-22 09:54:14,503][django.request.log_response():241] [ERROR] Internal Server Error: /bound/detail/
+Traceback (most recent call last):
+  File "d:\language\python38\lib\site-packages\asgiref\sync.py", line 472, in thread_handler
+    raise exc_info[1]
+  File "d:\language\python38\lib\site-packages\django\core\handlers\exception.py", line 42, in inner
+    response = await get_response(request)
+  File "d:\language\python38\lib\site-packages\django\core\handlers\base.py", line 253, in _get_response_async
+    response = await wrapped_callback(
+  File "d:\language\python38\lib\site-packages\asgiref\sync.py", line 435, in __call__
+    ret = await asyncio.wait_for(future, timeout=None)
+  File "d:\language\python38\lib\asyncio\tasks.py", line 455, in wait_for
+    return await fut
+  File "d:\language\python38\lib\concurrent\futures\thread.py", line 57, in run
+    result = self.fn(*self.args, **self.kwargs)
+  File "d:\language\python38\lib\site-packages\asgiref\sync.py", line 476, in thread_handler
+    return func(*args, **kwargs)
+  File "d:\language\python38\lib\site-packages\django\views\decorators\csrf.py", line 54, in wrapped_view
+    return view_func(*args, **kwargs)
+  File "d:\language\python38\lib\site-packages\rest_framework\viewsets.py", line 125, in view
+    return self.dispatch(request, *args, **kwargs)
+  File "d:\language\python38\lib\site-packages\rest_framework\views.py", line 509, in dispatch
+    response = self.handle_exception(exc)
+  File "d:\language\python38\lib\site-packages\rest_framework\views.py", line 469, in handle_exception
+    self.raise_uncaught_exception(exc)
+  File "d:\language\python38\lib\site-packages\rest_framework\views.py", line 480, in raise_uncaught_exception
+    raise exc
+  File "d:\language\python38\lib\site-packages\rest_framework\views.py", line 506, in dispatch
+    response = handler(request, *args, **kwargs)
+  File "D:\Document\code\vue\greater_wms\.\bound\views.py", line 263, in create
+    data['detail_code'] = f"DC-{data['bound_list']:02}{data['bound_batch']:02}"
+KeyError: 'bound_batch'
+[2025-04-22 09:54:38,825][django.request.log_response():241] [ERROR] Internal Server Error: /bound/detail/
+Traceback (most recent call last):
+  File "d:\language\python38\lib\site-packages\asgiref\sync.py", line 472, in thread_handler
+    raise exc_info[1]
+  File "d:\language\python38\lib\site-packages\django\core\handlers\exception.py", line 42, in inner
+    response = await get_response(request)
+  File "d:\language\python38\lib\site-packages\django\core\handlers\base.py", line 253, in _get_response_async
+    response = await wrapped_callback(
+  File "d:\language\python38\lib\site-packages\asgiref\sync.py", line 435, in __call__
+    ret = await asyncio.wait_for(future, timeout=None)
+  File "d:\language\python38\lib\asyncio\tasks.py", line 455, in wait_for
+    return await fut
+  File "d:\language\python38\lib\concurrent\futures\thread.py", line 57, in run
+    result = self.fn(*self.args, **self.kwargs)
+  File "d:\language\python38\lib\site-packages\asgiref\sync.py", line 476, in thread_handler
+    return func(*args, **kwargs)
+  File "d:\language\python38\lib\site-packages\django\views\decorators\csrf.py", line 54, in wrapped_view
+    return view_func(*args, **kwargs)
+  File "d:\language\python38\lib\site-packages\rest_framework\viewsets.py", line 125, in view
+    return self.dispatch(request, *args, **kwargs)
+  File "d:\language\python38\lib\site-packages\rest_framework\views.py", line 509, in dispatch
+    response = self.handle_exception(exc)
+  File "d:\language\python38\lib\site-packages\rest_framework\views.py", line 469, in handle_exception
+    self.raise_uncaught_exception(exc)
+  File "d:\language\python38\lib\site-packages\rest_framework\views.py", line 480, in raise_uncaught_exception
+    raise exc
+  File "d:\language\python38\lib\site-packages\rest_framework\views.py", line 506, in dispatch
+    response = handler(request, *args, **kwargs)
+  File "D:\Document\code\vue\greater_wms\.\bound\views.py", line 263, in create
+    data['detail_code'] = f"DC-{data['bound_list']:02}{data['bound_batch']:02}"
+KeyError: 'bound_batch'
+[2025-04-22 09:55:15,443][django.request.log_response():241] [ERROR] Internal Server Error: /bound/detail/
+Traceback (most recent call last):
+  File "d:\language\python38\lib\site-packages\asgiref\sync.py", line 472, in thread_handler
+    raise exc_info[1]
+  File "d:\language\python38\lib\site-packages\django\core\handlers\exception.py", line 42, in inner
+    response = await get_response(request)
+  File "d:\language\python38\lib\site-packages\django\core\handlers\base.py", line 253, in _get_response_async
+    response = await wrapped_callback(
+  File "d:\language\python38\lib\site-packages\asgiref\sync.py", line 435, in __call__
+    ret = await asyncio.wait_for(future, timeout=None)
+  File "d:\language\python38\lib\asyncio\tasks.py", line 455, in wait_for
+    return await fut
+  File "d:\language\python38\lib\concurrent\futures\thread.py", line 57, in run
+    result = self.fn(*self.args, **self.kwargs)
+  File "d:\language\python38\lib\site-packages\asgiref\sync.py", line 476, in thread_handler
+    return func(*args, **kwargs)
+  File "d:\language\python38\lib\site-packages\django\views\decorators\csrf.py", line 54, in wrapped_view
+    return view_func(*args, **kwargs)
+  File "d:\language\python38\lib\site-packages\rest_framework\viewsets.py", line 125, in view
+    return self.dispatch(request, *args, **kwargs)
+  File "d:\language\python38\lib\site-packages\rest_framework\views.py", line 509, in dispatch
+    response = self.handle_exception(exc)
+  File "d:\language\python38\lib\site-packages\rest_framework\views.py", line 469, in handle_exception
+    self.raise_uncaught_exception(exc)
+  File "d:\language\python38\lib\site-packages\rest_framework\views.py", line 480, in raise_uncaught_exception
+    raise exc
+  File "d:\language\python38\lib\site-packages\rest_framework\views.py", line 506, in dispatch
+    response = handler(request, *args, **kwargs)
+  File "D:\Document\code\vue\greater_wms\.\bound\views.py", line 263, in create
+    data['detail_code'] = f"DC-{data['bound_list']:02}{data['bound_batch']:02}"
+KeyError: 'bound_batch'
+[2025-04-22 11:24:14,028][django.request.log_response():241] [ERROR] Internal Server Error: /container/container_wcs/update
+Traceback (most recent call last):
+  File "d:\language\python38\lib\site-packages\asgiref\sync.py", line 472, in thread_handler
+    raise exc_info[1]
+  File "d:\language\python38\lib\site-packages\django\core\handlers\exception.py", line 42, in inner
+    response = await get_response(request)
+  File "d:\language\python38\lib\site-packages\django\utils\deprecation.py", line 148, in __acall__
+    response = await sync_to_async(
+  File "d:\language\python38\lib\site-packages\asgiref\sync.py", line 435, in __call__
+    ret = await asyncio.wait_for(future, timeout=None)
+  File "d:\language\python38\lib\asyncio\tasks.py", line 455, in wait_for
+    return await fut
+  File "d:\language\python38\lib\concurrent\futures\thread.py", line 57, in run
+    result = self.fn(*self.args, **self.kwargs)
+  File "d:\language\python38\lib\site-packages\asgiref\sync.py", line 476, in thread_handler
+    return func(*args, **kwargs)
+  File "d:\language\python38\lib\site-packages\django\middleware\common.py", line 54, in process_request
+    path = self.get_full_path_with_slash(request)
+  File "d:\language\python38\lib\site-packages\django\middleware\common.py", line 88, in get_full_path_with_slash
+    raise RuntimeError(
+RuntimeError: You called this URL via PUT, but the URL doesn't end in a slash and you have APPEND_SLASH set. Django can't redirect to the slash URL while maintaining PUT data. Change your form to point to 127.0.0.1:8008/container/container_wcs/update/ (note the trailing slash), or set APPEND_SLASH=False in your Django settings.

File diff ditekan karena terlalu besar
+ 1228 - 0
logs/server.log


+ 575 - 0
templates/src/components/goodscard copy.vue

@@ -0,0 +1,575 @@
+<template>
+    <div  :style="{ backgroundColor: bgColor }">
+        <div style="color: transparent;">1111</div>
+        <q-dialog v-model="clickedinput" transition-show="jump-down" transition-hide="jump-up">
+            <q-card style="min-width: 350px; ">
+                <q-bar class="bg-light-blue-10 text-white rounded-borders" style="height: 50px">
+                    <div>
+                        {{ $t("stock.bin_setting") }}
+                    </div>
+                    <q-space></q-space>
+                    <q-btn dense flat icon="close" v-close-popup>
+                        <q-tooltip content-class="bg-amber text-black shadow-4" :offset="[20, 20]"
+                            content-style="font-size: 12px">
+                            {{ $t("index.close") }}</q-tooltip>
+                    </q-btn>
+                </q-bar>
+                <q-card-section class="flex flex-center">
+                    <q-select ref="select" v-model="selected.label" :options="options" label="库位定义:" outlined
+                        stack-label dense option-label="label" option-value="value" style="width: 90%"
+                        class="q-my-md text-center" input-class="text-center">
+                        <template v-slot:option="scope">
+                            <q-item v-bind="scope.itemProps" class="text-center" @click="handleSelect(scope)">
+                                <q-item-section>{{ scope.opt.label }}</q-item-section>
+                            </q-item>
+                        </template>
+                    </q-select>
+                </q-card-section>
+                <div class="row justify-end q-pa-md q-gutter-x-md">
+                    <q-btn color="primary" text-color="white" style="margin-right: 25px" v-close-popup class="q-px-lg">
+                        {{ $t('cancel') }}</q-btn>
+                    <q-btn color="primary" text-color="white" style="margin-right: 25px" @click=submit()
+                        class="q-px-lg">
+                        {{ $t('submit') }}</q-btn>
+
+                </div>
+            </q-card>
+        </q-dialog>
+        <q-dialog v-model="storage_dialog" transition-show="jump-down" transition-hide="jump-up" @show=prepareDialog()>
+            <q-card style="min-width: 600px; ">
+                <q-bar class="bg-light-blue-10 text-white rounded-borders" style="height: 50px">
+                    <div>
+                        {{ $t("stock.shelf.shelf_details")  }} {{ rowIndex }}-{{ colIndex }}-{{layerIndex}}
+                    </div>
+                    <q-space></q-space>
+                    <q-btn dense flat icon="close" v-close-popup>
+                        <q-tooltip content-class="bg-amber text-black shadow-4" :offset="[20, 20]"
+                            content-style="font-size: 12px">
+                            {{ $t("index.close") }}</q-tooltip>
+                    </q-btn>
+                </q-bar>
+                <q-card-section class="q-pt-md ">
+                    <q-tabs v-model="activeTab">
+                        <q-tab name="tab1" label="货架属性" />
+                        <q-tab name="tab2" label="货物信息" />
+                        <q-tab name="tab3" label="库存明细" />
+                    </q-tabs>
+                </q-card-section>
+                <!-- 选项卡内容 -->
+                <q-tab-panels v-model="activeTab" animated>
+                    <q-tab-panel name="tab1" style="height:300px">
+                        <div class="row q-gutter-x-md">
+                            <div class="col column q-gutter-y-md">
+                                <q-input dense outlined square v-model="storage_form.shelf_warehouse"
+                                    :label="$t('stock.shelf.shelf_warehouse')" :readonly="onlyread"
+                                    :rules="[val => val?.length > 0 || error1]" />
+                                <q-input dense outlined square v-model="storage_form.shelf_name"
+                                    :label="$t('stock.shelf.shelf_name')" :readonly="onlyread"
+                                    :rules="[val => val?.length > 0 || error1]" />
+                                <q-input dense outlined square v-model="storage_form.goods_code"
+                                    :label="$t('stock.shelf.goods_code')" :readonly="onlyread"
+                                    :rules="[val => val?.length > 0 || error1]" />
+
+                            </div>
+                            <div class="col column q-gutter-y-md">
+                                <q-input dense outlined square v-model="storage_form.shelf_department"
+                                    :label="$t('stock.shelf.shelf_department')" :readonly="onlyread"
+                                    :rules="[val => val?.length > 0 || error1]" />
+                                <q-input dense outlined square v-model="storage_form.shelf_status"
+                                    :label="$t('stock.shelf.shelf_status')" :readonly="onlyread"
+                                    :rules="[val => val?.length > 0 || error1]" />
+
+                                <q-input dense outlined square v-model="storage_form.goods_name"
+                                    :label="$t('stock.shelf.goods_name')" :readonly="onlyread"
+                                    :rules="[val => val?.length > 0 || error1]" />
+
+                            </div>
+                        </div>
+
+                    </q-tab-panel>
+                    <q-tab-panel name="tab2" style="height:300px">
+                        <div class="row q-gutter-x-md">
+                            <div class="col column q-gutter-y-md">
+                                <q-input dense outlined square v-model="storage_form.goods_code"
+                                    :label="$t('stock.shelf.goods_code')" :readonly="onlyread"
+                                    :rules="[val => val?.length > 0 || error1]" />
+                                <q-input dense outlined square v-model="storage_form.goods_batch"
+                                    :label="$t('stock.shelf.goods_batch')" :readonly="onlyread"
+                                    :rules="[val => val?.length > 0 || error1]" />
+
+                                <q-input dense outlined square v-model="storage_form.goods_qty"
+                                    :label="$t('stock.shelf.goods_qty')" :readonly="onlyread"
+                                    :rules="[val => val >= 0 || error1]" class="col" />
+                                <q-input dense outlined square v-model="storage_form.goods_desc"
+                                    :label="$t('stock.shelf.goods_desc')" :readonly="onlyread"
+                                    :rules="[val => val?.length > 0 || error1]" />
+
+                            </div>
+                            <div class="col column q-gutter-y-md">
+                                <q-input dense outlined square v-model="storage_form.goods_name"
+                                    :label="$t('stock.shelf.goods_name')" :readonly="onlyread"
+                                    :rules="[val => val?.length > 0 || error1]" />
+                                <q-input dense outlined square v-model="storage_form.goods_std"
+                                    :label="$t('stock.shelf.goods_std')" :readonly="onlyread"
+                                    :rules="[val => val?.length > 0 || error1]" />
+
+                                <q-input dense outlined square v-model="storage_form.goods_unit"
+                                    :label="$t('stock.shelf.goods_unit')" :readonly="onlyread"
+                                    :rules="[val => val?.length > 0 || error1]" />
+                                <q-input dense outlined square v-model="storage_form.goods_notes"
+                                    :label="$t('stock.shelf.goods_notes')" :readonly="onlyread"
+                                    :rules="[val => val?.length > 0 || error1]" />
+
+
+                            </div>
+                        </div>
+                    </q-tab-panel>
+                    <q-tab-panel name="tab3" style="height:300px">
+                        <div class="row q-gutter-x-md">
+                            <div class="col column q-gutter-y-md">
+                            </div>
+                            <div class="col column q-gutter-y-md"></div>
+                        </div>
+                    </q-tab-panel>
+                </q-tab-panels>
+                <div style="position: absolute; right: 20px; bottom: 12px; z-index: 100">
+                    <q-btn-group push>
+                        <q-btn color="white" text-color="black" @click="shelfLocal = 'undefined'; handleclick()">
+                            {{ $t('stock.return') }}
+                        </q-btn>
+                        <q-btn color="white" text-color="black" @click="showInventoryDetails = !showInventoryDetails">
+                            {{ $t('stock.details') }}
+                        </q-btn>
+                        <q-btn color="primary" text-color="white" @click=handleEdit()>
+                            {{ onlyread ? $t('stock.shelf.shelf_edit') : $t("stock.shelf.shelf_confirm") }}
+                        </q-btn>
+                    </q-btn-group>
+                </div>
+
+                <div style="float: right; padding: 15px 15px 50px 15px ;min-width: 100%" flow="row wrap">
+                    <q-card class="q-mb-md" bordered v-if="showInventoryDetails">
+                        <q-card-actions class="q-px-none"
+                            style="position: absolute; right: 20px; top: 10px; z-index: 100">
+                            <q-btn v-if="!onlyread" @click=addInventoryDetail() icon="add" flat dense color="primary"
+                                :label="$t('stock.add')" />
+                            <q-btn v-if="!onlyread" @click=deleteInventoryDetail() icon="delete" flat dense
+                                color="primary" :label="$t('stock.delete')" />
+                        </q-card-actions>
+                        <q-card-section>
+
+                            <div class="text-h6 q-mb-md">{{ $t('stock.inventory_details') }}</div>
+
+                            <!-- 动态生成的输入行 -->
+                            <div v-for="(detail, index) in inventoryDetails" :key="index"
+                                class="row q-col-gutter-md q-mb-sm">
+                                <div class="col">
+                                    <q-input v-model="detail.id" :label="$t('stock.batch')" :readonly="onlyread" dense
+                                        outlined />
+                                </div>
+                                <div class="col">
+                                    <q-input v-model="detail.quantity" :label="$t('stock.quantity')"
+                                        :readonly="onlyread" type="number" dense outlined />
+                                </div>
+                                <div class="col">
+                                    <q-input v-model="detail.location" :label="$t('stock.location')"
+                                        :readonly="onlyread" dense standout outlined />
+                                </div>
+                            </div>
+                        </q-card-section>
+                    </q-card>
+                </div>
+            </q-card>
+        </q-dialog>
+        <q-dialog v-model="elevator_dialog" transition-show="jump-down" transition-hide="jump-up" @show=prepareDialog()>
+            <q-card style="min-width: 350px;">
+                <q-bar class="bg-light-blue-10 text-white rounded-borders" style="height: 50px">
+                    <div>
+                        {{ $t("stock.elevator.elevator") }}
+                    </div>
+                    <q-space></q-space>
+                    <q-btn dense flat icon="close" v-close-popup>
+                        <q-tooltip content-class="bg-amber text-black shadow-4" :offset="[20, 20]"
+                            content-style="font-size: 12px">
+                            {{ $t("index.close") }}</q-tooltip>
+                    </q-btn>
+                </q-bar>
+                <q-card-section class="q-pt-md">
+                    <q-input dense outlined square v-model="elevator_form.ip" :label="$t('stock.elevator.ip')"
+                        :readonly="onlyread" :rules="[val => val?.length > 0 || error1]" />
+                    <q-input dense outlined square v-model="elevator_form.port" :label="$t('stock.elevator.port')"
+                        type="number" :readonly="onlyread" :rules="[
+                            val => val !== null || error1,
+                            val => val >= 0 || error1,
+                        ]" />
+                    <q-input dense outlined square v-model="elevator_form.status" :label="$t('stock.conveyor.status')"
+                        :readonly="onlyread" :rules="[val => val?.length > 0 || error1]" />
+                    <!-- <q-input dense outlined square v-model="elevator_form.password"
+                        :label="$t('stock.elevator.password')" :readonly="onlyread"
+                        :rules="[val => val?.length > 0 || error1]" /> -->
+
+                    <!-- <q-input dense outlined square v-model="elevator_form.username"
+                        :label="$t('stock.elevator.username')" :readonly="onlyread"
+                        :rules="[val => val?.length > 0 || error1]" /> -->
+                </q-card-section>
+                <div style="float: right; padding: 15px 15px 15px 0">
+                    <q-btn color="white" text-color="black" style="margin-right: 25px"
+                        @click="shelfLocal = 'undefined'; handleclick()">
+                        {{ $t('stock.return') }}</q-btn>
+                    <q-btn color="primary" text-color="white" style="margin-right: 25px" @click=handleEdit()>
+                        {{ onlyread ? $t('stock.shelf.shelf_edit') : $t("stock.shelf.shelf_confirm") }}</q-btn>
+                </div>
+            </q-card>
+        </q-dialog>
+        <q-dialog v-model="conveyor_dialog" transition-show="jump-down" transition-hide="jump-up" @show=prepareDialog()>
+            <q-card style="min-width: 350px;">
+                <q-bar class="bg-light-blue-10 text-white rounded-borders" style="height: 50px">
+                    <div>
+                        {{ $t("stock.conveyor.conveyor") }}
+                    </div>
+                    <q-space></q-space>
+                    <q-btn dense flat icon="close" v-close-popup>
+                        <q-tooltip content-class="bg-amber text-black shadow-4" :offset="[20, 20]"
+                            content-style="font-size: 12px">
+                            {{ $t("index.close") }}</q-tooltip>
+                    </q-btn>
+                </q-bar>
+                <q-card-section class="q-pt-md">
+                    <q-input dense outlined square v-model="conveyor_form.ip" :label="$t('stock.conveyor.ip')"
+                        :readonly="onlyread" :rules="[val => val?.length > 0 || error1]" />
+                    <!-- <q-input dense outlined square v-model="conveyor_form.destination"
+                        :label="$t('stock.conveyor.destination')" :readonly="onlyread"
+                        :rules="[val => val?.length > 0 || error1]" /> -->
+                    <q-input dense outlined square v-model="conveyor_form.port" :label="$t('stock.elevator.port')"
+                        type="number" :readonly="onlyread" :rules="[
+                            val => val !== null || error1,
+                            val => val >= 0 || error1,
+                        ]" />
+                    <q-input dense outlined square v-model="conveyor_form.status" :label="$t('stock.conveyor.status')"
+                        :readonly="onlyread" :rules="[val => val?.length > 0 || error1]" />
+                </q-card-section>
+                <div style="float: right; padding: 15px 15px 15px 0">
+                    <q-btn color="white" text-color="black" style="margin-right: 25px"
+                        @click="shelfLocal = 'undefined'; handleclick()">
+                        {{ $t('stock.return') }}</q-btn>
+
+                    <q-btn color="primary" text-color="white" style="margin-right: 25px" @click=handleEdit()>
+                        {{ onlyread ? $t('stock.shelf.shelf_edit') : $t("stock.shelf.shelf_confirm") }}</q-btn>
+
+                </div>
+            </q-card>
+        </q-dialog>
+
+    </div>
+</template>
+
+<script>
+
+
+import { LocalStorage } from 'quasar'
+import { getauth, postauth, putauth, deleteauth, getfile } from 'boot/axios_request'
+
+
+
+export default {
+    props: {
+
+        rowIndex: Number,
+        colIndex: Number,
+        layerIndex: Number,
+        selectedShelfType: String,
+        goodsData: Object,
+
+
+    },
+    data() {
+        return {
+            pathname: 'bin/',
+            pathnamecontainer: 'container/detail/',
+            container_id: 123456,
+            storage_form: {
+                shelf_name: '货架名称',
+                shelf_department: '货架部门',
+                shelf_warehouse: '仓库',
+                shelf_status: '未满',
+                goods_code: 'A010203',
+                goods_name: '存货货物',
+                goods_std: '规格型号',
+                goods_desc: '存货描述',
+                goods_qty: '123456',
+                goods_unit: 'kg',
+                goods_price: '123456',
+                goods_batch: '存货批号',
+                goods_notes: '备注',
+                goods_in: '123456',
+                goods_out: '123456',
+            },
+            elevator_form: {
+                ip: '192.168.1.100',
+                port: 8080,
+                // username: 'admin',
+                // password: '123456',
+                status: '未连接',
+            },
+            conveyor_form: {
+                ip: '192.168.1.100',
+                port: 8080,
+                // destination: 'A010203',
+                status: '未连接',
+            },
+            showInventoryDetails: false,
+            inventoryDetails: [
+                {
+                    id: 1,
+                    batch: "20230701-001",
+                    quantity: 100,
+                    location: "A区-1号架",
+
+                },
+                {
+                    id: 2,
+                    batch: "20230815-002",
+                    quantity: 200,
+                    location: "B区-3号架",
+
+                }
+
+            ],
+            inventoryColumns: [
+                { name: 'batch', label: '批次', field: 'batch', align: 'left' },
+                { name: 'quantity', label: '数量', field: 'quantity', align: 'right' },
+                { name: 'location', label: '位置', field: 'location', align: 'left' },
+
+            ],
+            user_id: "",
+            auth_id: "",
+            onlyread: true,
+            clickedinput: false,
+            storage_dialog: false,
+            elevator_dialog: false,
+            conveyor_dialog: false,
+            bgColor: "transparent",
+            selected: { label: '请选择一个选项', value: 'undefined' },
+            shelf_type: { shelf_type: 'undefined' },
+            ip_change: { ip_address: '192.168.1.100', port: 8080, status: 'offline' },
+            goods_change: { shelf_status: '未满', goods_batch: '20230701-001', goods_code: 'A010203', goods_name: '存货货物', goods_std: '规格型号', goods_desc: '存货描述', goods_qty: 123456, goods_unit: 'kg', goods_price: 123456,  goods_notes: '备注', goods_in: 123456, goods_out: 123456 },
+            options: [
+                { label: '未定义', value: 'undefined' },
+                { label: '库位', value: 'storage' },
+                { label: '提升机', value: 'elevator' },
+                { label: '输送机', value: 'conveyor' },],
+            error1: this.$t('stock.shelf.error1'),
+            shelfLocal: "",
+            activeTab: 'tab1'
+        }
+    },
+    created() {
+        this.shelfLocal = this.selectedShelfType;
+        this.handleclick()
+    },
+
+    methods: {
+        deleteInventoryDetail() {
+
+            this.inventoryDetails.pop()
+
+        },
+        addInventoryDetail() {
+            if (this.inventoryDetails.length >= 8) {
+                this.$q.notify({
+                    message: '最多只能添加8条记录',
+                    icon: 'done',
+                    color: 'negative'
+                })
+                return
+            }
+
+            this.inventoryDetails.push({
+                id: this.inventoryDetails.length + 1,
+                batch: "批次",
+                quantity: 0,
+                location: "位置",
+            })
+        },
+        prepareDialog() {
+            this.onlyread = true;
+        },
+        handleSelect(scope) {
+            // 更新选中值
+            this.selected.value = scope.opt.value;
+            this.selected.label = scope.opt.label;
+            // 关闭下拉菜单
+            this.$refs.select.hidePopup();
+            // 如果仍不关闭,尝试强制更新
+            this.$nextTick(() => {
+                this.$refs.select.hidePopup();
+            });
+        },
+        newDataSubmit() {
+            console.log("newDataSubmit")
+            console.log(this.newFormData)
+
+        },                                                 
+        handleclick() {
+            this.shelfLocal = this.selectedShelfType;
+            
+      
+            if (this.shelfLocal == "undefined") { this.clickedinput = true, this.storage_dialog = false, this.elevator_dialog = false, this.conveyor_dialog = false }
+            if (this.shelfLocal == "storage") { this.getList(), this.clickedinput = false, this.storage_dialog = true, this.elevator_dialog = false, this.conveyor_dialog = false }
+            if (this.shelfLocal == "elevator") { this.getList(), this.clickedinput = false, this.storage_dialog = false, this.elevator_dialog = true, this.conveyor_dialog = false }
+            if (this.shelfLocal == "conveyor") { this.getList(), this.clickedinput = false, this.storage_dialog = false, this.elevator_dialog = false, this.conveyor_dialog = true }
+
+
+        },
+        handleEdit() {
+
+            if (this.onlyread == false) {
+
+                if (this.shelfLocal == "elevator") {
+                    this.ip_change.ip_address = this.elevator_form.ip
+                    this.ip_change.port = this.elevator_form.port
+                    this.ip_change.status = this.elevator_form.status
+                    putauth(this.pathname + this.goodsData.id + '/', this.ip_change)
+                }
+                if (this.shelfLocal == "conveyor") {
+                    this.ip_change.ip_address = this.conveyor_form.ip
+                    this.ip_change.port = this.conveyor_form.port
+                    this.ip_change.status = this.conveyor_form.status
+                    putauth(this.pathname + this.goodsData.id + '/', this.ip_change)
+                }
+                if (this.shelfLocal == "storage") {
+                    this.goods_change.goods_batch = this.storage_form.goods_batch
+                    this.goods_change.goods_code = this.storage_form.goods_code
+                    this.goods_change.goods_name = this.storage_form.goods_name
+                    this.goods_change.goods_std = this.storage_form.goods_std
+                    this.goods_change.goods_desc = this.storage_form.goods_desc
+                    this.goods_change.goods_qty = this.storage_form.goods_qty
+                    this.goods_change.goods_unit = this.storage_form.goods_unit
+                    this.goods_change.goods_price = this.storage_form.goods_price
+             
+                    this.goods_change.goods_notes = this.storage_form.goods_notes
+                    this.goods_change.goods_in = this.storage_form.goods_in
+                    this.goods_change.goods_out = this.storage_form.goods_out
+                    this.goods_change.shelf_status = this.storage_form.shelf_status
+                    putauth(this.pathname + this.goodsData.id + '/', this.goods_change)
+                }
+            }
+            this.user_id = LocalStorage.getItem('login_mode')
+            if (this.user_id == "Admin") {
+                this.onlyread = false
+                this.showInventoryDetails = true 
+
+            }
+            if (this.user_id == "Manager") {
+                this.auth_id = LocalStorage.getItem('auth_edit')
+                // console.log(this.auth_id)
+                //这里添加权限判断
+                if (this.auth_id == "1") {
+                    this.onlyread = false
+                    this.showInventoryDetails = true 
+
+                } else {
+                    this.onlyread = true
+                    this.$q.notify({
+                        message: '权限不足,请联系管理员',
+                        icon: 'close',
+                        color: 'negative'
+                    })
+                }
+            }
+
+        },
+        submit() {
+            this.shelfLocal = this.selected.value
+            this.shelf_type.shelf_type = this.selected.value
+            this.handleclick()
+            console.log(this.goodsData.id)
+            putauth(this.pathname + this.goodsData.id + '/', this.shelf_type)
+            this.getList()
+
+        },
+        // bgColorchanger() {
+        //     if (this.shelfLocal == "undefined") {
+        //         this.bgColor = "#808080" //灰色
+        //     }
+        //     if (this.shelfLocal == "elevator") {
+        //         this.bgColor = "#4CAF50" //绿色
+        //     }
+        //     if (this.shelfLocal == "conveyor") {
+        //         this.bgColor = "#FF9800" //橙色
+        //     }
+        //     if (this.shelfLocal == "storage") {
+        //         this.bgColor = "#008CBA" //蓝色
+        //     }
+        // },
+        getList() {
+            var _this = this;
+            getauth(_this.pathname + _this.goodsData.id + '/')
+                .then(res => {
+                    console.log(res)
+                    
+                    _this.container_id = res.current_containers[0]
+                    console.log("当前托盘ID",_this.container_id)
+                    getauth(_this.pathnamecontainer + '?container='+_this.container_id)
+                    .then(res => {
+                        console.log(res)
+                    if (res.shelf_type == "storage") {
+                        this.storage_form.goods_batch = res.goods_batch
+                        this.storage_form.goods_code = res.goods_code
+                        this.storage_form.goods_name = res.goods_name
+                        this.storage_form.goods_std = res.goods_std
+                        this.storage_form.goods_desc = res.goods_desc
+                        this.storage_form.goods_qty = res.goods_qty
+                        this.storage_form.goods_unit = res.goods_unit
+                        this.storage_form.goods_price = res.goods_price
+                        this.storage_form.goods_notes = res.goods_notes
+                        this.storage_form.goods_in = res.goods_in
+                        this.storage_form.goods_out = res.goods_out
+                        this.storage_form.shelf_name = res.shelf_name
+                        this.storage_form.shelf_department = res.shelf_department
+                        this.storage_form.shelf_warehouse = res.warehouse_name
+                        this.storage_form.shelf_status = res.shelf_status
+                    }
+                    else if (res.shelf_type == "elevator") {
+                        this.elevator_form.ip = res.ip_address
+                        this.elevator_form.port = res.port
+                        this.elevator_form.status = res.status
+                    }
+                    else if (res.shelf_type == "conveyor") {
+                        this.conveyor_form.ip = res.ip_address
+                        this.conveyor_form.port = res.port
+                        this.conveyor_form.status = res.status
+                    }
+
+                })
+                .catch(err => {
+                    _this.$q.notify({
+                        message: err.detail,
+                        icon: 'close',
+                        color: 'negative'
+                    });
+                });
+        },
+    }
+}
+
+</script>
+
+<style scoped>
+
+
+
+:deep(.q-field__label) {
+
+    margin-top: 8px;
+    align-self: center;
+
+}
+
+
+:deep(.q-field__control-container) {
+
+    padding-left: 50px;
+    margin-top: -5px;
+
+}
+</style>

+ 109 - 230
templates/src/components/goodscard.vue

@@ -1,40 +1,7 @@
 <template>
     <div  :style="{ backgroundColor: bgColor }">
-        <div style="color: transparent;">1111</div>
-        <q-dialog v-model="clickedinput" transition-show="jump-down" transition-hide="jump-up">
-            <q-card style="min-width: 350px; ">
-                <q-bar class="bg-light-blue-10 text-white rounded-borders" style="height: 50px">
-                    <div>
-                        {{ $t("stock.bin_setting") }}
-                    </div>
-                    <q-space></q-space>
-                    <q-btn dense flat icon="close" v-close-popup>
-                        <q-tooltip content-class="bg-amber text-black shadow-4" :offset="[20, 20]"
-                            content-style="font-size: 12px">
-                            {{ $t("index.close") }}</q-tooltip>
-                    </q-btn>
-                </q-bar>
-                <q-card-section class="flex flex-center">
-                    <q-select ref="select" v-model="selected.label" :options="options" label="库位定义:" outlined
-                        stack-label dense option-label="label" option-value="value" style="width: 90%"
-                        class="q-my-md text-center" input-class="text-center">
-                        <template v-slot:option="scope">
-                            <q-item v-bind="scope.itemProps" class="text-center" @click="handleSelect(scope)">
-                                <q-item-section>{{ scope.opt.label }}</q-item-section>
-                            </q-item>
-                        </template>
-                    </q-select>
-                </q-card-section>
-                <div class="row justify-end q-pa-md q-gutter-x-md">
-                    <q-btn color="primary" text-color="white" style="margin-right: 25px" v-close-popup class="q-px-lg">
-                        {{ $t('cancel') }}</q-btn>
-                    <q-btn color="primary" text-color="white" style="margin-right: 25px" @click=submit()
-                        class="q-px-lg">
-                        {{ $t('submit') }}</q-btn>
+ 
 
-                </div>
-            </q-card>
-        </q-dialog>
         <q-dialog v-model="storage_dialog" transition-show="jump-down" transition-hide="jump-up" @show=prepareDialog()>
             <q-card style="min-width: 600px; ">
                 <q-bar class="bg-light-blue-10 text-white rounded-borders" style="height: 50px">
@@ -51,7 +18,7 @@
                 <q-card-section class="q-pt-md ">
                     <q-tabs v-model="activeTab">
                         <q-tab name="tab1" label="货架属性" />
-                        <q-tab name="tab2" label="货物信息" />
+                        <q-tab name="tab2" label="批次信息" />
                         <q-tab name="tab3" label="库存明细" />
                     </q-tabs>
                 </q-card-section>
@@ -60,25 +27,14 @@
                     <q-tab-panel name="tab1" style="height:300px">
                         <div class="row q-gutter-x-md">
                             <div class="col column q-gutter-y-md">
-                                <q-input dense outlined square v-model="storage_form.shelf_warehouse"
-                                    :label="$t('stock.shelf.shelf_warehouse')" :readonly="onlyread"
-                                    :rules="[val => val?.length > 0 || error1]" />
-                                <q-input dense outlined square v-model="storage_form.shelf_name"
-                                    :label="$t('stock.shelf.shelf_name')" :readonly="onlyread"
-                                    :rules="[val => val?.length > 0 || error1]" />
+                            
                                 <q-input dense outlined square v-model="storage_form.goods_code"
                                     :label="$t('stock.shelf.goods_code')" :readonly="onlyread"
                                     :rules="[val => val?.length > 0 || error1]" />
-
+                    
                             </div>
                             <div class="col column q-gutter-y-md">
-                                <q-input dense outlined square v-model="storage_form.shelf_department"
-                                    :label="$t('stock.shelf.shelf_department')" :readonly="onlyread"
-                                    :rules="[val => val?.length > 0 || error1]" />
-                                <q-input dense outlined square v-model="storage_form.shelf_status"
-                                    :label="$t('stock.shelf.shelf_status')" :readonly="onlyread"
-                                    :rules="[val => val?.length > 0 || error1]" />
-
+  
                                 <q-input dense outlined square v-model="storage_form.goods_name"
                                     :label="$t('stock.shelf.goods_name')" :readonly="onlyread"
                                     :rules="[val => val?.length > 0 || error1]" />
@@ -98,8 +54,9 @@
                                     :rules="[val => val?.length > 0 || error1]" />
 
                                 <q-input dense outlined square v-model="storage_form.goods_qty"
-                                    :label="$t('stock.shelf.goods_qty')" :readonly="onlyread"
+                                    :label="'批次总数'" :readonly="onlyread"
                                     :rules="[val => val >= 0 || error1]" class="col" />
+
                                 <q-input dense outlined square v-model="storage_form.goods_desc"
                                     :label="$t('stock.shelf.goods_desc')" :readonly="onlyread"
                                     :rules="[val => val?.length > 0 || error1]" />
@@ -113,12 +70,14 @@
                                     :label="$t('stock.shelf.goods_std')" :readonly="onlyread"
                                     :rules="[val => val?.length > 0 || error1]" />
 
+                                <q-input dense outlined square v-model="storage_form.goods_notes"
+                                    :label="'库位容纳'" :readonly="onlyread"
+                                    :rules="[val => val >= 0 || error1]" class="col" />
+
                                 <q-input dense outlined square v-model="storage_form.goods_unit"
                                     :label="$t('stock.shelf.goods_unit')" :readonly="onlyread"
                                     :rules="[val => val?.length > 0 || error1]" />
-                                <q-input dense outlined square v-model="storage_form.goods_notes"
-                                    :label="$t('stock.shelf.goods_notes')" :readonly="onlyread"
-                                    :rules="[val => val?.length > 0 || error1]" />
+
 
 
                             </div>
@@ -283,34 +242,36 @@ export default {
     },
     data() {
         return {
-            pathname: 'stock/management/',
-            pathnameshelf: 'stock/management/shelf/',
+            pathname: 'bin/',
+            pathnamecontainer: 'container/detail/',
+            container_id: 123456,
+            results: [],
             storage_form: {
-                shelf_name: '货架名称',
-                shelf_department: '货架部门',
-                shelf_warehouse: '仓库',
-                shelf_status: '未满',
-                goods_code: 'A010203',
-                goods_name: '存货货物',
-                goods_std: '规格型号',
-                goods_desc: '存货描述',
-                goods_qty: '123456',
-                goods_unit: 'kg',
-                goods_price: '123456',
-                goods_batch: '存货批号',
-                goods_notes: '备注',
-                goods_in: '123456',
-                goods_out: '123456',
+                shelf_name: '',
+                shelf_department: '',
+                shelf_warehouse: '',
+                shelf_status: '',
+                goods_code: '',
+                goods_name: '',
+                goods_std: '',
+                goods_desc: '',
+                goods_qty: '',
+                goods_unit: '',
+                goods_price: '',
+                goods_batch: '',
+                goods_notes: '',
+                goods_in: '',
+                goods_out: '',
             },
             elevator_form: {
-                ip: '192.168.1.100',
+                ip: '',
                 port: 8080,
                 // username: 'admin',
                 // password: '123456',
                 status: '未连接',
             },
             conveyor_form: {
-                ip: '192.168.1.100',
+                ip: '',
                 port: 8080,
                 // destination: 'A010203',
                 status: '未连接',
@@ -319,16 +280,16 @@ export default {
             inventoryDetails: [
                 {
                     id: 1,
-                    batch: "20230701-001",
-                    quantity: 100,
-                    location: "A区-1号架",
+                    batch: "",
+                    quantity: 0,
+                    location: "",
 
                 },
                 {
                     id: 2,
-                    batch: "20230815-002",
-                    quantity: 200,
-                    location: "B区-3号架",
+                    batch: "",
+                    quantity: 0,
+                    location: "",
 
                 }
 
@@ -347,18 +308,14 @@ export default {
             elevator_dialog: false,
             conveyor_dialog: false,
             bgColor: "transparent",
-            selected: { label: '请选择一个选项', value: 'undefined' },
+
             shelf_type: { shelf_type: 'undefined' },
             ip_change: { ip_address: '192.168.1.100', port: 8080, status: 'offline' },
             goods_change: { shelf_status: '未满', goods_batch: '20230701-001', goods_code: 'A010203', goods_name: '存货货物', goods_std: '规格型号', goods_desc: '存货描述', goods_qty: 123456, goods_unit: 'kg', goods_price: 123456,  goods_notes: '备注', goods_in: 123456, goods_out: 123456 },
-            options: [
-                { label: '未定义', value: 'undefined' },
-                { label: '库位', value: 'storage' },
-                { label: '提升机', value: 'elevator' },
-                { label: '输送机', value: 'conveyor' },],
+
             error1: this.$t('stock.shelf.error1'),
             shelfLocal: "",
-            activeTab: 'tab1'
+            activeTab: 'tab2'
         }
     },
     created() {
@@ -367,174 +324,96 @@ export default {
     },
 
     methods: {
-        deleteInventoryDetail() {
 
-            this.inventoryDetails.pop()
-
-        },
-        addInventoryDetail() {
-            if (this.inventoryDetails.length >= 8) {
-                this.$q.notify({
-                    message: '最多只能添加8条记录',
-                    icon: 'done',
-                    color: 'negative'
-                })
-                return
-            }
-
-            this.inventoryDetails.push({
-                id: this.inventoryDetails.length + 1,
-                batch: "批次",
-                quantity: 0,
-                location: "位置",
-            })
-        },
         prepareDialog() {
             this.onlyread = true;
         },
-        handleSelect(scope) {
-            // 更新选中值
-            this.selected.value = scope.opt.value;
-            this.selected.label = scope.opt.label;
-            // 关闭下拉菜单
-            this.$refs.select.hidePopup();
-            // 如果仍不关闭,尝试强制更新
-            this.$nextTick(() => {
-                this.$refs.select.hidePopup();
-            });
-        },
-        newDataSubmit() {
-            console.log("newDataSubmit")
-            console.log(this.newFormData)
 
-        },                                                 
+                                               
         handleclick() {
             this.shelfLocal = this.selectedShelfType;
             
-      
             if (this.shelfLocal == "undefined") { this.clickedinput = true, this.storage_dialog = false, this.elevator_dialog = false, this.conveyor_dialog = false }
             if (this.shelfLocal == "storage") { this.getList(), this.clickedinput = false, this.storage_dialog = true, this.elevator_dialog = false, this.conveyor_dialog = false }
             if (this.shelfLocal == "elevator") { this.getList(), this.clickedinput = false, this.storage_dialog = false, this.elevator_dialog = true, this.conveyor_dialog = false }
             if (this.shelfLocal == "conveyor") { this.getList(), this.clickedinput = false, this.storage_dialog = false, this.elevator_dialog = false, this.conveyor_dialog = true }
 
-
         },
-        handleEdit() {
-
-            if (this.onlyread == false) {
 
-                if (this.shelfLocal == "elevator") {
-                    this.ip_change.ip_address = this.elevator_form.ip
-                    this.ip_change.port = this.elevator_form.port
-                    this.ip_change.status = this.elevator_form.status
-                    putauth(this.pathname + this.goodsData.id + '/', this.ip_change)
-                }
-                if (this.shelfLocal == "conveyor") {
-                    this.ip_change.ip_address = this.conveyor_form.ip
-                    this.ip_change.port = this.conveyor_form.port
-                    this.ip_change.status = this.conveyor_form.status
-                    putauth(this.pathname + this.goodsData.id + '/', this.ip_change)
-                }
-                if (this.shelfLocal == "storage") {
-                    this.goods_change.goods_batch = this.storage_form.goods_batch
-                    this.goods_change.goods_code = this.storage_form.goods_code
-                    this.goods_change.goods_name = this.storage_form.goods_name
-                    this.goods_change.goods_std = this.storage_form.goods_std
-                    this.goods_change.goods_desc = this.storage_form.goods_desc
-                    this.goods_change.goods_qty = this.storage_form.goods_qty
-                    this.goods_change.goods_unit = this.storage_form.goods_unit
-                    this.goods_change.goods_price = this.storage_form.goods_price
-             
-                    this.goods_change.goods_notes = this.storage_form.goods_notes
-                    this.goods_change.goods_in = this.storage_form.goods_in
-                    this.goods_change.goods_out = this.storage_form.goods_out
-                    this.goods_change.shelf_status = this.storage_form.shelf_status
-                    putauth(this.pathname + this.goodsData.id + '/', this.goods_change)
-                }
+        getList() {
+            var _this = this;
+            _this.storage_form = {
+                shelf_name: '',
+                shelf_department: '',
+                shelf_warehouse: '',
+                shelf_status: '',
+                goods_code: '',
+                goods_name: '',
+                goods_std: '',
+                goods_desc: '',
+                goods_qty: 0,
+                goods_unit: '',
+                goods_price: 0,
+                goods_batch: '',
+                goods_notes: 0,
+                goods_in: 0,
+                goods_out: 0,
             }
-            this.user_id = LocalStorage.getItem('login_mode')
-            if (this.user_id == "Admin") {
-                this.onlyread = false
-                this.showInventoryDetails = true 
+            _this.inventoryDetails = [
+                {
+                    id: 1,
+                    batch: "",
+                    quantity: 0,
+                    location: "",
 
-            }
-            if (this.user_id == "Manager") {
-                this.auth_id = LocalStorage.getItem('auth_edit')
-                // console.log(this.auth_id)
-                //这里添加权限判断
-                if (this.auth_id == "1") {
-                    this.onlyread = false
-                    this.showInventoryDetails = true 
-
-                } else {
-                    this.onlyread = true
-                    this.$q.notify({
-                        message: '权限不足,请联系管理员',
-                        icon: 'close',
-                        color: 'negative'
-                    })
+                },
+                {
+                    id: 2,
+                    batch: "",
+                    quantity: 0,
+                    location: "",
                 }
-            }
 
-        },
-        submit() {
-            this.shelfLocal = this.selected.value
-            this.shelf_type.shelf_type = this.selected.value
-            this.handleclick()
-            console.log(this.goodsData.id)
-            putauth(this.pathname + this.goodsData.id + '/', this.shelf_type)
-            this.getList()
-
-        },
-        // bgColorchanger() {
-        //     if (this.shelfLocal == "undefined") {
-        //         this.bgColor = "#808080" //灰色
-        //     }
-        //     if (this.shelfLocal == "elevator") {
-        //         this.bgColor = "#4CAF50" //绿色
-        //     }
-        //     if (this.shelfLocal == "conveyor") {
-        //         this.bgColor = "#FF9800" //橙色
-        //     }
-        //     if (this.shelfLocal == "storage") {
-        //         this.bgColor = "#008CBA" //蓝色
-        //     }
-        // },
-        getList() {
-            var _this = this;
+            ]
             getauth(_this.pathname + _this.goodsData.id + '/')
-                .then(res => {
-
-                    if (res.shelf_type == "storage") {
-                        this.storage_form.goods_batch = res.goods_batch
-                        this.storage_form.goods_code = res.goods_code
-                        this.storage_form.goods_name = res.goods_name
-                        this.storage_form.goods_std = res.goods_std
-                        this.storage_form.goods_desc = res.goods_desc
-                        this.storage_form.goods_qty = res.goods_qty
-                        this.storage_form.goods_unit = res.goods_unit
-                        this.storage_form.goods_price = res.goods_price
-                        this.storage_form.goods_notes = res.goods_notes
-                        this.storage_form.goods_in = res.goods_in
-                        this.storage_form.goods_out = res.goods_out
-                        this.storage_form.shelf_name = res.shelf_name
-                        this.storage_form.shelf_department = res.shelf_department
-                        this.storage_form.shelf_warehouse = res.warehouse_name
-                        this.storage_form.shelf_status = res.shelf_status
-                    }
-                    else if (res.shelf_type == "elevator") {
-                        this.elevator_form.ip = res.ip_address
-                        this.elevator_form.port = res.port
-                        this.elevator_form.status = res.status
+                .then(res1 => {
+                    console.log(res1)
+                    console.log(res1.current_containers)
+                    _this.container_id = res1.current_containers[0]
+                    console.log("当前托盘ID",_this.container_id)
+                    if(_this.container_id == undefined)
+                    {
+                        console.log("当前托盘ID为空")
+                        _this.$q.notify({
+                            message: "当前库位为空",
+                            icon: 'info',
+                            color: 'info'
+                        });
+                        return
                     }
-                    else if (res.shelf_type == "conveyor") {
-                        this.conveyor_form.ip = res.ip_address
-                        this.conveyor_form.port = res.port
-                        this.conveyor_form.status = res.status
+                    getauth(_this.pathnamecontainer + '?container='+_this.container_id)
+                    .then(res => {
+                        var results = res.results[0]
+                        this.storage_form.goods_batch = results.batch.bound_number
+                        this.storage_form.goods_code = results.batch.goods_code
+                        this.storage_form.goods_name = results.batch.goods_desc
+                        this.storage_form.goods_std = results.batch.goods_std
+                        this.storage_form.goods_desc = results.batch.goods_desc
+                        this.storage_form.goods_qty = results.batch.goods_qty
+                        this.storage_form.goods_unit = results.batch.goods_unit
+                        this.storage_form.goods_price = results.batch.goods_price
+                        this.storage_form.goods_notes = results.goods_qty
+                        this.storage_form.goods_in = results.batch.goods_in
+                        this.storage_form.goods_out = results.batch.goods_out
+                        this.storage_form.shelf_name = results.shelf_name
+                        this.storage_form.shelf_department = results.shelf_department
+                        this.storage_form.shelf_warehouse = results.warehouse_name
+                        this.storage_form.shelf_status = results.status
                     }
 
-                })
-                .catch(err => {
+
+                ) 
+            }).catch(err => {
                     _this.$q.notify({
                         message: err.detail,
                         icon: 'close',

+ 69 - 295
templates/src/pages/stock/emptybin.vue

@@ -1,314 +1,88 @@
-
 <template>
-  <div>
-    <transition appear enter-active-class="animated fadeIn">
-      <q-table class="my-sticky-header-column-table shadow-24" :data="table_list" row-key="id" :separator="separator"
-        :loading="loading" :filter="filter" :columns="columns" hide-bottom :pagination.sync="pagination"
-        no-data-label="No data" no-results-label="No data you want" :table-style="{ height: height }" flat bordered>
-        <template v-slot:top>
-          <q-btn-group push>
-            <q-btn :label="$t('refresh')" icon="refresh" @click="reFresh()">
-              <q-tooltip content-class="bg-amber text-black shadow-4" :offset="[10, 10]"
-                content-style="font-size: 12px">{{ $t('refreshtip') }}</q-tooltip>
-            </q-btn>
-          </q-btn-group>
-          <q-space />
-          <q-input outlined rounded dense debounce="300" color="primary" v-model="filter" :placeholder="$t('search')"
-            @input="getSearchList()" @keyup.enter="getSearchList()">
-            <template v-slot:append>
-              <q-icon name="search" @click="getSearchList()" />
-            </template>
-          </q-input>
-        </template>
-        <template v-slot:body="props">
-          <q-tr :props="props">
-            <q-td key="shelf_name" :props="props">{{ props.row.warehouse_name}}</q-td>
-            <q-td key="goods_code" :props="props">{{ props.row.goods_code }}</q-td>
-            <q-td key="goods_name" :props="props">{{ props.row.goods_name }}</q-td>
-            <q-td key="goods_in" :props="props">{{ props.row.goods_in }}</q-td>
-            <q-td key="goods_out" :props="props">{{ props.row.goods_out }}</q-td>
-            <q-td key="goods_qty" :props="props">{{ props.row.goods_qty}}</q-td>
-            <q-td key="action" :props="props" style="width: 50px">
-              <!-- <q-btn
-                v-show="$q.localStorage.getItem('staff_type') !== 'Inbound' && $q.localStorage.getItem('staff_type') !== 'Outbound'"
-                round flat push color="purple" icon="move_to_inbox" @click="BinMove(props.row)">
-                <q-tooltip content-class="bg-amber text-black shadow-4" :offset="[10, 10]"
-                  content-style="font-size: 12px">{{ $t('movetobin') }}</q-tooltip>
-              </q-btn> -->
-            </q-td>
-          </q-tr>
-        </template>
-      </q-table>
-    </transition>
-    <template>
-      <div v-show="max !== 0" class="q-pa-lg flex flex-center">
-        <div>{{ total }} </div>
-        <q-pagination v-model="current" color="black" :max="max" :max-pages="6" boundary-links @click="getList()" />
-        <div>
-          <input v-model="paginationIpt" @blur="changePageEnter" @keyup.enter="changePageEnter"
-            style="width: 60px; text-align: center" />
+  <div class="q-pa-md">
+    <div class="slider-container">
+      <div class="buttons-wrapper">
+        <div 
+          v-for="(type, index) in bin_type"
+          :key="type"
+          class="slider-button"
+          :class="{ 'active': current_bin_type === type }"
+          @click="handleSwitch(type, index)"
+        >
+          {{ bin_type_name[index] }}
         </div>
+        <div 
+          class="slider-track"
+          :style="sliderStyle"
+        ></div>
       </div>
-      <div v-show="max === 0" class="q-pa-lg flex flex-center">
-        <q-btn flat push color="dark" :label="$t('no_data')"></q-btn>
-      </div>
-    </template>
-    <!-- <q-dialog v-model="moveForm">
-      <q-card class="shadow-24">
-        <q-bar class="bg-light-blue-10 text-white rounded-borders" style="height: 50px">
-          <div>{{ movedata.goods_code }} {{ $t('frombin') }} {{ movedata.bin_name }}</div>
-          <q-space />
-          <q-btn dense flat icon="close" v-close-popup>
-            <q-tooltip>{{ $t('index.close') }}</q-tooltip>
-          </q-btn>
-        </q-bar>
-        <q-card-section style="max-height: 325px; width: 400px" class="scroll">
-          <q-input dense outlined square debounce="500" v-model.number="movedata.move_qty" type="number"
-            :label="$t('stock.view_stocklist.goods_qty')" style="margin-bottom: 5px"
-            :rules="[val => (val && val > 0) || error1]" @keyup.enter="MoveToBinSubmit()">
-            <template v-slot:before>
-              <q-select dense outlined square use-input hide-selected fill-input v-model="movedata.move_to_bin"
-                :label="$t('warehouse.view_binset.bin_name')" :options="options" @filter="filterFn"
-                @keyup.enter="MoveToBinSubmit()">
-                <template v-slot:no-option>
-                  <q-item><q-item-section class="text-grey">No results</q-item-section></q-item>
-                </template>
-                <template v-if="movedata.move_to_bin" v-slot:append>
-                  <q-icon name="cancel" @click.stop="movedata.move_to_bin = ''" class="cursor-pointer" />
-                </template>
-              </q-select>
-            </template>
-          </q-input>
-        </q-card-section>
-        <div style="float: right; padding: 15px 15px 15px 0">
-          <q-btn color="white" text-color="black" style="margin-right: 25px" @click="MoveToBinCancel()">{{ $t('cancel')
-            }}</q-btn>
-          <q-btn color="primary" @click="MoveToBinSubmit()">{{ $t('submit') }}</q-btn>
-        </div>
-      </q-card>
-    </q-dialog> -->
+    </div>
   </div>
 </template>
-<router-view />
 
 <script>
-import { getauth, postauth } from 'boot/axios_request'
-import { SessionStorage, LocalStorage } from 'quasar'
-
 export default {
-  name: 'Pageemptybin',
   data() {
     return {
-      openid: '',
-      login_name: '',
-      authin: '0',
-      pathname: 'stock/bin/',
-      pathname_previous: '',
-      pathname_next: '',
-      separator: 'cell',
-      loading: false,
-      height: '',
-      table_list: [],
-      bin_size_list: [],
-      bin_property_list: [],
-      warehouse_list: [],
-      columns: [
-        { name: 'shelf_name', required: true, label: this.$t('warehouse.view_binset.bin_name'), align: 'center', field: 'bin_name' },
-        { name: 'goods_code', label: this.$t('stock.view_stocklist.goods_code'), field: 'goods_code', align: 'center' },
-        { name: 'goods_name', label: '商品名称', field: 'goods_name', align: 'center' },
-        { name: 'goods_in', label: '入库数量', field: 'goods_in', align: 'center' },
-        { name: 'goods_out', label: '出库数量', field: 'goods_in', align: 'center' },
-        { name: 'goods_qty', label: '当前数量', field: 'goods_qty', align: 'center' },
-        { name: 'action', label: this.$t('action'), align: 'ceter' }
-      ],
-      filter: '',
-      pagination: {
-        page: 1,
-        rowsPerPage: '30'
-      },
-      options: [],
-      moveForm: false,
-      movedata: {},
-      error1: this.$t('inbound.view_sortstock.error1'),
-      current: 1,
-      max: 0,
-      total: 0,
-      paginationIpt: 1
+      current_bin_type: 'T1',
+      bin_type: ['T1', 'T2', 'T4', 'T5', 'S4'],
+      bin_type_name: ['散盘', '2托', '4托', '5托', '4散']
     }
   },
-  methods: {
-    getList() {
-      var _this = this
-      if (LocalStorage.has('auth')) {
-        getauth(_this.pathname + '?page=' + '' + _this.current + '&shelf_type=storage&empty_label=true', {})
-          .then(res => {
-            _this.table_list = res.results
-            _this.total = res.count
-            if (res.count === 0) {
-              _this.max = 0
-            } else {
-              if (Math.ceil(res.count / 30) === 1) {
-                _this.max = 0
-              } else {
-                _this.max = Math.ceil(res.count / 30)
-              }
-            }
-
-            _this.pathname_previous = res.previous
-            _this.pathname_next = res.next
-          })
-          .catch(err => {
-            _this.$q.notify({
-              message: err.detail,
-              icon: 'close',
-              color: 'negative'
-            })
-          })
-      }
-    },
-    changePageEnter(e) {
-      if (Number(this.paginationIpt) < 1) {
-        this.current = 1;
-        this.paginationIpt = 1;
-      } else if (Number(this.paginationIpt) > this.max) {
-        this.current = this.max;
-        this.paginationIpt = this.max;
-      } else {
-        this.current = Number(this.paginationIpt);
-      }
-      this.getList();
-    },
-    getSearchList() {
-      var _this = this
-      if (LocalStorage.has('auth')) {
-        _this.current = 1
-        _this.paginationIpt = 1
-        getauth(_this.pathname + '?goods_name__icontains=' + _this.filter + '&max_page=10000'  + '&shelf_type=storage', {})
-          .then(res => {
-            _this.table_list = res.results
-            _this.total = res.count
-            if (res.count === 0) {
-              _this.max = 0
-            } else {
-              if (Math.ceil(res.count / 30) === 1) {
-                _this.max = 0
-              } else {
-                _this.max = Math.ceil(res.count / 30)
-              }
-            }
-
-            _this.pathname_previous = res.previous
-            _this.pathname_next = res.next
-          })
-          .catch(err => {
-            _this.$q.notify({
-              message: err.detail,
-              icon: 'close',
-              color: 'negative'
-            })
-          })
-      } else {
-      }
-    },
-    getListPrevious() {
-      var _this = this
-      if (LocalStorage.has('auth')) {
-        getauth(_this.pathname_previous, {})
-          .then(res => {
-            _this.table_list = res.results
-            _this.pathname_previous = res.previous
-            _this.pathname_next = res.next
-          })
-          .catch(err => {
-            _this.$q.notify({
-              message: err.detail,
-              icon: 'close',
-              color: 'negative'
-            })
-          })
-      }
-    },
-    getListNext() {
-      var _this = this
-      if (LocalStorage.has('auth')) {
-        getauth(_this.pathname_next, {})
-          .then(res => {
-            _this.table_list = res.results
-
-            _this.pathname_previous = res.previous
-            _this.pathname_next = res.next
-          })
-          .catch(err => {
-            _this.$q.notify({
-              message: err.detail,
-              icon: 'close',
-              color: 'negative'
-            })
-          })
-      } else {
-      }
+  computed: {
+    activeIndex() {
+      return this.bin_type.indexOf(this.current_bin_type)
     },
-    reFresh() {
-      var _this = this
-      _this.getList()
-    },
-    filterFn(val, update, abort) {
-      var _this = this
-      if (val.length < 1) {
-        abort()
-        return
+    sliderStyle() {
+      return {
+        width: `${100 / this.bin_type.length}%`,
+        transform: `translateX(${100 * this.activeIndex}%)`
       }
-      update(() => {
-        const needle = val.toLowerCase()
-        getauth('binset/?bin_name__icontains=' + needle)
-          .then(res => {
-            var binlist = []
-            res.results.forEach(detail => {
-              binlist.push(detail.bin_name)
-            })
-            SessionStorage.set('bin_name', binlist)
-            _this.options = SessionStorage.getItem('bin_name')
-          })
-          .catch(err => {
-            _this.$q.notify({
-              message: err.detail,
-              icon: 'close',
-              color: 'negative'
-            })
-          })
-      })
-    }
-  },
-  created() {
-    var _this = this
-    if (LocalStorage.has('openid')) {
-      _this.openid = LocalStorage.getItem('openid')
-    } else {
-      _this.openid = ''
-      LocalStorage.set('openid', '')
-    }
-    if (LocalStorage.has('login_name')) {
-      _this.login_name = LocalStorage.getItem('login_name')
-    } else {
-      _this.login_name = ''
-      LocalStorage.set('login_name', '')
-    }
-    if (LocalStorage.has('auth')) {
-      _this.authin = '1'
-      _this.getList()
-    } else {
-      _this.authin = '0'
     }
   },
-  mounted() {
-    var _this = this
-    if (_this.$q.platform.is.electron) {
-      _this.height = String(_this.$q.screen.height - 290) + 'px'
-    } else {
-      _this.height = _this.$q.screen.height - 290 + '' + 'px'
+  methods: {
+    handleSwitch(type) {
+      this.current_bin_type = type
     }
-  },
-  updated() { },
-  destroyed() { }
+  }
 }
 </script>
+
+<style scoped>
+.slider-container {
+  position: relative;
+  max-width: 400px;
+  margin: 0 auto;
+}
+
+.buttons-wrapper {
+  position: relative;
+  display: flex;
+  border-radius: 8px;
+  background: #e0e0e0;
+  overflow: hidden;
+}
+
+.slider-button {
+  flex: 1;
+  position: relative;
+  padding: 12px 16px;
+  text-align: center;
+  cursor: pointer;
+  transition: color 0.3s;
+  z-index: 1;
+}
+
+.slider-button.active {
+  color: #fff;
+}
+
+.slider-track {
+  position: absolute;
+  height: 100%;
+  background: #2196F3;
+  border-radius: 6px;
+  transition: transform 0.3s cubic-bezier(0.4, 0, 0.2, 1);
+  box-shadow: 0 2px 4px rgba(0,0,0,0.1);
+}
+</style>

+ 2 - 2
templates/src/pages/stock/management.vue

@@ -141,8 +141,8 @@ export default {
             C1: 'rgba(128, 135, 128, 0.5)',  // 黄色半透明
             B1: 'rgba(0, 195, 0, 0.5)',  // 绿色半透明
 
-            reserved: 'rgba(20, 125, 255, 0.5)',  // 红色半透明
-
+            reserved: 'rgba(20, 125, 200, 0.25)',  // 蓝色半透明
+            occupied: 'rgba(20, 125, 255, 0.5)',  // 蓝色半透明  
             default: 'rgba(255, 0.5)' // 白色半透明
           
             } ,

+ 76 - 1
templates/src/pages/stock/stockbinlist.vue

@@ -12,6 +12,11 @@
                 content-style="font-size: 12px">{{ $t('refreshtip') }}</q-tooltip>
             </q-btn>
           </q-btn-group>
+          <q-space />
+          <!-- <div class="q-pa-md"> -->
+            
+      
+
           <q-space />
           <q-input outlined rounded dense debounce="300" color="primary" v-model="filter" :placeholder="$t('search')"
             @input="getSearchList()" @keyup.enter="getSearchList()">
@@ -46,6 +51,23 @@
     </transition>
     <template>
       <div v-show="max !== 0" class="q-pa-lg flex flex-center">
+        <div class="slider-container">
+              <div class="buttons-wrapper">
+                <div 
+                  v-for="(type, index) in bin_type"
+                  :key="type"
+                  class="slider-button"
+                  :class="{ 'active': current_bin_type === type }"
+                  @click="handleSwitch(type, index)"
+                >
+                  {{ bin_type_name[index] }}
+                </div>
+                <div 
+                  class="slider-track"
+                  :style="sliderStyle"
+                ></div>
+              </div>
+          </div>
         <div>{{ total }} </div>
         <q-pagination v-model="current" color="black" :max="max" :max-pages="6" boundary-links
           @click="getSearchList(current); paginationIpt = current" />
@@ -85,7 +107,9 @@ export default {
       searchUrl: '',
       pathname: 'bin/group/',
       pathfilename: 'reportcenter/file/',
-
+      current_bin_type: '',
+      bin_type : ['T1', 'T2', 'T4', 'T5', 'S4'],
+      bin_type_name : ['散盘', '2托', '4托', '5托', '4散'],
       pathname_previous: '',
       pathname_next: '',
       separator: 'cell',
@@ -158,7 +182,17 @@ export default {
   computed: {
     interval() {
       return this.$t('download_center.start') + ' - ' + this.$t('download_center.end')
+    },
+    activeIndex() {
+      return this.bin_type.indexOf(this.current_bin_type)
+    },
+    sliderStyle() {
+      return {
+        width: `${100 / this.bin_type.length}%`,
+        transform: `translateX(${100 * this.activeIndex}%)`
+      }
     }
+
   },
   methods: {
     getList(params = {}) {
@@ -267,6 +301,9 @@ export default {
       var _this = this
       _this.getSearchList()
     },
+    handleSwitch(type) {
+      this.current_bin_type = type
+    }
 
   
   },
@@ -314,4 +351,42 @@ export default {
 .q-date__range {
   background-color: rgba(25, 118, 210, 0.1);
 }
+
+.slider-container {
+  position: relative;
+  max-width: 400px;
+  height: 10px;
+  margin: 0 auto;
+}
+
+.buttons-wrapper {
+  position: relative;
+  display: flex;
+  border-radius: 8px;
+  background: #e0e0e0;
+  overflow: hidden;
+}
+
+.slider-button {
+  flex: 1;
+  position: relative;
+  padding: 12px 16px;
+  text-align: center;
+  cursor: pointer;
+  transition: color 0.3s;
+  z-index: 1;
+}
+
+.slider-button.active {
+  color: #fff;
+}
+
+.slider-track {
+  position: absolute;
+  height: 100%;
+  background: #2196F3;
+  border-radius: 6px;
+  transition: transform 0.3s cubic-bezier(0.4, 0, 0.2, 1);
+  box-shadow: 0 2px 4px rgba(0,0,0,0.1);
+}
 </style>