doum
3 天以前 66b84de58e3efae14c1e258ee716e02ad9557497
最新版本541200007
已添加6个文件
已删除1个文件
已修改30个文件
2032 ■■■■ 文件已修改
admin/package-lock.json 376 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
admin/package.json 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
admin/public/template/jkCustomerTemplate.xlsx 补丁 | 查看 | 原始文档 | blame | 历史
admin/public/template/jkCustomerTmeplate.xlsx 补丁 | 查看 | 原始文档 | blame | 历史
admin/public/template/jkLineTemplate.xlsx 补丁 | 查看 | 原始文档 | blame | 历史
admin/src/api/business/jkCustomer.js 4 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
admin/src/api/business/jkLine.js 8 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
admin/src/components/business/OperaCarsWindow.vue 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
admin/src/components/business/OperaJkCustomerImportWindow.vue 81 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
admin/src/components/business/OperaJkCustomerWindow.vue 88 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
admin/src/components/business/OperaJkLineImportWindow.vue 81 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
admin/src/components/business/OperaJkLineWindow.vue 105 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
admin/src/main.js 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
admin/src/views/business/jkCustomer.vue 140 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
admin/src/views/business/jkLine.vue 102 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
admin/src/views/vehicle/cars.vue 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
admin/src/views/vehicle/components/OperaCategoryWindow.vue 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
server/system_service/src/main/java/com/doumee/core/utils/Constants.java 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
server/system_timer/src/main/java/com/doumee/jobs/fegin/VisitServiceFegin.java 3 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
server/visits/admin_timer/src/main/java/com/doumee/api/JkCustomerTimerController.java 47 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
server/visits/admin_timer/src/main/resources/bootstrap-dev.yml 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
server/visits/admin_timer/src/main/resources/bootstrap.yml 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
server/visits/dmvisit_admin/src/main/java/com/doumee/cloud/admin/JkCustomerCloudController.java 36 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
server/visits/dmvisit_admin/src/main/java/com/doumee/cloud/admin/JkLineCloudController.java 43 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
server/visits/dmvisit_service/src/main/java/com/doumee/dao/admin/request/JkCustomerImport.java 32 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
server/visits/dmvisit_service/src/main/java/com/doumee/dao/admin/request/JkLineImport.java 34 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
server/visits/dmvisit_service/src/main/java/com/doumee/dao/business/JkCustomerMapper.java 3 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
server/visits/dmvisit_service/src/main/java/com/doumee/dao/business/JkLineMapper.java 3 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
server/visits/dmvisit_service/src/main/java/com/doumee/dao/business/model/JkCabinet.java 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
server/visits/dmvisit_service/src/main/java/com/doumee/dao/business/model/JkCustomer.java 67 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
server/visits/dmvisit_service/src/main/java/com/doumee/dao/business/model/JkLine.java 53 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
server/visits/dmvisit_service/src/main/java/com/doumee/service/business/JkCustomerService.java 11 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
server/visits/dmvisit_service/src/main/java/com/doumee/service/business/JkLineService.java 10 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
server/visits/dmvisit_service/src/main/java/com/doumee/service/business/impl/CarsServiceImpl.java 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
server/visits/dmvisit_service/src/main/java/com/doumee/service/business/impl/JkCabinetServiceImpl.java 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
server/visits/dmvisit_service/src/main/java/com/doumee/service/business/impl/JkCustomerServiceImpl.java 368 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
server/visits/dmvisit_service/src/main/java/com/doumee/service/business/impl/JkLineServiceImpl.java 314 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
admin/package-lock.json
@@ -262,6 +262,11 @@
        "@babel/types": "^7.12.13"
      }
    },
    "@babel/helper-string-parser": {
      "version": "7.27.1",
      "resolved": "https://registry.npmmirror.com/@babel/helper-string-parser/-/helper-string-parser-7.27.1.tgz",
      "integrity": "sha512-qMlSxKbpRlAridDExk92nSobyDdpPijUq2DW6oDnUqd0iOGxmQjyqhMIihI9+zv4LPyZdRje2cavWPbCbWm3eA=="
    },
    "@babel/helper-validator-identifier": {
      "version": "7.14.0",
      "resolved": "https://registry.nlark.com/@babel/helper-validator-identifier/download/@babel/helper-validator-identifier-7.14.0.tgz?cache=0&sync_timestamp=1619727556616&other_urls=https%3A%2F%2Fregistry.nlark.com%2F%40babel%2Fhelper-validator-identifier%2Fdownload%2F%40babel%2Fhelper-validator-identifier-7.14.0.tgz",
@@ -1152,6 +1157,11 @@
        "postcss": "^7.0.0"
      }
    },
    "@jridgewell/sourcemap-codec": {
      "version": "1.5.5",
      "resolved": "https://registry.npmmirror.com/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.5.tgz",
      "integrity": "sha512-cYQ9310grqxueWbl+WuIUIaiUaDcj7WOq5fVhEljNVgRfOUhY9fy2zTvfoqWsnebh8Sl70VScFbICvJnLKB0Og=="
    },
    "@juggle/resize-observer": {
      "version": "3.4.0",
      "resolved": "https://registry.npmjs.org/@juggle/resize-observer/-/resize-observer-3.4.0.tgz",
@@ -1876,6 +1886,63 @@
          "integrity": "sha1-/q7SVZc9LndVW4PbwIhRpsY1IPo=",
          "dev": true
        },
        "ansi-styles": {
          "version": "4.3.0",
          "resolved": "https://registry.npmmirror.com/ansi-styles/-/ansi-styles-4.3.0.tgz",
          "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==",
          "dev": true,
          "optional": true,
          "requires": {
            "color-convert": "^2.0.1"
          }
        },
        "chalk": {
          "version": "4.1.2",
          "resolved": "https://registry.npmmirror.com/chalk/-/chalk-4.1.2.tgz",
          "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==",
          "dev": true,
          "optional": true,
          "requires": {
            "ansi-styles": "^4.1.0",
            "supports-color": "^7.1.0"
          }
        },
        "color-convert": {
          "version": "2.0.1",
          "resolved": "https://registry.npmmirror.com/color-convert/-/color-convert-2.0.1.tgz",
          "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==",
          "dev": true,
          "optional": true,
          "requires": {
            "color-name": "~1.1.4"
          }
        },
        "color-name": {
          "version": "1.1.4",
          "resolved": "https://registry.npmmirror.com/color-name/-/color-name-1.1.4.tgz",
          "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==",
          "dev": true,
          "optional": true
        },
        "has-flag": {
          "version": "4.0.0",
          "resolved": "https://registry.npmmirror.com/has-flag/-/has-flag-4.0.0.tgz",
          "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==",
          "dev": true,
          "optional": true
        },
        "loader-utils": {
          "version": "2.0.4",
          "resolved": "https://registry.npmmirror.com/loader-utils/-/loader-utils-2.0.4.tgz",
          "integrity": "sha512-xXqpXoINfFhgua9xiqD8fPFHgkoq1mmmpE92WlDbm9rNRd/EbRb+Gqf908T2DMfuHjjJlksiK2RbHVOdD/MqSw==",
          "dev": true,
          "optional": true,
          "requires": {
            "big.js": "^5.2.2",
            "emojis-list": "^3.0.0",
            "json5": "^2.1.2"
          }
        },
        "ssri": {
          "version": "8.0.1",
          "resolved": "https://registry.npm.taobao.org/ssri/download/ssri-8.0.1.tgz?cache=0&sync_timestamp=1617826515595&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fssri%2Fdownload%2Fssri-8.0.1.tgz",
@@ -1883,6 +1950,28 @@
          "dev": true,
          "requires": {
            "minipass": "^3.1.1"
          }
        },
        "supports-color": {
          "version": "7.2.0",
          "resolved": "https://registry.npmmirror.com/supports-color/-/supports-color-7.2.0.tgz",
          "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==",
          "dev": true,
          "optional": true,
          "requires": {
            "has-flag": "^4.0.0"
          }
        },
        "vue-loader-v16": {
          "version": "npm:vue-loader@16.8.3",
          "resolved": "https://registry.npmmirror.com/vue-loader/-/vue-loader-16.8.3.tgz",
          "integrity": "sha512-7vKN45IxsKxe5GcVCbc2qFU5aWzyiLrYJyUuMz4BQLKctCj/fmCa0w6fGiiQ2cLFetNcek1ppGJQDCup0c1hpA==",
          "dev": true,
          "optional": true,
          "requires": {
            "chalk": "^4.1.0",
            "hash-sum": "^2.0.0",
            "loader-utils": "^2.0.0"
          }
        }
      }
