Explorar el Código

托盘界面更新

flower_mr hace 2 semanas
padre
commit
69f305220b
Se han modificado 70 ficheros con 319 adiciones y 1098 borrados
  1. 2 1
      .gitignore
  2. 5 0
      container/serializers.py
  3. 8 0
      logs/server.log
  4. 0 0
      templates/dist/spa/css/10.74deb849.css
  5. 0 0
      templates/dist/spa/css/11.601677c3.css
  6. 1 0
      templates/dist/spa/css/12.659f915f.css
  7. 0 1
      templates/dist/spa/css/13.80a6b71a.css
  8. 0 0
      templates/dist/spa/css/13.f721cf95.css
  9. 0 0
      templates/dist/spa/css/14.e18d8a65.css
  10. 1 0
      templates/dist/spa/css/15.954d38ee.css
  11. 1 0
      templates/dist/spa/css/22.4a53120f.css
  12. 0 1
      templates/dist/spa/css/22.8d4e7dc4.css
  13. 0 1
      templates/dist/spa/css/3.cadbb490.css
  14. 0 0
      templates/dist/spa/css/3.cd59f5a0.css
  15. 0 0
      templates/dist/spa/css/4.0ac6b60c.css
  16. 0 0
      templates/dist/spa/css/5.7100e471.css
  17. 0 0
      templates/dist/spa/css/6.eb31c91a.css
  18. 0 0
      templates/dist/spa/css/7.f57b1220.css
  19. 0 0
      templates/dist/spa/css/8.58670660.css
  20. 0 0
      templates/dist/spa/css/9.296f042c.css
  21. 1 0
      templates/dist/spa/css/chunk-common.ce13bc87.css
  22. 1 1
      templates/dist/spa/index.html
  23. 0 1
      templates/dist/spa/js/1.66e8190d.js
  24. BIN
      templates/dist/spa/js/1.66e8190d.js.gz
  25. 0 1
      templates/dist/spa/js/10.6087e287.js
  26. BIN
      templates/dist/spa/js/10.6087e287.js.gz
  27. 1 1
      templates/dist/spa/js/11.794b8487.js
  28. BIN
      templates/dist/spa/js/10.68b30aac.js.gz
  29. BIN
      templates/dist/spa/js/11.794b8487.js.gz
  30. 1 1
      templates/dist/spa/js/12.31f6681d.js
  31. BIN
      templates/dist/spa/js/12.31f6681d.js.gz
  32. 1 1
      templates/dist/spa/js/13.b2b0f6d2.js
  33. BIN
      templates/dist/spa/js/13.b2b0f6d2.js.gz
  34. 1 1
      templates/dist/spa/js/14.d55c8046.js
  35. BIN
      templates/dist/spa/js/14.d55c8046.js.gz
  36. 1 1
      templates/dist/spa/js/15.469af797.js
  37. 1 0
      templates/dist/spa/js/15.4ac137c7.js
  38. BIN
      templates/dist/spa/js/15.4ac137c7.js.gz
  39. 1 0
      templates/dist/spa/js/22.0374c685.js
  40. BIN
      templates/dist/spa/js/22.0374c685.js.gz
  41. 0 1
      templates/dist/spa/js/22.475a49a9.js
  42. BIN
      templates/dist/spa/js/22.475a49a9.js.gz
  43. 1 1
      templates/dist/spa/js/4.e6b6e96a.js
  44. BIN
      templates/dist/spa/js/4.e6b6e96a.js.gz
  45. 0 1
      templates/dist/spa/js/3.7da6147c.js
  46. BIN
      templates/dist/spa/js/3.7da6147c.js.gz
  47. 1 1
      templates/dist/spa/js/5.79d49a06.js
  48. 1 1
      templates/dist/spa/js/6.d9c96499.js
  49. BIN
      templates/dist/spa/js/5.889114d6.js.gz
  50. BIN
      templates/dist/spa/js/6.d9c96499.js.gz
  51. 1 1
      templates/dist/spa/js/7.0111f6ad.js
  52. BIN
      templates/dist/spa/js/7.0111f6ad.js.gz
  53. 1 1
      templates/dist/spa/js/8.c2e4e059.js
  54. BIN
      templates/dist/spa/js/7.5d443c13.js.gz
  55. 1 1
      templates/dist/spa/js/9.36fbbaf3.js
  56. BIN
      templates/dist/spa/js/8.583d8ab3.js.gz
  57. BIN
      templates/dist/spa/js/8.c2e4e059.js.gz
  58. BIN
      templates/dist/spa/js/9.36fbbaf3.js.gz
  59. 1 0
      templates/dist/spa/js/9.b28b7d14.js
  60. BIN
      templates/dist/spa/js/9.b28b7d14.js.gz
  61. 1 0
      templates/dist/spa/js/app.251fee65.js
  62. BIN
      templates/dist/spa/js/app.251fee65.js.gz
  63. 0 1
      templates/dist/spa/js/app.ad05200e.js
  64. BIN
      templates/dist/spa/js/app.ad05200e.js.gz
  65. 1 0
      templates/dist/spa/js/chunk-common.fe167124.js
  66. BIN
      templates/dist/spa/js/chunk-common.fe167124.js.gz
  67. 0 649
      templates/src/boot/axios_request.js
  68. 257 17
      templates/src/components/containercard.vue
  69. 25 410
      templates/src/pages/container/containerlist.vue
  70. 1 1
      templates/src/pages/inbound/asn.vue

+ 2 - 1
.gitignore

@@ -5,4 +5,5 @@ __pycache__/
 /migrations/
 
 # Ignore pycharm project files
-/logs/
+/logs/
+templates/src/boot/axios_request.js

+ 5 - 0
container/serializers.py

@@ -43,11 +43,16 @@ class ContainerListPostSerializer(serializers.ModelSerializer):
         read_only_fields = ['id' ]
 
 class ContainerDetailSimpleGetSerializer(serializers.ModelSerializer):
+    batch = serializers.SerializerMethodField()
     class Meta:
         # 指定模型和排除字段
         model = ContainerDetailModel
         fields= '__all__'
         read_only_fields = ['id']
+    def get_batch(self, obj):
+        """ 动态序列化关联的批次数据 """
+        from bound.models import BoundBatchModel
+        return BoundBatchModel.objects.get(id=obj.batch_id).bound_number
 
 class ContainerDetailGetSerializer(serializers.ModelSerializer):
     # 定义明细单列表的序列化器,用于获取操作,字段只读

+ 8 - 0
logs/server.log

@@ -25185,3 +25185,11 @@ NameError: name 'serializer' is not defined
 [2025-05-22 02:35:10,803][django.server.log_message():187] [INFO] "GET /bound/batch/count/?page=1&page_size=11 HTTP/1.1" 200 336
 [2025-05-22 02:35:14,653][django.server.log_message():187] [INFO] "OPTIONS /bound/batch/count/2/ HTTP/1.1" 200 0
 [2025-05-22 02:35:14,743][django.server.log_message():187] [INFO] "GET /bound/batch/count/2/ HTTP/1.1" 200 2956
