|
<template>
|
<div class="page-list-container">
|
<!--数据Table-->
|
<yrt-data-list :ref="dataListRef" :editor-ref="editorRef" :data-options="dataOptions" :fields.sync="dataListOptions.fields" :buttons="dataListOptions.buttons" :button-click="buttonClick" :data-list-selections.sync="dataListSelections" :auth-nodes="authNodes">
|
<template slot="common-column-slot" slot-scope="{row, col}">
|
<template v-if="col.prop=='statusText'">
|
<template>
|
<el-tag v-if="row[col.prop]=='确认出库'" color="#00fa9a" style="color:white;border:0">
|
{{ row[col.prop] }}
|
</el-tag>
|
<el-tag v-else-if="row[col.prop]=='终止'" color="#ff0066" style="color:white;border:0">
|
{{ row[col.prop] }}
|
</el-tag>
|
<el-tag v-else color="#ffff99" style="color:#888;">
|
{{ row[col.prop] }}
|
</el-tag>
|
</template>
|
</template>
|
<!--审核字段-->
|
<template v-else-if="col.prop=='auditing'">
|
<template>
|
<el-tag v-if="row[col.prop]==0" color="#ffff33" style="color:black;border:0">
|
{{ dataList.translateText(col.prop, row[col.prop], col.dropdown_Id) }}
|
</el-tag>
|
<el-tag v-else-if="row[col.prop]==1" color="#ff0033" style="color:white;border:0">
|
{{ dataList.translateText(col.prop, row[col.prop], col.dropdown_Id) }}
|
</el-tag>
|
<el-tag v-else-if="row[col.prop]==2" color="#33cc33" style="color:black;border:0;color:#fff;">
|
{{ dataList.translateText(col.prop, row[col.prop], col.dropdown_Id) }}
|
</el-tag>
|
<span v-else>
|
{{ row[col.prop] }}
|
</span>
|
</template>
|
</template>
|
<!--分拣状态字段-->
|
<template v-else-if="col.prop == 'sortingStatus'">
|
<template>
|
<el-tag v-if="row[col.prop] == 1" color="#ffff33" style="color:black;border:0">
|
{{ dataList.translateText( col.prop, row[col.prop], col.dropdown_Id ) }}
|
</el-tag>
|
<el-tag v-else-if="row[col.prop] == 2" color="#00ff99" style="color:black;border:0">
|
{{ dataList.translateText( col.prop, row[col.prop], col.dropdown_Id ) }}
|
</el-tag>
|
<el-tag v-else-if="row[col.prop] == 3" color="#ff0000" style="color:black;border:0;color:#fff;">
|
{{ dataList.translateText( col.prop, row[col.prop], col.dropdown_Id ) }}
|
</el-tag>
|
<el-tag v-else-if="row[col.prop] == 5" color="#6699FF" style="color:black;border:0;color:#fff;">
|
{{ dataList.translateText( col.prop, row[col.prop], col.dropdown_Id ) }}
|
</el-tag>
|
<span v-else>
|
{{ row[col.prop] }}
|
</span>
|
</template>
|
</template>
|
<!--连接字段-->
|
<template v-else-if="col.prop==dataOptions.linkColumn">
|
<el-link type="primary" @click.native="()=>{linkEditor(row[dataOptions.idField]);}">{{ row[col.prop] }}</el-link>
|
</template>
|
<template v-else>
|
<template v-if="['date', 'datetime'].indexOf(col.dataType)>=0 && col.formatter">
|
{{ common.formatDate(row[col.prop], col.formatter) }}
|
</template>
|
<template v-else-if="['byte', 'int32', 'int64', 'decimal', 'double'].indexOf(col.dataType)>=0 && col.formatter">
|
{{ common.formatNumber(row[col.prop], col.formatter) }}
|
</template>
|
<template v-else>
|
{{ row[col.prop] }}
|
</template>
|
</template>
|
</template>
|
</yrt-data-list>
|
|
<!--数据编辑器Editor-->
|
<yrt-editor :ref="editorRef" :data-list-ref="dataListRef" v-bind="editorOptions" :data-options="dataOptions" :action.sync="editorOptions.action" :top.sync="editorOptions.top" :visible.sync="editorOptions.config.visible" :detail-button-click="detailButtonClick" :auth-nodes="authNodes" :on-save-before="onSaveBefore" :btn-read-only="btnReadOnly" @on-add-load-after="onEditLoadAfter" @on-edit-load-after="onEditLoadAfter" @on-detail-change="onDetailChange" @on-row-change="onRowChange">
|
<!--自定义按钮插槽-->
|
<template slot="footer-button-region" slot-scope="{ formData }">
|
<el-button :disabled="btnReadOnly.sorting" type="success" icon="el-icon-yrt-shuaxin" @click.native="multiBatchSort(formData)">分拣</el-button>
|
<!--自定义审核按钮-->
|
<el-button :disabled="btnReadOnly.confirm" type="success" icon="el-icon-yrt-qiyong" @click.native="onConfirm(formData)">确认出库</el-button>
|
</template>
|
</yrt-editor>
|
|
<el-dialog v-dialogDrag :visible.sync="dialogImport" width="600px" class="import-dialog-container">
|
<el-form>
|
<el-upload ref="upload" :on-preview="handlePreview" :on-remove="handleRemove" :on-success="handleSuccess" :file-list="fileList" :auto-upload="true" :action="upLoadUrl()" :limit="1" class="upload-bill">
|
<el-button slot="trigger" size="small" type="primary">选取文件</el-button>
|
<el-button style="margin-left: 10px;" size="small" type="success" @click="submitImport()">开始导入</el-button>
|
<el-button style="margin-left: 10px;" size="small" type="primary" plain>
|
<a :href="common.ossDomain+'/node-wms/template/其他出库导入模板.xlsx'" style="color:while;font-size:12px;">下载模板</a>
|
</el-button>
|
<div slot="tip" class="el-upload__tip">只能上传扩展名为.xlsx的excel文件</div>
|
</el-upload>
|
</el-form>
|
<el-scrollbar ref="scrollbar" :noresize="false" :native="false" wrap-class="scrollbar-wrap">
|
<ul class="msg-container">
|
<li v-for="(item, index) in msgList" :key="index" class="msg-item" v-html="item">
|
{{ index + 1 }}、{{ item }}
|
</li>
|
</ul>
|
</el-scrollbar>
|
<div ref="loading"></div>
|
</el-dialog>
|
|
<!--明细选择器-->
|
<yrt-selector ref="selector-position-dialog" :config="selectorPositionConfig" :visible.sync="selectorPositionConfig.visible" :url="selectorPositionConfig.url" :set-search-default="setSearchDefault" :get-custom-where="getCustomWhere" @on-selected="onPositionSelected">
|
<template slot="search-form-item">
|
<el-select v-model="operationType" splaceholder="账面库存量" class="w-150">
|
<el-option label="库存大于0" value=">0">
|
</el-option>
|
<el-option label="库存大于等于0" value=">=0">
|
</el-option>
|
<el-option label="库存等于0" value="=0">
|
</el-option>
|
<el-option label="全部" value="">
|
</el-option>
|
</el-select>
|
</template>
|
</yrt-selector>
|
</div>
|
</template>
|
|
<script>
|
import baseLayout from "@/components/common/base-layout.vue";
|
import yrtSelector from "@/components/common/yrtSelector.vue";
|
// import outerImport from "./components/outer-import.vue";
|
export default {
|
name: "storage-operation-outer",
|
components: {
|
yrtSelector
|
// outerImport
|
},
|
mixins: [baseLayout],
|
data() {
|
return {
|
selectorConfig: {
|
title: "物料选择器",
|
width: "1000px",
|
visible: false,
|
// 配置路由
|
router: "/selector/s-product-selector",
|
// 编辑规则验证
|
rules: {
|
positionType: [{ required: true, message: "请选择货位类型", trigger: "blur" }]
|
}
|
},
|
selectorPositionConfig: {
|
title: "物料库存选择器",
|
width: "1000px",
|
visible: false,
|
// 配置路由
|
router: "/selector/x-product-selector",
|
url: "/api/common/GroupDataList"
|
},
|
// 导入页面是否显示
|
outerimportVisible: false,
|
// 库存值操作符
|
operationType: null,
|
|
// 显示审核对话框
|
auditVisible: false,
|
// 正在审核
|
isAuditing: false,
|
// 消息内容
|
msgList: [],
|
|
// 弹出导入框
|
dialogImport: false,
|
fileList: [],
|
|
// 导入获得消息interval handle
|
intervalHandler: null,
|
// 文件名
|
fileUrl: null,
|
// 导入key
|
uploadKey: null
|
};
|
},
|
// 自定义初始化数据
|
init(the) {
|
var userInfo = the.common.getUserInfo();
|
// 设置经手人不是超级管理员,不允许编辑
|
if (!userInfo.isAdministrator) {
|
the.editorOptions.fields.forEach(cols => {
|
cols.columns &&
|
cols.columns.forEach(col => {
|
col.fields.forEach(item => {
|
if (item.options.prop === "UserTrueName") {
|
item.options.disabled = true;
|
}
|
});
|
});
|
});
|
}
|
},
|
mounted() {
|
this.uploadKey = this.common.getGUID();
|
},
|
methods: {
|
// 列表页面按钮点击事件
|
buttonClick(authNode) {
|
switch (authNode) {
|
case "import":
|
// 导入
|
this.import();
|
return true;
|
case "print":
|
// 打印
|
this.print();
|
break;
|
}
|
},
|
// 自定义查询条件改变
|
getCustomWhere(val) {
|
var where = {};
|
if (this.operationType === ">0") {
|
where.productStorage = {
|
operator: ">",
|
value: 0
|
};
|
} else if (this.operationType === ">=0") {
|
where.productStorage = {
|
operator: ">=",
|
value: 0
|
};
|
} else if (this.operationType === "=0") {
|
where.productStorage = {
|
operator: "=",
|
value: 0
|
};
|
}
|
return where;
|
},
|
// 明细按钮点击事件
|
detailButtonClick(authNode) {
|
switch (authNode) {
|
case "detailAdd":
|
// 明细添加
|
this.openPositionSelected();
|
return true;
|
}
|
},
|
// 打开库存选择器
|
openPositionSelected() {
|
var editorRef = this.editor;
|
if (!editorRef.formData.consignorName) {
|
this.$message({
|
message: "请选择货主!",
|
type: "warning"
|
});
|
return;
|
}
|
const selector = this.$refs["selector-position-dialog"];
|
selector.setSearchValue("consignor_Id", [editorRef.formData.consignor_Id]);
|
selector.setSearchValue("storage_Id", [editorRef.formData.storage_Id]);
|
if (editorRef.formData.positionType) {
|
selector.setSearchValue("positionType", [editorRef.formData.positionType]);
|
}
|
selector.setReadOnly("storage_Id", true); // 设为只读
|
selector.setReadOnly("consignor_Id", true); // 设为只读
|
selector.loadData();
|
this.selectorPositionConfig.visible = true;
|
},
|
// 将选择器选择中的数据填充到明细表中
|
onPositionSelected(rows) {
|
rows.forEach(item => {
|
item.weight = 0;
|
if (item.productStorage !== 0 && item.totalWeight) {
|
item.weight = Math.Round(item.totalWeight / item.productStorage, 2);
|
item.totalWeight = 0;
|
item.quantity = item.usingStorage;
|
}
|
});
|
this.editor.addDetailDataRow(rows);
|
this.selectorPositionConfig.visible = false;
|
},
|
// 批量分拣
|
multiBatchSort(formData) {
|
this.$confirm("请点击“开始分拣”按钮进行出库单分拣,判断库存是否满足出库?", "分拣", {
|
confirmButtonText: "开始分拣",
|
cancelButtonText: "取消",
|
type: "warning"
|
}).then(() => {
|
if (!formData.outer_Id) {
|
this.$message({
|
message: "当前数据没有保存!",
|
type: "warning"
|
});
|
return;
|
}
|
const the = this;
|
this.isAuditing = true;
|
if (formData.statusText !== "新建") {
|
this.$message({
|
message: "只有新建状态才允许审核操作!",
|
type: "warning"
|
});
|
return;
|
}
|
const url = "/api/storage/outer/startSorting";
|
const outer_Id = formData.outer_Id;
|
const params = {
|
outer_Id: outer_Id
|
};
|
var callback = res => {
|
the.common.showMsg(res);
|
if (res.msg) {
|
this.dataList.reload();
|
this.editorOptions.config.visible = false;
|
}
|
};
|
this.common.ajax(url, params, callback, true);
|
});
|
},
|
// 开始审核
|
onConfirm(formData) {
|
this.$confirm("请点击“确认出库”按钮进行出库?", "确认出库", {
|
confirmButtonText: "确认出库",
|
cancelButtonText: "取消",
|
type: "warning"
|
}).then(() => {
|
if (!formData.outer_Id) {
|
this.$message({
|
message: "当前数据没有保存!",
|
type: "warning"
|
});
|
return;
|
}
|
const the = this;
|
this.isAuditing = true;
|
if (formData.sortingStatus !== 2) {
|
this.$message({
|
message: "只有分拣成功状态允许确认出库操作!",
|
type: "warning"
|
});
|
return;
|
}
|
const url = "/api/storage/outer/onConfirm";
|
const outer_Id = formData.outer_Id;
|
const params = {
|
outer_Id: outer_Id
|
};
|
var callback = res => {
|
the.common.showMsg(res);
|
if (res.msg) {
|
this.dataList.reload();
|
this.editorOptions.config.visible = false;
|
}
|
};
|
this.common.ajax(url, params, callback, true);
|
});
|
},
|
// 点击文件时的钩子
|
handlePreview(file) {},
|
handleRemove(file, fileList) {
|
this.fileUrl = null;
|
},
|
// 上传附件Url
|
upLoadUrl: function() {
|
var domain = this.common.domain;
|
return domain + "/api/common/uploadSingleFile";
|
},
|
// 上传成功后
|
handleSuccess(res, file) {
|
this.common.showMsg("上传成功!");
|
this.fileUrl = res.data.url;
|
},
|
// 导入
|
submitImport() {
|
if (!this.fileUrl) {
|
this.$message.error("请上传文件!");
|
return;
|
}
|
this.msgList = [];
|
const url = "/api/storage/outer/importExcel";
|
const params = {
|
url: this.fileUrl,
|
key: this.uploadKey
|
};
|
var callback = res => {
|
if (res.result) {
|
window.clearTimeout(this.intervalHandler);
|
this.intervalHandler = false;
|
this.getMsg();
|
this.fileList = [];
|
}
|
};
|
this.common.ajax(url, params, callback, true);
|
},
|
// 获得导入消息
|
getMsg() {
|
// 获得同步消息
|
const url = "/api/common/getUploadMsg";
|
const params = {
|
openNodeApi: true,
|
key: this.uploadKey
|
};
|
// const ref = this.dataList;
|
var callBack = res => {
|
// 自动滚动到最后一行
|
window.setTimeout(() => {
|
const div = this.$refs.scrollbar.$refs.wrap;
|
div.scrollTop = div.scrollHeight + 1000;
|
}, 1500);
|
if (!res.result) {
|
window.clearTimeout(this.intervalHandler);
|
this.intervalHandler = false;
|
if (Array.isArray(res.data)) {
|
this.msgList = this.msgList.concat(res.data);
|
}
|
return;
|
}
|
|
if (Array.isArray(res.data)) {
|
this.msgList = this.msgList.concat(res.data.filter(item => item !== "-1"));
|
}
|
if (res.data.indexOf("-1") >= 0) {
|
window.clearTimeout(this.intervalHandler);
|
this.intervalHandler = null;
|
this.dataList.reload();
|
return;
|
}
|
this.intervalHandler = window.setTimeout(this.getMsg, 1000);
|
};
|
this.common.ajax(url, params, callBack, this.$refs.loading);
|
},
|
// 导入
|
import() {
|
this.dialogImport = true;
|
},
|
// 主表数据改变
|
onChange(ref, val, field, formData) {
|
switch (field.options.prop) {
|
case "storageName":
|
this.$refs["selector-position-dialog"].setSearchValue("storageName", formData.storageName);
|
this.$refs["selector-position-dialog"].loadData();
|
break;
|
case "consignorName":
|
this.$refs["selector-position-dialog"].setSearchValue("consignorName", formData.consignorName);
|
this.$refs["selector-position-dialog"].loadData();
|
break;
|
}
|
},
|
// 对选择器默认值操作
|
setSearchDefault(searchData) {},
|
// 保存前事件
|
onSaveBefore(formData) {
|
return this.setTotal();
|
},
|
// 数据加载后
|
onEditLoadAfter(formData) {
|
var statusText = formData.statusText;
|
var sortingStatus = formData.sortingStatus;
|
if (statusText === "确认出库") {
|
this.$set(this.btnReadOnly, "sorting", true);
|
this.$set(this.btnReadOnly, "confirm", true);
|
this.$set(this.btnReadOnly, "stop", true);
|
this.$set(this.btnReadOnly, "open", true);
|
this.editorOptions.config.disabled = true; // 整个对话框不可用
|
} else if (statusText === "终止") {
|
this.$set(this.btnReadOnly, "sorting", true);
|
this.$set(this.btnReadOnly, "confirm", true);
|
this.$set(this.btnReadOnly, "stop", false);
|
this.$set(this.btnReadOnly, "open", true);
|
this.editorOptions.config.disabled = true; // 整个对话框不可用
|
} else if (sortingStatus === 2) {
|
this.$set(this.btnReadOnly, "sorting", true);
|
this.$set(this.btnReadOnly, "confirm", false);
|
this.$set(this.btnReadOnly, "stop", false);
|
this.$set(this.btnReadOnly, "open", true);
|
this.editorOptions.config.disabled = true; // 整个对话框不可用
|
} else {
|
this.$set(this.btnReadOnly, "sorting", false);
|
this.$set(this.btnReadOnly, "confirm", true);
|
this.$set(this.btnReadOnly, "stop", false);
|
this.$set(this.btnReadOnly, "open", true);
|
this.editorOptions.config.disabled = false; // 整个对话框可用
|
}
|
},
|
// 明细字段改变
|
onDetailChange(ref, val, row, field) {
|
this.setTotal();
|
},
|
// 明细求和
|
setTotal() {
|
let hasQty = true; // 预出库数量
|
var formData = this.editor.formData;
|
var detailRows = formData["Storage_OuterList"].rows;
|
let totalWeight = 0;
|
let totalQuantity = 0;
|
let totalMoney = 0;
|
const containerNos = []; // 集装箱号
|
detailRows.forEach(item => {
|
if (item.quantity <= 0 || !item.quantity) {
|
hasQty = false;
|
}
|
if (item.containerNo) {
|
if (!containerNos.find(row => row.containerNo === item.containerNo)) {
|
containerNos.push(item.containerNo);
|
}
|
}
|
item.saleMoney = (item.quantity || 0) * (item.salePrice || 0);
|
item.totalWeight = (item.quantity || 0) * (item.weight || 0);
|
totalWeight += item.totalWeight;
|
|
totalQuantity += item.quantity;
|
totalMoney += item.saleMoney;
|
});
|
const containerNo = Array.from(new Set(containerNos)).join(",");
|
this.editor.changeValue("totalWeight", totalWeight);
|
this.editor.changeValue("totalQuantity", totalQuantity);
|
this.editor.changeValue("totalMoney", totalMoney);
|
this.editor.changeValue("containerNo", containerNo);
|
if (!hasQty) {
|
this.$message({
|
message: "明细列表的数量必须大于0!",
|
type: "warning"
|
});
|
return false;
|
}
|
},
|
|
// 记录打印次数
|
print() {
|
var ids = [];
|
this.dataListSelections.forEach(item => {
|
ids.push(item[this.dataOptions.idField]);
|
});
|
if (!ids.length) {
|
this.$message.error("至少选择一项!");
|
return;
|
}
|
const url = "/api/storage/outer/print";
|
const params = {
|
ids: ids
|
};
|
this.common.ajax(url, params, res => {
|
this.common.showMsg(res);
|
if (res.result) {
|
this.dataList.reload();
|
}
|
});
|
},
|
// 表格下拉框字段改变事件
|
onRowChange(ref, val, field) {
|
// 货主和仓库改变
|
if (["consignorName", "storageName"].indexOf(field.options.prop) >= 0) {
|
window.setTimeout(() => {
|
this.getDefaultItems();
|
}, 200);
|
}
|
},
|
// 获取一次性收费项默认值
|
getDefaultItems() {
|
const formData = this.editor.formData;
|
if (formData.feeItem_Ids && this.editorOptions.config.action !== "add") return; // 已经有值了不在设置默认值
|
|
const url = "/api/finance/baseOneCharge/getDefaultItems";
|
const params = {
|
associatedTasks: "出库单",
|
consignor_Id: formData.consignor_Id,
|
storage_Id: formData.storage_Id
|
};
|
this.common.ajax(url, params, res => {
|
this.common.showMsg(res);
|
if (res.result) {
|
this.$set(formData, "feeItem_Ids", res.data);
|
}
|
});
|
}
|
}
|
};
|
</script>
|
|
<style lang="scss" scoped>
|
.box-card {
|
.upload-bill {
|
width: 480px;
|
.el-upload__tip {
|
margin-top: 20px;
|
}
|
}
|
/deep/ .scrollbar-wrap {
|
max-height: 400px !important;
|
margin-top: 10px;
|
font-size: 14px;
|
.msg-container {
|
margin: 0;
|
padding: 0;
|
.msg-item {
|
margin: 0;
|
padding: 5px 0;
|
word-wrap: break-word;
|
}
|
}
|
}
|
}
|
|
.import-dialog-container {
|
.msg-container {
|
margin: 0;
|
padding: 0;
|
.msg-item {
|
margin: 0;
|
padding: 5px 0;
|
word-wrap: break-word;
|
}
|
}
|
}
|
|
.tip {
|
padding: 8px 16px;
|
background-color: #ecf8ff;
|
border-radius: 4px;
|
border-left: 5px solid #50bfff;
|
margin: 5px 0;
|
}
|
.dialog-info {
|
overflow: hidden;
|
width: 100%;
|
}
|
.dialog-left {
|
float: left;
|
width: 45%;
|
}
|
.dialog-right {
|
margin-left: 30px;
|
float: left;
|
width: 45%;
|
}
|
.deleteRule-span {
|
cursor: pointer;
|
}
|
.page-list-container {
|
min-height: calc(100vh - 110px);
|
overflow: hidden;
|
position: relative;
|
}
|
|
@media screen and (max-height: 900px) {
|
.page-list-container {
|
min-height: 600px;
|
}
|
}
|
</style>
|