@@ -1905,6 +1994,120 @@
        "request": "^2.88.2",
        "semver": "^6.1.0",
        "strip-ansi": "^6.0.0"
      }
    },
    "@vue/compiler-core": {
      "version": "3.5.22",
      "resolved": "https://registry.npmmirror.com/@vue/compiler-core/-/compiler-core-3.5.22.tgz",
      "integrity": "sha512-jQ0pFPmZwTEiRNSb+i9Ow/I/cHv2tXYqsnHKKyCQ08irI2kdF5qmYedmF8si8mA7zepUFmJ2hqzS8CQmNOWOkQ==",
      "requires": {
        "@babel/parser": "^7.28.4",
        "@vue/shared": "3.5.22",
        "entities": "^4.5.0",
        "estree-walker": "^2.0.2",
        "source-map-js": "^1.2.1"
      },
      "dependencies": {
        "@babel/helper-validator-identifier": {
          "version": "7.27.1",
          "resolved": "https://registry.npmmirror.com/@babel/helper-validator-identifier/-/helper-validator-identifier-7.27.1.tgz",
          "integrity": "sha512-D2hP9eA+Sqx1kBZgzxZh0y1trbuU+JoDkiEwqhQ36nodYqJwyEIhPSdMNd7lOm/4io72luTPWH20Yda0xOuUow=="
        },
        "@babel/parser": {
          "version": "7.28.4",
          "resolved": "https://registry.npmmirror.com/@babel/parser/-/parser-7.28.4.tgz",
          "integrity": "sha512-yZbBqeM6TkpP9du/I2pUZnJsRMGGvOuIrhjzC1AwHwW+6he4mni6Bp/m8ijn0iOuZuPI2BfkCoSRunpyjnrQKg==",
          "requires": {
            "@babel/types": "^7.28.4"
          }
        },
        "@babel/types": {
          "version": "7.28.4",
          "resolved": "https://registry.npmmirror.com/@babel/types/-/types-7.28.4.tgz",
          "integrity": "sha512-bkFqkLhh3pMBUQQkpVgWDWq/lqzc2678eUyDlTBhRqhCHFguYYGM0Efga7tYk4TogG/3x0EEl66/OQ+WGbWB/Q==",
          "requires": {
            "@babel/helper-string-parser": "^7.27.1",
            "@babel/helper-validator-identifier": "^7.27.1"
          }
        },
        "entities": {
          "version": "4.5.0",
          "resolved": "https://registry.npmmirror.com/entities/-/entities-4.5.0.tgz",
          "integrity": "sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw=="
        }
      }
    },
    "@vue/compiler-dom": {
      "version": "3.5.22",
      "resolved": "https://registry.npmmirror.com/@vue/compiler-dom/-/compiler-dom-3.5.22.tgz",
      "integrity": "sha512-W8RknzUM1BLkypvdz10OVsGxnMAuSIZs9Wdx1vzA3mL5fNMN15rhrSCLiTm6blWeACwUwizzPVqGJgOGBEN/hA==",
      "requires": {
        "@vue/compiler-core": "3.5.22",
        "@vue/shared": "3.5.22"
      }
    },
    "@vue/compiler-sfc": {
      "version": "3.5.22",
      "resolved": "https://registry.npmmirror.com/@vue/compiler-sfc/-/compiler-sfc-3.5.22.tgz",
      "integrity": "sha512-tbTR1zKGce4Lj+JLzFXDq36K4vcSZbJ1RBu8FxcDv1IGRz//Dh2EBqksyGVypz3kXpshIfWKGOCcqpSbyGWRJQ==",
      "requires": {
        "@babel/parser": "^7.28.4",
        "@vue/compiler-core": "3.5.22",
        "@vue/compiler-dom": "3.5.22",
        "@vue/compiler-ssr": "3.5.22",
        "@vue/shared": "3.5.22",
        "estree-walker": "^2.0.2",
        "magic-string": "^0.30.19",
        "postcss": "^8.5.6",
        "source-map-js": "^1.2.1"
      },
      "dependencies": {
        "@babel/helper-validator-identifier": {
          "version": "7.27.1",
          "resolved": "https://registry.npmmirror.com/@babel/helper-validator-identifier/-/helper-validator-identifier-7.27.1.tgz",
          "integrity": "sha512-D2hP9eA+Sqx1kBZgzxZh0y1trbuU+JoDkiEwqhQ36nodYqJwyEIhPSdMNd7lOm/4io72luTPWH20Yda0xOuUow=="
        },
        "@babel/parser": {
          "version": "7.28.4",
          "resolved": "https://registry.npmmirror.com/@babel/parser/-/parser-7.28.4.tgz",
          "integrity": "sha512-yZbBqeM6TkpP9du/I2pUZnJsRMGGvOuIrhjzC1AwHwW+6he4mni6Bp/m8ijn0iOuZuPI2BfkCoSRunpyjnrQKg==",
          "requires": {
            "@babel/types": "^7.28.4"
          }
        },
        "@babel/types": {
          "version": "7.28.4",
          "resolved": "https://registry.npmmirror.com/@babel/types/-/types-7.28.4.tgz",
          "integrity": "sha512-bkFqkLhh3pMBUQQkpVgWDWq/lqzc2678eUyDlTBhRqhCHFguYYGM0Efga7tYk4TogG/3x0EEl66/OQ+WGbWB/Q==",
          "requires": {
            "@babel/helper-string-parser": "^7.27.1",
            "@babel/helper-validator-identifier": "^7.27.1"
          }
        },
        "nanoid": {
          "version": "3.3.11",
          "resolved": "https://registry.npmmirror.com/nanoid/-/nanoid-3.3.11.tgz",
          "integrity": "sha512-N8SpfPUnUp1bK+PMYW8qSWdl9U+wwNWI4QKxOYDy9JAro3WMX7p2OeVRF9v+347pnakNevPmiHhNmZ2HbFA76w=="
        },
        "postcss": {
          "version": "8.5.6",
          "resolved": "https://registry.npmmirror.com/postcss/-/postcss-8.5.6.tgz",
          "integrity": "sha512-3Ybi1tAuwAP9s0r1UQ2J4n5Y0G05bJkpUIO0/bI9MhwmD70S5aTWbXGBwxHrelT+XM1k6dM0pk+SwNkpTRN7Pg==",
          "requires": {
            "nanoid": "^3.3.11",
            "picocolors": "^1.1.1",
            "source-map-js": "^1.2.1"
          }
        }
      }
    },
    "@vue/compiler-ssr": {
      "version": "3.5.22",
      "resolved": "https://registry.npmmirror.com/@vue/compiler-ssr/-/compiler-ssr-3.5.22.tgz",
      "integrity": "sha512-GdgyLvg4R+7T8Nk2Mlighx7XGxq/fJf9jaVofc3IL0EPesTE86cP/8DD1lT3h1JeZr2ySBvyqKQJgbS54IX1Ww==",
      "requires": {
        "@vue/compiler-dom": "3.5.22",
        "@vue/shared": "3.5.22"
      }
    },
    "@vue/component-compiler-utils": {
@@ -1970,6 +2173,48 @@
      "resolved": "https://registry.npm.taobao.org/@vue/preload-webpack-plugin/download/@vue/preload-webpack-plugin-1.1.2.tgz?cache=0&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2F%40vue%2Fpreload-webpack-plugin%2Fdownload%2F%40vue%2Fpreload-webpack-plugin-1.1.2.tgz",
      "integrity": "sha1-zrkktOyzucQ4ccekKaAvhCPmIas=",
      "dev": true
    },
    "@vue/reactivity": {
      "version": "3.5.22",
      "resolved": "https://registry.npmmirror.com/@vue/reactivity/-/reactivity-3.5.22.tgz",
      "integrity": "sha512-f2Wux4v/Z2pqc9+4SmgZC1p73Z53fyD90NFWXiX9AKVnVBEvLFOWCEgJD3GdGnlxPZt01PSlfmLqbLYzY/Fw4A==",
      "requires": {
        "@vue/shared": "3.5.22"
      }
    },
    "@vue/runtime-core": {
      "version": "3.5.22",
      "resolved": "https://registry.npmmirror.com/@vue/runtime-core/-/runtime-core-3.5.22.tgz",
      "integrity": "sha512-EHo4W/eiYeAzRTN5PCextDUZ0dMs9I8mQ2Fy+OkzvRPUYQEyK9yAjbasrMCXbLNhF7P0OUyivLjIy0yc6VrLJQ==",
      "requires": {
        "@vue/reactivity": "3.5.22",
        "@vue/shared": "3.5.22"
      }
    },
    "@vue/runtime-dom": {
      "version": "3.5.22",
      "resolved": "https://registry.npmmirror.com/@vue/runtime-dom/-/runtime-dom-3.5.22.tgz",
      "integrity": "sha512-Av60jsryAkI023PlN7LsqrfPvwfxOd2yAwtReCjeuugTJTkgrksYJJstg1e12qle0NarkfhfFu1ox2D+cQotww==",
      "requires": {
        "@vue/reactivity": "3.5.22",
        "@vue/runtime-core": "3.5.22",
        "@vue/shared": "3.5.22",
        "csstype": "^3.1.3"
      }
    },
    "@vue/server-renderer": {
      "version": "3.5.22",
      "resolved": "https://registry.npmmirror.com/@vue/server-renderer/-/server-renderer-3.5.22.tgz",
      "integrity": "sha512-gXjo+ao0oHYTSswF+a3KRHZ1WszxIqO7u6XwNHqcqb9JfyIL/pbWrrh/xLv7jeDqla9u+LK7yfZKHih1e1RKAQ==",
      "requires": {
        "@vue/compiler-ssr": "3.5.22",
        "@vue/shared": "3.5.22"
      }
    },
    "@vue/shared": {
      "version": "3.5.22",
      "resolved": "https://registry.npmmirror.com/@vue/shared/-/shared-3.5.22.tgz",
      "integrity": "sha512-F4yc6palwq3TT0u+FYf0Ns4Tfl9GRFURDN2gWG7L1ecIaS/4fCIuFOjMTnCyjsu/OK6vaDKLCrGAa+KvvH+h4w=="
    },
    "@vue/web-component-wrapper": {
      "version": "1.3.0",
@@ -4487,6 +4732,11 @@
        }
      }
    },
    "csstype": {
      "version": "3.1.3",
      "resolved": "https://registry.npmmirror.com/csstype/-/csstype-3.1.3.tgz",
      "integrity": "sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw=="
    },
    "currently-unhandled": {
      "version": "0.4.1",
      "resolved": "https://registry.npm.taobao.org/currently-unhandled/download/currently-unhandled-0.4.1.tgz",
@@ -5880,6 +6130,11 @@
      "resolved": "https://registry.npm.taobao.org/estraverse/download/estraverse-4.3.0.tgz?cache=0&sync_timestamp=1596642998635&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Festraverse%2Fdownload%2Festraverse-4.3.0.tgz",
      "integrity": "sha1-OYrT88WiSUi+dyXoPRGn3ijNvR0=",
      "dev": true
    },
    "estree-walker": {
      "version": "2.0.2",
      "resolved": "https://registry.npmmirror.com/estree-walker/-/estree-walker-2.0.2.tgz",
      "integrity": "sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w=="
    },
    "esutils": {
      "version": "2.0.3",
@@ -8861,6 +9116,14 @@
        "yallist": "^3.0.2"
      }
    },
    "magic-string": {
      "version": "0.30.19",
      "resolved": "https://registry.npmmirror.com/magic-string/-/magic-string-0.30.19.tgz",
      "integrity": "sha512-2N21sPY9Ws53PZvsEpVtNuSW+ScYbQdp4b9qUaL+9QkHUrGFKo56Lg9Emg5s9V/qrtNBmiR01sYhUOwu3H+VOw==",
      "requires": {
        "@jridgewell/sourcemap-codec": "^1.5.5"
      }
    },
    "make-dir": {
      "version": "3.1.0",
      "resolved": "https://registry.npm.taobao.org/make-dir/download/make-dir-3.1.0.tgz?cache=0&sync_timestamp=1587567572251&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fmake-dir%2Fdownload%2Fmake-dir-3.1.0.tgz",
@@ -10227,6 +10490,11 @@
      "resolved": "https://registry.npm.taobao.org/performance-now/download/performance-now-2.1.0.tgz",
      "integrity": "sha1-Ywn04OX6kT7BxpMHrjZLSzd8nns=",
      "dev": true
    },
    "picocolors": {
      "version": "1.1.1",
      "resolved": "https://registry.npmmirror.com/picocolors/-/picocolors-1.1.1.tgz",
      "integrity": "sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA=="
    },
    "picomatch": {
      "version": "2.2.3",
@@ -12525,6 +12793,11 @@
      "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=",
      "dev": true
    },
    "source-map-js": {
      "version": "1.2.1",
      "resolved": "https://registry.npmmirror.com/source-map-js/-/source-map-js-1.2.1.tgz",
      "integrity": "sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA=="
    },
    "source-map-resolve": {
      "version": "0.5.3",
      "resolved": "https://registry.npm.taobao.org/source-map-resolve/download/source-map-resolve-0.5.3.tgz?cache=0&sync_timestamp=1584829515586&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fsource-map-resolve%2Fdownload%2Fsource-map-resolve-0.5.3.tgz",
@@ -13772,6 +14045,28 @@
      "integrity": "sha1-sj5DWK+oogL+ehAK8fX4g/AgB+4=",
      "dev": true
    },
    "v-clipboard": {
      "version": "3.0.0-next.1",
      "resolved": "https://registry.npmmirror.com/v-clipboard/-/v-clipboard-3.0.0-next.1.tgz",
      "integrity": "sha512-UvCnzetQMlVfk9yoiyew8ldGiCzeER5aYdmXXtZp8LC6rt2QXQS0AayEDn1K7rlXpd3M8d+JeYNUV+ZNgtaS4A==",
      "requires": {
        "vue": "^3.2.45"
      },
      "dependencies": {
        "vue": {
          "version": "3.5.22",
          "resolved": "https://registry.npmmirror.com/vue/-/vue-3.5.22.tgz",
          "integrity": "sha512-toaZjQ3a/G/mYaLSbV+QsQhIdMo9x5rrqIpYRObsJ6T/J+RyCSFwN2LHNVH9v8uIcljDNa3QzPVdv3Y6b9hAJQ==",
          "requires": {
            "@vue/compiler-dom": "3.5.22",
            "@vue/compiler-sfc": "3.5.22",
            "@vue/runtime-dom": "3.5.22",
            "@vue/server-renderer": "3.5.22",
            "@vue/shared": "3.5.22"
          }
        }
      }
    },
    "v8-compile-cache": {
      "version": "2.3.0",
      "resolved": "https://registry.npm.taobao.org/v8-compile-cache/download/v8-compile-cache-2.3.0.tgz?cache=0&sync_timestamp=1614993639567&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fv8-compile-cache%2Fdownload%2Fv8-compile-cache-2.3.0.tgz",
@@ -13909,87 +14204,6 @@
          "resolved": "https://registry.npm.taobao.org/hash-sum/download/hash-sum-1.0.2.tgz",
          "integrity": "sha1-M7QHd3VMZDJXPBIMw4CLvRDUfwQ=",
          "dev": true
        }
      }
    },
    "vue-loader-v16": {
      "version": "npm:vue-loader@16.8.3",
      "resolved": "https://registry.npmmirror.com/vue-loader/-/vue-loader-16.8.3.tgz",
      "integrity": "sha512-7vKN45IxsKxe5GcVCbc2qFU5aWzyiLrYJyUuMz4BQLKctCj/fmCa0w6fGiiQ2cLFetNcek1ppGJQDCup0c1hpA==",
      "dev": true,
      "optional": true,
      "requires": {
        "chalk": "^4.1.0",
        "hash-sum": "^2.0.0",
        "loader-utils": "^2.0.0"
      },
      "dependencies": {
        "ansi-styles": {
          "version": "4.3.0",
          "resolved": "https://registry.npmmirror.com/ansi-styles/-/ansi-styles-4.3.0.tgz",
          "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==",
          "dev": true,
          "optional": true,
          "requires": {
            "color-convert": "^2.0.1"
          }
        },
        "chalk": {
          "version": "4.1.2",
          "resolved": "https://registry.npmmirror.com/chalk/-/chalk-4.1.2.tgz",
          "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==",
          "dev": true,
          "optional": true,
          "requires": {
            "ansi-styles": "^4.1.0",
            "supports-color": "^7.1.0"
          }
        },
        "color-convert": {
          "version": "2.0.1",
          "resolved": "https://registry.npmmirror.com/color-convert/-/color-convert-2.0.1.tgz",
          "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==",
          "dev": true,
          "optional": true,
          "requires": {
            "color-name": "~1.1.4"
          }
        },
        "color-name": {
          "version": "1.1.4",
          "resolved": "https://registry.npmmirror.com/color-name/-/color-name-1.1.4.tgz",
          "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==",
          "dev": true,
          "optional": true
        },
        "has-flag": {
          "version": "4.0.0",
          "resolved": "https://registry.npmmirror.com/has-flag/-/has-flag-4.0.0.tgz",
          "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==",
          "dev": true,
          "optional": true
        },
        "loader-utils": {
          "version": "2.0.4",
          "resolved": "https://registry.npmmirror.com/loader-utils/-/loader-utils-2.0.4.tgz",
          "integrity": "sha512-xXqpXoINfFhgua9xiqD8fPFHgkoq1mmmpE92WlDbm9rNRd/EbRb+Gqf908T2DMfuHjjJlksiK2RbHVOdD/MqSw==",
          "dev": true,
          "optional": true,
          "requires": {
            "big.js": "^5.2.2",
            "emojis-list": "^3.0.0",
            "json5": "^2.1.2"
          }
        },
        "supports-color": {
          "version": "7.2.0",
          "resolved": "https://registry.npmmirror.com/supports-color/-/supports-color-7.2.0.tgz",
          "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==",
          "dev": true,
          "optional": true,
          "requires": {
            "has-flag": "^4.0.0"
          }
        }
      }
    },
admin/package.json
@@ -28,6 +28,7 @@
    "js-file-download": "^0.4.12",
    "path": "^0.12.7",
    "qrcodejs2": "0.0.2",
    "v-clipboard": "^3.0.0-next.1",
    "vue": "^2.6.11",
    "vue-clipboard2": "^0.3.1",
    "vue-cropper": "^0.6.5",
admin/public/template/jkCustomerTemplate.xlsx
Binary files differ
admin/public/template/jkCustomerTmeplate.xlsx
Binary files differ
admin/public/template/jkLineTemplate.xlsx
Binary files differ
admin/src/api/business/jkCustomer.js
@@ -19,7 +19,9 @@
export function create (data) {
  return request.post('/visitsAdmin/cloudService/business/jkCustomer/create', data)
}
export function importExcel (data) {
  return request.post('/visitsAdmin/cloudService/business/jkCustomer/importExcel', data)
}
// ä¿®æ”¹
export function updateById (data) {
  return request.post('/visitsAdmin/cloudService/business/jkCustomer/updateById', data)
admin/src/api/business/jkLine.js
@@ -6,6 +6,11 @@
    trim: true
  })
}
export function allList (data) {
  return request.post('/visitsAdmin/cloudService/business/jkLine/list', data, {
    trim: true
  })
}
// å¯¼å‡ºExcel
export function exportExcel (data) {
@@ -20,6 +25,9 @@
  return request.post('/visitsAdmin/cloudService/business/jkLine/create', data)
}
export function importExcel (data) {
  return request.post('/visitsAdmin/cloudService/business/jkLine/importExcel', data)
}
// ä¿®æ”¹
export function updateById (data) {
  return request.post('/visitsAdmin/cloudService/business/jkLine/updateById', data)
admin/src/components/business/OperaCarsWindow.vue
@@ -187,7 +187,7 @@
    },
    getCate () {
      fetchList({
        model: {},
        model: {type:1},
        capacity: 1000,
        page: 1
      }).then(res => {
admin/src/components/business/OperaJkCustomerImportWindow.vue
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,81 @@
<template>
  <el-dialog
      class="center-title"
      :title="title"
      width="500px"
      top="30vh"
      :visible.sync="visible"
      :confirm-working="isWorking"
      @confirm="confirm"
  >
    <p class="tip-warn"><i class="el-icon-warning"></i>导入说明:<br>
      1.请先下载文件模板,并按照模板要去填写表格内容;<br>
    </p>
    <el-form class="demo-form-inline" >
      <el-form-item label="客户信息" required>
        <div style="width: 100%;display: flex;align-items: center;">
          <el-button type="primary"   @click="clickRef">点击上传</el-button>
          <el-button type="text" @click="exportTemplate">点击下载模版.EXCEL</el-button>
        </div>
        <div style="font-size: 14px; color: black;" v-if="fileName">{{fileName}}</div>
      </el-form-item>
    </el-form>
    <input type="file" style="position: fixed; left: 0; top: -50px;" accept=".xlsx" ref="fileExcel" @change="result" />
    <template   v-slot:footer>
      <el-button @click="visible=false">返回</el-button>
    </template>
  </el-dialog>
</template>
<script>
import BaseOpera from '@/components/base/BaseOpera'
import GlobalWindow from '@/components/common/GlobalWindow'
import { importExcel } from '@/api/business/jkCustomer'
export default {
  extends: BaseOpera,
  // eslint-disable-next-line vue/no-unused-components
  components: { GlobalWindow },
  data () {
    return {
      importing:false,
      fileName: ''
    }
  },
  methods: {
    open (title) {
      this.title = title
      this.fileName = ''
      this.visible = true
    },
    // å¯¼å‡ºæ¨¡æ¿
    exportTemplate () {
      // æŠ•保申请
      window.open('/template/jkCustomerTemplate.xlsx')
    },
    clickRef () {
      this.$refs.fileExcel.click()
    },
    result (e) {
      const data = new FormData()
      data.append('file', e.target.files[0])
      importExcel(data)
        .then(res => {
          this.$message.success('导入成功')
          this.$emit('success')
          this.visible = false
        })
        .catch(err => {
          // this.$message.error(err)
          this.fileName = ''
        })
        .finally(() => {
          this.$refs.fileExcel.value = null
        })
    }
  }
}
</script>
<style lang="scss" scoped>
</style>
admin/src/components/business/OperaJkCustomerWindow.vue
@@ -3,55 +3,35 @@
    :title="title"
    :visible.sync="visible"
    :confirm-working="isWorking"
    width="50%"
    @confirm="confirm"
  >
    <el-form :model="form" ref="form" :rules="rules">
      <el-form-item label="创建人编码" prop="creator">
        <el-input v-model="form.creator" placeholder="请输入创建人编码" v-trim/>
      <el-form-item label="" prop="name">
        <span  style="width: 100px;text-align: right;margin-right: 30px;">客户简码:</span>
        <span>{{form.code}}</span>
      </el-form-item>
      <el-form-item label="创建时间" prop="createDate">
        <el-date-picker v-model="form.createDate" value-format="yyyy-MM-dd" placeholder="请输入创建时间"></el-date-picker>
      <el-form-item label="" prop="name">
        <span  style="width: 100px;text-align: right;margin-right: 30px;">客户名称:</span>
        <span>{{form.name}}</span>
      </el-form-item>
      <el-form-item label="更新人编码" prop="editor">
        <el-input v-model="form.editor" placeholder="请输入更新人编码" v-trim/>
      <el-form-item label="" prop="lineName">
        <span  style="width: 100px;text-align: right;margin-right: 30px;">送货线路:</span>
        <span>{{form.lineName}}</span>
      </el-form-item>
      <el-form-item label="更新时间" prop="editDate">
        <el-date-picker v-model="form.editDate" value-format="yyyy-MM-dd" placeholder="请输入更新时间"></el-date-picker>
      <el-form-item label="" prop="categoryName">
        <span  style="width: 100px;text-align: right;margin-right: 30px;">所属主线路</span>
        <span>{{form.categoryName}}</span>
      </el-form-item>
      <el-form-item label="是否删除0否 1是" prop="isdeleted">
        <el-input v-model="form.isdeleted" placeholder="请输入是否删除0否 1是" v-trim/>
      <el-form-item label="" prop="location">
        <span style="width: 100px;text-align: right;margin-right: 30px;">地址: </span>
        <span>{{form.location}}</span>
      </el-form-item>
      <el-form-item label="备注" prop="info">
        <el-input v-model="form.info" placeholder="请输入备注" v-trim/>
      <el-button style="color: blue;margin-bottom: 10px;" v-clipboard:copy="form.location" v-clipboard:success="onCopy" v-clipboard:error="onError">点击复制客户地址,前往经纬度在线提取器</el-button>
      <el-form-item label="经纬度:" prop="locationInfo">
        <el-input v-model="form.locationInfo" placeholder="请输入经纬度" v-trim/>
      </el-form-item>
      <el-form-item label="名称" prop="name">
        <el-input v-model="form.name" placeholder="请输入名称" v-trim/>
      </el-form-item>
      <el-form-item label="编码" prop="code">
        <el-input v-model="form.code" placeholder="请输入编码" v-trim/>
      </el-form-item>
      <el-form-item label="所在位置" prop="lacation">
        <el-input v-model="form.lacation" placeholder="请输入所在位置" v-trim/>
      </el-form-item>
      <el-form-item label="经度" prop="longitude">
        <el-input v-model="form.longitude" placeholder="请输入经度" v-trim/>
      </el-form-item>
      <el-form-item label="维度" prop="latitude">
        <el-input v-model="form.latitude" placeholder="请输入维度" v-trim/>
      </el-form-item>
      <el-form-item label="配送周期" prop="weeks">
        <el-input v-model="form.weeks" placeholder="请输入配送周期" v-trim/>
      </el-form-item>
      <el-form-item label="送货路线编码(关联jk_line)" prop="lineId">
        <el-input v-model="form.lineId" placeholder="请输入送货路线编码(关联jk_line)" v-trim/>
      </el-form-item>
      <el-form-item label="状态 0正常 ç¦ç”¨" prop="status">
        <el-input v-model="form.status" placeholder="请输入状态 0正常 ç¦ç”¨" v-trim/>
      </el-form-item>
      <el-form-item label="排序码" prop="sortnum">
        <el-input v-model="form.sortnum" placeholder="请输入排序码" v-trim/>
      </el-form-item>
    </el-form>
     </el-form>
  </GlobalWindow>
</template>
@@ -67,24 +47,16 @@
      // è¡¨å•数据
      form: {
        id: null,
        creator: '',
        createDate: '',
        editor: '',
        editDate: '',
        isdeleted: '',
        info: '',
        locationInfo: '',
        name: '',
        code: '',
        lacation: '',
        longitude: '',
        latitude: '',
        weeks: '',
        lineId: '',
        status: '',
        sortnum: ''
        location: '',
        lineName: '',
        categoryName: ''
      },
      // éªŒè¯è§„则
      rules: {
        locationInfo: [{ required: true, message: '请输入经纬度信息' }]
      }
    }
  },
@@ -93,6 +65,16 @@
      api: '/business/jkCustomer',
      'field.id': 'id'
    })
  },
  methods: {
    onCopy () {
      console.log('Text copied!');
      window.open('https://lbs.amap.com/tools/picker')
    },
    onError () {
      console.error('Failed to copy text');
      window.open('https://lbs.amap.com/tools/picker')
    }
  }
}
</script>
admin/src/components/business/OperaJkLineImportWindow.vue
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,81 @@
<template>
  <el-dialog
      class="center-title"
      :title="title"
      width="500px"
      top="30vh"
      :visible.sync="visible"
      :confirm-working="isWorking"
      @confirm="confirm"
  >
    <p class="tip-warn"><i class="el-icon-warning"></i>导入说明:<br>
      1.请先下载文件模板,并按照模板要去填写表格内容;<br>
    </p>
    <el-form class="demo-form-inline" >
      <el-form-item label="新路信息" required>
        <div style="width: 100%;display: flex;align-items: center;">
          <el-button type="primary"   @click="clickRef">点击上传</el-button>
          <el-button type="text" @click="exportTemplate">点击下载模版.EXCEL</el-button>
        </div>
        <div style="font-size: 14px; color: black;" v-if="fileName">{{fileName}}</div>
      </el-form-item>
    </el-form>
    <input type="file" style="position: fixed; left: 0; top: -50px;" accept=".xlsx" ref="fileExcel" @change="result" />
    <template   v-slot:footer>
      <el-button @click="visible=false">返回</el-button>
    </template>
  </el-dialog>