+[2025-05-23 01:41:29,387][django.request.log_response():241] [WARNING] Not Found: /container/containerdetail/
+[2025-05-23 01:41:29,410][django.request.log_response():241] [WARNING] Not Found: /container/locationdetail/
+[2025-05-23 02:03:22,140][django.request.log_response():241] [WARNING] Not Found: /container/containerdetail/
+[2025-05-23 02:03:22,159][django.request.log_response():241] [WARNING] Not Found: /container/locationdetail/
+[2025-05-23 02:03:22,224][django.request.log_response():241] [WARNING] Not Found: /container/locationdetail/
+[2025-05-23 02:03:22,238][django.request.log_response():241] [WARNING] Not Found: /container/containerdetail/
+[2025-05-23 02:03:22,294][django.request.log_response():241] [WARNING] Not Found: /container/locationdetail/
+[2025-05-23 02:03:22,310][django.request.log_response():241] [WARNING] Not Found: /container/containerdetail/

templates/dist/spa/css/11.74deb849.css → templates/dist/spa/css/10.74deb849.css


templates/dist/spa/css/12.601677c3.css → templates/dist/spa/css/11.601677c3.css


La diferencia del archivo ha sido suprimido porque es demasiado grande
+ 1 - 0
templates/dist/spa/css/12.659f915f.css


La diferencia del archivo ha sido suprimido porque es demasiado grande
+ 0 - 1
templates/dist/spa/css/13.80a6b71a.css


templates/dist/spa/css/14.f721cf95.css → templates/dist/spa/css/13.f721cf95.css


templates/dist/spa/css/15.e18d8a65.css → templates/dist/spa/css/14.e18d8a65.css


+ 1 - 0
templates/dist/spa/css/15.954d38ee.css

