| New file |
| | |
| | | -- 将 生成出库任务 菜单挂载到:作业流程 |
| | | -- 说明:执行本脚本后,请在“角色授权”里给对应角色勾选新菜单和“查看”权限。 |
| | | |
| | | SET @wrk_batch_out_parent_id := ( |
| | | SELECT id |
| | | FROM sys_resource |
| | | WHERE code = 'workFlow' AND level = 1 |
| | | ORDER BY id |
| | | LIMIT 1 |
| | | ); |
| | | |
| | | SET @wrk_batch_out_sort := COALESCE( |
| | | ( |
| | | SELECT MAX(COALESCE(sort, 0)) + 1 |
| | | FROM sys_resource |
| | | WHERE resource_id = @wrk_batch_out_parent_id |
| | | AND level = 2 |
| | | ), |
| | | 1 |
| | | ); |
| | | |
| | | INSERT INTO sys_resource(code, name, resource_id, level, sort, status) |
| | | SELECT 'wrkBatchOut/wrkBatchOut.html', '生成出库任务', @wrk_batch_out_parent_id, 2, @wrk_batch_out_sort, 1 |
| | | FROM dual |
| | | WHERE @wrk_batch_out_parent_id IS NOT NULL |
| | | AND NOT EXISTS ( |
| | | SELECT 1 |
| | | FROM sys_resource |
| | | WHERE code = 'wrkBatchOut/wrkBatchOut.html' AND level = 2 |
| | | ); |
| | | |
| | | UPDATE sys_resource |
| | | SET name = '生成出库任务', |
| | | resource_id = @wrk_batch_out_parent_id, |
| | | level = 2, |
| | | sort = @wrk_batch_out_sort, |
| | | status = 1 |
| | | WHERE code = 'wrkBatchOut/wrkBatchOut.html' AND level = 2; |
| | | |
| | | SET @wrk_batch_out_id := ( |
| | | SELECT id |
| | | FROM sys_resource |
| | | WHERE code = 'wrkBatchOut/wrkBatchOut.html' AND level = 2 |
| | | ORDER BY id |
| | | LIMIT 1 |
| | | ); |
| | | |
| | | INSERT INTO sys_resource(code, name, resource_id, level, sort, status) |
| | | SELECT 'wrkBatchOut/wrkBatchOut.html#view', '查看', @wrk_batch_out_id, 3, 1, 1 |
| | | FROM dual |
| | | WHERE @wrk_batch_out_id IS NOT NULL |
| | | AND NOT EXISTS ( |
| | | SELECT 1 |
| | | FROM sys_resource |
| | | WHERE code = 'wrkBatchOut/wrkBatchOut.html#view' AND level = 3 |
| | | ); |
| | | |
| | | UPDATE sys_resource |
| | | SET name = '查看', |
| | | resource_id = @wrk_batch_out_id, |
| | | level = 3, |
| | | sort = 1, |
| | | status = 1 |
| | | WHERE code = 'wrkBatchOut/wrkBatchOut.html#view' AND level = 3; |
| | | |
| | | SELECT id, code, name, resource_id, level, sort, status |
| | | FROM sys_resource |
| | | WHERE code IN ( |
| | | 'wrkBatchOut/wrkBatchOut.html', |
| | | 'wrkBatchOut/wrkBatchOut.html#view' |
| | | ) |
| | | ORDER BY level, sort, id; |
| New file |
| | |
| | | (function () { |
| | | function createSearchForm() { |
| | | return { |
| | | loc_no: "", |
| | | barcode: "", |
| | | row1: "", |
| | | bay1: "", |
| | | lev1: "", |
| | | loc_type: "", |
| | | qr_code_value: "" |
| | | }; |
| | | } |
| | | |
| | | function createForm() { |
| | | return { |
| | | staNo: "", |
| | | taskPri: 100 |
| | | }; |
| | | } |
| | | |
| | | function createBatchNo() { |
| | | var now = new Date(); |
| | | var pad = function (value) { |
| | | return value < 10 ? "0" + value : String(value); |
| | | }; |
| | | return "MANUAL_OUT_" + now.getFullYear() |
| | | + pad(now.getMonth() + 1) |
| | | + pad(now.getDate()) |
| | | + pad(now.getHours()) |
| | | + pad(now.getMinutes()) |
| | | + pad(now.getSeconds()); |
| | | } |
| | | |
| | | function listSelectedLocNos(selectedLocMap, selectedLocOrder) { |
| | | return selectedLocOrder.filter(function (locNo) { |
| | | return !!selectedLocMap[locNo]; |
| | | }); |
| | | } |
| | | |
| | | function buildOutStationsFromDevps(records) { |
| | | var stationMap = {}; |
| | | var stationList = []; |
| | | |
| | | (records || []).forEach(function (record) { |
| | | var outStations = record["outStationList$"] || []; |
| | | outStations.forEach(function (station) { |
| | | var stationId = station && station.stationId; |
| | | if (!stationId || stationMap[stationId]) { |
| | | return; |
| | | } |
| | | stationMap[stationId] = true; |
| | | stationList.push({ |
| | | stationId: stationId, |
| | | deviceNo: station.deviceNo, |
| | | stationLev: station.stationLev |
| | | }); |
| | | }); |
| | | }); |
| | | |
| | | stationList.sort(function (left, right) { |
| | | return Number(left.stationId) - Number(right.stationId); |
| | | }); |
| | | return stationList; |
| | | } |
| | | |
| | | new Vue({ |
| | | el: "#app", |
| | | data: function () { |
| | | return { |
| | | loading: false, |
| | | stationLoading: false, |
| | | submitting: false, |
| | | advancedVisible: false, |
| | | tableData: [], |
| | | outStationOptions: [], |
| | | searchForm: createSearchForm(), |
| | | form: createForm(), |
| | | page: { |
| | | curr: 1, |
| | | limit: 30, |
| | | total: 0 |
| | | }, |
| | | selectedLocMap: {}, |
| | | selectedLocOrder: [], |
| | | restoringSelection: false, |
| | | layoutTimer: null |
| | | }; |
| | | }, |
| | | computed: { |
| | | selectedLocNos: function () { |
| | | return listSelectedLocNos(this.selectedLocMap, this.selectedLocOrder); |
| | | }, |
| | | selectedCount: function () { |
| | | return this.selectedLocNos.length; |
| | | }, |
| | | selectedPreviewLocNos: function () { |
| | | return this.selectedLocNos.slice(0, 18); |
| | | }, |
| | | selectedPreviewOverflow: function () { |
| | | return Math.max(0, this.selectedCount - this.selectedPreviewLocNos.length); |
| | | }, |
| | | tableHeight: function () { |
| | | return this.advancedVisible ? "calc(100vh - 410px)" : "calc(100vh - 350px)"; |
| | | } |
| | | }, |
| | | created: function () { |
| | | this.loadOutStations(); |
| | | this.loadTable(); |
| | | }, |
| | | beforeDestroy: function () { |
| | | if (this.layoutTimer) { |
| | | clearTimeout(this.layoutTimer); |
| | | this.layoutTimer = null; |
| | | } |
| | | }, |
| | | methods: { |
| | | requestTableLayout: function (delay) { |
| | | var vm = this; |
| | | if (vm.layoutTimer) { |
| | | clearTimeout(vm.layoutTimer); |
| | | } |
| | | vm.$nextTick(function () { |
| | | vm.layoutTimer = setTimeout(function () { |
| | | if (vm.$refs.dataTable && typeof vm.$refs.dataTable.doLayout === "function") { |
| | | vm.$refs.dataTable.doLayout(); |
| | | } |
| | | vm.restoreTableSelection(); |
| | | }, delay || 40); |
| | | }); |
| | | }, |
| | | buildQueryParams: function () { |
| | | var params = { |
| | | curr: this.page.curr, |
| | | limit: this.page.limit, |
| | | status: 1, |
| | | loc_sts: "F", |
| | | orderByField: "locNo", |
| | | orderByType: "asc" |
| | | }; |
| | | var key; |
| | | |
| | | for (key in this.searchForm) { |
| | | if (Object.prototype.hasOwnProperty.call(this.searchForm, key) && this.searchForm[key] !== "" && this.searchForm[key] !== null) { |
| | | params[key] = this.searchForm[key]; |
| | | } |
| | | } |
| | | return params; |
| | | }, |
| | | loadTable: function () { |
| | | var vm = this; |
| | | vm.loading = true; |
| | | $.ajax({ |
| | | url: baseUrl + "/locMast/list/auth", |
| | | headers: { token: localStorage.getItem("token") }, |
| | | method: "GET", |
| | | data: vm.buildQueryParams(), |
| | | success: function (res) { |
| | | if (res.code === 200) { |
| | | vm.tableData = (res.data && res.data.records) || []; |
| | | vm.page.total = (res.data && res.data.total) || 0; |
| | | vm.requestTableLayout(80); |
| | | return; |
| | | } |
| | | if (res.code === 403) { |
| | | top.location.href = baseUrl + "/"; |
| | | return; |
| | | } |
| | | vm.$message.error(res.msg || "库位加载失败"); |
| | | }, |
| | | error: function () { |
| | | vm.$message.error("库位加载失败"); |
| | | }, |
| | | complete: function () { |
| | | vm.loading = false; |
| | | } |
| | | }); |
| | | }, |
| | | loadOutStations: function () { |
| | | var vm = this; |
| | | vm.stationLoading = true; |
| | | $.ajax({ |
| | | url: baseUrl + "/basDevp/list/auth", |
| | | headers: { token: localStorage.getItem("token") }, |
| | | method: "GET", |
| | | data: { |
| | | curr: 1, |
| | | limit: 200, |
| | | status: 1, |
| | | orderByField: "devpNo", |
| | | orderByType: "asc" |
| | | }, |
| | | success: function (res) { |
| | | if (res.code === 200) { |
| | | vm.outStationOptions = buildOutStationsFromDevps((res.data && res.data.records) || []); |
| | | return; |
| | | } |
| | | if (res.code === 403) { |
| | | top.location.href = baseUrl + "/"; |
| | | return; |
| | | } |
| | | vm.$message.error(res.msg || "出库站点加载失败"); |
| | | }, |
| | | error: function () { |
| | | vm.$message.error("出库站点加载失败"); |
| | | }, |
| | | complete: function () { |
| | | vm.stationLoading = false; |
| | | } |
| | | }); |
| | | }, |
| | | formatStationOptionLabel: function (station) { |
| | | var parts = []; |
| | | if (!station) { |
| | | return ""; |
| | | } |
| | | if (station.stationId !== null && station.stationId !== undefined && station.stationId !== "") { |
| | | parts.push("站点" + station.stationId); |
| | | } |
| | | if (station.deviceNo !== null && station.deviceNo !== undefined) { |
| | | parts.push("设备" + station.deviceNo); |
| | | } |
| | | if (station.stationLev !== null && station.stationLev !== undefined) { |
| | | parts.push(station.stationLev + "层"); |
| | | } |
| | | return parts.join(" / "); |
| | | }, |
| | | toggleAdvanced: function () { |
| | | this.advancedVisible = !this.advancedVisible; |
| | | this.requestTableLayout(180); |
| | | }, |
| | | handleSearch: function () { |
| | | this.page.curr = 1; |
| | | this.loadTable(); |
| | | }, |
| | | handleReset: function () { |
| | | this.searchForm = createSearchForm(); |
| | | this.advancedVisible = false; |
| | | this.page.curr = 1; |
| | | this.loadTable(); |
| | | }, |
| | | handleCurrentChange: function (curr) { |
| | | this.page.curr = curr; |
| | | this.loadTable(); |
| | | }, |
| | | handleSizeChange: function (limit) { |
| | | this.page.limit = limit; |
| | | this.page.curr = 1; |
| | | this.loadTable(); |
| | | }, |
| | | handleSelectionChange: function (rows) { |
| | | var vm = this; |
| | | var selectedOnPage = {}; |
| | | |
| | | if (vm.restoringSelection) { |
| | | return; |
| | | } |
| | | |
| | | (rows || []).forEach(function (row) { |
| | | selectedOnPage[row.locNo] = row; |
| | | }); |
| | | |
| | | vm.tableData.forEach(function (row) { |
| | | if (!row || !row.locNo) { |
| | | return; |
| | | } |
| | | if (selectedOnPage[row.locNo]) { |
| | | vm.selectedLocMap[row.locNo] = row; |
| | | if (vm.selectedLocOrder.indexOf(row.locNo) === -1) { |
| | | vm.selectedLocOrder.push(row.locNo); |
| | | } |
| | | } else if (vm.selectedLocMap[row.locNo]) { |
| | | vm.$delete(vm.selectedLocMap, row.locNo); |
| | | } |
| | | }); |
| | | |
| | | vm.selectedLocOrder = vm.selectedLocOrder.filter(function (locNo) { |
| | | return !!vm.selectedLocMap[locNo]; |
| | | }); |
| | | }, |
| | | restoreTableSelection: function () { |
| | | var vm = this; |
| | | if (!vm.$refs.dataTable) { |
| | | return; |
| | | } |
| | | vm.restoringSelection = true; |
| | | vm.$refs.dataTable.clearSelection(); |
| | | vm.tableData.forEach(function (row) { |
| | | if (row && row.locNo && vm.selectedLocMap[row.locNo]) { |
| | | vm.$refs.dataTable.toggleRowSelection(row, true); |
| | | } |
| | | }); |
| | | vm.restoringSelection = false; |
| | | }, |
| | | clearSelectedLocs: function () { |
| | | this.selectedLocMap = {}; |
| | | this.selectedLocOrder = []; |
| | | if (this.$refs.dataTable) { |
| | | this.$refs.dataTable.clearSelection(); |
| | | } |
| | | }, |
| | | removeSelectedLoc: function (locNo) { |
| | | if (!locNo || !this.selectedLocMap[locNo]) { |
| | | return; |
| | | } |
| | | this.$delete(this.selectedLocMap, locNo); |
| | | this.selectedLocOrder = this.selectedLocOrder.filter(function (item) { |
| | | return item !== locNo; |
| | | }); |
| | | this.restoreTableSelection(); |
| | | }, |
| | | submitBatchOutTask: function () { |
| | | var vm = this; |
| | | var batchNo; |
| | | var taskList; |
| | | var locNos = vm.selectedLocNos; |
| | | |
| | | if (!vm.form.staNo) { |
| | | vm.$message.warning("请选择目标站点"); |
| | | return; |
| | | } |
| | | if (!locNos.length) { |
| | | vm.$message.warning("请先勾选至少一个库位"); |
| | | return; |
| | | } |
| | | |
| | | batchNo = createBatchNo(); |
| | | taskList = locNos.map(function (locNo, index) { |
| | | return { |
| | | locNo: locNo, |
| | | staNo: Number(vm.form.staNo), |
| | | taskPri: vm.form.taskPri, |
| | | batch: batchNo, |
| | | batchSeq: index + 1 |
| | | }; |
| | | }); |
| | | |
| | | vm.submitting = true; |
| | | $.ajax({ |
| | | url: baseUrl + "/openapi/createOutTaskBatch", |
| | | contentType: "application/json", |
| | | headers: { token: localStorage.getItem("token") }, |
| | | data: JSON.stringify({ taskList: taskList }), |
| | | method: "POST", |
| | | success: function (res) { |
| | | if (res.code === 200) { |
| | | vm.$message.success("已生成" + locNos.length + "条出库任务"); |
| | | vm.clearSelectedLocs(); |
| | | vm.loadTable(); |
| | | return; |
| | | } |
| | | if (res.code === 403) { |
| | | top.location.href = baseUrl + "/"; |
| | | return; |
| | | } |
| | | vm.$message.error(res.msg || "批量生成出库任务失败"); |
| | | }, |
| | | error: function (xhr) { |
| | | var message = "批量生成出库任务失败"; |
| | | if (xhr && xhr.responseJSON && xhr.responseJSON.msg) { |
| | | message = xhr.responseJSON.msg; |
| | | } |
| | | vm.$message.error(message); |
| | | }, |
| | | complete: function () { |
| | | vm.submitting = false; |
| | | } |
| | | }); |
| | | } |
| | | } |
| | | }); |
| | | })(); |
| | |
| | | saveVisibleColumns(this.visibleColumnKeys); |
| | | this.scheduleTableLayout(); |
| | | }, |
| | | openBatchOutPage: function () { |
| | | window.open(baseUrl + "/views/wrkBatchOut/wrkBatchOut.html", "_blank"); |
| | | }, |
| | | handleRowCommand: function (command, row) { |
| | | if (command === "complete") { |
| | | this.completeTask(row); |
| New file |
| | |
| | | <!DOCTYPE html> |
| | | <html lang="zh-CN"> |
| | | <head> |
| | | <meta charset="UTF-8"> |
| | | <title>批量出库任务</title> |
| | | <meta name="renderer" content="webkit"> |
| | | <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1"> |
| | | <meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1"> |
| | | <link rel="stylesheet" href="../../static/vue/element/element.css"> |
| | | <link rel="stylesheet" href="../../static/css/cool.css"> |
| | | <style> |
| | | :root { |
| | | --card-bg: rgba(255, 255, 255, 0.94); |
| | | --card-border: rgba(216, 226, 238, 0.95); |
| | | --text-main: #243447; |
| | | } |
| | | |
| | | [v-cloak] { |
| | | display: none; |
| | | } |
| | | |
| | | html, |
| | | body { |
| | | margin: 0; |
| | | min-height: 100%; |
| | | color: var(--text-main); |
| | | font-family: "Avenir Next", "PingFang SC", "Microsoft YaHei", sans-serif; |
| | | background: |
| | | radial-gradient(1000px 420px at 0% -10%, rgba(44, 107, 193, 0.12), transparent 56%), |
| | | radial-gradient(900px 400px at 100% 0%, rgba(28, 150, 126, 0.10), transparent 58%), |
| | | linear-gradient(180deg, #f2f6fb 0%, #f8fafc 100%); |
| | | } |
| | | |
| | | .page-shell { |
| | | max-width: 1700px; |
| | | margin: 0 auto; |
| | | padding: 14px; |
| | | box-sizing: border-box; |
| | | } |
| | | |
| | | .card-shell { |
| | | position: relative; |
| | | border-radius: 24px; |
| | | border: 1px solid var(--card-border); |
| | | background: |
| | | radial-gradient(760px 220px at -8% 0%, rgba(43, 117, 196, 0.05), transparent 55%), |
| | | radial-gradient(680px 200px at 108% 10%, rgba(24, 150, 129, 0.05), transparent 58%), |
| | | var(--card-bg); |
| | | box-shadow: 0 16px 32px rgba(44, 67, 96, 0.08); |
| | | overflow: hidden; |
| | | } |
| | | |
| | | .card-body { |
| | | position: relative; |
| | | z-index: 1; |
| | | } |
| | | |
| | | .list-toolbar { |
| | | padding: 12px 16px 10px; |
| | | border-bottom: 1px solid rgba(222, 230, 239, 0.92); |
| | | } |
| | | |
| | | .toolbar-main { |
| | | display: flex; |
| | | align-items: flex-start; |
| | | justify-content: space-between; |
| | | gap: 8px; |
| | | flex-wrap: wrap; |
| | | } |
| | | |
| | | .toolbar-left { |
| | | flex: 1 1 960px; |
| | | display: flex; |
| | | align-items: center; |
| | | gap: 8px; |
| | | flex-wrap: wrap; |
| | | } |
| | | |
| | | .toolbar-search { |
| | | flex: 1 1 auto; |
| | | display: flex; |
| | | align-items: center; |
| | | gap: 8px; |
| | | flex-wrap: wrap; |
| | | } |
| | | |
| | | .toolbar-search-item { |
| | | flex: 0 0 152px; |
| | | min-width: 152px; |
| | | } |
| | | |
| | | .toolbar-search-item.keyword { |
| | | flex: 0 0 220px; |
| | | min-width: 220px; |
| | | } |
| | | |
| | | .toolbar-search-item.station { |
| | | flex: 0 0 230px; |
| | | min-width: 230px; |
| | | } |
| | | |
| | | .toolbar-search-item.priority { |
| | | flex: 0 0 150px; |
| | | min-width: 150px; |
| | | } |
| | | |
| | | .toolbar-query-actions, |
| | | .toolbar-ops { |
| | | display: flex; |
| | | gap: 8px; |
| | | flex-wrap: wrap; |
| | | } |
| | | |
| | | .toolbar-ops { |
| | | justify-content: flex-end; |
| | | align-items: center; |
| | | } |
| | | |
| | | .list-toolbar .el-input__inner, |
| | | .advanced-panel .el-input__inner, |
| | | .list-toolbar .el-input-number, |
| | | .list-toolbar .el-input-number .el-input__inner, |
| | | .advanced-panel .el-input-number .el-input__inner { |
| | | height: 32px; |
| | | line-height: 32px; |
| | | } |
| | | |
| | | .list-toolbar .el-input__icon, |
| | | .advanced-panel .el-input__icon { |
| | | line-height: 32px; |
| | | } |
| | | |
| | | .list-toolbar .el-button, |
| | | .advanced-panel .el-button { |
| | | padding: 8px 12px; |
| | | border-radius: 8px; |
| | | } |
| | | |
| | | .advanced-panel { |
| | | padding: 10px 16px 12px; |
| | | border-bottom: 1px solid rgba(222, 230, 239, 0.92); |
| | | background: rgba(248, 251, 254, 0.78); |
| | | } |
| | | |
| | | .advanced-grid { |
| | | display: grid; |
| | | grid-template-columns: repeat(5, minmax(0, 1fr)); |
| | | gap: 8px; |
| | | } |
| | | |
| | | .advanced-item { |
| | | min-width: 0; |
| | | } |
| | | |
| | | .selection-panel { |
| | | padding: 12px 16px; |
| | | border-bottom: 1px solid rgba(222, 230, 239, 0.92); |
| | | background: rgba(248, 251, 254, 0.78); |
| | | } |
| | | |
| | | .selection-head { |
| | | display: flex; |
| | | align-items: center; |
| | | justify-content: space-between; |
| | | gap: 12px; |
| | | flex-wrap: wrap; |
| | | margin-bottom: 10px; |
| | | } |
| | | |
| | | .selection-title { |
| | | display: flex; |
| | | align-items: center; |
| | | gap: 10px; |
| | | color: #53677d; |
| | | font-size: 13px; |
| | | font-weight: 700; |
| | | } |
| | | |
| | | .selection-tags { |
| | | display: flex; |
| | | flex-wrap: wrap; |
| | | gap: 8px; |
| | | } |
| | | |
| | | .selection-empty { |
| | | color: #8a97a8; |
| | | font-size: 13px; |
| | | line-height: 20px; |
| | | } |
| | | |
| | | .selection-count { |
| | | display: inline-flex; |
| | | align-items: center; |
| | | justify-content: center; |
| | | min-width: 24px; |
| | | padding: 0 8px; |
| | | height: 24px; |
| | | border-radius: 12px; |
| | | background: rgba(64, 158, 255, 0.12); |
| | | color: #2b6cb0; |
| | | font-size: 12px; |
| | | font-weight: 700; |
| | | } |
| | | |
| | | .table-wrap { |
| | | padding: 10px 16px; |
| | | } |
| | | |
| | | .table-shell { |
| | | border-radius: 20px; |
| | | overflow: hidden; |
| | | border: 1px solid rgba(217, 227, 238, 0.98); |
| | | background: rgba(255, 255, 255, 0.95); |
| | | } |
| | | |
| | | .table-shell .el-table { |
| | | border-radius: 20px; |
| | | overflow: hidden; |
| | | } |
| | | |
| | | .table-shell .el-table th { |
| | | background: #f7fafc; |
| | | color: #53677d; |
| | | font-weight: 700; |
| | | } |
| | | |
| | | .payload-cell { |
| | | display: inline-block; |
| | | max-width: 280px; |
| | | white-space: nowrap; |
| | | overflow: hidden; |
| | | text-overflow: ellipsis; |
| | | } |
| | | |
| | | .pager-bar { |
| | | padding: 0 16px 16px; |
| | | display: flex; |
| | | align-items: center; |
| | | justify-content: flex-end; |
| | | } |
| | | |
| | | @media (max-width: 1480px) { |
| | | .advanced-grid { |
| | | grid-template-columns: repeat(4, minmax(0, 1fr)); |
| | | } |
| | | } |
| | | |
| | | @media (max-width: 1180px) { |
| | | .advanced-grid { |
| | | grid-template-columns: repeat(3, minmax(0, 1fr)); |
| | | } |
| | | } |
| | | |
| | | @media (max-width: 900px) { |
| | | .page-shell { |
| | | padding: 10px; |
| | | } |
| | | |
| | | .list-toolbar, |
| | | .advanced-panel, |
| | | .selection-panel, |
| | | .table-wrap, |
| | | .pager-bar { |
| | | padding-left: 12px; |
| | | padding-right: 12px; |
| | | } |
| | | |
| | | .toolbar-search-item, |
| | | .toolbar-search-item.keyword, |
| | | .toolbar-search-item.station, |
| | | .toolbar-search-item.priority { |
| | | flex: 1 1 100%; |
| | | min-width: 100%; |
| | | } |
| | | |
| | | .advanced-grid { |
| | | grid-template-columns: repeat(2, minmax(0, 1fr)); |
| | | } |
| | | } |
| | | |
| | | @media (max-width: 560px) { |
| | | .advanced-grid { |
| | | grid-template-columns: 1fr; |
| | | } |
| | | } |
| | | </style> |
| | | </head> |
| | | <body> |
| | | <div id="app" class="page-shell" v-cloak> |
| | | <section class="card-shell"> |
| | | <div class="card-body"> |
| | | <div class="list-toolbar"> |
| | | <div class="toolbar-main"> |
| | | <div class="toolbar-left"> |
| | | <div class="toolbar-search"> |
| | | <div class="toolbar-search-item keyword"> |
| | | <el-input |
| | | v-model.trim="searchForm.loc_no" |
| | | clearable |
| | | size="small" |
| | | placeholder="库位号" |
| | | @keyup.enter.native="handleSearch"> |
| | | </el-input> |
| | | </div> |
| | | <div class="toolbar-search-item"> |
| | | <el-input |
| | | v-model.trim="searchForm.barcode" |
| | | clearable |
| | | size="small" |
| | | placeholder="托盘码" |
| | | @keyup.enter.native="handleSearch"> |
| | | </el-input> |
| | | </div> |
| | | <div class="toolbar-search-item"> |
| | | <el-input |
| | | v-model.trim="searchForm.row1" |
| | | clearable |
| | | size="small" |
| | | placeholder="排" |
| | | @keyup.enter.native="handleSearch"> |
| | | </el-input> |
| | | </div> |
| | | <div class="toolbar-search-item"> |
| | | <el-input |
| | | v-model.trim="searchForm.bay1" |
| | | clearable |
| | | size="small" |
| | | placeholder="列" |
| | | @keyup.enter.native="handleSearch"> |
| | | </el-input> |
| | | </div> |
| | | <div class="toolbar-search-item"> |
| | | <el-input |
| | | v-model.trim="searchForm.lev1" |
| | | clearable |
| | | size="small" |
| | | placeholder="层" |
| | | @keyup.enter.native="handleSearch"> |
| | | </el-input> |
| | | </div> |
| | | <div class="toolbar-query-actions"> |
| | | <el-button size="small" type="primary" icon="el-icon-search" @click="handleSearch">搜索</el-button> |
| | | <el-button size="small" plain icon="el-icon-refresh-left" @click="handleReset">重置</el-button> |
| | | <el-button size="small" plain :icon="advancedVisible ? 'el-icon-arrow-up' : 'el-icon-arrow-down'" @click="toggleAdvanced"> |
| | | {{ advancedVisible ? '收起' : '筛选' }} |
| | | </el-button> |
| | | </div> |
| | | </div> |
| | | </div> |
| | | <div class="toolbar-ops"> |
| | | <div class="toolbar-search-item station"> |
| | | <el-select |
| | | v-model="form.staNo" |
| | | size="small" |
| | | clearable |
| | | filterable |
| | | :loading="stationLoading" |
| | | placeholder="目标站点" |
| | | style="width: 100%;"> |
| | | <el-option |
| | | v-for="station in outStationOptions" |
| | | :key="'station-' + station.stationId" |
| | | :label="formatStationOptionLabel(station)" |
| | | :value="station.stationId"> |
| | | </el-option> |
| | | </el-select> |
| | | </div> |
| | | <div class="toolbar-search-item priority"> |
| | | <el-input-number |
| | | v-model="form.taskPri" |
| | | size="small" |
| | | :min="1" |
| | | :max="9999" |
| | | controls-position="right" |
| | | style="width: 100%;"> |
| | | </el-input-number> |
| | | </div> |
| | | <el-button size="small" plain icon="el-icon-refresh" :loading="loading" @click="loadTable">刷新库位</el-button> |
| | | <el-button size="small" plain :disabled="selectedCount === 0" @click="clearSelectedLocs">清空已选</el-button> |
| | | <el-button size="small" type="primary" icon="el-icon-s-promotion" :loading="submitting" @click="submitBatchOutTask">生成出库任务</el-button> |
| | | </div> |
| | | </div> |
| | | </div> |
| | | |
| | | <div v-show="advancedVisible" class="advanced-panel"> |
| | | <div class="advanced-grid"> |
| | | <div class="advanced-item"> |
| | | <el-input |
| | | v-model.trim="searchForm.loc_type" |
| | | clearable |
| | | size="small" |
| | | placeholder="库位类型" |
| | | @keyup.enter.native="handleSearch"> |
| | | </el-input> |
| | | </div> |
| | | <div class="advanced-item"> |
| | | <el-input |
| | | v-model.trim="searchForm.qr_code_value" |
| | | clearable |
| | | size="small" |
| | | placeholder="二维码" |
| | | @keyup.enter.native="handleSearch"> |
| | | </el-input> |
| | | </div> |
| | | </div> |
| | | </div> |
| | | |
| | | <div class="selection-panel"> |
| | | <div class="selection-head"> |
| | | <div class="selection-title"> |
| | | <span>已选库位</span> |
| | | <span class="selection-count">{{ selectedCount }}</span> |
| | | </div> |
| | | </div> |
| | | <div v-if="selectedPreviewLocNos.length" class="selection-tags"> |
| | | <el-tag |
| | | v-for="locNo in selectedPreviewLocNos" |
| | | :key="'selected-' + locNo" |
| | | closable |
| | | size="small" |
| | | @close="removeSelectedLoc(locNo)"> |
| | | {{ locNo }} |
| | | </el-tag> |
| | | <el-tag v-if="selectedPreviewOverflow > 0" size="small" type="info"> |
| | | 还有 {{ selectedPreviewOverflow }} 个 |
| | | </el-tag> |
| | | </div> |
| | | <div v-else class="selection-empty"> |
| | | 暂无已选库位 |
| | | </div> |
| | | </div> |
| | | |
| | | <div class="table-wrap"> |
| | | <div class="table-shell"> |
| | | <el-table |
| | | ref="dataTable" |
| | | v-loading="loading" |
| | | :data="tableData" |
| | | border |
| | | stripe |
| | | row-key="locNo" |
| | | :height="tableHeight" |
| | | @selection-change="handleSelectionChange"> |
| | | <el-table-column type="selection" width="52" align="center" :reserve-selection="true"></el-table-column> |
| | | <el-table-column prop="locNo" label="库位号" min-width="150" show-overflow-tooltip></el-table-column> |
| | | <el-table-column prop="barcode" label="托盘码" min-width="180" show-overflow-tooltip></el-table-column> |
| | | <el-table-column label="库位状态" width="110" align="center"> |
| | | <template slot-scope="scope"> |
| | | <el-tag size="mini" type="success">{{ scope.row['locSts$'] || scope.row.locSts || '-' }}</el-tag> |
| | | </template> |
| | | </el-table-column> |
| | | <el-table-column prop="row1" label="排" width="90" align="center"></el-table-column> |
| | | <el-table-column prop="bay1" label="列" width="90" align="center"></el-table-column> |
| | | <el-table-column prop="lev1" label="层" width="90" align="center"></el-table-column> |
| | | <el-table-column prop="locType" label="库位类型" min-width="140" show-overflow-tooltip></el-table-column> |
| | | <el-table-column prop="qrCodeValue" label="二维码" min-width="180" show-overflow-tooltip></el-table-column> |
| | | <el-table-column label="异常说明" min-width="220" show-overflow-tooltip> |
| | | <template slot-scope="scope"> |
| | | <span class="payload-cell">{{ scope.row.errorMemo || '-' }}</span> |
| | | </template> |
| | | </el-table-column> |
| | | </el-table> |
| | | </div> |
| | | </div> |
| | | |
| | | <div class="pager-bar"> |
| | | <el-pagination |
| | | small |
| | | background |
| | | layout="total, sizes, prev, pager, next, jumper" |
| | | :current-page="page.curr" |
| | | :page-size="page.limit" |
| | | :page-sizes="[30, 50, 100, 200, 500]" |
| | | :total="page.total" |
| | | @current-change="handleCurrentChange" |
| | | @size-change="handleSizeChange"> |
| | | </el-pagination> |
| | | </div> |
| | | </div> |
| | | </section> |
| | | </div> |
| | | </body> |
| | | <script type="text/javascript" src="../../static/js/jquery/jquery-3.3.1.min.js"></script> |
| | | <script type="text/javascript" src="../../static/js/common.js?v=20260309_i18n_fix1"></script> |
| | | <script type="text/javascript" src="../../static/vue/js/vue.min.js"></script> |
| | | <script type="text/javascript" src="../../static/vue/element/element.js"></script> |
| | | <script type="text/javascript" src="../../static/js/wrkBatchOut/wrkBatchOut.js?v=20260321_batch_outbound_table_v5"></script> |
| | | </html> |
| | |
| | | </div> |
| | | <el-button slot="reference" size="small" plain icon="el-icon-setting">列设置</el-button> |
| | | </el-popover> |
| | | <el-button size="small" type="primary" plain icon="el-icon-s-promotion" @click="openBatchOutPage">批量出库</el-button> |
| | | <el-button size="small" plain icon="el-icon-refresh" :loading="loading" @click="loadList">刷新</el-button> |
| | | </div> |
| | | </div> |
| | |
| | | <script type="text/javascript" src="../../static/js/common.js?v=20260309_i18n_fix1"></script> |
| | | <script type="text/javascript" src="../../static/vue/js/vue.min.js"></script> |
| | | <script type="text/javascript" src="../../static/vue/element/element.js"></script> |
| | | <script type="text/javascript" src="../../static/js/wrkMast/wrkMast.js?v=20260311_wrk_mast_vue"></script> |
| | | <script type="text/javascript" src="../../static/js/wrkMast/wrkMast.js?v=20260321_batch_outbound_page"></script> |
| | | </html> |