</template>
<script>
import BaseOpera from '@/components/base/BaseOpera'
import GlobalWindow from '@/components/common/GlobalWindow'
import { importExcel } from '@/api/business/jkLine'
export default {
  extends: BaseOpera,
  // eslint-disable-next-line vue/no-unused-components
  components: { GlobalWindow },
  data () {
    return {
      importing:false,
      fileName: ''
    }
  },
  methods: {
    open (title) {
      this.title = title
      this.fileName = ''
      this.visible = true
    },
    // å¯¼å‡ºæ¨¡æ¿
    exportTemplate () {
      // æŠ•保申请
      window.open('/template/jkLineTemplate.xlsx')
    },
    clickRef () {
      this.$refs.fileExcel.click()
    },
    result (e) {
      const data = new FormData()
      data.append('file', e.target.files[0])
      importExcel(data)
        .then(res => {
          this.$message.success('导入成功')
          this.$emit('success')
          this.visible = false
        })
        .catch(err => {
          // this.$message.error(err)
          this.fileName = ''
        })
        .finally(() => {
          this.$refs.fileExcel.value = null
        })
    }
  }
}
</script>
<style lang="scss" scoped>
</style>
admin/src/components/business/OperaJkLineWindow.vue
@@ -1,49 +1,41 @@
<template>
  <GlobalWindow
    :title="title"
    width="50%"
    :visible.sync="visible"
    :confirm-working="isWorking"
    @confirm="confirm"
  >
    <el-form :model="form" ref="form" :rules="rules">
      <el-form-item label="创建人编码" prop="creator">
        <el-input v-model="form.creator" placeholder="请输入创建人编码" v-trim/>
      <el-form-item label="所属主线路" prop="categoryId">
        <el-select v-model="form.categoryId"  filterable placeholder="请选择所属主线路" >
          <el-option v-for="item in categoryList" :key="item.id" :label="item.name" :value="item.id">
          </el-option>
        </el-select>
      </el-form-item>
      <el-form-item label="创建时间" prop="createDate">
        <el-date-picker v-model="form.createDate" value-format="yyyy-MM-dd" placeholder="请输入创建时间"></el-date-picker>
      </el-form-item>
      <el-form-item label="更新人编码" prop="editor">
        <el-input v-model="form.editor" placeholder="请输入更新人编码" v-trim/>
      </el-form-item>
      <el-form-item label="更新时间" prop="editDate">
        <el-date-picker v-model="form.editDate" value-format="yyyy-MM-dd" placeholder="请输入更新时间"></el-date-picker>
      </el-form-item>
      <el-form-item label="是否删除0否 1是" prop="isdeleted">
        <el-input v-model="form.isdeleted" placeholder="请输入是否删除0否 1是" v-trim/>
      </el-form-item>
      <el-form-item label="备注" prop="info">
        <el-input v-model="form.info" placeholder="请输入备注" v-trim/>
      </el-form-item>
      <el-form-item label="名称" prop="name">
      <el-form-item label="线路名称" prop="name">
        <el-input v-model="form.name" placeholder="请输入名称" v-trim/>
      </el-form-item>
      <el-form-item label="班组编码(关联category)" prop="categoryId">
        <el-input v-model="form.categoryId" placeholder="请输入班组编码(关联category)" v-trim/>
      <el-form-item label="送货车辆" prop="carId">
        <el-select v-model="form.carId"  filterable placeholder="请选择送货车辆" >
          <el-option v-for="item in carsList" :key="item.id" :label="item.code" :value="item.id">
          </el-option>
        </el-select>
      </el-form-item>
      <el-form-item label="所属车辆(关联cars)" prop="carId">
        <el-input v-model="form.carId" placeholder="请输入所属车辆(关联cars)" v-trim/>
      <el-form-item label="客户量" prop="maxCustomer">
        <el-input type="number" v-model="form.maxCustomer" placeholder="请输入最大客户量" v-trim/>
      </el-form-item>
      <el-form-item label="最大客户量" prop="maxCustomer">
        <el-input v-model="form.maxCustomer" placeholder="请输入最大客户量" v-trim/>
      <el-form-item label="订单量" prop="maxOrder">
        <el-input type="number" v-model="form.maxOrder" placeholder="请输入最大订单量" v-trim/>
      </el-form-item>
      <el-form-item label="最大订单量" prop="maxOrder">
        <el-input v-model="form.maxOrder" placeholder="请输入最大订单量" v-trim/>
      <el-form-item label="周期" prop="weeks">
        <el-select v-model="form.weeks"  filterable placeholder="请选择送货车辆" >
          <el-option v-for="item in weeksList" :key="item" :label="item" :value="item">
          </el-option>
        </el-select>
      </el-form-item>
      <el-form-item label="状态 0未绑定 1在位 2借出" prop="status">
        <el-input v-model="form.status" placeholder="请输入状态 0未绑定 1在位 2借出" v-trim/>
      </el-form-item>
      <el-form-item label="排序码" prop="sortnum">
        <el-input v-model="form.sortnum" placeholder="请输入排序码" v-trim/>
      <el-form-item label="序号" prop="code">
        <el-input v-model="form.code" placeholder="请输入序号" v-trim/>
      </el-form-item>
    </el-form>
  </GlobalWindow>
@@ -52,6 +44,8 @@
<script>
import BaseOpera from '@/components/base/BaseOpera'
import GlobalWindow from '@/components/common/GlobalWindow'
import { fetchCateList } from '@/api/business/category'
import { allList } from '@/api/business/cars'
export default {
  name: 'OperaJkLineWindow',
  extends: BaseOpera,
@@ -61,13 +55,9 @@
      // è¡¨å•数据
      form: {
        id: null,
        creator: '',
        createDate: '',
        editor: '',
        editDate: '',
        isdeleted: '',
        info: '',
        weeks:null,
        name: '',
        code: '',
        categoryId: '',
        carId: '',
        maxCustomer: '',
@@ -75,8 +65,13 @@
        status: '',
        sortnum: ''
      },
      categoryList: [],
      carsList: [],
      weeksList: ['周一','周二','周三','周四','周五','周六','周日'],
      // éªŒè¯è§„则
      rules: {
        name: [{ required: true, message: '请输入线路名称' }],
        categoryId: [{ required: true, message: '请选择所属主线路' }]
      }
    }
  },
@@ -85,6 +80,42 @@
      api: '/business/jkLine',
      'field.id': 'id'
    })
  },
  methods: {
    open (title, target) {
      this.title = title
      this.loadCategory()
      this.loadCars()
      this.visible = true
      // æ–°å»º
      if (target == null) {
        this.$nextTick(() => {
          this.$refs.form.resetFields()
          this.form[this.configData['field.id']] = null
        })
        return
      }
      // ç¼–辑
      this.$nextTick(() => {
        for (const key in this.form) {
          this.form[key] = target[key]
        }
      })
    },
    loadCategory () {
      fetchCateList({
        type: 4
      }).then(res => {
        this.categoryList = res
      })
    },
    loadCars () {
      allList({
        type: 1//查询全部车辆
      }).then(res => {
        this.carsList = res
      })
    }
  }
}
</script>
admin/src/main.js
@@ -15,6 +15,7 @@
import preventReClick from '@/directives/directive'
import Treeselect from '@riophae/vue-treeselect'
import '@riophae/vue-treeselect/dist/vue-treeselect.css'
Vue.component('treeselect', Treeselect)
Vue.use(preventReClick)
admin/src/views/business/jkCustomer.vue
@@ -2,53 +2,32 @@
  <TableLayout :permissions="['business:jkcustomer:query']">
    <!-- æœç´¢è¡¨å• -->
    <el-form ref="searchForm" slot="search-form" :model="searchForm" label-width="100px" inline>
      <el-form-item label="主键" prop="id">
        <el-input v-model="searchForm.id" placeholder="请输入主键" @keypress.enter.native="search"></el-input>
      <el-form-item label="客户简码" prop="code">
        <el-input v-model="searchForm.code" placeholder="请输入客户简码" clearable @keypress.enter.native="search"></el-input>
      </el-form-item>
      <el-form-item label="创建人编码" prop="creator">
        <el-input v-model="searchForm.creator" placeholder="请输入创建人编码" @keypress.enter.native="search"></el-input>
      <el-form-item label="客户名称" prop="name">
        <el-input v-model="searchForm.name" placeholder="请输入客户名称" clearable @keypress.enter.native="search"></el-input>
      </el-form-item>
      <el-form-item label="创建时间" prop="createDate">
        <el-date-picker v-model="searchForm.createDate" value-format="yyyy-MM-dd" placeholder="请输入创建时间" @change="search"/>
      <el-form-item label="地址" prop="location">
        <el-input v-model="searchForm.location" placeholder="请输入地址"  clearable @keypress.enter.native="search"></el-input>
      </el-form-item>
      <el-form-item label="更新人编码" prop="editor">
        <el-input v-model="searchForm.editor" placeholder="请输入更新人编码" @keypress.enter.native="search"></el-input>
      <el-form-item label="配送周期" prop="lineWeeks">
        <el-select v-model="searchForm.lineWeeks" clearable filterable placeholder="请选择配送周期"  @change="search">
          <el-option v-for="item in weeksList" :key="item" :label="item" :value="item">
          </el-option>
        </el-select>
      </el-form-item>
      <el-form-item label="更新时间" prop="editDate">
        <el-date-picker v-model="searchForm.editDate" value-format="yyyy-MM-dd" placeholder="请输入更新时间" @change="search"/>
      <el-form-item label="所属主线路" prop="categoryId">
        <el-select v-model="searchForm.categoryId" clearable filterable placeholder="请选择所属主线路"  @change="loadLines();search()">
          <el-option v-for="item in categoryList" :key="item.id" :label="item.name" :value="item.id">
          </el-option>
        </el-select>
      </el-form-item>
      <el-form-item label="是否删除0否 1是" prop="isdeleted">
        <el-input v-model="searchForm.isdeleted" placeholder="请输入是否删除0否 1是" @keypress.enter.native="search"></el-input>
      </el-form-item>
      <el-form-item label="备注" prop="info">
        <el-input v-model="searchForm.info" placeholder="请输入备注" @keypress.enter.native="search"></el-input>
      </el-form-item>
      <el-form-item label="名称" prop="name">
        <el-input v-model="searchForm.name" placeholder="请输入名称" @keypress.enter.native="search"></el-input>
      </el-form-item>
      <el-form-item label="编码" prop="code">
        <el-input v-model="searchForm.code" placeholder="请输入编码" @keypress.enter.native="search"></el-input>
      </el-form-item>
      <el-form-item label="所在位置" prop="lacation">
        <el-input v-model="searchForm.lacation" placeholder="请输入所在位置" @keypress.enter.native="search"></el-input>
      </el-form-item>
      <el-form-item label="经度" prop="longitude">
        <el-input v-model="searchForm.longitude" placeholder="请输入经度" @keypress.enter.native="search"></el-input>
      </el-form-item>
      <el-form-item label="维度" prop="latitude">
        <el-input v-model="searchForm.latitude" placeholder="请输入维度" @keypress.enter.native="search"></el-input>
      </el-form-item>
      <el-form-item label="配送周期" prop="weeks">
        <el-input v-model="searchForm.weeks" placeholder="请输入配送周期" @keypress.enter.native="search"></el-input>
      </el-form-item>
      <el-form-item label="送货路线编码(关联jk_line)" prop="lineId">
        <el-input v-model="searchForm.lineId" placeholder="请输入送货路线编码(关联jk_line)" @keypress.enter.native="search"></el-input>
      </el-form-item>
      <el-form-item label="状态 0正常 ç¦ç”¨" prop="status">
        <el-input v-model="searchForm.status" placeholder="请输入状态 0正常 ç¦ç”¨" @keypress.enter.native="search"></el-input>
      </el-form-item>
      <el-form-item label="排序码" prop="sortnum">
        <el-input v-model="searchForm.sortnum" placeholder="请输入排序码" @keypress.enter.native="search"></el-input>
      <el-form-item label="送货线路" prop="lineId">
        <el-select v-model="searchForm.lineId" clearable filterable placeholder="请选择送货线路"  @change="search">
          <el-option v-for="item in lineList" :key="item.id" :label="item.name" :value="item.id">
          </el-option>
        </el-select>
      </el-form-item>
      <section>
        <el-button type="primary" @click="search">搜索</el-button>
@@ -59,8 +38,11 @@
    <!-- è¡¨æ ¼å’Œåˆ†é¡µ -->
    <template v-slot:table-wrap>
      <ul class="toolbar" v-permissions="['business:jkcustomer:create', 'business:jkcustomer:delete']">
<!--
        <li><el-button type="primary" @click="$refs.operaJkCustomerWindow.open('新建交控-客户信息表')" icon="el-icon-plus" v-permissions="['business:jkcustomer:create']">新建</el-button></li>
        <li><el-button @click="deleteByIdInBatch" icon="el-icon-delete" v-permissions="['business:jkcustomer:delete']">删除</el-button></li>
-->
        <li><el-button icon="el-icon-upload"  type="primary" @click="$refs.OperaJkCustomerImportWindowRef.open('客户导入')"  v-permissions="['business:jkcustomer:create']">客户导入</el-button></li>
        <li><el-button type="danger" @click="deleteByIdInBatch" icon="el-icon-delete" v-permissions="['business:jkcustomer:delete']">删除</el-button></li>
      </ul>
      <el-table
        v-loading="isWorking.search"