@@ -0,0 +1 @@
+.q-date__calendar-item--selected[data-v-f2e1b45a]{transition:all 0.3s ease;background-color:#1976d2!important}.q-date__range[data-v-f2e1b45a]{background-color:rgba(25,118,210,0.1)}.custom-title[data-v-f2e1b45a]{font-size:0.9rem;font-weight:500}.custom-timeline[data-v-f2e1b45a]{--q-timeline-color:#e0e0e0}.custom-node .q-timeline__dot[data-v-f2e1b45a]{background:#485573!important;border:2px solid #5c6b8c!important}.custom-node .q-timeline__content[data-v-f2e1b45a]{color:#485573}

+ 1 - 0
templates/dist/spa/css/22.4a53120f.css

@@ -0,0 +1 @@
+.q-date__calendar-item--selected[data-v-caa3275a]{transition:all 0.3s ease;background-color:#1976d2!important}.q-date__range[data-v-caa3275a]{background-color:rgba(25,118,210,0.1)}

+ 0 - 1
templates/dist/spa/css/22.8d4e7dc4.css

@@ -1 +0,0 @@
-.q-date__calendar-item--selected[data-v-f81b652a]{transition:all 0.3s ease;background-color:#1976d2!important}.q-date__range[data-v-f81b652a]{background-color:rgba(25,118,210,0.1)}

La diferencia del archivo ha sido suprimido porque es demasiado grande
+ 0 - 1
templates/dist/spa/css/3.cadbb490.css


templates/dist/spa/css/4.cd59f5a0.css → templates/dist/spa/css/3.cd59f5a0.css


templates/dist/spa/css/5.0ac6b60c.css → templates/dist/spa/css/4.0ac6b60c.css


templates/dist/spa/css/6.7100e471.css → templates/dist/spa/css/5.7100e471.css


templates/dist/spa/css/7.eb31c91a.css → templates/dist/spa/css/6.eb31c91a.css


templates/dist/spa/css/8.f57b1220.css → templates/dist/spa/css/7.f57b1220.css


templates/dist/spa/css/9.58670660.css → templates/dist/spa/css/8.58670660.css


templates/dist/spa/css/10.296f042c.css → templates/dist/spa/css/9.296f042c.css


+ 1 - 0
templates/dist/spa/css/chunk-common.ce13bc87.css

@@ -0,0 +1 @@
+[data-v-6cb08e33] .q-field__label{margin-top:8px;align-self:center}[data-v-6cb08e33] .q-field__control-container{padding-left:50px;margin-top:-5px}

La diferencia del archivo ha sido suprimido porque es demasiado grande
+ 1 - 1
templates/dist/spa/index.html


La diferencia del archivo ha sido suprimido porque es demasiado grande
+ 0 - 1
templates/dist/spa/js/1.66e8190d.js


BIN
templates/dist/spa/js/1.66e8190d.js.gz


La diferencia del archivo ha sido suprimido porque es demasiado grande
+ 0 - 1
templates/dist/spa/js/10.6087e287.js


BIN
templates/dist/spa/js/10.6087e287.js.gz


La diferencia del archivo ha sido suprimido porque es demasiado grande
+ 1 - 1
templates/dist/spa/js/11.794b8487.js


BIN
templates/dist/spa/js/10.68b30aac.js.gz


BIN
templates/dist/spa/js/11.794b8487.js.gz


La diferencia del archivo ha sido suprimido porque es demasiado grande
+ 1 - 1
templates/dist/spa/js/12.31f6681d.js


BIN
templates/dist/spa/js/12.31f6681d.js.gz


La diferencia del archivo ha sido suprimido porque es demasiado grande
+ 1 - 1
templates/dist/spa/js/13.b2b0f6d2.js


BIN
templates/dist/spa/js/13.b2b0f6d2.js.gz


La diferencia del archivo ha sido suprimido porque es demasiado grande
+ 1 - 1
templates/dist/spa/js/14.d55c8046.js


BIN
templates/dist/spa/js/14.d55c8046.js.gz


La diferencia del archivo ha sido suprimido porque es demasiado grande
+ 1 - 1
templates/dist/spa/js/15.469af797.js


La diferencia del archivo ha sido suprimido porque es demasiado grande
+ 1 - 0
templates/dist/spa/js/15.4ac137c7.js


BIN
templates/dist/spa/js/15.4ac137c7.js.gz


La diferencia del archivo ha sido suprimido porque es demasiado grande
+ 1 - 0
templates/dist/spa/js/22.0374c685.js


BIN
templates/dist/spa/js/22.0374c685.js.gz


La diferencia del archivo ha sido suprimido porque es demasiado grande
+ 0 - 1
templates/dist/spa/js/22.475a49a9.js


BIN
templates/dist/spa/js/22.475a49a9.js.gz


La diferencia del archivo ha sido suprimido porque es demasiado grande
+ 1 - 1
templates/dist/spa/js/4.e6b6e96a.js


BIN
templates/dist/spa/js/4.e6b6e96a.js.gz


La diferencia del archivo ha sido suprimido porque es demasiado grande
+ 0 - 1
templates/dist/spa/js/3.7da6147c.js


BIN
templates/dist/spa/js/3.7da6147c.js.gz


La diferencia del archivo ha sido suprimido porque es demasiado grande
+ 1 - 1
templates/dist/spa/js/5.79d49a06.js


La diferencia del archivo ha sido suprimido porque es demasiado grande
+ 1 - 1
templates/dist/spa/js/6.d9c96499.js


BIN
templates/dist/spa/js/5.889114d6.js.gz


BIN
templates/dist/spa/js/6.d9c96499.js.gz


La diferencia del archivo ha sido suprimido porque es demasiado grande
+ 1 - 1
templates/dist/spa/js/7.0111f6ad.js


BIN
templates/dist/spa/js/7.0111f6ad.js.gz


La diferencia del archivo ha sido suprimido porque es demasiado grande
+ 1 - 1
templates/dist/spa/js/8.c2e4e059.js


BIN
templates/dist/spa/js/7.5d443c13.js.gz


La diferencia del archivo ha sido suprimido porque es demasiado grande
+ 1 - 1
templates/dist/spa/js/9.36fbbaf3.js


BIN
templates/dist/spa/js/8.583d8ab3.js.gz


BIN
templates/dist/spa/js/8.c2e4e059.js.gz


BIN
templates/dist/spa/js/9.36fbbaf3.js.gz


La diferencia del archivo ha sido suprimido porque es demasiado grande
+ 1 - 0
templates/dist/spa/js/9.b28b7d14.js


BIN
templates/dist/spa/js/9.b28b7d14.js.gz


La diferencia del archivo ha sido suprimido porque es demasiado grande
+ 1 - 0
templates/dist/spa/js/app.251fee65.js


BIN
templates/dist/spa/js/app.251fee65.js.gz


La diferencia del archivo ha sido suprimido porque es demasiado grande
+ 0 - 1
templates/dist/spa/js/app.ad05200e.js


BIN
templates/dist/spa/js/app.ad05200e.js.gz


La diferencia del archivo ha sido suprimido porque es demasiado grande
+ 1 - 0
templates/dist/spa/js/chunk-common.fe167124.js


BIN
templates/dist/spa/js/chunk-common.fe167124.js.gz


+ 0 - 649
templates/src/boot/axios_request.js

@@ -1,649 +0,0 @@
-import Vue from 'vue'
-import axios from 'axios'
-import { SessionStorage, LocalStorage, Notify, Loading } from 'quasar'
-import { i18n } from './i18n'
-import Bus from './bus.js'
-
-function getBaseUrl (name) {
-  const xhr = new XMLHttpRequest()
-  const okStatus = document.location.protocol === 'file:' ? 0 : 200
-  xhr.open('GET', '../../statics/' + name, false)
-  xhr.overrideMimeType('text/html; charset=utf-8')
-  xhr.send(null)
-  return xhr.status === okStatus ? xhr.responseText : null
-}
-// 注意以后修改成服务器的地址
-// const baseurl = 'http://localhost:8008'
-const baseurl = 'http://192.168.18.200:8008'
-
-const axiosInstance = axios.create({
-  baseURL: baseurl
-})
-
-const axiosInstanceVersion = axios.create({
-  baseURL: baseurl
-})
-
-const axiosInstanceAuth = axios.create({
-  baseURL: baseurl
-})
-
-const axiosInstanceAuthScan = axios.create({
-  baseURL: baseurl
-})
-
-var lang = LocalStorage.getItem('lang')
-if (LocalStorage.has('lang')) {
-  lang = lang || 'zh-hans'
-} else {
-  LocalStorage.set('lang', 'zh-hans')
-  lang = 'zh-hans'
-}
-
-const axiosFile = axios.create({
-  baseURL: baseurl
-})
-
-axiosInstanceAuth.interceptors.request.use(
-  function (config) {
-    const auth = LocalStorage.getItem('auth')
-    const login = SessionStorage.getItem('axios_check')
-    if (auth || login) {
-      config.headers.post['Content-Type'] = 'application/json, charset="utf-8"'
-      config.headers.patch['Content-Type'] = 'application/json, charset="utf-8"'
-      config.headers.put['Content-Type'] = 'application/json, charset="utf-8"'
-      config.headers.token = LocalStorage.getItem('openid')
-      config.headers.appid = LocalStorage.getItem('appid')
-
-      config.headers.operator = LocalStorage.getItem('login_id')
-      config.headers.language = lang
-      if (config.method === 'post' || config.method === 'patch' || config.method === 'put' || config.method === 'delete') {
-        Loading.show()
-      }
-      return config
-    } else {
-      Loading.hide()
-      Bus.$emit('needLogin', true)
-    }
-  },
-  function (error) {
-    Loading.hide()
-    return Promise.reject(error)
-  }
-)
-
-axiosInstanceAuth.interceptors.response.use(
-  function (response) {
-    if (response.data.detail) {
-      if (response.data.detail !== 'success') {
-        Notify.create({
-          message: response.data.detail,
-          icon: 'close',
-          color: 'negative',
-          timeout: 1500
-        })
-      }
-    }
-    if (response.data.results) {
-      var sslcheck = baseurl.split(':')
-      if (response.data.next !== null) {
-        if (sslcheck.length === 2) {
-          var nextlinkcheck = (response.data.next).toString().split(sslcheck[1])
-          response.data.next = nextlinkcheck[1]
-        } else {
-          var nextlinkcheck1 = (response.data.next).toString().split(sslcheck[1] + ':' + sslcheck[2])
-          response.data.next = nextlinkcheck1[1]
-        }
-      } else {
-        response.data.next = null
-      }
-      if (response.data.previous !== null) {
-        if (sslcheck.length === 2) {
-          var previouslinkcheck = (response.data.previous).toString().split(sslcheck[1])
-          response.data.previous = previouslinkcheck[1]
-        } else {
-          var previouslinkcheck1 = (response.data.previous).toString().split(sslcheck[1] + ':' + sslcheck[2])
-          response.data.previous = previouslinkcheck1[1]
-        }
-      } else {
-        response.data.previous = null
-      }
-      Loading.hide()
-      return response.data
-    }
-    Loading.hide()
-    return response.data
-  },
-  function (error) {
-    const defaultNotify = {
-      message: i18n.t('notice.unknow_error'),
-      icon: 'close',
-      color: 'negative',
-      timeout: 1500
-    }
-    if (error.code === 'ECONNABORTED' || error.message.indexOf('timeout') !== -1 || error.message === 'Network Error') {
-      defaultNotify.message = i18n.t('notice.network_error')
-      Notify.create(defaultNotify)
-      Loading.hide()
-      return Promise.reject(error)
-    }
-    switch (error.response.status) {
-      case 400:
-        defaultNotify.message = i18n.t('notice.400')
-        Notify.create(defaultNotify)
-        break
-      case 401:
-        defaultNotify.message = i18n.t('notice.401')
-        Notify.create(defaultNotify)
-        break
-      case 403:
-        defaultNotify.message = i18n.t('notice.403')
-        Notify.create(defaultNotify)
-        break
-      case 404:
-        defaultNotify.message = i18n.t('notice.404')
-        Notify.create(defaultNotify)
-        break
-      case 405:
-        defaultNotify.message = i18n.t('notice.405')
-        Notify.create(defaultNotify)
-        break
-      case 408:
-        defaultNotify.message = i18n.t('notice.408')
-        Notify.create(defaultNotify)
-        break
-      case 409:
-        defaultNotify.message = i18n.t('notice.409')
-        Notify.create(defaultNotify)
-        break
-      case 410:
-        defaultNotify.message = i18n.t('notice.410')
-        Notify.create(defaultNotify)
-        break
-      case 500:
-        defaultNotify.message = i18n.t('notice.500')
-        Notify.create(defaultNotify)
-        break
-      case 501:
-        defaultNotify.message = i18n.t('notice.501')
-        Notify.create(defaultNotify)
-        break
-      case 502:
-        defaultNotify.message = i18n.t('notice.502')
-        Notify.create(defaultNotify)
-        break
-      case 503:
-        defaultNotify.message = i18n.t('notice.503')
-        Notify.create(defaultNotify)
-        break
-      case 504:
-        defaultNotify.message = i18n.t('notice.504')
-        Notify.create(defaultNotify)
-        break
-      case 505:
-        defaultNotify.message = i18n.t('notice.505')
-        Notify.create(defaultNotify)
-        break
-      default:
-        Notify.create(defaultNotify)
-        break
-    }
-    Loading.hide()
-    return Promise.reject(error)
-  }
-)
-
-axiosInstanceAuthScan.interceptors.request.use(
-  function (config) {
-    // 从 LocalStorage 获取认证信息
-    const auth = LocalStorage.getItem('auth')
-    // 从 SessionStorage 获取 axios 检查标志
-    const login = SessionStorage.getItem('axios_check')
-    // 如果存在认证信息或登录标志,则设置请求头并显示加载状态
-    if (auth || login) {
-      config.headers.post['Content-Type'] = 'application/json, charset="utf-8"'
-      config.headers.patch['Content-Type'] = 'application/json, charset="utf-8"'
-      config.headers.put['Content-Type'] = 'application/json, charset="utf-8"'
-      config.headers.token = LocalStorage.getItem('openid')
-      config.headers.appid = LocalStorage.getItem('appid')
-      config.headers.operator = LocalStorage.getItem('login_id')
-      config.headers.language = lang
-      // 对于 POST, PATCH, PUT 和 DELETE 方法,显示加载状态
-      if (config.method === 'post' || config.method === 'patch' || config.method === 'put' || config.method === 'delete') {
-        Loading.show()
-      }
-      return config
-    } else {
-      // 隐藏加载状态并发出需要登录的事件
-      Loading.hide()
-      Bus.$emit('needLogin', true)
-    }
-  },
-  function (error) {
-    // 隐藏加载状态并拒绝请求
-    Loading.hide()
-    return Promise.reject(error)
-  }
-)
-
-axiosInstanceAuthScan.interceptors.response.use(
-  function (response) {
-    if (response.data.results) {
-      var sslcheck = baseurl.split(':')
-      if (response.data.next !== null) {
-        if (sslcheck.length === 2) {
-          var nextlinkcheck = (response.data.next).toString().split(sslcheck[1])
-          response.data.next = nextlinkcheck[1]
-        } else {
-          var nextlinkcheck1 = (response.data.next).toString().split(sslcheck[1] + ':' + sslcheck[2])
-          response.data.next = nextlinkcheck1[1]
-        }
-      } else {
-        response.data.next = null
-      }
-      if (response.data.previous !== null) {
-        if (sslcheck.length === 2) {
-          var previouslinkcheck = (response.data.previous).toString().split(sslcheck[1])
-          response.data.previous = previouslinkcheck[1]
-        } else {
-          var previouslinkcheck1 = (response.data.previous).toString().split(sslcheck[1] + ':' + sslcheck[2])
-          response.data.previous = previouslinkcheck1[1]
-        }
-      } else {
-        response.data.previous = null
-      }
-      Loading.hide()
-      return response.data
-    }
-    Loading.hide()
-    return response.data
-  },
-  function (error) {
-    const defaultNotify = {
-      message: i18n.t('notice.unknow_error'),
-      icon: 'close',
-      color: 'negative',
-      timeout: 1500
-    }
-    if (error.code === 'ECONNABORTED' || error.message.indexOf('timeout') !== -1 || error.message === 'Network Error') {
-      defaultNotify.message = i18n.t('notice.network_error')
-      Notify.create(defaultNotify)
-      Loading.hide()
-      return Promise.reject(error)
-    }
-    switch (error.response.status) {
-      case 400:
-        defaultNotify.message = i18n.t('notice.400')
-        Notify.create(defaultNotify)
-        break
-      case 401:
-        defaultNotify.message = i18n.t('notice.401')
-        Notify.create(defaultNotify)
-        break
-      case 403:
-        defaultNotify.message = i18n.t('notice.403')
-        Notify.create(defaultNotify)
-        break
-      case 404:
-        defaultNotify.message = i18n.t('notice.404')
-        Notify.create(defaultNotify)
-        break
-      case 405:
-        defaultNotify.message = i18n.t('notice.405')
-        Notify.create(defaultNotify)
-        break
-      case 408:
-        defaultNotify.message = i18n.t('notice.408')
-        Notify.create(defaultNotify)
-        break
-      case 409:
-        defaultNotify.message = i18n.t('notice.409')
-        Notify.create(defaultNotify)
-        break
-      case 410:
-        defaultNotify.message = i18n.t('notice.410')
-        Notify.create(defaultNotify)
-        break
-      case 500:
-        defaultNotify.message = i18n.t('notice.500')
-        Notify.create(defaultNotify)
-        break
-      case 501:
-        defaultNotify.message = i18n.t('notice.501')
-        Notify.create(defaultNotify)
-        break
-      case 502:
-        defaultNotify.message = i18n.t('notice.502')
-        Notify.create(defaultNotify)
-        break
-      case 503:
-        defaultNotify.message = i18n.t('notice.503')
-        Notify.create(defaultNotify)
-        break
-      case 504:
-        defaultNotify.message = i18n.t('notice.504')
-        Notify.create(defaultNotify)
-        break
-      case 505:
-        defaultNotify.message = i18n.t('notice.505')
-        Notify.create(defaultNotify)
-        break
-      default:
-        Notify.create(defaultNotify)
-        break
-    }
-    Loading.hide()
-    return Promise.reject(error)
-  }
-)
-
-axiosInstance.interceptors.request.use(
-  function (config) {
-    config.headers.post['Content-Type'] = 'application/json, charset="utf-8"'
-    config.headers.language = lang
-    if (config.method === 'post' || config.method === 'patch' || config.method === 'put' || config.method === 'delete') {
-      Loading.show()
-    }
-    return config
-  },
-  function (error) {
-    Loading.hide()
-    return Promise.reject(error)
-  }
-)
-
-axiosInstance.interceptors.response.use(
-  function (response) {
-    if (response.data.detail) {
-      if (response.data.detail !== 'success') {
-        Notify.create({
-          message: response.data.detail,
-          icon: 'close',
-          color: 'negative',
-          timeout: 1500
-        })
-      }
-    }
-    Loading.hide()
-    return response.data
-  },
-  function (error) {
-    const defaultNotify = {
-      message: i18n.t('notice.network_error'),
-      icon: 'close',
-      color: 'negative',
-      timeout: 1500
-    }
-    if (error.code === 'ECONNABORTED' || error.message.indexOf('timeout') !== -1 || error.message === 'Network Error') {
-      defaultNotify.message = i18n.t('notice.network_error')
-      Notify.create(defaultNotify)
-      Loading.hide()
-      return Promise.reject(error)
-    }
-    switch (error.response.status) {
-      case 400:
-        defaultNotify.message = i18n.t('notice.400')
-        Notify.create(defaultNotify)
-        break
-      case 401:
-        defaultNotify.message = i18n.t('notice.401')
-        Notify.create(defaultNotify)
-        break
-      case 403:
-        defaultNotify.message = i18n.t('notice.403')
-        Notify.create(defaultNotify)
-        break
-      case 404:
-        defaultNotify.message = i18n.t('notice.404')
-        Notify.create(defaultNotify)
-        break
-      case 405:
-        defaultNotify.message = i18n.t('notice.405')
-        Notify.create(defaultNotify)
-        break
-      case 408:
-        defaultNotify.message = i18n.t('notice.408')
-        Notify.create(defaultNotify)
-        break
-      case 409:
-        defaultNotify.message = i18n.t('notice.409')
-        Notify.create(defaultNotify)
-        break
-      case 410:
-        defaultNotify.message = i18n.t('notice.410')
-        Notify.create(defaultNotify)
-        break
-      case 500:
-        defaultNotify.message = i18n.t('notice.500')
-        Notify.create(defaultNotify)
-        break
-      case 501:
-        defaultNotify.message = i18n.t('notice.501')
-        Notify.create(defaultNotify)
-        break
-      case 502:
-        defaultNotify.message = i18n.t('notice.502')
-        Notify.create(defaultNotify)
-        break
-      case 503:
-        defaultNotify.message = i18n.t('notice.503')
-        Notify.create(defaultNotify)
-        break
-      case 504:
-        defaultNotify.message = i18n.t('notice.504')
-        Notify.create(defaultNotify)
-        break
-      case 505:
-        defaultNotify.message = i18n.t('notice.505')
-        Notify.create(defaultNotify)
-        break
-      default:
-        Notify.create(defaultNotify)
-        break
-    }
-    Loading.hide()
-    return Promise.reject(error)
-  }
-)
-
-axiosInstanceVersion.interceptors.request.use(
-  function (config) {
-    const auth = LocalStorage.getItem('auth')
-    const login = SessionStorage.getItem('axios_check')
-    if (auth || login) {
-      if (config.method === 'post' || config.method === 'patch' || config.method === 'put' || config.method === 'delete') {
-        Loading.show()
-      }
-      return config
-    } else {
-      Loading.hide()
-      Bus.$emit('needLogin', true)
-    }
-  },
-  function (error) {
-    Loading.hide()
-    return Promise.reject(error)
-  }
-)
-
-axiosInstanceVersion.interceptors.response.use(
-  function (response) {
-    Loading.hide()
-    return response.data
-  },
-  function (error) {
-    Loading.hide()
-    return Promise.reject(error)
-  }
-)
-
-axiosFile.interceptors.request.use(
-  function (config) {
-    const auth = LocalStorage.getItem('auth')
-    const login = SessionStorage.getItem('axios_check')
-    if (auth || login) {
-      config.headers.get['Content-Type'] = 'application/vnd.ms-excel'
-      config.headers.token = LocalStorage.getItem('openid')
-      config.headers.appid = LocalStorage.getItem('appid')
-      config.headers.operator = LocalStorage.getItem('login_id')
-      config.headers.language = lang
-      if (config.method === 'post' || config.method === 'patch' || config.method === 'put' || config.method === 'delete') {
-        Loading.show()
-      }
-      return config
-    } else {
-      Loading.hide()
-      Bus.$emit('needLogin', true)
-    }
-  },
-  function (error) {
-    Loading.hide()
-    return Promise.reject(error)
-  }
-)
-
-axiosFile.interceptors.response.use(
-  function (response) {
-    if (response.data.detail) {
-      if (response.data.detail !== 'success') {
-        Notify.create({
-          message: response.data.detail,
-          icon: 'close',
-          color: 'negative',
-          timeout: 1500
-        })
-      }
-    }
-    Loading.hide()
-    return response
-  },
-  function (error) {
-    const defaultNotify = {
-      message: i18n.t('notice.network_error'),
-      icon: 'close',
-      color: 'negative',
-      timeout: 1500
-    }
-    if (error.code === 'ECONNABORTED' || error.message.indexOf('timeout') !== -1 || error.message === 'Network Error') {
-      defaultNotify.message = i18n.t('notice.network_error')
-      Notify.create(defaultNotify)
-      Loading.hide()
-      return Promise.reject(error)
-    }
-    switch (error.response.status) {
-      case 400:
-        defaultNotify.message = i18n.t('notice.400')
-        Notify.create(defaultNotify)
-        break
-      case 401:
-        defaultNotify.message = i18n.t('notice.401')
-        Notify.create(defaultNotify)
-        break
-      case 403:
-        defaultNotify.message = i18n.t('notice.403')
-        Notify.create(defaultNotify)
-        break
-      case 404:
-        defaultNotify.message = i18n.t('notice.404')
-        Notify.create(defaultNotify)
-        break
-      case 405:
-        defaultNotify.message = i18n.t('notice.405')
-        Notify.create(defaultNotify)
-        break
-      case 408:
-        defaultNotify.message = i18n.t('notice.408')
-        Notify.create(defaultNotify)
-        break
-      case 409:
-        defaultNotify.message = i18n.t('notice.409')
-        Notify.create(defaultNotify)
-        break
-      case 410:
-        defaultNotify.message = i18n.t('notice.410')
-        Notify.create(defaultNotify)
-        break
-      case 500:
-        defaultNotify.message = i18n.t('notice.500')
-        Notify.create(defaultNotify)
-        break
-      case 501:
-        defaultNotify.message = i18n.t('notice.501')
-        Notify.create(defaultNotify)
-        break
-      case 502:
-        defaultNotify.message = i18n.t('notice.502')
-        Notify.create(defaultNotify)
-        break
-      case 503:
-        defaultNotify.message = i18n.t('notice.503')
-        Notify.create(defaultNotify)
-        break
-      case 504:
-        defaultNotify.message = i18n.t('notice.504')
-        Notify.create(defaultNotify)
-        break
-      case 505:
-        defaultNotify.message = i18n.t('notice.505')
-        Notify.create(defaultNotify)
-        break
-      default:
-        Notify.create(defaultNotify)
-        break
-    }
-    Loading.hide()
-    return Promise.reject(error)
-  }
-)
-
-function getauth (url) {
-  return axiosInstanceAuth.get(url)
-}
-
-function get (url) {
-  return axiosInstance.get(url)
-}
-
-function versioncheck (url) {
-  return axiosInstanceVersion.get(url)
-}
-
-function post (url, data) {
-  return axiosInstance.post(url, data)
-}
-
-function postauth (url, data) {
-  return axiosInstanceAuth.post(url, data)
-}
-
-function putauth (url, data) {
-  return axiosInstanceAuth.put(url, data)
-}
-
-function patchauth (url, data) {
-  return axiosInstanceAuth.patch(url, data)
-}
-
-function deleteauth (url) {
-  return axiosInstanceAuth.delete(url)
-}
-
-function ViewPrintAuth (url) {
-  return axiosInstanceAuth.get(url)
-}
-
-function scangetauth (url) {
-  return axiosInstanceAuthScan.get(url)
-}
-
-function scanpostauth (url, data) {
-  return axiosInstanceAuthScan.post(url, data)
-}
-
-function getfile (url) {
-  return axiosFile.get(url)
-}
-
-Vue.prototype.$axios = axios
-
-export { baseurl, get, versioncheck, post, getauth, postauth, putauth, deleteauth, patchauth, ViewPrintAuth, getfile, scangetauth, scanpostauth }

+ 257 - 17
templates/src/components/containercard.vue

@@ -6,7 +6,7 @@
       transition-hide="jump-up"
       @show="prepareDialog()"
     >
-      <q-card style="min-width: 800px">
+      <q-card style="min-width: 1000px">
         <q-bar
           class="bg-light-blue-10 text-white rounded-borders"
           style="height: 50px"
@@ -21,10 +21,11 @@
           <q-tabs v-model="activeTab">
             <q-tab name="tab2" label="托盘信息" />
             <q-tab name="tab3" label="托盘详情" />
+            <q-tab name="tab1" label="操作记录" />
           </q-tabs>
         </q-card-section>
         <q-tab-panels v-model="activeTab" animated>
-          <q-tab-panel name="tab2" style="height: 300px">
+          <q-tab-panel name="tab2" style="height: 600px">
             <template>
               <div class="text-h6 q-mb-md">{{ "托盘信息" }}</div>
               <q-table
@@ -84,18 +85,8 @@
               </div>
             </template>
           </q-tab-panel>
-          <q-tab-panel name="tab3" style="height: 300px">
-            <q-btn
-              flat
-              dense
-              color="primary"
-              align="right"
-              @click="showInventoryDetails = !showInventoryDetails"
-            >
-              {{ showInventoryDetails ? "收起" : "展开" }}
-            </q-btn>
+          <q-tab-panel name="tab3" style="height: 600px">
             <q-table
-              v-if="showInventoryDetails"
               :data="container_table"
               :columns="coloums_container"
               row-key="id"
@@ -103,7 +94,7 @@
               bordered
               hide-pagination
               class="my-sticky-table scrollable-table"
-              :style="{ 'max-height': '400px' }"
+              :style="{ 'max-height': '600px' }"
               :container-style="{ height: 'auto' }"
               :pagination="{ rowsPerPage: 0 }"
             >
@@ -131,6 +122,71 @@
               </template>
             </q-table>
           </q-tab-panel>
+          <q-tab-panel name="tab1" style="height: 600px">
+            <div
+              style="
+                float: right;
+                padding: 15px 15px 50px 15px;
+                min-width: 100%;
+              "
+              flow="row wrap"
+            >
+              <q-card class="q-mb-md" bordered>
+                <q-card-section>
+                  <template>
+                    <div
+                      class="text-h6 q-mb-md"
+                      style="display: flex; justify-content: space-between"
+                    >
+                      {{ "操作记录" }}
+                    </div>
+                    <q-btn
+                      class="q-ml-sm"
+                      color="primary"
+                      icon="event"
+                      @click="sortoperatedetail"
+                      >近一个月操作记录</q-btn
+                    >
+                    <template v-if="listSize > 0">
+                      <q-list bordered class="rounded-borders">
+                        <q-expansion-item
+                          v-for="(node, index) in nodeList"
+                          v-if="node.value && node.value.length > 0"
+                          :key="index"
+                          group="op-group"
+                          :caption="`操作类型: ${formatType(
+                            node.value[0].operation_type
+                          )} ----- 操作时间:${node.value[0].timestamp}`"
+                        >
+                          <q-card>
+                            <q-card-section>
+
+                                <q-table
+
+                                  :data="node.value"
+                                  :columns="columns_operate"
+                                  row-key="id"
+                                  flat
+                                  bordered
+                                  hide-pagination
+                                  class="my-sticky-table scrollable-table"
+                                  :style="{ 'max-height': '400px' }"
+                                  :container-style="{ height: 'auto' }"
+                                  :pagination="{ rowsPerPage: 0 }"
+                                >
+                                </q-table>
+
+                            </q-card-section>
+                          </q-card>
+                        </q-expansion-item>
+                      </q-list>
+                    </template>
+                    <div v-else class="text-grey-8">暂无操作记录</div>
+                  </template>
+                </q-card-section>
+              </q-card>
+            </div>
+          </q-tab-panel>
         </q-tab-panels>
 
         <div style="float: right; padding: 15px 15px 15px 0">
@@ -153,8 +209,72 @@
 </template>
 
 <script>
+class ListNode {
+  constructor (value) {
+    this.value = value
+    this.next = null
+  }
+}
+
+class LinkedList {
+  constructor () {
+    this.head = null
+    this.size = 0
+  }
+
+  append (value) {
+    const newNode = new ListNode(value)
+    if (!this.head) {
+      this.head = newNode
+    } else {
+      let current = this.head
+      while (current.next) {
+        current = current.next
+      }
+      current.next = newNode
+    }
+    this.size++
+  }
+
+  delete (value) {
+    if (!this.head) return
+
+    if (this.head.value === value) {
+      this.head = this.head.next
+      this.size--
+      return
+    }
+
+    let current = this.head
+    while (current.next) {
+      if (current.next.value === value) {
+        current.next = current.next.next
+        this.size--
+        return
+      }
+      current = current.next
+    }
+  }
+
+  toArray () {
+    const result = []
+    let current = this.head
+    while (current) {
+      result.push({ value: current.value })
+      current = current.next
+    }
+    return result
+  }
+
+  clear () {
+    this.head = null
+    this.size = 0
+  }
+}
+
 import { getauth, putauth, deleteauth } from 'boot/axios_request'
 import { LocalStorage } from 'quasar'
+
 export default {
   props: {
     containerCode: Number,
@@ -195,15 +315,21 @@ export default {
           align: 'center'
         },
         {
-          label: '每件重量',
-          field: (row) => row.goods_qty,
+          label: '物料批次',
+          field: (row) => row.bound_number,
           align: 'center'
         },
+
         {
           label: '件数',
           field: (row) => row.group_qty,
           align: 'center'
         },
+        {
+          label: '每件重量',
+          field: (row) => row.goods_qty,
+          align: 'center'
+        },
         {
           label: '批次计划重量',
           field: (row) => row.batch_total_qty,
@@ -231,6 +357,11 @@ export default {
           field: (row) => row.goods_desc,
           align: 'center'
         },
+        {
+          label: '物料批次',
+          field: (row) => row.batch,
+          align: 'center'
+        },
         {
           label: '入库重量',
           field: (row) => row.goods_qty,
@@ -252,6 +383,45 @@ export default {
           headerStyle: 'width: 80px' // 固定列宽
         }
       ],
+      columns_operate: [
+        {
+          name: 'timestamp',
+          label: '操作时间',
+          field: (row) => row.timestamp,
+          align: 'center'
+        },
+        {
+          name: 'operator',
+          label: '经手人',
+          field: (row) => row.operator,
+          align: 'center'
+        },
+        {
+          name: 'batch',
+          label: '批次',
+          field: (row) => row.batch.bound_number,
+          align: 'center'
+        },
+        {
+          name: 'memo',
+          label: '备注',
+          field: (row) => row.memo,
+          align: 'center'
+        },
+        {
+
+          label: '当前位置',
+          field: (row) => row.from_location,
+
+          align: 'center'
+        },
+        {
+
+          label: '目标位置',
+          field: (row) => row.to_location,
+          align: 'center'
+        }
+      ],
       user_id: '',
       auth_id: '',
       can_edit_detail: false,
@@ -260,14 +430,83 @@ export default {
       bgColor: 'transparent',
       error1: this.$t('stock.shelf.error1'),
       shelfLocal: '',
-      activeTab: 'tab2'
+      activeTab: 'tab2',
+      operate_detail: [],
+      linkedList: new LinkedList()
     }
   },
   created () {
     this.handleclick()
   },
+  computed: {
+    nodeList () {
+      return this.linkedList.toArray()
+    },
 
+    listSize () {
+      return this.linkedList.size
+    }
+  },
   methods: {
+    sortoperatedetail () {
+      var _this = this
+      console.log('近一个月操作记录', _this.nodeList)
+    },
+    formatType (type) {
+      switch (type) {
+        case 'container':
+          return '组盘'
+        case 'outbound':
+          return '出库'
+        case 'inbound':
+          return '入库'
+        case '4':
+          return '移库'
+        case '5':
+          return '调拨'
+        case '6':
+          return '其他'
+        default:
+          return '未知'
+      }
+    },
+    getOperationRecord () {
+      var _this = this
+      _this.operate_detail = []
+      var operate_detail_container = []
+      _this.linkedList.clear()
+      getauth('container/operate/?status=1&container=' + _this.containerNumber)
+        .then((res) => {
+          _this.operate_detail = res.results
+          if (_this.operate_detail.length === 0) return
+
+          // 初始化第一个元素
+          operate_detail_container.push(_this.operate_detail[0])
+
+          for (let i = 0; i < _this.operate_detail.length - 1; i++) {
+            const current = _this.operate_detail[i]
+            const next = _this.operate_detail[i + 1]
+            if (current.operation_type === next.operation_type) {
+              operate_detail_container.push(next)
+            } else {
+              _this.linkedList.append([...operate_detail_container])
+              operate_detail_container = [next]
+            }
+          }
+
+          // 添加最后一个分组
+          if (operate_detail_container.length > 0) {
+            _this.linkedList.append([...operate_detail_container])
+          }
+        })
+        .catch((err) => {
+          _this.$q.notify({
+            message: err.detail,
+            icon: 'close',
+            color: 'negative'
+          })
+        })
+    },
     handleRowdelete (rowData) {
       if (this.can_edit_detail === true) {
         console.log('当前行数据:', rowData)
@@ -389,6 +628,7 @@ export default {
     handleclick () {
       this.getList()
       this.get_container_table()
+      this.getOperationRecord()
       this.storage_dialog = true
     },
     get_container_table () {

+ 25 - 410
templates/src/pages/container/containerlist.vue

@@ -202,355 +202,34 @@
       </div>
     </template>
 
-    <q-dialog
-      v-model="detailForm"
-      transition-show="jump-down"
-      transition-hide="jump-up"
-    >
-      <q-card style="min-width: 900px">
-        <q-bar
-          class="bg-light-blue-10 text-white rounded-borders"
-          style="height: 50px"
-        >
-          <div>
-            {{ "批次信息" }}
-          </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-tabs>
-        </q-card-section>
-        <!-- 选项卡内容 -->
-        <q-tab-panels v-model="activeTab" animated>
-          <q-tab-panel name="tab1" style="height: 70px">
-            <div class="row q-gutter-x-md">
-              <div class="col column q-gutter-y-md">
-                <q-input
-                  dense
-                  outlined
-                  square
-                  v-model="table_detail[0].container.container_code"
-                  :label="'托盘编码'"
-                  :readonly="true"
-                />
-              </div>
-              <div class="col column q-gutter-y-md">
-                <q-input
-                  dense
-                  outlined
-                  square
-                  v-model="table_detail[0].container.current_location"
-                  :label="'当前位置'"
-                  :readonly="true"
-                />
-              </div>
-            </div>
-            <div
-              style="
-                float: right;
-                padding: 15px 15px 50px 15px;
-                min-width: 100%;
-              "
-              flow="row wrap"
-            >
-              <q-card class="q-mb-md" bordered>
-                <q-card-section>
-                  <template>
-                    <div class="text-h6 q-mb-md">{{ "托盘物料" }}</div>
-                    <template v-if="table_detail.length > 0">
-                      <div
-                        v-for="(item, index) in table_detail"
-                        :key="index"
-                        class="row q-col-gutter-md q-mb-sm"
-                      >
-                        <div class="col" style="min-width: 150px">
-                          <q-input
-                            v-model="item.batch.bound_number"
-                            :label="'批次'"
-                            :readonly="onlyread"
-                            dense
-                            outlined
-                          />
-                        </div>
-                        <div class="col">
-                          <q-input
-                            v-model="item.batch.goods_desc"
-                            :label="'货物'"
-                            :readonly="onlyread"
-                            dense
-                            outlined
-                          />
-                        </div>
-                        <div class="col">
-                          <q-input
-                            v-model="item.batch.goods_weight"
-                            :label="'单重'"
-                            :readonly="onlyread"
-                            dense
-                            outlined
-                          />
-                        </div>
-                        <div class="col">
-                          <q-input
-                            v-model="item.goods_qty"
-                            :label="'数量'"
-                            :readonly="onlyread"
-                            dense
-                            outlined
-                          />
-                        </div>
-                        <div class="col">
-                          <q-input
-                            v-model="item.batch.creater"
-                            :label="'组盘'"
-                            :readonly="onlyread"
-                            dense
-                            outlined
-                          />
-                        </div>
-                      </div>
-                    </template>
-                  </template>
-                </q-card-section>
-              </q-card>
-            </div>
-          </q-tab-panel>
-          <q-tab-panel name="tab2" style="height: 70px">
-            <div class="row q-gutter-x-md">
-              <div class="col column q-gutter-y-md">
-                <q-input
-                  dense
-                  outlined
-                  square
-                  v-model="table_detail[0].container.container_code"
-                  :label="'托盘编码'"
-                  :readonly="true"
-                />
-              </div>
-              <div class="col column q-gutter-y-md">
-                <q-input
-                  dense
-                  outlined
-                  square
-                  v-model="table_detail[0].container.current_location"
-                  :label="'当前位置'"
-                  :readonly="true"
-                />
-              </div>
-            </div>
-            <div
-              style="
-                float: right;
-                padding: 15px 15px 50px 15px;
-                min-width: 100%;
-              "
-              flow="row wrap"
-            >
-              <q-card class="q-mb-md" bordered>
-                <q-card-section>
-                  <template>
-                    <div
-                      class="text-h6 q-mb-md"
-                      style="display: flex; justify-content: space-between"
-                    >
-                      {{ "操作记录" }}
-                      <q-btn
-                        class="q-ml-sm"
-                        color="primary"
-                        icon="event"
-                        @click="sortoperatedetail"
-                        >近一个月操作记录</q-btn
-                      >
-                    </div>
-                    <template v-if="listSize > 0">
-                      <q-list bordered class="rounded-borders">
-                        <q-expansion-item
-                          v-for="(node, index) in nodeList"
-                          v-if="node.value && node.value.length > 0"
-                          :key="index"
-                          group="op-group"
-                          :caption="`操作类型: ${formatType(
-                            node.value[0].operation_type
-                          )} ----- 操作时间:${node.value[0].timestamp}`"
-                        >
-                          <!-- 展开后的详细信息 -->
-                          <q-card>
-                            <q-card-section>
-                              <div
-                                v-for="(item, detailindex) in node.value"
-                                :key="detailindex"
-                                class="row q-col-gutter-md q-mb-sm"
-                                style="
-                                  display: flex;
-                                  justify-content: space-between;
-                                "
-                              >
-                                <div class="col" style="min-width: 150px">
-                                  <q-input
-                                    v-model="item.batch.bound_number"
-                                    :label="'批次'"
-                                    :readonly="onlyread"
-                                    dense
-                                    outlined
-                                  />
-                                </div>
-                                <div class="col">
-                                  <q-input
-                                    v-model="item.batch.goods_desc"
-                                    :label="'货物'"
-                                    :readonly="onlyread"
-                                    dense
-                                    outlined
-                                  />
-                                </div>
-                                <div class="col">
-                                  <q-input
-                                    v-model="item.batch.goods_weight"
-                                    :label="'单重'"
-                                    :readonly="onlyread"
-                                    dense
-                                    outlined
-                                  />
-                                </div>
-                                <div class="col">
-                                  <q-input
-                                    v-model="item.goods_qty"
-                                    :label="'数量'"
-                                    :readonly="onlyread"
-                                    dense
-                                    outlined
-                                  />
-                                </div>
-                                <div class="col">
-                                  <q-input
-                                    v-model="item.operator"
-                                    :label="'经手人'"
-                                    :readonly="onlyread"
-                                    dense
-                                    outlined
-                                  />
-                                </div>
-                                <div class="col">
-                                  <q-input
-                                    v-model="item.memo"
-                                    label="备注"
-                                    :readonly="onlyread"
-                                    dense
-                                    outlined
-                                    type="textarea"
-                                    :input-style="{
-                                      whiteSpace: 'pre-wrap',
-                                      overflowY: 'auto',
-                                      minHeight: '40px',
-                                    }"
-                                    style="min-width: 100px; max-width: 600px"
-                                  />
-                                </div>
-                              </div>
-                            </q-card-section>
-                          </q-card>
-                        </q-expansion-item>
-                      </q-list>
-                    </template>
-                    <div v-else class="text-grey-8">暂无操作记录</div>
-                  </template>
-                </q-card-section>
-              </q-card>
-            </div>
-          </q-tab-panel>
-        </q-tab-panels>
-      </q-card>
-    </q-dialog>
     <div id="printBarcode" class="print-area">
       <div class="q-pa-md text-center" style="flex: none">
         <svg ref="barcodeElement" style="width: 100%; height: auto"></svg>
       </div>
     </div>
+    <containercard
+      v-if="showInventoryDetails"
+      ref="containercard"
+      :container-number="select_container_number"
+      :container-code="select_container_code"
+      :key="select_container_number"
+
+    />
+  </div>
   </div>
 </template>
 
 <script>
-class ListNode {
-  constructor (value) {
-    this.value = value
-    this.next = null
-  }
-}
-
-class LinkedList {
-  constructor () {
-    this.head = null
-    this.size = 0
-  }
-
-  append (value) {
-    const newNode = new ListNode(value)
-    if (!this.head) {
-      this.head = newNode
-    } else {
-      let current = this.head
-      while (current.next) {
-        current = current.next
-      }
-      current.next = newNode
-    }
-    this.size++
-  }
-
-  delete (value) {
-    if (!this.head) return
-
-    if (this.head.value === value) {
-      this.head = this.head.next
-      this.size--
-      return
-    }
-
-    let current = this.head
-    while (current.next) {
-      if (current.next.value === value) {
-        current.next = current.next.next
-        this.size--
-        return
-      }
-      current = current.next
-    }
-  }
-
-  toArray () {
-    const result = []
-    let current = this.head
-    while (current) {
-      result.push({ value: current.value })
-      current = current.next
-    }
-    return result
-  }
-
-  clear () {
-    this.head = null
-    this.size = 0
-  }
-}
-
 import { getauth, postauth } from 'boot/axios_request'
+import containercard from 'components/containercard.vue'
 import JsBarcode from 'jsbarcode'
 import { LocalStorage } from 'quasar'
 
 export default {
   name: 'PageContainerlist',
+  components: {
+    containercard
+  },
   data () {
     return {
       goods_code: '',
@@ -615,7 +294,7 @@ export default {
         }
       ],
       operate_detail: [],
-      linkedList: new LinkedList(),
+
       newValue: '',
 
       error1: this.$t('goods.view_goodslist.error1'),
@@ -624,7 +303,10 @@ export default {
       total: 0,
       paginationIpt: 1,
       onlyread: true,
-      currentBarcode: ''
+      currentBarcode: '',
+      select_container_number: 0,
+      select_container_code: 0,
+      showInventoryDetails: false
     }
   },
 
@@ -778,7 +460,6 @@ export default {
     },
     detailData (e) {
       var _this = this
-      _this.detailForm = true
       _this.detailid = e.id
       console.log('detail查询的id是:', _this.detailid)
       getauth(
@@ -803,12 +484,15 @@ export default {
             ]
             _this.$q.notify({
               message: '该托盘暂无物料信息',
-              icon: 'close',
-              color: 'negative'
+              icon: 'info',
+              color: 'positive'
             })
             return
           }
-          _this.table_detail = res.results
+          _this.showInventoryDetails = true
+          _this.select_container_number = e.id
+          _this.select_container_code = e.container_code
+          _this.$refs.containercard.handleclick()
         })
         .catch((err) => {
           _this.$q.notify({
@@ -817,66 +501,6 @@ export default {
             color: 'negative'
           })
         })
-      _this.getOperationRecord(e)
-    },
-    getOperationRecord (row) {
-      var _this = this
-      _this.operate_detail = []
-      var operate_detail_container = []
-      _this.linkedList.clear()
-      getauth('container/operate/?status=1&container=' + row.id)
-        .then((res) => {
-          _this.operate_detail = res.results
-          if (_this.operate_detail.length === 0) return
-
-          // 初始化第一个元素
-          operate_detail_container.push(_this.operate_detail[0])
-
-          for (let i = 0; i < _this.operate_detail.length - 1; i++) {
-            const current = _this.operate_detail[i]
-            const next = _this.operate_detail[i + 1]
-            if (current.operation_type === next.operation_type) {
-              operate_detail_container.push(next)
-            } else {
-              _this.linkedList.append([...operate_detail_container])
-              operate_detail_container = [next]
-            }
-          }
-
-          // 添加最后一个分组
-          if (operate_detail_container.length > 0) {
-            _this.linkedList.append([...operate_detail_container])
-          }
-        })
-        .catch((err) => {
-          _this.$q.notify({
-            message: err.detail,
-            icon: 'close',
-            color: 'negative'
-          })
-        })
-    },
-    formatType (type) {
-      switch (type) {
-        case 'container':
-          return '组盘'
-        case 'outbound':
-          return '出库'
-        case '3':
-          return '盘点'
-        case '4':
-          return '移库'
-        case '5':
-          return '调拨'
-        case '6':
-          return '其他'
-        default:
-          return '未知'
-      }
-    },
-    sortoperatedetail () {
-      var _this = this
-      console.log('近一个月操作记录', _this.nodeList)
     }
   },
   created () {
@@ -909,16 +533,7 @@ export default {
     }
   },
   updated () {},
-  destroyed () {},
-  computed: {
-    nodeList () {
-      return this.linkedList.toArray()
-    },
-
-    listSize () {
-      return this.linkedList.size
-    }
-  }
+  destroyed () {}
 }
 </script>
 <style scoped>

+ 1 - 1
templates/src/pages/inbound/asn.vue

@@ -1671,7 +1671,7 @@ export default {
     batch_number_batch: function (val) {
       console.log(val)
       this.newBatchFormData.bound_batch_order =
-        this.batch_number_year * 10000 + this.batch_number_month * 100 + val
+        this.batch_number_year * 100000 + this.batch_number_month * 1000 + Number(val)
     },
     createDate1 (val) {
       if (val) {