@@ -69,22 +51,15 @@
        @selection-change="handleSelectionChange"
      >
        <el-table-column type="selection" width="55"></el-table-column>
        <el-table-column prop="id" label="主键" min-width="100px"></el-table-column>
        <el-table-column prop="creator" label="创建人编码" min-width="100px"></el-table-column>
        <el-table-column prop="createDate" label="创建时间" min-width="100px"></el-table-column>
        <el-table-column prop="editor" label="更新人编码" min-width="100px"></el-table-column>
        <el-table-column prop="editDate" label="更新时间" min-width="100px"></el-table-column>
        <el-table-column prop="isdeleted" label="是否删除0否 1是" min-width="100px"></el-table-column>
        <el-table-column prop="info" label="备注" min-width="100px"></el-table-column>
        <el-table-column prop="name" label="名称" min-width="100px"></el-table-column>
        <el-table-column prop="code" label="编码" min-width="100px"></el-table-column>
        <el-table-column prop="lacation" label="所在位置" min-width="100px"></el-table-column>
        <el-table-column prop="longitude" label="经度" min-width="100px"></el-table-column>
        <el-table-column prop="latitude" label="维度" min-width="100px"></el-table-column>
        <el-table-column prop="weeks" label="配送周期" min-width="100px"></el-table-column>
        <el-table-column prop="lineId" label="送货路线编码(关联jk_line)" min-width="100px"></el-table-column>
        <el-table-column prop="status" label="状态 0正常 ç¦ç”¨" min-width="100px"></el-table-column>
        <el-table-column prop="sortnum" label="排序码" min-width="100px"></el-table-column>
        <el-table-column prop="code" label="客户简码" min-width="100px"></el-table-column>
        <el-table-column prop="name" label="客户名称" min-width="100px"></el-table-column>
        <el-table-column prop="location" label="地址" min-width="200px" show-tooltip-when-overflow></el-table-column>
        <el-table-column prop="locationInfo" label="经纬度" min-width="150px">  </el-table-column>
        <el-table-column prop="lineWeeks" label="配送周期" min-width="100px"></el-table-column>
        <el-table-column prop="lineName" label="送货线路" min-width="200px" show-tooltip-when-overflow></el-table-column>
        <el-table-column prop="categoryName" label="所属主线路" min-width="100px"></el-table-column>
        <el-table-column prop="sortno" label="序号" min-width="100px"></el-table-column>
        <el-table-column prop="editDate" label="更新时间" min-width="140px"></el-table-column>
        <el-table-column
          v-if="containPermissions(['business:jkcustomer:update', 'business:jkcustomer:delete'])"
          label="操作"
@@ -92,8 +67,8 @@
          fixed="right"
        >
          <template slot-scope="{row}">
            <el-button type="text" @click="$refs.operaJkCustomerWindow.open('编辑交控-客户信息表', row)" icon="el-icon-edit" v-permissions="['business:jkcustomer:update']">编辑</el-button>
            <el-button type="text" @click="deleteById(row)" icon="el-icon-delete" v-permissions="['business:jkcustomer:delete']">删除</el-button>
            <el-button type="text" @click="$refs.operaJkCustomerWindow.open('编辑客户信息', row)" icon="el-icon-edit" v-permissions="['business:jkcustomer:update']">编辑</el-button>
            <el-button type="text" style="color: red" @click="deleteById(row)" icon="el-icon-delete" v-permissions="['business:jkcustomer:delete']">删除</el-button>
          </template>
        </el-table-column>
      </el-table>
@@ -106,6 +81,7 @@
    </template>
    <!-- æ–°å»º/修改 -->
    <OperaJkCustomerWindow ref="operaJkCustomerWindow" @success="handlePageChange"/>
    <OperaJkCustomerImportWindow ref="OperaJkCustomerImportWindowRef" @success="handlePageChange" />
  </TableLayout>
</template>
@@ -114,31 +90,30 @@
import TableLayout from '@/layouts/TableLayout'
import Pagination from '@/components/common/Pagination'
import OperaJkCustomerWindow from '@/components/business/OperaJkCustomerWindow'
import OperaJkCustomerImportWindow from '@/components/business/OperaJkCustomerImportWindow'
import { fetchCateList } from '@/api/business/category'
import { allList } from '@/api/business/jkLine'
export default {
  name: 'JkCustomer',
  extends: BaseTable,
  components: { TableLayout, Pagination, OperaJkCustomerWindow },
  components: { TableLayout, Pagination, OperaJkCustomerWindow, OperaJkCustomerImportWindow },
  data () {
    return {
      // æœç´¢
      searchForm: {
        id: '',
        creator: '',
        createDate: '',
        editor: '',
        editDate: '',
        isdeleted: '',
        info: '',
        categoryId: '',
        name: '',
        code: '',
        lacation: '',
        longitude: '',
        latitude: '',
        weeks: '',
        location: '',
        lineWeeks: '',
        lineId: '',
        status: '',
        sortnum: ''
      }
      },
      categoryList: [],
      lineList: [],
      weeksList: ['周一', '周二', '周三', '周四', '周五', '周六', '周日']
    }
  },
  created () {
@@ -149,6 +124,25 @@
      'field.main': 'id'
    })
    this.search()
    this.loadCategory()
    this.loadLines()
  },
  methods: {
    loadCategory () {
      fetchCateList({
        type: 4
      }).then(res => {
        this.categoryList = res
      })
    },
    loadLines () {
      this.searchForm.lineId =''
      allList({
        categoryId: this.searchForm.categoryId
      }).then(res => {
        this.lineList = res
      })
    }
  }
}
</script>
admin/src/views/business/jkLine.vue
@@ -2,47 +2,20 @@
  <TableLayout :permissions="['business:jkline:query']">
    <!-- æœç´¢è¡¨å• -->
    <el-form ref="searchForm" slot="search-form" :model="searchForm" label-width="100px" inline>
      <el-form-item label="主键" prop="id">
        <el-input v-model="searchForm.id" placeholder="请输入主键" @keypress.enter.native="search"></el-input>
      </el-form-item>
      <el-form-item label="创建人编码" prop="creator">
        <el-input v-model="searchForm.creator" placeholder="请输入创建人编码" @keypress.enter.native="search"></el-input>
      </el-form-item>
      <el-form-item label="创建时间" prop="createDate">
        <el-date-picker v-model="searchForm.createDate" value-format="yyyy-MM-dd" placeholder="请输入创建时间" @change="search"/>
      </el-form-item>
      <el-form-item label="更新人编码" prop="editor">
        <el-input v-model="searchForm.editor" placeholder="请输入更新人编码" @keypress.enter.native="search"></el-input>
      </el-form-item>
      <el-form-item label="更新时间" prop="editDate">
        <el-date-picker v-model="searchForm.editDate" value-format="yyyy-MM-dd" placeholder="请输入更新时间" @change="search"/>
      </el-form-item>
      <el-form-item label="是否删除0否 1是" prop="isdeleted">
        <el-input v-model="searchForm.isdeleted" placeholder="请输入是否删除0否 1是" @keypress.enter.native="search"></el-input>
      </el-form-item>
      <el-form-item label="备注" prop="info">
        <el-input v-model="searchForm.info" placeholder="请输入备注" @keypress.enter.native="search"></el-input>
      </el-form-item>
      <el-form-item label="名称" prop="name">
        <el-input v-model="searchForm.name" placeholder="请输入名称" @keypress.enter.native="search"></el-input>
        <el-input v-model="searchForm.name" placeholder="请输入名称" clearable @keypress.enter.native="search"></el-input>
      </el-form-item>
      <el-form-item label="班组编码(关联category)" prop="categoryId">
        <el-input v-model="searchForm.categoryId" placeholder="请输入班组编码(关联category)" @keypress.enter.native="search"></el-input>
      <el-form-item label="所属主线路" prop="categoryId">
        <el-select v-model="searchForm.categoryId" clearable filterable placeholder="请选择所属主线路"  @change="search">
          <el-option v-for="item in categoryList" :key="item.id" :label="item.name" :value="item.id">
          </el-option>
        </el-select>
      </el-form-item>
      <el-form-item label="所属车辆(关联cars)" prop="carId">
        <el-input v-model="searchForm.carId" placeholder="请输入所属车辆(关联cars)" @keypress.enter.native="search"></el-input>
      <el-form-item label="运送车辆" prop="carId">
        <el-input v-model="searchForm.carCode" placeholder="请输入运送车辆" clearable @keypress.enter.native="search"></el-input>
      </el-form-item>
      <el-form-item label="最大客户量" prop="maxCustomer">
        <el-input v-model="searchForm.maxCustomer" placeholder="请输入最大客户量" @keypress.enter.native="search"></el-input>
      </el-form-item>
      <el-form-item label="最大订单量" prop="maxOrder">
        <el-input v-model="searchForm.maxOrder" placeholder="请输入最大订单量" @keypress.enter.native="search"></el-input>
      </el-form-item>
      <el-form-item label="状态 0未绑定 1在位 2借出" prop="status">
        <el-input v-model="searchForm.status" placeholder="请输入状态 0未绑定 1在位 2借出" @keypress.enter.native="search"></el-input>
      </el-form-item>
      <el-form-item label="排序码" prop="sortnum">
        <el-input v-model="searchForm.sortnum" placeholder="请输入排序码" @keypress.enter.native="search"></el-input>
      <el-form-item label="序号" prop="code">
        <el-input v-model="searchForm.code" placeholder="请输入序号" @keypress.enter.native="search"></el-input>
      </el-form-item>
      <section>
        <el-button type="primary" @click="search">搜索</el-button>
@@ -54,7 +27,8 @@
    <template v-slot:table-wrap>
      <ul class="toolbar" v-permissions="['business:jkline:create', 'business:jkline:delete']">
        <li><el-button type="primary" @click="$refs.operaJkLineWindow.open('新建交控-线路信息表')" icon="el-icon-plus" v-permissions="['business:jkline:create']">新建</el-button></li>
        <li><el-button @click="deleteByIdInBatch" icon="el-icon-delete" v-permissions="['business:jkline:delete']">删除</el-button></li>
        <li><el-button icon="el-icon-upload"  type="primary" @click="$refs.OperaJkLineImportWindowRef.open('线路导入')"  v-permissions="['business:jkline:create']">线路导入</el-button></li>
        <li><el-button type="danger" @click="deleteByIdInBatch" icon="el-icon-delete" v-permissions="['business:jkline:delete']">删除</el-button></li>
      </ul>
      <el-table
        v-loading="isWorking.search"
@@ -63,20 +37,14 @@
        @selection-change="handleSelectionChange"
      >
        <el-table-column type="selection" width="55"></el-table-column>
        <el-table-column prop="id" label="主键" min-width="100px"></el-table-column>
        <el-table-column prop="creator" label="创建人编码" min-width="100px"></el-table-column>
        <el-table-column prop="createDate" label="创建时间" min-width="100px"></el-table-column>
        <el-table-column prop="editor" label="更新人编码" min-width="100px"></el-table-column>
        <el-table-column prop="editDate" label="更新时间" min-width="100px"></el-table-column>
        <el-table-column prop="isdeleted" label="是否删除0否 1是" min-width="100px"></el-table-column>
        <el-table-column prop="info" label="备注" min-width="100px"></el-table-column>
        <el-table-column prop="name" label="名称" min-width="100px"></el-table-column>
        <el-table-column prop="categoryId" label="班组编码(关联category)" min-width="100px"></el-table-column>
        <el-table-column prop="carId" label="所属车辆(关联cars)" min-width="100px"></el-table-column>
        <el-table-column prop="maxCustomer" label="最大客户量" min-width="100px"></el-table-column>
        <el-table-column prop="maxOrder" label="最大订单量" min-width="100px"></el-table-column>
        <el-table-column prop="status" label="状态 0未绑定 1在位 2借出" min-width="100px"></el-table-column>
        <el-table-column prop="sortnum" label="排序码" min-width="100px"></el-table-column>
        <el-table-column prop="name" label="名称" min-width="200px" show-tooltip-when-overflow></el-table-column>
        <el-table-column prop="categoryName" label="所属主线路" min-width="140px"></el-table-column>
        <el-table-column prop="carCode" label="所属车辆" min-width="100px"></el-table-column>
        <el-table-column prop="maxCustomer" label="客户量" min-width="100px"></el-table-column>
        <el-table-column prop="maxOrder" label="订单量" min-width="100px"></el-table-column>
        <el-table-column prop="weeks" label="配送周期" min-width="140px"></el-table-column>
        <el-table-column prop="code" label="序号" min-width="100px"></el-table-column>
        <el-table-column prop="editDate" label="更新时间" min-width="150px"></el-table-column>
        <el-table-column
          v-if="containPermissions(['business:jkline:update', 'business:jkline:delete'])"
          label="操作"
@@ -98,6 +66,7 @@
    </template>
    <!-- æ–°å»º/修改 -->
    <OperaJkLineWindow ref="operaJkLineWindow" @success="handlePageChange"/>
    <OperaJkLineImportWindow ref="OperaJkLineImportWindowRef" @success="handlePageChange" />
  </TableLayout>
</template>
@@ -106,29 +75,22 @@
import TableLayout from '@/layouts/TableLayout'
import Pagination from '@/components/common/Pagination'
import OperaJkLineWindow from '@/components/business/OperaJkLineWindow'
import OperaJkLineImportWindow from '@/components/business/OperaJkLineImportWindow'
import { fetchCateList } from '@/api/business/category'
export default {
  name: 'JkLine',
  extends: BaseTable,
  components: { TableLayout, Pagination, OperaJkLineWindow },
  components: { TableLayout, Pagination, OperaJkLineWindow,OperaJkLineImportWindow },
  data () {
    return {
      // æœç´¢
      searchForm: {
        id: '',
        creator: '',
        createDate: '',
        editor: '',
        editDate: '',
        isdeleted: '',
        info: '',
        name: '',
        categoryId: '',
        carId: '',
        maxCustomer: '',
        maxOrder: '',
        status: '',
        sortnum: ''
      }
        carCode: '',
        code: ''
      },
      categoryList: []
    }
  },
  created () {
@@ -139,6 +101,14 @@
      'field.main': 'id'
    })
    this.search()
    this.loadCategory()
  },
  methods: {
    loadCategory () {
      fetchCateList({ type: 4 }).then(res => {
        this.categoryList = res || []
      })
    }
  }
}
</script>
admin/src/views/vehicle/cars.vue
@@ -198,7 +198,7 @@
    },
    getCate() {
      fetchList({
        model: {},
        model: {type:1},
        capacity: 1000,
        page: 1,
      }).then(res => {
admin/src/views/vehicle/components/OperaCategoryWindow.vue
@@ -76,7 +76,7 @@
  },
  methods: {
    getList () {
      fetchCateList({}).then(res => {
      fetchCateList({type:1}).then(res => {
        this.dataList = res || []
      })
    },
server/system_service/src/main/java/com/doumee/core/utils/Constants.java
@@ -161,6 +161,7 @@
    public static final String LIQUID_LEVEL_UNIT ="LIQUID_LEVEL_UNIT" ;
    public static final String OUT_HY_LOT_TOTAL ="OUT_HY_LOT_TOTAL" ;
    public static final String BANNER_IMG ="BANNER_IMG" ;
    public static final String GAODE_LOCATION_GEOAPI_URL = "GAODE_LOCATION_GEOAPI_URL";
    public static  boolean DEALING_HK_SYNCPRIVILEGE= false;
    public static  boolean DEALING_HK_SYNCDEVICE = false;
@@ -518,6 +519,9 @@
    public interface RedisKeys {
        public static final String IMPORTING_CARS ="IMPORTING_CARS";
        public static final String CHECKING_JKCUSTOMER_LOCATION ="CHECKING_JKCUSTOMER_LOCATION";
        public static final String IMPORTING_JKCUSTOMER ="IMPORTING_JKCUSTOMER";
        public static final String IMPORTING_JKLINE ="IMPORTING_JKLINE";
        public static final String IMPORTING_MEMBER ="IMPORTING_MEMBER";
        public static final String BIGSCREEN_UUID ="BIGSCREEN_UUID";
        public static final String IMPORTING_GAS ="IMPORTING_GAS";
server/system_timer/src/main/java/com/doumee/jobs/fegin/VisitServiceFegin.java
@@ -17,6 +17,9 @@
    @ApiOperation("【访客系统】定时查询人员设备授权结果")
    @PostMapping("/timer/empower/syncEmpowerDetailData")
    ApiResponse syncEmpowerDetailData();
    @ApiOperation("【访客系统】更新交控中心客户经纬度信息")
    @PostMapping("/timer/jkCustomer/getCustomerLocationInfo")
    ApiResponse getCustomerLocationInfo();
    @ApiOperation("【访客系统】定时查询人员设备授权下载进度")
    @PostMapping("/timer/empower/syncEmpowerResultData")
    ApiResponse syncEmpowerResultData();
server/visits/admin_timer/src/main/java/com/doumee/api/JkCustomerTimerController.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,47 @@
package com.doumee.api;
import com.alibaba.fastjson.JSONObject;
import com.doumee.biz.system.SystemDictDataBiz;
import com.doumee.core.utils.Constants;
import com.doumee.core.utils.HttpsUtil;
import com.doumee.core.wx.WXConstant;
import com.doumee.dao.system.model.SystemDictData;
import com.doumee.service.business.JkCustomerService;
import com.doumee.service.business.third.model.ApiResponse;
import com.doumee.service.system.SystemDictDataService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.mgt.DefaultSecurityManager;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import java.util.Date;
import java.util.Objects;
/**
 * @author æ±Ÿè¹„蹄
 * @date 2023/11/30 15:33
 */
@Api(tags = "交控中心客户定时器")
@RestController
@RequestMapping("/timer/jkCustomer")
public class JkCustomerTimerController extends BaseController {
    @Autowired
    private JkCustomerService jkCustomerService;
    @ApiOperation("更新交控中心客户经纬度信息")
    @PostMapping("/getCustomerLocationInfo")
    public ApiResponse getCustomerLocationInfo() {
        DefaultSecurityManager securityManager = new DefaultSecurityManager();
        SecurityUtils.setSecurityManager(securityManager);
        jkCustomerService.checkNullLocation();
        return ApiResponse.success("更新交控中心客户经纬度信息");
    }
}
server/visits/admin_timer/src/main/resources/bootstrap-dev.yml
@@ -23,7 +23,7 @@
#        data-id: com.doumee.meeting.admin
      discovery:
        server-addr: http://192.168.0.212:8848 #配置Nacos地址
        namespace: dmvisit
        namespace: wuhu_visit_dev
        username: nacos
        password: nacos
server/visits/admin_timer/src/main/resources/bootstrap.yml
@@ -1,6 +1,6 @@
spring:
  profiles:
    active: pro
    active: dev
  application:
    name: visitsTimer
    # å®‰å…¨é…ç½®
server/visits/dmvisit_admin/src/main/java/com/doumee/cloud/admin/JkCustomerCloudController.java
@@ -6,16 +6,18 @@
import com.doumee.core.annotation.pr.PreventRepeat;
import com.doumee.core.utils.Constants;
import com.doumee.dao.business.model.JkCustomer;
import com.doumee.dao.business.model.JkLine;
import com.doumee.service.business.JkCustomerService;
import com.doumee.service.business.third.model.ApiResponse;
import com.doumee.service.business.third.model.PageData;
import com.doumee.service.business.third.model.PageWrap;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;
import javax.servlet.http.HttpServletResponse;
import java.io.File;
import java.util.ArrayList;
import java.util.List;
@@ -35,35 +37,36 @@
    @ApiOperation("新建")
    @PostMapping("/create")
    @CloudRequiredPermission("business:jkcustomer:create")
    public ApiResponse create(@RequestBody JkCustomer jkCustomer) {
    public ApiResponse create(@RequestBody JkCustomer jkCustomer, @RequestHeader(Constants.HEADER_USER_TOKEN) String token) {
        return ApiResponse.success(jkCustomerService.create(jkCustomer));
    }
    @ApiOperation("根据ID删除")
    @GetMapping("/delete/{id}")
    @CloudRequiredPermission("business:jkcustomer:delete")
    public ApiResponse deleteById(@PathVariable Integer id) {
        jkCustomerService.deleteById(id);
    public ApiResponse deleteById(@PathVariable Integer id, @RequestHeader(Constants.HEADER_USER_TOKEN) String token) {
        jkCustomerService.deleteById(id,this.getLoginUser(token));
        return ApiResponse.success(null);
    }
    @ApiOperation("批量删除")
    @GetMapping("/delete/batch")
    @CloudRequiredPermission("business:jkcustomer:delete")
    public ApiResponse deleteByIdInBatch(@RequestParam String ids) {
    public ApiResponse deleteByIdInBatch(@RequestParam String ids, @RequestHeader(Constants.HEADER_USER_TOKEN) String token) {
        String [] idArray = ids.split(",");
        List<Integer> idList = new ArrayList<>();
        for (String id : idArray) {
            idList.add(Integer.valueOf(id));
        }
        jkCustomerService.deleteByIdInBatch(idList);
        jkCustomerService.deleteByIdInBatch(idList,this.getLoginUser(token));
        return ApiResponse.success(null);
    }
    @ApiOperation("根据ID修改")
    @PostMapping("/updateById")
    @CloudRequiredPermission("business:jkcustomer:update")
    public ApiResponse updateById(@RequestBody JkCustomer jkCustomer) {
    public ApiResponse updateById(@RequestBody JkCustomer jkCustomer, @RequestHeader(Constants.HEADER_USER_TOKEN) String token) {
        jkCustomer.setLoginUserInfo(this.getLoginUser(token));
        jkCustomerService.updateById(jkCustomer);
        return ApiResponse.success(null);
    }
@@ -71,21 +74,32 @@
    @ApiOperation("分页查询")
    @PostMapping("/page")
    @CloudRequiredPermission("business:jkcustomer:query")
    public ApiResponse<PageData<JkCustomer>> findPage (@RequestBody PageWrap<JkCustomer> pageWrap) {
    public ApiResponse<PageData<JkCustomer>> findPage (@RequestBody PageWrap<JkCustomer> pageWrap, @RequestHeader(Constants.HEADER_USER_TOKEN) String token) {
        return ApiResponse.success(jkCustomerService.findPage(pageWrap));
    }
    @ApiOperation("导出Excel")
    @PostMapping("/exportExcel")
    @CloudRequiredPermission("business:jkcustomer:exportExcel")
    public void exportExcel (@RequestBody PageWrap<JkCustomer> pageWrap, HttpServletResponse response) {
    public void exportExcel (@RequestBody PageWrap<JkCustomer> pageWrap, HttpServletResponse response, @RequestHeader(Constants.HEADER_USER_TOKEN) String token) {
        ExcelExporter.build(JkCustomer.class).export(jkCustomerService.findPage(pageWrap).getRecords(), "交控-客户信息表", response);
    }
    @ApiOperation("根据ID查询")
    @GetMapping("/{id}")
    @CloudRequiredPermission("business:jkcustomer:query")
    public ApiResponse findById(@PathVariable Integer id) {
    public ApiResponse findById(@PathVariable Integer id, @RequestHeader(Constants.HEADER_USER_TOKEN) String token) {
        return ApiResponse.success(jkCustomerService.findById(id));
    }
    @ApiOperation(value = "客户信息导入" ,notes = "客户信息导入")
    @PostMapping("/importExcel")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "file", value = "file", required = true, paramType = "query", dataType = "file", dataTypeClass = File.class),
    })
    @CloudRequiredPermission("business:cars:create")
    public ApiResponse<String> importExcel (@ApiParam(value = "file") MultipartFile file, @RequestHeader(Constants.HEADER_USER_TOKEN) String token) {
        List<JkCustomer> list = jkCustomerService.importBatch(file,this.getLoginUser(token));
        return ApiResponse.success("导入成功");
    }
}
server/visits/dmvisit_admin/src/main/java/com/doumee/cloud/admin/JkLineCloudController.java
@@ -5,17 +5,19 @@
import com.doumee.core.annotation.excel.ExcelExporter;
import com.doumee.core.annotation.pr.PreventRepeat;
import com.doumee.core.utils.Constants;
import com.doumee.dao.business.model.Cars;
import com.doumee.dao.business.model.JkLine;
import com.doumee.service.business.JkLineService;
import com.doumee.service.business.third.model.ApiResponse;
import com.doumee.service.business.third.model.PageData;
import com.doumee.service.business.third.model.PageWrap;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;
import javax.servlet.http.HttpServletResponse;
import java.io.File;
import java.util.ArrayList;
import java.util.List;
@@ -35,35 +37,37 @@
    @ApiOperation("新建")
    @PostMapping("/create")
    @CloudRequiredPermission("business:jkline:create")
    public ApiResponse create(@RequestBody JkLine jkLine) {
    public ApiResponse create(@RequestBody JkLine jkLine, @RequestHeader(Constants.HEADER_USER_TOKEN) String token) {
        jkLine.setLoginUserInfo(this.getLoginUser(token));
        return ApiResponse.success(jkLineService.create(jkLine));
    }
    @ApiOperation("根据ID删除")
    @GetMapping("/delete/{id}")
    @CloudRequiredPermission("business:jkline:delete")
    public ApiResponse deleteById(@PathVariable Integer id) {
        jkLineService.deleteById(id);
    public ApiResponse deleteById(@PathVariable Integer id, @RequestHeader(Constants.HEADER_USER_TOKEN) String token) {
        jkLineService.deleteById(id,this.getLoginUser(token));
        return ApiResponse.success(null);
    }
    @ApiOperation("批量删除")
    @GetMapping("/delete/batch")
    @CloudRequiredPermission("business:jkline:delete")
    public ApiResponse deleteByIdInBatch(@RequestParam String ids) {
    public ApiResponse deleteByIdInBatch(@RequestParam String ids, @RequestHeader(Constants.HEADER_USER_TOKEN) String token) {
        String [] idArray = ids.split(",");
        List<Integer> idList = new ArrayList<>();
        for (String id : idArray) {
            idList.add(Integer.valueOf(id));
        }
        jkLineService.deleteByIdInBatch(idList);
        jkLineService.deleteByIdInBatch(idList,this.getLoginUser(token));
        return ApiResponse.success(null);
    }
    @ApiOperation("根据ID修改")
    @PostMapping("/updateById")
    @CloudRequiredPermission("business:jkline:update")
    public ApiResponse updateById(@RequestBody JkLine jkLine) {
    public ApiResponse updateById(@RequestBody JkLine jkLine, @RequestHeader(Constants.HEADER_USER_TOKEN) String token) {
        jkLine.setLoginUserInfo(this.getLoginUser(token));
        jkLineService.updateById(jkLine);
        return ApiResponse.success(null);
    }
@@ -71,21 +75,38 @@
    @ApiOperation("分页查询")
    @PostMapping("/page")
    @CloudRequiredPermission("business:jkline:query")
    public ApiResponse<PageData<JkLine>> findPage (@RequestBody PageWrap<JkLine> pageWrap) {
    public ApiResponse<PageData<JkLine>> findPage (@RequestBody PageWrap<JkLine> pageWrap, @RequestHeader(Constants.HEADER_USER_TOKEN) String token) {
        return ApiResponse.success(jkLineService.findPage(pageWrap));
    }
    @ApiOperation("查询全部")
    @PostMapping("/list")
    @CloudRequiredPermission("business:jkline:query")
    public ApiResponse<List<JkLine>> list (@RequestBody JkLine pageWrap, @RequestHeader(Constants.HEADER_USER_TOKEN) String token) {
        return ApiResponse.success(jkLineService.findList(pageWrap));
    }
    @ApiOperation("导出Excel")
    @PostMapping("/exportExcel")
    @CloudRequiredPermission("business:jkline:exportExcel")
    public void exportExcel (@RequestBody PageWrap<JkLine> pageWrap, HttpServletResponse response) {
    public void exportExcel (@RequestBody PageWrap<JkLine> pageWrap, HttpServletResponse response, @RequestHeader(Constants.HEADER_USER_TOKEN) String token) {
        ExcelExporter.build(JkLine.class).export(jkLineService.findPage(pageWrap).getRecords(), "交控-线路信息表", response);
    }
    @ApiOperation("根据ID查询")
    @GetMapping("/{id}")
    @CloudRequiredPermission("business:jkline:query")
    public ApiResponse findById(@PathVariable Integer id) {
    public ApiResponse findById(@PathVariable Integer id, @RequestHeader(Constants.HEADER_USER_TOKEN) String token) {
        return ApiResponse.success(jkLineService.findById(id));
    }
    @ApiOperation(value = "线路信息导入" ,notes = "线路信息导入")
    @PostMapping("/importExcel")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "file", value = "file", required = true, paramType = "query", dataType = "file", dataTypeClass = File.class),
    })
    @CloudRequiredPermission("business:cars:create")
    public ApiResponse<String> importExcel (@ApiParam(value = "file") MultipartFile file, @RequestHeader(Constants.HEADER_USER_TOKEN) String token) {
        List<JkLine> list = jkLineService.importBatch(file,this.getLoginUser(token));
        return ApiResponse.success("导入成功");
    }
}
server/visits/dmvisit_service/src/main/java/com/doumee/dao/admin/request/JkCustomerImport.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,32 @@
package com.doumee.dao.admin.request;
import com.doumee.core.annotation.excel.ExcelColumn;
import io.swagger.annotations.ApiModel;
import lombok.Data;
/**
 * å‘˜å·¥ä¿¡æ¯å¯¼å…¥è¡¨
 * @author æ±Ÿè¹„蹄
 * @date 2024/01/16 10:03
 */
@Data
@ApiModel("线路客户信息导入")
public class JkCustomerImport {
    @ExcelColumn(name="客户简码",value = "code",index = 0)
    private String code;
    @ExcelColumn(name="客户名称",value = "name",index = 1)
    private String name;
    @ExcelColumn(name="线路",value = "lineName",index = 2)
    private String lineName;
    @ExcelColumn(name="序号",value = "sortno",index = 3)
    private String sortno;
    @ExcelColumn(name="地址",value = "location",index = 4)
    private String location;
    @ExcelColumn(name="经纬度" , value = "locationInfo",index = 5)
    private String locationInfo;
}
server/visits/dmvisit_service/src/main/java/com/doumee/dao/admin/request/JkLineImport.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,34 @@
package com.doumee.dao.admin.request;
import com.doumee.core.annotation.excel.ExcelColumn;
import io.swagger.annotations.ApiModel;
import lombok.Data;
/**
 * å‘˜å·¥ä¿¡æ¯å¯¼å…¥è¡¨
 * @author æ±Ÿè¹„蹄
 * @date 2024/01/16 10:03
 */
@Data
@ApiModel("线路信息导入")
public class JkLineImport {
    @ExcelColumn(name="线路名称",value = "name",index = 0)
    private String name;
    @ExcelColumn(name="所属主线路",value = "categoryName",index = 1)
    private String categoryName;
    @ExcelColumn(name="序号",value = "code",index = 2)
    private String code;
    @ExcelColumn(name="送货车辆",value = "carCode",index = 3)
    private String carCode;
    @ExcelColumn(name="客户量" , value = "maxCustomer" ,index = 4)
    private String maxCustomer;
    @ExcelColumn(name="订单量" , value = "maxOrder",index = 5)
    private String maxOrder;
    @ExcelColumn(name="周期" , value = "weeks",index = 6)
    private String weeks;
}
server/visits/dmvisit_service/src/main/java/com/doumee/dao/business/JkCustomerMapper.java
@@ -2,11 +2,12 @@
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.doumee.dao.business.model.JkCustomer;
import com.github.yulichang.base.MPJBaseMapper;
/**
 * @author æ±Ÿè¹„蹄
 * @date 2025/09/28 09:01
 */
public interface JkCustomerMapper extends BaseMapper<JkCustomer> {
public interface JkCustomerMapper extends MPJBaseMapper<JkCustomer> {
}
server/visits/dmvisit_service/src/main/java/com/doumee/dao/business/JkLineMapper.java
@@ -2,11 +2,12 @@
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.doumee.dao.business.model.JkLine;
import com.github.yulichang.base.MPJBaseMapper;
/**
 * @author æ±Ÿè¹„蹄
 * @date 2025/09/28 09:01
 */
public interface JkLineMapper extends BaseMapper<JkLine> {
public interface JkLineMapper extends MPJBaseMapper<JkLine> {
}
server/visits/dmvisit_service/src/main/java/com/doumee/dao/business/model/JkCabinet.java
@@ -111,7 +111,7 @@
    @ApiModelProperty(value = "所在位置")
    @ExcelColumn(name="所在位置")
    private String lacation;
    private String location;
    @ApiModelProperty(value = "经度", example = "1")
    @ExcelColumn(name="经度")
server/visits/dmvisit_service/src/main/java/com/doumee/dao/business/model/JkCustomer.java
@@ -1,5 +1,6 @@
package com.doumee.dao.business.model;
import com.baomidou.mybatisplus.annotation.TableField;
import com.doumee.core.annotation.excel.ExcelColumn;
import com.doumee.service.business.third.model.LoginUserModel;
import io.swagger.annotations.ApiModel;
@@ -23,69 +24,89 @@
public class JkCustomer  extends LoginUserModel {
    @ApiModelProperty(value = "主键", example = "1")
    @ExcelColumn(name="主键")
    //@ExcelColumn(name="主键")
    private Integer id;
    @ApiModelProperty(value = "创建人编码", example = "1")
    @ExcelColumn(name="创建人编码")
    //@ExcelColumn(name="创建人编码")
    private Integer creator;
    @ApiModelProperty(value = "创建时间")
    @ExcelColumn(name="创建时间")
    @JsonFormat(pattern = "yyyy-MM-dd")
    //@ExcelColumn(name="创建时间")IMPORTING_JKCUSTOMER
    private Date createDate;
    @ApiModelProperty(value = "更新人编码", example = "1")
    @ExcelColumn(name="更新人编码")
    //@ExcelColumn(name="更新人编码")
    private Integer editor;
    @ApiModelProperty(value = "更新时间")
    @ExcelColumn(name="更新时间")
    @JsonFormat(pattern = "yyyy-MM-dd")
    //@ExcelColumn(name="更新时间")IMPORTING_JKCUSTOMER
    private Date editDate;
    @ApiModelProperty(value = "是否删除0否 1是", example = "1")
    @ExcelColumn(name="是否删除0否 1是")
    //@ExcelColumn(name="是否删除0否 1是")
    private Integer isdeleted;
    @ApiModelProperty(value = "备注")
    @ExcelColumn(name="备注")
    //@ExcelColumn(name="备注")
    private String info;
    @ApiModelProperty(value = "名称", example = "1")
    @ExcelColumn(name="名称")
    private Integer name;
    @ExcelColumn(name="客户名称",index = 2,width = 10)
    private String name;
    @ApiModelProperty(value = "编码", example = "1")
    @ExcelColumn(name="编码")
    private Integer code;
    @ExcelColumn(name="客户简码",index = 1,width = 10)
    private String code;
    @ApiModelProperty(value = "所在位置")
    @ExcelColumn(name="所在位置")
    private String lacation;
    @ExcelColumn(name="地址",index = 3,width = 10)
    private String location;
    @ApiModelProperty(value = "经度", example = "1")
    @ExcelColumn(name="经度")
    //@ExcelColumn(name="经度")
    private BigDecimal longitude;
    @ApiModelProperty(value = "维度", example = "1")
    @ExcelColumn(name="维度")
    //@ExcelColumn(name="维度")
    private BigDecimal latitude;
    @ApiModelProperty(value = "配送周期")
    @ExcelColumn(name="配送周期")
    private String weeks;
    @ApiModelProperty(value = "客户序号")
    @ExcelColumn(name="序号",index = 8,width = 10)
    private String sortno;
    @ApiModelProperty(value = "经纬度", example = "1")
    @ExcelColumn(name="经纬度",index = 3,width = 10)
    @TableField(exist = false)
    private String locationInfo;
    @ApiModelProperty(value = "送货路线编码(关联jk_line)", example = "1")
    @ExcelColumn(name="送货路线编码(关联jk_line)")
    //@ExcelColumn(name="送货路线编码(关联jk_line)")
    private Integer lineId;
    @ApiModelProperty(value = "状态 0正常 ç¦ç”¨", example = "1")
    @ExcelColumn(name="状态 0正常 ç¦ç”¨")
    //@ExcelColumn(name="状态 0正常 ç¦ç”¨")
    private Integer status;
    @ApiModelProperty(value = "排序码", example = "1")
    @ExcelColumn(name="排序码")
    //@ExcelColumn(name="排序码")
    private Integer sortnum;
    @ApiModelProperty(value = "所属主线路", example = "1")
    @ExcelColumn(name="所属主线路",index = 7,width = 10)
    @TableField(exist = false)
    private String categoryName;
    @ApiModelProperty(value = "所属主线路编码", example = "1")
    @TableField(exist = false)
    private Integer categoryId;
    @ApiModelProperty(value = "线路", example = "1")
    @ExcelColumn(name="送货线路",index = 6,width = 10)
    @TableField(exist = false)
    private String lineName;
    @ApiModelProperty(value = "配送周期", example = "1")
    @ExcelColumn(name="配送周期",index = 5,width = 10)
    @TableField(exist = false)
    private String lineWeeks;
    @ApiModelProperty(value = "是否新增, 0否 1是", example = "1")
    @TableField(exist = false)
    private int isnew;
}
server/visits/dmvisit_service/src/main/java/com/doumee/dao/business/model/JkLine.java
@@ -1,5 +1,6 @@
package com.doumee.dao.business.model;
import com.baomidou.mybatisplus.annotation.TableField;
import com.doumee.core.annotation.excel.ExcelColumn;
import com.doumee.service.business.third.model.LoginUserModel;
import io.swagger.annotations.ApiModel;
@@ -22,61 +23,79 @@
public class JkLine  extends LoginUserModel {
    @ApiModelProperty(value = "主键", example = "1")
    @ExcelColumn(name="主键")
    //@ExcelColumn(name="主键")
    private Integer id;
    @ApiModelProperty(value = "创建人编码", example = "1")
    @ExcelColumn(name="创建人编码")
    //@ExcelColumn(name="创建人编码")
    private Integer creator;
    @ApiModelProperty(value = "创建时间")
    @ExcelColumn(name="创建时间")
    @JsonFormat(pattern = "yyyy-MM-dd")
    //@ExcelColumn(name="创建时间")
    private Date createDate;
    @ApiModelProperty(value = "更新人编码", example = "1")
    @ExcelColumn(name="更新人编码")
    //@ExcelColumn(name="更新人编码")
    private Integer editor;
    @ApiModelProperty(value = "更新时间")
    @ExcelColumn(name="更新时间")
    @JsonFormat(pattern = "yyyy-MM-dd")
    //@ExcelColumn(name="更新时间")
    private Date editDate;
    @ApiModelProperty(value = "是否删除0否 1是", example = "1")
    @ExcelColumn(name="是否删除0否 1是")
    //@ExcelColumn(name="是否删除0否 1是")
    private Integer isdeleted;
    @ApiModelProperty(value = "备注")
    @ExcelColumn(name="备注")
    //@ExcelColumn(name="备注")
    private String info;
    @ApiModelProperty(value = "序号")
    @ExcelColumn(name="序号",index = 7,width = 10)
    private String code;
    @ApiModelProperty(value = "名称", example = "1")
    @ExcelColumn(name="名称")
    private Integer name;
    @ExcelColumn(name="名称",index = 1,width = 10)
    private String name;
    @ApiModelProperty(value = "班组编码(关联category)", example = "1")
    @ExcelColumn(name="班组编码(关联category)")
    //@ExcelColumn(name="班组编码(关联category)")
    private Integer categoryId;
    @ApiModelProperty(value = "所属车辆(关联cars)", example = "1")
    @ExcelColumn(name="所属车辆(关联cars)")
    //@ExcelColumn(name="所属车辆(关联cars)")
    private Integer carId;
    @ApiModelProperty(value = "最大客户量", example = "1")
    @ExcelColumn(name="最大客户量")
    @ExcelColumn(name="最大客户量",index = 5,width = 10)
    private Integer maxCustomer;
    @ApiModelProperty(value = "最大订单量", example = "1")
    @ExcelColumn(name="最大订单量")
    @ExcelColumn(name="最大订单量",index = 6,width = 10)
    private Integer maxOrder;
    @ApiModelProperty(value = "状态 0未绑定 1在位 2借出", example = "1")
    @ExcelColumn(name="状态 0未绑定 1在位 2借出")
    //@ExcelColumn(name="状态 0未绑定 1在位 2借出")
    private Integer status;
    @ApiModelProperty(value = "排序码", example = "1")
    @ExcelColumn(name="排序码")
//    @ExcelColumn(name="排序码")
    private Integer sortnum;
    @ApiModelProperty(value = "配送周期")
    @ExcelColumn(name="配送周期",index = 3,width = 10)
    private String weeks;
    @ApiModelProperty(value = "是否新增, 0否 1是", example = "1")
    @TableField(exist = false)
    private int isnew;
    @ApiModelProperty(value = "送货车辆", example = "1")
    @ExcelColumn(name="送货车辆",index = 4,width = 10)
    @TableField(exist = false)
    private String carCode;
    @ApiModelProperty(value = "所属主线路", example = "1")
    @ExcelColumn(name="所属主线路",index = 2,width = 10)
    @TableField(exist = false)
    private String categoryName;
}
server/visits/dmvisit_service/src/main/java/com/doumee/service/business/JkCustomerService.java
@@ -1,8 +1,11 @@
package com.doumee.service.business;
import com.doumee.service.business.third.model.LoginUserInfo;
import com.doumee.service.business.third.model.PageData;
import com.doumee.service.business.third.model.PageWrap;
import com.doumee.dao.business.model.JkCustomer;
import org.springframework.web.multipart.MultipartFile;
import java.util.List;
/**
@@ -25,7 +28,7 @@
     *
     * @param id ä¸»é”®
     */
    void deleteById(Integer id);
    void deleteById(Integer id,LoginUserInfo user);
    /**
     * åˆ é™¤
@@ -39,7 +42,7 @@
     *
     * @param ids ä¸»é”®é›†
     */
    void deleteByIdInBatch(List<Integer> ids);
    void deleteByIdInBatch(List<Integer> ids,LoginUserInfo user);
    /**
     * ä¸»é”®æ›´æ–°
@@ -94,4 +97,8 @@
     * @return long
     */
    long count(JkCustomer jkCustomer);
    List<JkCustomer> importBatch(MultipartFile file, LoginUserInfo loginUser);
    void checkNullLocation();
}
server/visits/dmvisit_service/src/main/java/com/doumee/service/business/JkLineService.java
@@ -1,8 +1,12 @@
package com.doumee.service.business;
import com.doumee.dao.business.model.Cars;
import com.doumee.service.business.third.model.LoginUserInfo;
import com.doumee.service.business.third.model.PageData;
import com.doumee.service.business.third.model.PageWrap;
import com.doumee.dao.business.model.JkLine;
import org.springframework.web.multipart.MultipartFile;
import java.util.List;
/**
@@ -25,7 +29,7 @@
     *
     * @param id ä¸»é”®
     */
    void deleteById(Integer id);
    void deleteById(Integer id, LoginUserInfo user);
    /**
     * åˆ é™¤
@@ -39,7 +43,7 @@
     *
     * @param ids ä¸»é”®é›†
     */
    void deleteByIdInBatch(List<Integer> ids);
    void deleteByIdInBatch(List<Integer> ids, LoginUserInfo user);
    /**
     * ä¸»é”®æ›´æ–°
@@ -94,4 +98,6 @@
     * @return long
     */
    long count(JkLine jkLine);
    List<JkLine> importBatch(MultipartFile file, LoginUserInfo loginUser);
}
server/visits/dmvisit_service/src/main/java/com/doumee/service/business/impl/CarsServiceImpl.java
@@ -359,6 +359,7 @@
        && Constants.equalsInteger(Constants.ZERO,cars.getType())){
            return this.getGwCar();
        }
        cars.setType(null);
        QueryWrapper<Cars> wrapper = new QueryWrapper<>(cars);
        wrapper.lambda().eq(Cars::getIsdeleted,Constants.ZERO);
        return carsMapper.selectList(wrapper);
server/visits/dmvisit_service/src/main/java/com/doumee/service/business/impl/JkCabinetServiceImpl.java
@@ -155,8 +155,8 @@
            queryWrapper.lambda().ge(JkCabinet::getHaertTime, Utils.Date.getStart(pageWrap.getModel().getHaertTime()));
            queryWrapper.lambda().le(JkCabinet::getHaertTime, Utils.Date.getEnd(pageWrap.getModel().getHaertTime()));
        }
        if (pageWrap.getModel().getLacation() != null) {
            queryWrapper.lambda().eq(JkCabinet::getLacation, pageWrap.getModel().getLacation());
        if (pageWrap.getModel().getLocation() != null) {
            queryWrapper.lambda().eq(JkCabinet::getLocation, pageWrap.getModel().getLocation());
        }
        if (pageWrap.getModel().getLongitude() != null) {
            queryWrapper.lambda().eq(JkCabinet::getLongitude, pageWrap.getModel().getLongitude());
server/visits/dmvisit_service/src/main/java/com/doumee/service/business/impl/JkCustomerServiceImpl.java
@@ -1,19 +1,42 @@
package com.doumee.service.business.impl;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.doumee.biz.system.SystemDictDataBiz;
import com.doumee.core.annotation.excel.ExcelImporter;
import com.doumee.core.constants.ResponseStatus;
import com.doumee.core.exception.BusinessException;
import com.doumee.core.utils.Constants;
import com.doumee.core.utils.HttpsUtil;
import com.doumee.dao.admin.request.JkCustomerImport;
import com.doumee.dao.admin.request.JkLineImport;
import com.doumee.dao.business.JkLineMapper;
import com.doumee.dao.business.model.*;
import com.doumee.dao.system.model.SystemUser;
import com.doumee.service.business.third.model.LoginUserInfo;
import com.doumee.service.business.third.model.PageData;
import com.doumee.service.business.third.model.PageWrap;
import com.doumee.core.utils.Utils;
import com.doumee.dao.business.JkCustomerMapper;
import com.doumee.dao.business.model.JkCustomer;
import com.doumee.service.business.JkCustomerService;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.github.yulichang.wrapper.MPJLambdaWrapper;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;
import org.springframework.web.multipart.MultipartFile;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
/**
@@ -22,11 +45,18 @@
 * @date 2025/09/28 09:01
 */
@Service
@Slf4j
public class JkCustomerServiceImpl implements JkCustomerService {
    @Autowired
    private JkCustomerMapper jkCustomerMapper;
    @Autowired
    private JkLineMapper jkLineMapper;
    @Autowired
    private SystemDictDataBiz systemDictDataBiz;
    @Autowired
    private RedisTemplate<String, Object> redisTemplate;
    @Override
    public Integer create(JkCustomer jkCustomer) {
        jkCustomerMapper.insert(jkCustomer);
@@ -34,8 +64,13 @@
    }
    @Override
    public void deleteById(Integer id) {
        jkCustomerMapper.deleteById(id);
    public void deleteById(Integer id,LoginUserInfo user) {
        jkCustomerMapper.update(null,new UpdateWrapper<JkCustomer>().lambda()
                .set(JkCustomer::getIsdeleted,Constants.ONE)
                .set(JkCustomer::getEditor,user.getId())
                .set(JkCustomer::getEditDate,new Date())
                .eq(JkCustomer::getId,id)
        );
    }
    @Override
@@ -45,16 +80,39 @@
    }
    @Override
    public void deleteByIdInBatch(List<Integer> ids) {
    public void deleteByIdInBatch(List<Integer> ids,LoginUserInfo user) {
        if (CollectionUtils.isEmpty(ids)) {
            return;
        }
        jkCustomerMapper.deleteBatchIds(ids);
        jkCustomerMapper.update(null,new UpdateWrapper<JkCustomer>().lambda()
                .set(JkCustomer::getIsdeleted,Constants.ONE)
                .set(JkCustomer::getEditor,user.getId())
                .set(JkCustomer::getEditDate,new Date())
                .in(JkCustomer::getId,ids)
        );
    }
    @Override
    public void updateById(JkCustomer jkCustomer) {
        jkCustomerMapper.updateById(jkCustomer);
        if(jkCustomer.getId() == null
            ||jkCustomer.getLocationInfo() ==null ){
                throw  new BusinessException(ResponseStatus.BAD_REQUEST);
        }
        String[] strs = jkCustomer.getLocationInfo().split(",");
        jkCustomer.setLongitude(getDecimalByVal(strs[0]));//经度
        jkCustomer.setLatitude(strs.length>1?getDecimalByVal(strs[1]):null);//纬度
        if(jkCustomer.getLatitude() == null || jkCustomer.getLongitude() ==null){
            //非成对出现,无效经纬度不维护
            throw  new BusinessException(ResponseStatus.BAD_REQUEST);
        }
        jkCustomerMapper.update(null,new UpdateWrapper<JkCustomer>().lambda()
                .set(JkCustomer::getLatitude,jkCustomer.getLatitude())
                .set(JkCustomer::getLongitude,jkCustomer.getLongitude())
                .set(JkCustomer::getEditor,jkCustomer.getLoginUserInfo().getId())
                .set(JkCustomer::getEditDate,new Date())
                .eq(JkCustomer::getId,jkCustomer.getId())
        );
    }
    @Override
@@ -87,71 +145,315 @@
    @Override
    public PageData<JkCustomer> findPage(PageWrap<JkCustomer> pageWrap) {
        IPage<JkCustomer> page = new Page<>(pageWrap.getPage(), pageWrap.getCapacity());
        QueryWrapper<JkCustomer> queryWrapper = new QueryWrapper<>();
        MPJLambdaWrapper<JkCustomer> queryWrapper = new MPJLambdaWrapper<>();
        Utils.MP.blankToNull(pageWrap.getModel());
        pageWrap.getModel().setIsdeleted(Constants.ZERO);
        queryWrapper.selectAll(JkCustomer.class )
                .selectAs(JkLine::getName,JkCustomer::getLineName)
                .selectAs(JkLine::getWeeks,JkCustomer::getLineWeeks)
                .selectAs(Category::getId,JkCustomer::getCategoryId)
                .selectAs(Category::getName,JkCustomer::getCategoryName)
                .leftJoin(JkLine.class,JkLine::getId,JkCustomer::getLineId )
                .leftJoin(Category.class,Category::getId,JkLine::getCategoryId );
        queryWrapper.eq( pageWrap.getModel().getCategoryId()!=null,JkLine::getCategoryId, pageWrap.getModel().getCategoryId());
        queryWrapper.eq(StringUtils.isNotBlank(pageWrap.getModel().getLineWeeks()),JkLine::getWeeks, pageWrap.getModel().getLineWeeks());
        queryWrapper.like(StringUtils.isNotBlank(pageWrap.getModel().getCategoryName()),Category::getName, pageWrap.getModel().getCategoryName());
        queryWrapper.like(StringUtils.isNotBlank(pageWrap.getModel().getLineName()),JkLine::getName, pageWrap.getModel().getLineName());
        queryWrapper.like(StringUtils.isNotBlank(pageWrap.getModel().getCategoryName()),Category::getName, pageWrap.getModel().getCategoryName());
        if (pageWrap.getModel().getId() != null) {
            queryWrapper.lambda().eq(JkCustomer::getId, pageWrap.getModel().getId());
            queryWrapper.eq(JkCustomer::getId, pageWrap.getModel().getId());
        }
        if (pageWrap.getModel().getCreator() != null) {
            queryWrapper.lambda().eq(JkCustomer::getCreator, pageWrap.getModel().getCreator());
            queryWrapper.eq(JkCustomer::getCreator, pageWrap.getModel().getCreator());
        }
        if (pageWrap.getModel().getCreateDate() != null) {
            queryWrapper.lambda().ge(JkCustomer::getCreateDate, Utils.Date.getStart(pageWrap.getModel().getCreateDate()));
            queryWrapper.lambda().le(JkCustomer::getCreateDate, Utils.Date.getEnd(pageWrap.getModel().getCreateDate()));
            queryWrapper.ge(JkCustomer::getCreateDate, Utils.Date.getStart(pageWrap.getModel().getCreateDate()));
            queryWrapper.le(JkCustomer::getCreateDate, Utils.Date.getEnd(pageWrap.getModel().getCreateDate()));
        }
        if (pageWrap.getModel().getEditor() != null) {
            queryWrapper.lambda().eq(JkCustomer::getEditor, pageWrap.getModel().getEditor());
            queryWrapper.eq(JkCustomer::getEditor, pageWrap.getModel().getEditor());
        }
        if (pageWrap.getModel().getEditDate() != null) {
            queryWrapper.lambda().ge(JkCustomer::getEditDate, Utils.Date.getStart(pageWrap.getModel().getEditDate()));
            queryWrapper.lambda().le(JkCustomer::getEditDate, Utils.Date.getEnd(pageWrap.getModel().getEditDate()));
            queryWrapper.ge(JkCustomer::getEditDate, Utils.Date.getStart(pageWrap.getModel().getEditDate()));
            queryWrapper.le(JkCustomer::getEditDate, Utils.Date.getEnd(pageWrap.getModel().getEditDate()));
        }
        if (pageWrap.getModel().getIsdeleted() != null) {
            queryWrapper.lambda().eq(JkCustomer::getIsdeleted, pageWrap.getModel().getIsdeleted());
            queryWrapper.eq(JkCustomer::getIsdeleted, pageWrap.getModel().getIsdeleted());
        }
        if (pageWrap.getModel().getInfo() != null) {
            queryWrapper.lambda().eq(JkCustomer::getInfo, pageWrap.getModel().getInfo());
            queryWrapper.eq(JkCustomer::getInfo, pageWrap.getModel().getInfo());
        }
        if (pageWrap.getModel().getName() != null) {
            queryWrapper.lambda().eq(JkCustomer::getName, pageWrap.getModel().getName());
            queryWrapper.like(JkCustomer::getName, pageWrap.getModel().getName());
        }
        if (pageWrap.getModel().getCode() != null) {
            queryWrapper.lambda().eq(JkCustomer::getCode, pageWrap.getModel().getCode());
            queryWrapper.like(JkCustomer::getCode, pageWrap.getModel().getCode());
        }
        if (pageWrap.getModel().getLacation() != null) {
            queryWrapper.lambda().eq(JkCustomer::getLacation, pageWrap.getModel().getLacation());
        if (pageWrap.getModel().getLocation() != null) {
            queryWrapper.like(JkCustomer::getLocation, pageWrap.getModel().getLocation());
        }
        if (pageWrap.getModel().getLongitude() != null) {
            queryWrapper.lambda().eq(JkCustomer::getLongitude, pageWrap.getModel().getLongitude());
            queryWrapper.eq(JkCustomer::getLongitude, pageWrap.getModel().getLongitude());
        }
        if (pageWrap.getModel().getLatitude() != null) {
            queryWrapper.lambda().eq(JkCustomer::getLatitude, pageWrap.getModel().getLatitude());
            queryWrapper.eq(JkCustomer::getLatitude, pageWrap.getModel().getLatitude());
        }
        if (pageWrap.getModel().getWeeks() != null) {
            queryWrapper.lambda().eq(JkCustomer::getWeeks, pageWrap.getModel().getWeeks());
        if (pageWrap.getModel().getSortno() != null) {
            queryWrapper.eq(JkCustomer::getSortno, pageWrap.getModel().getSortno());
        }
        if (pageWrap.getModel().getLineId() != null) {
            queryWrapper.lambda().eq(JkCustomer::getLineId, pageWrap.getModel().getLineId());
            queryWrapper.eq(JkCustomer::getLineId, pageWrap.getModel().getLineId());
        }
        if (pageWrap.getModel().getStatus() != null) {
            queryWrapper.lambda().eq(JkCustomer::getStatus, pageWrap.getModel().getStatus());
            queryWrapper.eq(JkCustomer::getStatus, pageWrap.getModel().getStatus());
        }
        if (pageWrap.getModel().getSortnum() != null) {
            queryWrapper.lambda().eq(JkCustomer::getSortnum, pageWrap.getModel().getSortnum());
            queryWrapper.eq(JkCustomer::getSortnum, pageWrap.getModel().getSortnum());
        }
        for(PageWrap.SortData sortData: pageWrap.getSorts()) {
            if (sortData.getDirection().equalsIgnoreCase(PageWrap.DESC)) {
                queryWrapper.orderByDesc(sortData.getProperty());
            } else {
                queryWrapper.orderByAsc(sortData.getProperty());
        queryWrapper.orderByAsc(JkCustomer::getCode);
        IPage<JkCustomer> result = jkCustomerMapper.selectJoinPage(page, JkCustomer.class,queryWrapper);
        if(result.getRecords()!=null && result.getRecords().size()>0){
            for(JkCustomer model :result.getRecords()){
                if(model.getLongitude()!=null && model.getLatitude()!=null){
                    model.setLocationInfo(model.getLongitude().setScale(6, RoundingMode.HALF_UP).doubleValue()
                            +","+model.getLatitude().setScale(6, RoundingMode.HALF_UP).doubleValue());
                }
            }
        }
        return PageData.from(jkCustomerMapper.selectPage(page, queryWrapper));
        return PageData.from(result);
    }
    @Override
    public     void checkNullLocation() {
        log.error("更新交控中心客户经纬度信息===============开始");
        Boolean importing = (Boolean) redisTemplate.opsForValue().get(Constants.RedisKeys.CHECKING_JKCUSTOMER_LOCATION);
        if(importing!=null && importing){
            throw new BusinessException(ResponseStatus.BAD_REQUEST.getCode(),"对不起,上次任务正在执行中,请稍后再试!");
        }
        redisTemplate.opsForValue().set(Constants.RedisKeys.CHECKING_JKCUSTOMER_LOCATION,true);
        try {
            LambdaQueryWrapper<JkCustomer> queryWrapper = new LambdaQueryWrapper<>();
            queryWrapper.isNotNull(JkCustomer::getLocation);
            queryWrapper.and(wrapper ->{
                wrapper.isNull(JkCustomer::getLatitude)
                        .or().isNull(JkCustomer::getLongitude); });
            //查询全部有地址,但是没有经纬度的客户信息
            List<JkCustomer>  list = jkCustomerMapper.selectList(queryWrapper);
            if(list ==null || list.size()==0){
                return;
            }
            String url = systemDictDataBiz.queryByCode(Constants.SYSTEM,Constants.GAODE_LOCATION_GEOAPI_URL).getCode();
            for(JkCustomer c : list){
                try {
                    String result = HttpsUtil.get(url.replace("${param}",c.getLocation()),true);
                    JSONObject json = JSONObject.parseObject(result);
                    if(json!=null
                            && json.getInteger("status")!=null
                            && json.getInteger("status") ==1
                            && json.getJSONArray("geocodes")!=null
                            && json.getJSONArray("geocodes").size()>0
                            && json.getJSONArray("geocodes").getJSONObject(0)!=null
                            && json.getJSONArray("geocodes").getJSONObject(0).getString("location")!=null){
                        //请求成功
                        String[] strs =json.getJSONArray("geocodes").getJSONObject(0).getString("location").split(",");
                        c.setLongitude(getDecimalByVal(strs[0]));//经度
                        c.setLatitude(strs.length>1?getDecimalByVal(strs[1]):null);//纬度
                        if(c.getLatitude() != null && c.getLongitude() !=null){
                            //非成对出现,无效经纬度不维护
                            jkCustomerMapper.update(null,new UpdateWrapper<JkCustomer>().lambda()
                                    .set(JkCustomer::getLatitude,c.getLatitude())
                                    .set(JkCustomer::getLongitude,c.getLongitude())
                                    .set(JkCustomer::getEditDate,new Date())
                                    .eq(JkCustomer::getId,c.getId())
                            );
                        }
                    }else{
                        log.error("更新交控中心客户经纬度信息=====获取失败=========="+c.getName()+"-"+c.getLocation());
                    }
                }catch (Exception e){
                    log.error("更新交控中心客户经纬度信息=====失败=========="+c.getName()+"-"+c.getLocation());
                }
            }
        }catch (Exception e){
                log.error("更新交控中心客户经纬度信息===============",e.getMessage());
        }finally {
            redisTemplate.delete(Constants.RedisKeys.CHECKING_JKCUSTOMER_LOCATION);
        }
        log.error("更新交控中心客户经纬度信息===============结束");
    }
    @Override
    public long count(JkCustomer jkCustomer) {
        QueryWrapper<JkCustomer> wrapper = new QueryWrapper<>(jkCustomer);
        return jkCustomerMapper.selectCount(wrapper);
    }
    @Override
    @Transactional(rollbackFor = {BusinessException.class,Exception.class})
    public List<JkCustomer> importBatch(MultipartFile file, LoginUserInfo loginUserInfo){
        Boolean importing = (Boolean) redisTemplate.opsForValue().get(Constants.RedisKeys.IMPORTING_JKCUSTOMER);
        if(importing!=null && importing){
            throw new BusinessException(ResponseStatus.BAD_REQUEST.getCode(),"对不起,已存在导入任务正在执行中,请稍后再试!");
        }
        redisTemplate.opsForValue().set(Constants.RedisKeys.IMPORTING_JKCUSTOMER,true);
        try {
            ExcelImporter ie = null;
            List<JkCustomerImport> dataList =null;
            try {
                ie = new ExcelImporter(file,1,0);
                dataList = ie.getDataList(JkCustomerImport.class,null);
            }  catch (Exception e) {
                e.printStackTrace();
            }
            if(dataList == null || dataList.size() ==0){
                throw new BusinessException(ResponseStatus.BAD_REQUEST.getCode(),"对不起,录入数据为空!");
            }
            //当前所有线路
            List<JkLine> lineList =  jkLineMapper.selectJoinList(JkLine.class,new MPJLambdaWrapper<JkLine>()
                    .selectAll(JkLine.class)
                    .eq(JkLine::getIsdeleted,Constants.ZERO)
            );
            List<JkCustomer> allList =  jkCustomerMapper.selectJoinList(JkCustomer.class,new MPJLambdaWrapper<JkCustomer>()
                    .selectAll(JkCustomer.class)
                    .eq(JkCustomer::getIsdeleted,Constants.ZERO)
            );
            List<JkCustomer> newList = new ArrayList<>();
            List<JkCustomer> updateList = new ArrayList<>();
            for(int i=0;i<dataList.size();i++){
                JkCustomerImport model = dataList.get(i);
                if(StringUtils.isBlank(model.getName())
                        &&StringUtils.isBlank(model.getCode())
                        &&StringUtils.isBlank(model.getLocation())
                        &&StringUtils.isBlank(model.getSortno())
                        &&StringUtils.isBlank(model.getLocationInfo())
                        &&StringUtils.isBlank(model.getLineName()) ){
                    continue;
                }
                checkModelParam(model,newList,updateList,i,loginUserInfo,allList,lineList );
            }
            if((newList == null || newList.size() ==0) && updateList.size() == 0){
                throw new BusinessException(ResponseStatus.BAD_REQUEST.getCode(),"对不起,录入有效数据为空!");
            }
            if(newList.size()>0){
                jkCustomerMapper.insert(newList);
            }
            if(updateList.size()>0){
                for (JkCustomer c : updateList){
                    jkCustomerMapper.updateById(c);
                }
            }
            newList.addAll(updateList);
            return newList;
        }catch (BusinessException e){
            throw e;
        }catch (Exception e){
            e.printStackTrace();
            throw  new BusinessException(ResponseStatus.SERVER_ERROR.getCode(),"信息导入失败,请稍后重试");
        }finally {
            redisTemplate.delete(Constants.RedisKeys.IMPORTING_JKCUSTOMER);
        }
    }
    private JkCustomer checkModelParam(JkCustomerImport model, List<JkCustomer> newList
            , List<JkCustomer> updateList
            ,int index
            ,LoginUserInfo loginUserInfo
            ,List<JkCustomer> allList
            ,List<JkLine> lineList ) {
        if(StringUtils.isBlank(model.getName())
                ||StringUtils.isBlank(model.getCode())
                ||StringUtils.isBlank(model.getLocation()) ){
            throw  new BusinessException(ResponseStatus.BAD_REQUEST.getCode(),"对不起,第"+(index+3)+"行客户信息不完整,请检查表格内容!");
        }
        for(JkCustomer param: newList){
            if(StringUtils.isNotBlank(model.getCode())&&StringUtils.isNotBlank(param.getCode())) {
                if (StringUtils.equals(model.getCode(), param.getCode())) {
                    throw new BusinessException(ResponseStatus.BAD_REQUEST.getCode(), "对不起,第" + (index + 3) + "行客户简码【" + model.getName() + "】重复出现,请检查表格内容!");
                }
            }
        }
        JkLine line = findLineFromListByName(model.getLineName(),lineList);
        if(line == null){
            throw new BusinessException(ResponseStatus.BAD_REQUEST.getCode(), "对不起,第" + (index + 3) + "行线路【" + model.getLineName() + "】不存在,请检查表格内容!");
        }
        JkCustomer tModel = findModelFromList(model.getCode(),allList);
        if(tModel == null){
            tModel = new JkCustomer();
            tModel.setCreator(loginUserInfo.getId());
            tModel.setCreateDate(new Date());
            tModel.setIsnew(Constants.ONE);
            newList.add(tModel);
        }else{
            tModel.setIsnew(Constants.ZERO);
            updateList.add(tModel);
        }
        tModel.setName(model.getName());
        tModel.setCode(model.getCode());
        tModel.setLocation(model.getLocation());
        tModel.setSortno(model.getSortno());
        tModel.setLineId(line.getId());
        if(StringUtils.isNotBlank(model.getLocationInfo())){
            String[] strs = model.getLocationInfo().split(",");
            tModel.setLongitude(getDecimalByVal(strs[0]));//经度
            tModel.setLatitude(strs.length>1?getDecimalByVal(strs[1]):null);//纬度
        }
        if(tModel.getLatitude() == null || tModel.getLongitude() ==null){
            //非成对出现,无效经纬度不维护
            tModel.setLongitude(null);
            tModel.setLatitude(null);
        }
        tModel.setEditDate(new Date());
        tModel.setEditor(loginUserInfo.getId());
        tModel.setIsdeleted(Constants.ZERO);
        return tModel;
    }
    private BigDecimal getDecimalByVal(String val) {
        try {
            return new BigDecimal(val);
        }catch (Exception e){
        }
        return null;
    }
    private Company findCompanyFromList(String companyName, List<Company> companyList) {
        if(companyList !=null){
            for(Company company : companyList){
                if(StringUtils.equals(companyName,company.getCompanyNamePath())){
                    return  company;
                }
            }
        }
        return null;
    }
    private JkCustomer findModelFromList(String code, List<JkCustomer> list) {
        if(list !=null){
            for(JkCustomer model : list){
                if(StringUtils.equals(code,model.getCode())){
                    return  model;
                }
            }
        }
        return null;
    }
    private JkLine findLineFromListByName(String name, List<JkLine> list) {
        if(list !=null){
            for(JkLine model : list){
                if(StringUtils.equals(name,model.getName())){
                    return model;
                }
            }
        }
        return null;
    }
}
server/visits/dmvisit_service/src/main/java/com/doumee/service/business/impl/JkLineServiceImpl.java
@@ -1,19 +1,38 @@
package com.doumee.service.business.impl;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.doumee.core.annotation.excel.ExcelImporter;
import com.doumee.core.constants.ResponseStatus;
import com.doumee.core.exception.BusinessException;
import com.doumee.core.utils.Constants;
import com.doumee.core.utils.ScientificNotationTUtil;
import com.doumee.dao.admin.request.CarsImport;
import com.doumee.dao.admin.request.JkLineImport;
import com.doumee.dao.business.CarsMapper;
import com.doumee.dao.business.CategoryMapper;
import com.doumee.dao.business.model.*;
import com.doumee.service.business.third.model.LoginUserInfo;
import com.doumee.service.business.third.model.PageData;
import com.doumee.service.business.third.model.PageWrap;
import com.doumee.core.utils.Utils;
import com.doumee.dao.business.JkLineMapper;
import com.doumee.dao.business.model.JkLine;
import com.doumee.service.business.JkLineService;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.github.yulichang.wrapper.MPJLambdaWrapper;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;
import org.springframework.web.multipart.MultipartFile;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
/**
@@ -25,17 +44,45 @@
public class JkLineServiceImpl implements JkLineService {
    @Autowired
    private RedisTemplate<String, Object> redisTemplate;
    @Autowired
    private JkLineMapper jkLineMapper;
    @Autowired
    private CategoryMapper categoryMapper;
    @Autowired
    private CarsMapper carsMapper;
    @Override
    public Integer create(JkLine jkLine) {
        if(jkLineMapper.selectCount(new QueryWrapper<JkLine>().lambda()
                .eq(JkLine::getIsdeleted,Constants.ZERO)
                .eq(JkLine::getName,jkLine.getName()) )>0){
            throw new BusinessException(ResponseStatus.BAD_REQUEST.getCode(),"对不起,线路名称已存在,请返回刷新页面查看!");
        }
        if(categoryMapper.selectOne(new QueryWrapper<Category>().lambda()
                .eq(Category::getId,jkLine.getCategoryId())
                .eq(Category::getType,Constants.FOUR)
                .eq(Category::getIsdeleted,Constants.ZERO)) ==null){
                throw new BusinessException(ResponseStatus.BAD_REQUEST.getCode(),"对不起,所属主线路不存在,请返回刷新页面查看!");
        }
        jkLine.setStatus(Constants.formatIntegerNum(jkLine.getStatus()));
        jkLine.setIsdeleted(Constants.ZERO);
        jkLine.setCreator(jkLine.getLoginUserInfo().getId());
        jkLine.setCreateDate(new Date());
        jkLine.setEditDate(jkLine.getCreateDate());
        jkLine.setEditor(jkLine.getCreator());
        jkLineMapper.insert(jkLine);
        return jkLine.getId();
    }
    @Override
    public void deleteById(Integer id) {
        jkLineMapper.deleteById(id);
    public void deleteById(Integer id, LoginUserInfo user) {
        jkLineMapper.update(null,new UpdateWrapper<JkLine>().lambda()
                .set(JkLine::getIsdeleted,Constants.ONE)
                .set(JkLine::getEditor,user.getId())
                .set(JkLine::getEditDate,new Date())
                .eq(JkLine::getId,id)
        );
    }
    @Override
@@ -45,15 +92,34 @@
    }
    @Override
    public void deleteByIdInBatch(List<Integer> ids) {
    public void deleteByIdInBatch(List<Integer> ids, LoginUserInfo user) {
        if (CollectionUtils.isEmpty(ids)) {
            return;
        }
        jkLineMapper.deleteBatchIds(ids);
        jkLineMapper.update(null,new UpdateWrapper<JkLine>().lambda()
                .set(JkLine::getIsdeleted,Constants.ONE)
                .set(JkLine::getEditor,user.getId())
                .set(JkLine::getEditDate,new Date())
                .in(JkLine::getId,ids)
        );
    }
    @Override
    public void updateById(JkLine jkLine) {
        if(jkLineMapper.selectCount(new QueryWrapper<JkLine>().lambda()
                .ne(JkLine::getId,jkLine.getId())
                .eq(JkLine::getIsdeleted,Constants.ZERO)
                .eq(JkLine::getName,jkLine.getName()) )>0){
            throw new BusinessException(ResponseStatus.BAD_REQUEST.getCode(),"对不起,线路名称已存在,请返回刷新页面查看!");
        }
        if(categoryMapper.selectOne(new QueryWrapper<Category>().lambda()
                .eq(Category::getId,jkLine.getCategoryId())
                .eq(Category::getType,Constants.FOUR)
                .eq(Category::getIsdeleted,Constants.ZERO)) ==null){
            throw new BusinessException(ResponseStatus.BAD_REQUEST.getCode(),"对不起,所属主线路不存在,请返回刷新页面查看!");
        }
        jkLine.setEditor(jkLine.getLoginUserInfo().getId());
        jkLine.setEditDate(new Date());
        jkLineMapper.updateById(jkLine);
    }
@@ -80,67 +146,75 @@
    @Override
    public List<JkLine> findList(JkLine jkLine) {
        jkLine.setIsdeleted(Constants.ZERO);
        QueryWrapper<JkLine> wrapper = new QueryWrapper<>(jkLine);
        wrapper.lambda().orderByAsc(JkLine::getCode);
        return jkLineMapper.selectList(wrapper);
    }
  
    @Override
    public PageData<JkLine> findPage(PageWrap<JkLine> pageWrap) {
        IPage<JkLine> page = new Page<>(pageWrap.getPage(), pageWrap.getCapacity());
        QueryWrapper<JkLine> queryWrapper = new QueryWrapper<>();
        MPJLambdaWrapper<JkLine> queryWrapper = new MPJLambdaWrapper<>();
        Utils.MP.blankToNull(pageWrap.getModel());
        pageWrap.getModel().setIsdeleted(Constants.ZERO);
        queryWrapper.selectAll(JkLine.class )
                .selectAs(Cars::getCode,JkLine::getCarCode)
                .selectAs(Category::getName,JkLine::getCategoryName)
                    .leftJoin(Category.class,Category::getId,JkLine::getCategoryId )
                    .leftJoin(Cars.class,Cars::getId,JkLine::getCarId );
        queryWrapper.like(StringUtils.isNotBlank(pageWrap.getModel().getCarCode()),Cars::getCode, pageWrap.getModel().getCarCode());
        queryWrapper.like(StringUtils.isNotBlank(pageWrap.getModel().getCategoryName()),Category::getName, pageWrap.getModel().getCategoryName());
        queryWrapper.like(StringUtils.isNotBlank(pageWrap.getModel().getCode()),JkLine::getCode, pageWrap.getModel().getCode());
        queryWrapper.eq(StringUtils.isNotBlank(pageWrap.getModel().getWeeks()),JkLine::getWeeks, pageWrap.getModel().getWeeks());
        if (pageWrap.getModel().getId() != null) {
            queryWrapper.lambda().eq(JkLine::getId, pageWrap.getModel().getId());
            queryWrapper.eq(JkLine::getId, pageWrap.getModel().getId());
        }
        if (pageWrap.getModel().getCreator() != null) {
            queryWrapper.lambda().eq(JkLine::getCreator, pageWrap.getModel().getCreator());
            queryWrapper.eq(JkLine::getCreator, pageWrap.getModel().getCreator());
        }
        if (pageWrap.getModel().getCreateDate() != null) {
            queryWrapper.lambda().ge(JkLine::getCreateDate, Utils.Date.getStart(pageWrap.getModel().getCreateDate()));
            queryWrapper.lambda().le(JkLine::getCreateDate, Utils.Date.getEnd(pageWrap.getModel().getCreateDate()));
            queryWrapper.ge(JkLine::getCreateDate, Utils.Date.getStart(pageWrap.getModel().getCreateDate()));
            queryWrapper.le(JkLine::getCreateDate, Utils.Date.getEnd(pageWrap.getModel().getCreateDate()));
        }
        if (pageWrap.getModel().getEditor() != null) {
            queryWrapper.lambda().eq(JkLine::getEditor, pageWrap.getModel().getEditor());
            queryWrapper.eq(JkLine::getEditor, pageWrap.getModel().getEditor());
        }
        if (pageWrap.getModel().getEditDate() != null) {
            queryWrapper.lambda().ge(JkLine::getEditDate, Utils.Date.getStart(pageWrap.getModel().getEditDate()));
            queryWrapper.lambda().le(JkLine::getEditDate, Utils.Date.getEnd(pageWrap.getModel().getEditDate()));
            queryWrapper.ge(JkLine::getEditDate, Utils.Date.getStart(pageWrap.getModel().getEditDate()));
            queryWrapper.le(JkLine::getEditDate, Utils.Date.getEnd(pageWrap.getModel().getEditDate()));
        }
        if (pageWrap.getModel().getIsdeleted() != null) {
            queryWrapper.lambda().eq(JkLine::getIsdeleted, pageWrap.getModel().getIsdeleted());
            queryWrapper.eq(JkLine::getIsdeleted, pageWrap.getModel().getIsdeleted());
        }
        if (pageWrap.getModel().getInfo() != null) {
            queryWrapper.lambda().eq(JkLine::getInfo, pageWrap.getModel().getInfo());
            queryWrapper.eq(JkLine::getInfo, pageWrap.getModel().getInfo());
        }
        if (pageWrap.getModel().getName() != null) {
            queryWrapper.lambda().eq(JkLine::getName, pageWrap.getModel().getName());
            queryWrapper.like(JkLine::getName, pageWrap.getModel().getName());
        }
        if (pageWrap.getModel().getCategoryId() != null) {
            queryWrapper.lambda().eq(JkLine::getCategoryId, pageWrap.getModel().getCategoryId());
            queryWrapper.eq(JkLine::getCategoryId, pageWrap.getModel().getCategoryId());
        }
        if (pageWrap.getModel().getCarId() != null) {
            queryWrapper.lambda().eq(JkLine::getCarId, pageWrap.getModel().getCarId());
            queryWrapper.eq(JkLine::getCarId, pageWrap.getModel().getCarId());
        }
        if (pageWrap.getModel().getMaxCustomer() != null) {
            queryWrapper.lambda().eq(JkLine::getMaxCustomer, pageWrap.getModel().getMaxCustomer());
            queryWrapper.eq(JkLine::getMaxCustomer, pageWrap.getModel().getMaxCustomer());
        }
        if (pageWrap.getModel().getMaxOrder() != null) {
            queryWrapper.lambda().eq(JkLine::getMaxOrder, pageWrap.getModel().getMaxOrder());
            queryWrapper.eq(JkLine::getMaxOrder, pageWrap.getModel().getMaxOrder());
        }
        if (pageWrap.getModel().getStatus() != null) {
            queryWrapper.lambda().eq(JkLine::getStatus, pageWrap.getModel().getStatus());
            queryWrapper.eq(JkLine::getStatus, pageWrap.getModel().getStatus());
        }
        if (pageWrap.getModel().getSortnum() != null) {
            queryWrapper.lambda().eq(JkLine::getSortnum, pageWrap.getModel().getSortnum());
            queryWrapper.eq(JkLine::getSortnum, pageWrap.getModel().getSortnum());
        }
        for(PageWrap.SortData sortData: pageWrap.getSorts()) {
            if (sortData.getDirection().equalsIgnoreCase(PageWrap.DESC)) {
                queryWrapper.orderByDesc(sortData.getProperty());
            } else {
                queryWrapper.orderByAsc(sortData.getProperty());
            }
        }
        return PageData.from(jkLineMapper.selectPage(page, queryWrapper));
        queryWrapper.orderByAsc(JkLine::getCode);
        IPage<JkLine> result = jkLineMapper.selectJoinPage(page, JkLine.class,queryWrapper);
        return PageData.from(result);
    }
    @Override
@@ -148,4 +222,184 @@
        QueryWrapper<JkLine> wrapper = new QueryWrapper<>(jkLine);
        return jkLineMapper.selectCount(wrapper);
    }
    @Override
    @Transactional(rollbackFor = {BusinessException.class,Exception.class})
    public List<JkLine> importBatch(MultipartFile file, LoginUserInfo loginUserInfo){
        Boolean importing = (Boolean) redisTemplate.opsForValue().get(Constants.RedisKeys.IMPORTING_JKLINE);
        if(importing!=null && importing){
            throw new BusinessException(ResponseStatus.BAD_REQUEST.getCode(),"对不起,已存在导入任务正在执行中,请稍后再试!");
        }
        redisTemplate.opsForValue().set(Constants.RedisKeys.IMPORTING_JKLINE,true);
        try {
            ExcelImporter ie = null;
            List<JkLineImport> dataList =null;
            try {
                ie = new ExcelImporter(file,1,0);
                dataList = ie.getDataList(JkLineImport.class,null);
            }  catch (Exception e) {
                e.printStackTrace();
            }
            if(dataList == null || dataList.size() ==0){
                throw new BusinessException(ResponseStatus.BAD_REQUEST.getCode(),"对不起,录入数据为空!");
            }
            //当前所有线路
            List<JkLine> allList =  jkLineMapper.selectJoinList(JkLine.class,new MPJLambdaWrapper<JkLine>()
                    .selectAll(JkLine.class)
                    .eq(JkLine::getIsdeleted,Constants.ZERO)
            );
            //所有主线路
            List<Category> categoryList =  categoryMapper.selectJoinList(Category.class,new MPJLambdaWrapper<Category>()
                    .selectAll(Category.class)
                    .eq(Category::getIsdeleted,Constants.ZERO)
                    .eq(Category::getType,Constants.FOUR)
            );
            //所有物流车车辆
            List<Cars> cars =  carsMapper.selectJoinList(Cars.class,new MPJLambdaWrapper<Cars>()
                    .selectAll(Cars.class)
                    .eq(Cars::getIsdeleted,Constants.ZERO)
//                    .eq(Cars::getType,Constants.ONE)
            );
            List<JkLine> newList = new ArrayList<>();
            List<JkLine> updateList = new ArrayList<>();
            for(int i=0;i<dataList.size();i++){
                JkLineImport model = dataList.get(i);
                if(StringUtils.isBlank(model.getName())
                        &&StringUtils.isBlank(model.getCategoryName())
                        &&StringUtils.isBlank(model.getCarCode())
                        &&StringUtils.isBlank(model.getWeeks())
                        &&StringUtils.isBlank(model.getCode())
                        &&StringUtils.isBlank(model.getMaxCustomer())
                        &&StringUtils.isBlank(model.getMaxOrder()) ){
                    continue;
                }
                checkModelParam(model,newList,updateList,i,loginUserInfo,allList,categoryList,cars);
            }
            if((newList == null || newList.size() ==0) && updateList.size() == 0){
                throw new BusinessException(ResponseStatus.BAD_REQUEST.getCode(),"对不起,录入有效数据为空!");
            }
            if(newList.size()>0){
                jkLineMapper.insert(newList);
            }
            if(updateList.size()>0){
                for (JkLine c : updateList){
                    jkLineMapper.updateById(c);
                }
            }
            newList.addAll(updateList);
            return newList;
        }catch (BusinessException e){
            throw e;
        }catch (Exception e){
            e.printStackTrace();
            throw  new BusinessException(ResponseStatus.SERVER_ERROR.getCode(),"信息导入失败,请稍后重试");
        }finally {
            redisTemplate.delete(Constants.RedisKeys.IMPORTING_JKLINE);
        }
    }
    private JkLine checkModelParam(JkLineImport model, List<JkLine> newList
            , List<JkLine> updateList
            ,int index
            ,LoginUserInfo loginUserInfo
            ,List<JkLine> allList
            ,List<Category> categoryList
            , List<Cars> carsList) {
        if(StringUtils.isBlank(model.getName())
                ||StringUtils.isBlank(model.getCategoryName()) ){
            throw  new BusinessException(ResponseStatus.BAD_REQUEST.getCode(),"对不起,第"+(index+3)+"行线路信息不完整,请检查表格内容!");
        }
        for(JkLine param: newList){
            if(StringUtils.isNotBlank(model.getName())&&StringUtils.isNotBlank(param.getName())) {
                if (StringUtils.equals(model.getName(), param.getName())) {
                    throw new BusinessException(ResponseStatus.BAD_REQUEST.getCode(), "对不起,第" + (index + 3) + "行线路名称【" + model.getName() + "】重复出现,请检查表格内容!");
                }
            }
        }
        Category cate = findCategoryFromListByName(model.getCategoryName(),categoryList);
        if(cate == null){
            throw new BusinessException(ResponseStatus.BAD_REQUEST.getCode(), "对不起,第" + (index + 3) + "行所属主线路【" + model.getCategoryName() + "】不存在,请检查表格内容!");
        }
        Cars car = findCarFromListByName(model.getCarCode(),carsList);
        if(car == null){
            throw new BusinessException(ResponseStatus.BAD_REQUEST.getCode(), "对不起,第" + (index + 3) + "行送车车辆【" + model.getCarCode() + "】不存在,请检查表格内容!");
        }
        JkLine line = findModelFromList(model.getName(),allList);
        if(line == null){
            line = new JkLine();
            line.setCreator(loginUserInfo.getId());
            line.setCreateDate(new Date());
            line.setIsnew(Constants.ONE);
            newList.add(line);
        }else{
            line.setIsnew(Constants.ZERO);
            updateList.add(line);
        }
        line.setName(model.getName());
        line.setCode(model.getCode());
        line.setCategoryId(cate.getId());
        line.setCarId(car.getId());
        line.setWeeks(model.getWeeks());
        line.setMaxCustomer(getIntegerByVal(model.getMaxCustomer()));
        line.setMaxOrder(getIntegerByVal(model.getMaxOrder()));
        line.setEditDate(new Date());
        line.setEditor(loginUserInfo.getId());
        line.setIsdeleted(Constants.ZERO);
        return line;
    }
    private Integer getIntegerByVal(String maxCustomer) {
        try {
            return Integer.parseInt(maxCustomer);
        }catch (Exception e){
        }
        return null;
    }
    private Company findCompanyFromList(String companyName, List<Company> companyList) {
        if(companyList !=null){
            for(Company company : companyList){
                if(StringUtils.equals(companyName,company.getCompanyNamePath())){
                    return  company;
                }
            }
        }
        return null;
    }
    private JkLine findModelFromList(String name, List<JkLine> list) {
        if(list !=null){
            for(JkLine model : list){
                if(StringUtils.equals(name,model.getName())){
                    return  model;
                }
            }
        }
        return null;
    }
    private Category findCategoryFromListByName(String name, List<Category> list) {
        if(list !=null){
            for(Category model : list){
                if(StringUtils.equals(name,model.getName())){
                    return model;
                }
            }
        }
        return null;
    }
    private Cars findCarFromListByName(String name, List<Cars> list) {
        if(list !=null){
            for(Cars model : list){
                if(StringUtils.equals(name,model.getCode())){
                    return model;
                }
            }
        }
        return null;
    }
}