From b680585c3a6d43f0c72a83a115ea537ce8c91a07 Mon Sep 17 00:00:00 2001
From: 647556386 <647556386@qq.com>
Date: 星期六, 13 十二月 2025 17:44:10 +0800
Subject: [PATCH] Merge branch 'master' of http://115.159.85.185:8098/r/ZhongRui/ALDbanyunxiangmu
---
项目资料/数据库字典/ALD_20251212105252.pdf | 0
项目代码/WIDESEA_WMSClient/src/views/stock/stockView.vue | 2
项目代码/WIDESEA_WMSClient/src/extension/inbound/extend/EmptyTrayInbound.vue | 96 ++++-
项目代码/WIDESEA_WMSClient/src/views/basic/locationInfo.vue | 4
项目代码/WIDESEA_WMSClient/src/views/system/Log.vue | 346 +++++++++++++++++++++
项目代码/WMS无仓储版/WIDESEA_WMSServer/WIDESEA_WMSServer/Controllers/System/Sys_LogController.cs | 384 +++++++++++++++++++++++
项目代码/WIDESEA_WMSClient/src/router/viewGird.js | 8
项目代码/WMS无仓储版/WIDESEA_WMSServer/WIDESEA_TaskInfoService/TaskService.cs | 118 ++++---
项目资料/数据库字典/WIDESEAWMS_ALDZhongRui.sql | 0
9 files changed, 880 insertions(+), 78 deletions(-)
diff --git "a/\351\241\271\347\233\256\344\273\243\347\240\201/WIDESEA_WMSClient/src/extension/inbound/extend/EmptyTrayInbound.vue" "b/\351\241\271\347\233\256\344\273\243\347\240\201/WIDESEA_WMSClient/src/extension/inbound/extend/EmptyTrayInbound.vue"
index 7105202..d1914ac 100644
--- "a/\351\241\271\347\233\256\344\273\243\347\240\201/WIDESEA_WMSClient/src/extension/inbound/extend/EmptyTrayInbound.vue"
+++ "b/\351\241\271\347\233\256\344\273\243\347\240\201/WIDESEA_WMSClient/src/extension/inbound/extend/EmptyTrayInbound.vue"
@@ -1,17 +1,17 @@
<template>
<vol-box v-model="show" title="绌烘墭鍏ュ簱" :width="800" :height="1200">
<template #content>
- <el-form ref="form" :model="form" label-width="90px">
- <el-form-item label="鍏ュ簱鍖哄煙:">
+ <el-form ref="form" :model="form" :rules="rules" label-width="90px">
+ <el-form-item label="鍏ュ簱鍖哄煙:" prop="locationType">
<el-select v-model="form.locationType" placeholder="璇烽�夋嫨鍏ュ簱鍖哄煙">
<el-option v-for="item in locationTypes" :key="item.locationType" :label="item.locationTypeDesc"
:value="item.locationType" />
</el-select>
</el-form-item>
- <el-form-item label="鎵樼洏鏉$爜:">
- <el-input v-model="form.palletCode" placeholder="璇锋壂鎻�/杈撳叆鎵樼洏鏉$爜" @keyup.enter="submit" @keyup.13="submit"
- clearable maxlength="50" @paste="handlePaste" @input="handleInput" ref="boxCodeInput" />
+ <el-form-item label="鎵樼洏鏉$爜:" prop="palletCode">
+ <el-input v-model="form.palletCode" placeholder="璇锋壂鎻�/杈撳叆鎵樼洏鏉$爜锛圓寮�澶达紝鍚庤窡鏁板瓧锛�" @keyup.enter="submit" clearable
+ @paste="handlePaste" @input="handleInput" ref="boxCodeInput" />
</el-form-item>
</el-form>
</template>
@@ -34,13 +34,37 @@
value: { type: Boolean, default: false }
},
data() {
+ // 鑷畾涔夋潯鐮侀獙璇佽鍒�
+ const validatePalletCode = (rule, value, callback) => {
+ if (!value) {
+ return callback(new Error('璇疯緭鍏ユ墭鐩樻潯鐮�'));
+ }
+
+ // 楠岃瘉鏉$爜鏍煎紡锛欰寮�澶达紝鍚庨潰鑷冲皯1浣嶆暟瀛楋紙涓嶉檺鍒跺叿浣撻暱搴︼級
+ const codePattern = /^A\d+$/;
+ if (!codePattern.test(value)) {
+ return callback(new Error('鏉$爜鏍煎紡涓嶆纭紒姝g‘鏍煎紡锛欰寮�澶达紝鍚庤窡鏁板瓧锛屽锛欰000008080'));
+ }
+
+ callback();
+ };
+
return {
show: false,
form: {
palletCode: '',
locationType: ''
},
- locationTypes: []
+ locationTypes: [],
+ // 琛ㄥ崟楠岃瘉瑙勫垯
+ rules: {
+ locationType: [
+ { required: true, message: '璇烽�夋嫨鍏ュ簱鍖哄煙', trigger: 'change' }
+ ],
+ palletCode: [
+ { validator: validatePalletCode, trigger: ['blur', 'change'] }
+ ]
+ }
}
},
methods: {
@@ -62,15 +86,13 @@
},
async submit() {
- if (!this.form.palletCode) {
- this.$message.warning('璇疯緭鍏ユ墭鐩樻潯鐮�')
- this.focusInput()
- return
- }
-
- if (!this.form.locationType) {
- this.$message.warning('璇烽�夋嫨鍏ュ簱鍖哄煙')
- return
+ // 琛ㄥ崟楠岃瘉
+ try {
+ await this.$refs.form.validate();
+ } catch (error) {
+ // 楠岃瘉澶辫触锛岃仛鐒﹁緭鍏ユ
+ this.focusAndSelectInput();
+ return;
}
try {
@@ -88,6 +110,8 @@
this.$message.success("缁勭洏鎴愬姛");
// 娓呯┖杈撳叆妗嗘暟鎹�
this.form.palletCode = '';
+ // 閲嶇疆楠岃瘉鐘舵��
+ this.$refs.form.clearValidate('palletCode');
// 鑱氱劍骞堕�変腑杈撳叆妗�
this.focusAndSelectInput();
} else {
@@ -104,15 +128,39 @@
// 鎵弿鏋紭鍖栧鐞�
handleInput(value) {
- // 杩囨护闈炴暟瀛楀拰鏉$爜甯哥敤瀛楃
- this.form.palletCode = value.replace(/[^a-zA-Z0-9\-]/g, '')
+ // 杩囨护闈炴暟瀛楀拰鏉$爜甯哥敤瀛楃锛屽厑璁窤寮�澶�
+ this.form.palletCode = value.replace(/[^a-zA-Z0-9]/g, '')
+
+ // 鑷姩杞崲涓哄ぇ鍐欙紙鏉$爜閫氬父涓哄ぇ鍐欙級
+ this.form.palletCode = this.form.palletCode.toUpperCase();
+
+ // 鑷姩瑙﹀彂楠岃瘉
+ this.$nextTick(() => {
+ this.$refs.form.validateField('palletCode');
+ });
},
handlePaste(e) {
- // 绮樿创鏃惰嚜鍔ㄦ彁浜�
- setTimeout(this.submit, 100)
+ // 鑾峰彇绮樿创鐨勫唴瀹�
+ const clipboardData = e.clipboardData || window.clipboardData;
+ const pastedText = clipboardData.getData('text');
+
+ // 澶勭悊绮樿创鍐呭
+ const cleanedText = pastedText.replace(/[^a-zA-Z0-9]/g, '').toUpperCase();
+
+ // 濡傛灉绮樿创鍐呭绗﹀悎鏉$爜鏍煎紡锛岃嚜鍔ㄥ~鍏呭苟鎻愪氦
+ if (cleanedText.startsWith('A')) {
+ this.form.palletCode = cleanedText;
+ // 寤惰繜鎻愪氦锛岀‘淇濊〃鍗曞凡鏇存柊
+ setTimeout(() => {
+ this.submit();
+ }, 50);
+ }
+
+ // 闃绘榛樿绮樿创琛屼负锛屼娇鐢ㄦ垜浠鐞嗗悗鐨勫��
+ e.preventDefault();
},
-
+
// 鑱氱劍骞堕�変腑杈撳叆妗�
focusAndSelectInput() {
this.$nextTick(() => {
@@ -129,7 +177,7 @@
}, 100);
});
},
-
+
// 鍙仛鐒﹁緭鍏ユ锛堜笉娓呯┖鏁版嵁锛�
focusInput() {
this.$nextTick(() => {
@@ -140,10 +188,14 @@
}
});
},
-
+
// 娓呯┖琛ㄥ崟鏁版嵁
clearForm() {
this.form.palletCode = '';
+ // 閲嶇疆楠岃瘉鐘舵��
+ if (this.$refs.form) {
+ this.$refs.form.clearValidate();
+ }
// 涓嶆竻绌� locationType锛屼繚鎸佸尯鍩熼�夋嫨
}
},
diff --git "a/\351\241\271\347\233\256\344\273\243\347\240\201/WIDESEA_WMSClient/src/router/viewGird.js" "b/\351\241\271\347\233\256\344\273\243\347\240\201/WIDESEA_WMSClient/src/router/viewGird.js"
index e4c2aca..5f34601 100644
--- "a/\351\241\271\347\233\256\344\273\243\347\240\201/WIDESEA_WMSClient/src/router/viewGird.js"
+++ "b/\351\241\271\347\233\256\344\273\243\347\240\201/WIDESEA_WMSClient/src/router/viewGird.js"
@@ -227,7 +227,13 @@
path:'/printForm',
name: 'printForm',
component: () => import('@/views/outbound/printForm.vue')
- },
+ },{
+ path: '/Log',
+ name: 'Log',
+ component: () => import('@/views/system/Log.vue'),
+ meta: {
+ }
+ }
]
export default viewgird
diff --git "a/\351\241\271\347\233\256\344\273\243\347\240\201/WIDESEA_WMSClient/src/views/basic/locationInfo.vue" "b/\351\241\271\347\233\256\344\273\243\347\240\201/WIDESEA_WMSClient/src/views/basic/locationInfo.vue"
index b6a588f..6237c87 100644
--- "a/\351\241\271\347\233\256\344\273\243\347\240\201/WIDESEA_WMSClient/src/views/basic/locationInfo.vue"
+++ "b/\351\241\271\347\233\256\344\273\243\347\240\201/WIDESEA_WMSClient/src/views/basic/locationInfo.vue"
@@ -48,7 +48,7 @@
[
{ title: "璐т綅缂栧彿", field: "locationCode", type: "like" },
{ title: "宸烽亾缂栧彿", field: "roadwayNo",type:"like" },
- { title: "璐т綅绫诲瀷", field: "locationType",type: "select",dataKey: "locationTypeEnum",data: [], },
+ { title: "璐т綅鍖哄煙", field: "locationType",type: "select",dataKey: "locationTypeEnum",data: [], },
{ title: "绂佺敤鐘舵��", field: "enableStatus" ,type: "select",dataKey: "enableStatusEnum",data: [],},
],
[
@@ -132,7 +132,7 @@
},
{
field: "locationType",
- title: "璐т綅绫诲瀷",
+ title: "璐т綅鍖哄煙",
type: "string",
width: 120,
align: "left",
diff --git "a/\351\241\271\347\233\256\344\273\243\347\240\201/WIDESEA_WMSClient/src/views/stock/stockView.vue" "b/\351\241\271\347\233\256\344\273\243\347\240\201/WIDESEA_WMSClient/src/views/stock/stockView.vue"
index f208fc2..fe81dcc 100644
--- "a/\351\241\271\347\233\256\344\273\243\347\240\201/WIDESEA_WMSClient/src/views/stock/stockView.vue"
+++ "b/\351\241\271\347\233\256\344\273\243\347\240\201/WIDESEA_WMSClient/src/views/stock/stockView.vue"
@@ -158,7 +158,7 @@
},
{
field: "locationType",
- title: "璐т綅绫诲瀷",
+ title: "璐т綅鍖哄煙",
type: "string",
width: 140,
align: "left",
diff --git "a/\351\241\271\347\233\256\344\273\243\347\240\201/WIDESEA_WMSClient/src/views/system/Log.vue" "b/\351\241\271\347\233\256\344\273\243\347\240\201/WIDESEA_WMSClient/src/views/system/Log.vue"
new file mode 100644
index 0000000..1766626
--- /dev/null
+++ "b/\351\241\271\347\233\256\344\273\243\347\240\201/WIDESEA_WMSClient/src/views/system/Log.vue"
@@ -0,0 +1,346 @@
+<template>
+ <div class="tree-container">
+ <el-input placeholder="杈撳叆鍏抽敭瀛楄繘琛岃繃婊�" v-model="filterText" class="filter-input">
+ </el-input>
+ <div class="custom-tree-wrapper">
+ <el-tree ref="tree" class="filter-tree" :filter-node-method="filterNode" :data="data" node-key="id" accordion>
+ <template #default="{ node, data }">
+ <div class="custom-tree-node">
+ <span class="node-label">{{ node.label }}</span>
+ <span v-if="data.hidden" class="node-actions">
+ <el-button type="text" size="mini" @click="() => view(data)" class="action-btn">
+ 鏌ョ湅
+ </el-button>
+ <el-button type="text" size="mini" @click="() => dowmload(node, data)" class="action-btn">
+ 涓嬭浇
+ </el-button>
+ </span>
+ </div>
+ </template>
+ </el-tree>
+ </div>
+ </div>
+ <div class="log-container">
+ <el-card shadow="always" v-if="logName" class="log-card">
+ <template #header>
+ <div class="card-header">
+ <el-tag type="info" size="small">鏃ュ織鏂囦欢</el-tag>
+ <span class="log-title">{{ logName }}</span>
+ </div>
+ </template>
+ <div class="log-content">
+ <div v-for="(item, index) in log" :key="index" class="log-line">
+ <span class="line-number">{{ index + 1 }}</span>
+ <span class="line-content">{{ item }}</span>
+ </div>
+ </div>
+ </el-card>
+ <div v-else class="empty-log">
+ <el-empty description="璇烽�夋嫨鏃ュ織鏂囦欢杩涜鏌ョ湅" />
+ </div>
+ </div>
+</template>
+
+<script>
+export default {
+ data() {
+ return {
+ data: [],
+ defaultProps: {
+ children: "children",
+ label: "label",
+ },
+ filterText: "",
+ logName: "",
+ log: [],
+ };
+ },
+ watch: {
+ filterText(val) {
+ this.$refs.tree.filter(val);
+ },
+ },
+ created() {
+ this.getLogName();
+ },
+
+ methods: {
+ filterNode(value, data) {
+ if (!value) return true;
+ return data.label.indexOf(value) !== -1;
+ },
+ getLogName() {
+ this.http
+ .post("/api/Sys_Log/GetLogName", null, "姝e湪鎵ц涓�...")
+ .then((x) => {
+ if (x.status) {
+ this.data = x.data;
+ }
+ });
+ },
+
+ view(data) {
+ // var params = {
+ // MainData: { fileName: data.label },
+ // };
+ this.http
+ .post("/api/Sys_Log/GetLog?fileName=" + data.label, "姝e湪鏌ヨ涓�...")
+ .then((x) => {
+ if (x.status) {
+ this.logName = data.label;
+ this.log = x.data;
+ }
+ });
+ },
+
+ dowmload(node, data) {
+ let ipAddress = this.http.ipAddress;
+ let url =
+ "api/Sys_Log/DownLoadLog?fileName=" +
+ data.fatherNode +
+ "\\" +
+ data.label;
+ let fileName = data.label;
+ let xmlResquest = new XMLHttpRequest();
+ xmlResquest.open("GET", ipAddress + url, true);
+ xmlResquest.setRequestHeader("Content-type", "application/json");
+ xmlResquest.setRequestHeader(
+ "Authorization",
+ this.$store.getters.getToken()
+ );
+ let elink = this.$refs.template;
+ xmlResquest.responseType = "blob";
+ let $_vue = this;
+ this.loadingStatus = true;
+ xmlResquest.onload = function (e) {
+ // 璇锋眰鎴愬姛
+ if (this.status == 200) {
+ let blob = this.response;
+ let a = document.createElement("a");
+ //window.URL.createObjectURL() 闈欐�佹柟娉曚細鍒涘缓涓�涓� DOMString锛屽叾涓寘鍚竴涓〃绀哄弬鏁颁腑缁欏嚭鐨勫璞$殑URL銆傝繖涓� URL 鐨勭敓鍛藉懆鏈熷拰鍒涘缓瀹冪殑绐楀彛涓殑 document 缁戝畾銆傝繖涓柊鐨刄RL 瀵硅薄琛ㄧず鎸囧畾鐨� File 瀵硅薄鎴� Blob 瀵硅薄銆�
+ let url = window.URL.createObjectURL(blob);
+ a.href = url;
+ a.download = fileName;
+ a.click();
+ //URL.revokeObjectURL() 闈欐�佹柟娉曠敤鏉ラ噴鏀句竴涓箣鍓嶅凡缁忓瓨鍦ㄧ殑銆侀�氳繃璋冪敤 URL.createObjectURL() 鍒涘缓鐨� URL 瀵硅薄銆傚綋浣犵粨鏉熶娇鐢ㄦ煇涓� URL 瀵硅薄涔嬪悗锛屽簲璇ラ�氳繃璋冪敤杩欎釜鏂规硶鏉ヨ娴忚鍣ㄧ煡閬撲笉鐢ㄥ湪鍐呭瓨涓户缁繚鐣欏杩欎釜鏂囦欢鐨勫紩鐢ㄤ簡銆�
+ window.URL.revokeObjectURL(url);
+
+ } else {
+ //涓嬭浇澶辫触澶勭悊
+
+ }
+ };
+ xmlResquest.send();
+ },
+ },
+};
+</script>
+
+<style scoped>
+.tree-container {
+ width: 30%;
+ float: left;
+ padding: 16px;
+ background: #f8f9fa;
+ border-radius: 8px;
+ box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
+}
+
+.filter-input {
+ margin-bottom: 16px;
+}
+
+.filter-input :deep(.el-input__inner) {
+ border-radius: 20px;
+ border-color: #dcdfe6;
+ transition: all 0.3s;
+}
+
+.filter-input :deep(.el-input__inner):focus {
+ border-color: #409eff;
+ box-shadow: 0 0 0 2px rgba(64, 158, 255, 0.1);
+}
+
+.custom-tree-wrapper {
+ height: 760px;
+ overflow-y: auto;
+ padding: 8px;
+ background: white;
+ border-radius: 6px;
+ border: 1px solid #ebeef5;
+}
+
+.filter-tree :deep(.el-tree-node__content) {
+ height: 40px;
+ margin: 2px 0;
+ border-radius: 4px;
+ transition: all 0.2s;
+}
+
+.filter-tree :deep(.el-tree-node__content:hover) {
+ background-color: #f0f9ff;
+}
+
+.filter-tree :deep(.el-tree-node.is-current > .el-tree-node__content) {
+ background-color: #ecf5ff;
+ font-weight: 600;
+}
+
+.custom-tree-node {
+ display: flex;
+ align-items: center;
+ justify-content: space-between;
+ width: 100%;
+ padding: 0 8px;
+}
+
+.node-label {
+ font-size: 14px;
+ color: #606266;
+ flex: 1;
+ overflow: hidden;
+ text-overflow: ellipsis;
+ white-space: nowrap;
+}
+
+.node-actions {
+ display: flex;
+ gap: 8px;
+ margin-left: 12px;
+}
+
+.action-btn {
+ padding: 4px 8px;
+ font-size: 12px;
+ color: #409eff;
+ border-radius: 3px;
+}
+
+.action-btn:hover {
+ background-color: rgba(64, 158, 255, 0.1);
+}
+
+.log-container {
+ width: 68%;
+ float: right;
+ padding: 16px;
+}
+
+.log-card {
+ height: 800px;
+ border-radius: 8px;
+ border: 1px solid #ebeef5;
+}
+
+.log-card :deep(.el-card__header) {
+ background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
+ border-bottom: 1px solid #ebeef5;
+ padding: 16px 20px;
+}
+
+.card-header {
+ display: flex;
+ align-items: center;
+ gap: 12px;
+}
+
+.log-title {
+ font-size: 16px;
+ font-weight: 600;
+ color: white;
+ flex: 1;
+ overflow: hidden;
+ text-overflow: ellipsis;
+ white-space: nowrap;
+}
+
+.log-content {
+ height: 700px;
+ overflow-y: auto;
+ font-family: 'Consolas', 'Monaco', 'Courier New', monospace;
+ background: #f8f9fa;
+ padding: 12px;
+ border-radius: 4px;
+}
+
+.log-line {
+ display: flex;
+ align-items: flex-start;
+ margin-bottom: 4px;
+ line-height: 1.5;
+ background: white;
+ padding: 8px 12px;
+ border-radius: 4px;
+ border-left: 3px solid #409eff;
+ transition: all 0.2s;
+}
+
+.log-line:hover {
+ background: #f0f9ff;
+ transform: translateX(2px);
+}
+
+.line-number {
+ display: inline-block;
+ min-width: 40px;
+ padding-right: 12px;
+ text-align: right;
+ color: #909399;
+ font-size: 12px;
+ user-select: none;
+}
+
+.line-content {
+ flex: 1;
+ color: #303133;
+ font-size: 13px;
+ word-break: break-all;
+ white-space: pre-wrap;
+}
+
+.empty-log {
+ height: 800px;
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ background: white;
+ border-radius: 8px;
+ box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
+}
+
+.empty-log :deep(.el-empty__description) {
+ margin-top: 8px;
+}
+
+/* 婊氬姩鏉℃牱寮� */
+.custom-tree-wrapper::-webkit-scrollbar,
+.log-content::-webkit-scrollbar {
+ width: 6px;
+ height: 6px;
+}
+
+.custom-tree-wrapper::-webkit-scrollbar-track,
+.log-content::-webkit-scrollbar-track {
+ background: #f1f1f1;
+ border-radius: 3px;
+}
+
+.custom-tree-wrapper::-webkit-scrollbar-thumb,
+.log-content::-webkit-scrollbar-thumb {
+ background: #c1c1c1;
+ border-radius: 3px;
+}
+
+.custom-tree-wrapper::-webkit-scrollbar-thumb:hover,
+.log-content::-webkit-scrollbar-thumb:hover {
+ background: #a8a8a8;
+}
+
+/* 娓呴櫎娴姩 */
+.tree-container::after,
+.log-container::after {
+ content: "";
+ display: table;
+ clear: both;
+}
+</style>
\ No newline at end of file
diff --git "a/\351\241\271\347\233\256\344\273\243\347\240\201/WMS\346\227\240\344\273\223\345\202\250\347\211\210/WIDESEA_WMSServer/WIDESEA_TaskInfoService/TaskService.cs" "b/\351\241\271\347\233\256\344\273\243\347\240\201/WMS\346\227\240\344\273\223\345\202\250\347\211\210/WIDESEA_WMSServer/WIDESEA_TaskInfoService/TaskService.cs"
index b65d4c3..eb77ed2 100644
--- "a/\351\241\271\347\233\256\344\273\243\347\240\201/WMS\346\227\240\344\273\223\345\202\250\347\211\210/WIDESEA_WMSServer/WIDESEA_TaskInfoService/TaskService.cs"
+++ "b/\351\241\271\347\233\256\344\273\243\347\240\201/WMS\346\227\240\344\273\223\345\202\250\347\211\210/WIDESEA_WMSServer/WIDESEA_TaskInfoService/TaskService.cs"
@@ -714,7 +714,7 @@
_logger.LogInformation($"InPickTaskCompleted AddLocationStatusChangeRecord : {ex.Message} ");
}
- _logger.LogInformation($"鎵樼洏鍥炲簱瀹屾垚澶勭悊鎴愬姛 - 浠诲姟鍙�: {task.TaskNum}, 鎵樼洏: {task.PalletCode}, 璁㈠崟: {task.OrderNo}");
+ _logger.LogInformation($"鎵樼洏鍥炲簱瀹屾垚澶勭悊鎴愬姛 - 浠诲姟鍙�: {task.TaskNum}, 鎵樼洏: {task.PalletCode}, 璁㈠崟: {task.OrderNo} 璐т綅鐘舵�侊細{locationInfo.LocationStatus}");
_ = Task.Run(async () =>
{
try
@@ -1136,33 +1136,36 @@
allocatefeedmodel.Details.Add(detailModel);
}
- var groupedResult = allocatefeedmodel.Details.GroupBy(item => new
- {
- item.WarehouseCode,
- item.MaterialCode,
- item.Unit,
- item.LineNo
- }).Select(group => new AllocateDtoDetail
- {
- WarehouseCode = group.Key.WarehouseCode,
- MaterialCode = group.Key.MaterialCode,
- LineNo = group.Key.LineNo,
- Qty = group.Sum(x => x.Qty),
- Unit = group.Key.Unit,
- Barcodes = group.SelectMany(x => x.Barcodes)
- .GroupBy(b => b.Barcode)
- .Select(b => new BarcodeInfo
- {
- Barcode = b.Key,
- BatchNo = b.First().BatchNo,
- SupplyCode = b.First().SupplyCode,
- Qty = b.Max(x => x.Qty),
- Unit = b.First().Unit
- }) .ToList()
- }) .ToList();
+ var groupedResult = allocatefeedmodel.Details
+ .GroupBy(item => new { item.WarehouseCode, item.MaterialCode, item.Unit, item.LineNo })
+ .Select(group =>
+ {
+
+ var deduplicatedBarcodes = group.SelectMany(x => x.Barcodes)
+ .GroupBy(b => b.Barcode)
+ .Select(b => new BarcodeInfo
+ {
+ Barcode = b.Key,
+ BatchNo = b.First().BatchNo,
+ SupplyCode = b.First().SupplyCode,
+ Qty = b.Max(x => x.Qty),
+ Unit = b.First().Unit
+ }).ToList();
+ return new AllocateDtoDetail
+ {
+ WarehouseCode = group.Key.WarehouseCode,
+ MaterialCode = group.Key.MaterialCode,
+ LineNo = group.Key.LineNo,
+ Qty = deduplicatedBarcodes.Sum(b => b.Qty),
+ Unit = group.Key.Unit,
+ Barcodes = deduplicatedBarcodes
+ };
+ }).ToList();
+
allocatefeedmodel.Details = groupedResult;
- var result = await _invokeMESService.FeedbackAllocate(allocatefeedmodel);
+
+ var result = await _invokeMESService.FeedbackAllocate(allocatefeedmodel);
if (result != null && result.code == 200)
{
await _outboundOrderDetailService.Db.Updateable<Dt_OutboundOrderDetail>()
@@ -1175,6 +1178,19 @@
ReturnToMESStatus = 1,
}).Where(x => x.OrderNo == orderNo).ExecuteCommandAsync();
}
+ else
+ {
+ await _outboundOrderDetailService.Db.Updateable<Dt_OutboundOrderDetail>()
+ .SetColumns(x => x.ReturnToMESStatus == 2)
+ .Where(x => x.OrderId == outboundOrder.Id)
+ .ExecuteCommandAsync();
+
+ await _outboundOrderService.Db.Updateable<Dt_OutboundOrder>()
+ .SetColumns(it => new Dt_OutboundOrder { ReturnToMESStatus = 2, Remark = result.message })
+ .Where(x => x.OrderNo == orderNo)
+ .ExecuteCommandAsync();
+ }
+
}
}
else if (outboundOrder.OrderType == OutOrderTypeEnum.ReCheck.ObjToInt())
@@ -1247,30 +1263,32 @@
}
feedmodel.details.Add(detailModel);
}
- var groupedResult = feedmodel.details.GroupBy(item => new
- {
- item.warehouseCode,
- item.materialCode,
- item.unit,
- item.lineNo
- }).Select(group => new FeedbackOutboundDetailsModel
- {
- warehouseCode = group.Key.warehouseCode,
- materialCode = group.Key.materialCode,
- lineNo = group.Key.lineNo,
- qty = group.Sum(x => x.qty),
- unit = group.Key.unit,
- barcodes = group.SelectMany(x => x.barcodes)
- .GroupBy(b => b.barcode)
- .Select(b => new WIDESEA_DTO.Outbound.BarcodesModel
- {
- barcode = b.Key,
- batchNo = b.First().batchNo,
- supplyCode = b.First().supplyCode,
- qty = b.Max(x => x.qty),
- unit = b.First().unit
- }).ToList()
- }).ToList();
+
+ var groupedResult = feedmodel.details
+ .GroupBy(item => new { item.warehouseCode, item.materialCode, item.unit, item.lineNo })
+ .Select(group =>
+ {
+ var deduplicatedBarcodes = group.SelectMany(x => x.barcodes)
+ .GroupBy(b => b.barcode)
+ .Select(b => new WIDESEA_DTO.Outbound.BarcodesModel
+ {
+ barcode = b.Key,
+ batchNo = b.First().batchNo,
+ supplyCode = b.First().supplyCode,
+ qty = b.Max(x => x.qty),
+ unit = b.First().unit
+ }).ToList();
+ return new FeedbackOutboundDetailsModel
+ {
+ warehouseCode = group.Key.warehouseCode,
+ materialCode = group.Key.materialCode,
+ lineNo = group.Key.lineNo,
+ qty = deduplicatedBarcodes.Sum(b => b.qty),
+ unit = group.Key.unit,
+ barcodes = deduplicatedBarcodes
+ };
+ }).ToList();
+
feedmodel.details = groupedResult;
var result = await _invokeMESService.FeedbackOutbound(feedmodel);
diff --git "a/\351\241\271\347\233\256\344\273\243\347\240\201/WMS\346\227\240\344\273\223\345\202\250\347\211\210/WIDESEA_WMSServer/WIDESEA_WMSServer/Controllers/System/Sys_LogController.cs" "b/\351\241\271\347\233\256\344\273\243\347\240\201/WMS\346\227\240\344\273\223\345\202\250\347\211\210/WIDESEA_WMSServer/WIDESEA_WMSServer/Controllers/System/Sys_LogController.cs"
index 3cd2f46..8fd6406 100644
--- "a/\351\241\271\347\233\256\344\273\243\347\240\201/WMS\346\227\240\344\273\223\345\202\250\347\211\210/WIDESEA_WMSServer/WIDESEA_WMSServer/Controllers/System/Sys_LogController.cs"
+++ "b/\351\241\271\347\233\256\344\273\243\347\240\201/WMS\346\227\240\344\273\223\345\202\250\347\211\210/WIDESEA_WMSServer/WIDESEA_WMSServer/Controllers/System/Sys_LogController.cs"
@@ -1,5 +1,8 @@
-锘縰sing Microsoft.AspNetCore.Http;
+锘縰sing Microsoft.AspNetCore.Authorization;
+using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
+using System.Text;
+using WIDESEA_Core;
using WIDESEA_Core.BaseController;
using WIDESEA_ISystemService;
using WIDESEA_Model.Models;
@@ -13,8 +16,385 @@
[ApiController]
public class Sys_LogController : ApiBaseController<ISys_LogService, Sys_Log>
{
+ // 閰嶇疆甯搁噺
+ private const int MAX_FILE_SIZE_MB = 50;
+ private const int MAX_RETRY_COUNT = 3;
+ private const int RETRY_DELAY_MS = 100;
+ private static readonly string[] ALLOWED_FILE_TYPES = { ".txt", ".log", ".csv", ".json", ".xml" };
+
public Sys_LogController(ISys_LogService service) : base(service)
{
}
+
+ [HttpPost, Route("GetLogName"), AllowAnonymous]
+ public WebResponseContent GetLogName()
+ {
+ WebResponseContent content = new WebResponseContent();
+ try
+ {
+ List<object> data = new List<object>();
+ DirectoryInfo folder = new DirectoryInfo(AppContext.BaseDirectory + "\\logs\\");
+ DirectoryInfo[] firstDirectoryInfos = folder.GetDirectories().OrderByDescending(x => x.CreationTime).ToArray();
+ int k = 2020;
+ for (int i = 0; i < firstDirectoryInfos.Length; i++)
+ {
+ if (firstDirectoryInfos[i].Name != "Info")
+ {
+ FileInfo[] nextFileInfos = firstDirectoryInfos[i].GetFiles();
+ List<object> values = new List<object>();
+ for (int j = 0; j < nextFileInfos.Length; j++)
+ {
+ values.Add(new { label = nextFileInfos[j].Name, id = k, hidden = true, fatherNode = firstDirectoryInfos[i].Name });
+ k++;
+ }
+ data.Add(new { label = firstDirectoryInfos[i].Name, children = values, id = i, hidden = false });
+ }
+ }
+
+ FileInfo[] nextFileInfo = folder.GetFiles();
+ List<object> value = new List<object>();
+ for (int j = 0; j < nextFileInfo.Length; j++)
+ {
+ value.Add(new { label = nextFileInfo[j].Name, id = k, hidden = true, fatherNode = folder.Name });
+ k++;
+ }
+ data.Add(new { label = folder.Name, children = value, id = 1, hidden = false });
+
+ return WebResponseContent.Instance.OK(data: data);
+ }
+ catch (Exception ex)
+ {
+ return WebResponseContent.Instance.Error(ex.Message);
+ }
+ }
+
+ [HttpPost, Route("GetLog"), AllowAnonymous]
+ public WebResponseContent GetLog(string fileName)
+ {
+ WebResponseContent content = new WebResponseContent();
+ try
+ {
+ List<FileInfo> files = new List<FileInfo>();
+ DirectoryInfo folder = new DirectoryInfo(AppContext.BaseDirectory + "\\logs\\");
+ DirectoryInfo[] firstDirectoryInfos = folder.GetDirectories();
+ for (int i = 0; i < firstDirectoryInfos.Length; i++)
+ {
+ FileInfo[] nextFileInfos = firstDirectoryInfos[i].GetFiles();
+ files.AddRange(nextFileInfos);
+ }
+
+ FileInfo[] nextFileInfo = folder.GetFiles();
+ files.AddRange(nextFileInfo);
+ if (files.Count > 0)
+ {
+ FileInfo file = files.Where(x => x.Name == fileName).FirstOrDefault();
+ if (file == null)
+ {
+ return WebResponseContent.Instance.Error($"鏈壘鍒版棩蹇楁枃浠�: {fileName}");
+ }
+
+ // 浣跨敤鍏变韩璇诲彇妯″紡
+ using (FileStream stream = new FileStream(
+ file.FullName,
+ FileMode.Open,
+ FileAccess.Read,
+ FileShare.ReadWrite))
+ using (StreamReader reader = new StreamReader(stream, Encoding.UTF8))
+ {
+ StringBuilder text = new StringBuilder();
+ List<string> lines = new List<string>();
+ while (!reader.EndOfStream)
+ {
+ var line = reader.ReadLine();
+ lines.Add(line);
+ }
+
+ content = WebResponseContent.Instance.OK(data: lines);
+ }
+ }
+ else
+ {
+ content = WebResponseContent.Instance.Error($"鏈壘鍒版棩蹇楁枃浠�,銆恵fileName}銆�");
+ }
+ }
+ catch (IOException ex)
+ {
+ if (IsFileLockedException(ex))
+ {
+ content = WebResponseContent.Instance.Error($"鏃ュ織鏂囦欢姝e湪琚郴缁熷啓鍏ワ紝璇风◢鍚庡啀璇�");
+ }
+ else
+ {
+ content = WebResponseContent.Instance.Error($"鎵撳紑鏃ュ織鏂囦欢閿欒,{ex.Message}");
+ }
+ }
+ catch (Exception ex)
+ {
+ content = WebResponseContent.Instance.Error($"鎵撳紑鏃ュ織鏂囦欢閿欒,{ex.Message}");
+ }
+ return content;
+ }
+
+ [HttpPost, HttpGet, Route("DownLoadLog"), AllowAnonymous]
+ public virtual async Task<ActionResult> DownLoadLog(string fileName)
+ {
+ try
+ {
+ // 1. 鍙傛暟楠岃瘉
+ if (string.IsNullOrWhiteSpace(fileName))
+ {
+ return BadRequest("鏂囦欢鍚嶄笉鑳戒负绌�");
+ }
+
+ // 瀹夊叏鎬ф鏌ワ細闃叉璺緞閬嶅巻鏀诲嚮
+ if (fileName.Contains("..") || Path.IsPathRooted(fileName))
+ {
+ return BadRequest("鏃犳晥鐨勬枃浠跺悕");
+ }
+
+ //string logDirectory = Path.Combine(AppContext.BaseDirectory, "logs");
+ string logDirectory = Path.Combine(AppContext.BaseDirectory);
+
+ if (!Directory.Exists(logDirectory))
+ {
+ Directory.CreateDirectory(logDirectory);
+ }
+
+ string filePath = Path.Combine(logDirectory, fileName);
+
+ if (Directory.Exists(filePath))
+ {
+ return NotFound($"鏂囦欢 {fileName} 涓嶅瓨鍦�");
+ }
+
+ string extension = Path.GetExtension(fileName).ToLowerInvariant();
+ if (!IsAllowedFileType(extension))
+ {
+ return BadRequest($"涓嶆敮鎸佺殑鏂囦欢绫诲瀷: {extension}");
+ }
+
+ FileInfo fileInfo = new FileInfo(filePath);
+
+ if (fileInfo.Length > MAX_FILE_SIZE_MB * 1024 * 1024)
+ {
+ return BadRequest($"鏂囦欢杩囧ぇ锛岃秴杩噞MAX_FILE_SIZE_MB}MB闄愬埗");
+ }
+
+ // 鏂规1锛氫娇鐢ㄩ噸璇曟満鍒� + 鍏变韩璇诲彇锛堟帹鑽愶級
+ byte[] fileBytes = await ReadFileWithRetryAsync(filePath);
+
+ if (fileBytes == null)
+ {
+ return StatusCode(500, "鏂囦欢琚崰鐢紝鏃犳硶涓嬭浇锛岃绋嶅悗閲嶈瘯");
+ }
+
+ string contentType = GetContentType(extension);
+
+ // 璁剧疆涓嬭浇澶�
+ Response.Headers.Add("Content-Disposition", $"attachment; filename=\"{System.Web.HttpUtility.UrlEncode(fileName, Encoding.UTF8)}\"");
+ Response.Headers.Add("Cache-Control", "no-cache, no-store, must-revalidate");
+ Response.Headers.Add("Pragma", "no-cache");
+ Response.Headers.Add("Expires", "0");
+
+ return File(fileBytes, contentType, fileName);
+ }
+ catch (UnauthorizedAccessException)
+ {
+ return StatusCode(403, "娌℃湁璁块棶璇ユ枃浠剁殑鏉冮檺");
+ }
+ catch (PathTooLongException)
+ {
+ return BadRequest("鏂囦欢璺緞杩囬暱");
+ }
+ catch (IOException ex)
+ {
+ if (IsFileLockedException(ex))
+ {
+ return StatusCode(500, "鏂囦欢琚攣瀹氾紝鍙兘姝e湪琚郴缁熷啓鍏ワ紝璇风◢鍚庡啀璇�");
+ }
+ return StatusCode(500, $"鏂囦欢璇诲彇澶辫触: {ex.Message}");
+ }
+ catch (Exception ex)
+ {
+ // 璁板綍寮傚父鏃ュ織锛堣繖閲岀畝鍖栦负杩斿洖锛屽疄闄呴」鐩腑搴旇璁板綍鍒版棩蹇楃郴缁燂級
+ return StatusCode(500, $"鏈嶅姟鍣ㄥ唴閮ㄩ敊璇�: {ex.Message}");
+ }
+ }
+
+ /// <summary>
+ /// 甯﹂噸璇曟満鍒剁殑鏂囦欢璇诲彇鏂规硶
+ /// </summary>
+ private async Task<byte[]> ReadFileWithRetryAsync(string filePath)
+ {
+ for (int attempt = 0; attempt < MAX_RETRY_COUNT; attempt++)
+ {
+ try
+ {
+ // 浣跨敤 FileShare.ReadWrite 鍏佽鍏朵粬杩涚▼鍚屾椂璇诲彇鍜屽啓鍏�
+ // 浣跨敤寮傛璇诲彇鎻愰珮鎬ц兘
+ using (var fileStream = new FileStream(
+ filePath,
+ FileMode.Open,
+ FileAccess.Read,
+ FileShare.ReadWrite | FileShare.Delete, // 鍏佽鍒犻櫎鎿嶄綔
+ bufferSize: 4096,
+ useAsync: true))
+ {
+ using (var memoryStream = new MemoryStream())
+ {
+ await fileStream.CopyToAsync(memoryStream);
+ return memoryStream.ToArray();
+ }
+ }
+ }
+ catch (IOException) when (attempt < MAX_RETRY_COUNT - 1)
+ {
+ // 濡傛灉涓嶆槸鏈�鍚庝竴娆¢噸璇曪紝绛夊緟涓�娈垫椂闂�
+ await Task.Delay(RETRY_DELAY_MS * (attempt + 1));
+ }
+ catch (IOException ex)
+ {
+ // 鏈�鍚庝竴娆″皾璇曚篃澶辫触浜�
+ throw;
+ }
+ }
+ return null;
+ }
+
+ /// <summary>
+ /// 鍒ゆ柇鏄惁涓烘枃浠惰閿佸畾鐨勫紓甯�
+ /// </summary>
+ private bool IsFileLockedException(IOException ex)
+ {
+ int errorCode = ex.HResult & 0xFFFF;
+ return errorCode == 32 || errorCode == 33; // ERROR_SHARING_VIOLATION or ERROR_LOCK_VIOLATION
+ }
+
+ /// <summary>
+ /// 妫�鏌ユ枃浠剁被鍨嬫槸鍚﹀厑璁�
+ /// </summary>
+ private bool IsAllowedFileType(string extension)
+ {
+ return ALLOWED_FILE_TYPES.Contains(extension);
+ }
+
+ /// <summary>
+ /// 鑾峰彇Content-Type
+ /// </summary>
+ private string GetContentType(string extension)
+ {
+ return extension.ToLowerInvariant() switch
+ {
+ ".txt" => "text/plain; charset=utf-8",
+ ".log" => "text/plain; charset=utf-8",
+ ".csv" => "text/csv; charset=utf-8",
+ ".json" => "application/json; charset=utf-8",
+ ".xml" => "application/xml; charset=utf-8",
+ _ => "application/octet-stream"
+ };
+ }
+
+ /// <summary>
+ /// 澶囬�夋柟妗堬細鍒涘缓涓存椂鍓湰涓嬭浇锛堟渶瀹夊叏锛屼絾鎬ц兘绋嶅樊锛�
+ /// </summary>
+ [HttpPost, HttpGet, Route("DownLoadLogCopy"), AllowAnonymous]
+ public virtual async Task<ActionResult> DownLoadLogCopy(string fileName)
+ {
+ try
+ {
+ // 鍙傛暟楠岃瘉锛堝悓涓婏級
+ if (string.IsNullOrWhiteSpace(fileName))
+ {
+ return BadRequest("鏂囦欢鍚嶄笉鑳戒负绌�");
+ }
+
+ string logDirectory = Path.Combine(AppContext.BaseDirectory, "logs");
+ string filePath = Path.Combine(logDirectory, fileName);
+
+ if (Directory.Exists(filePath))
+ {
+ return NotFound($"鏂囦欢 {fileName} 涓嶅瓨鍦�");
+ }
+
+ // 鐢熸垚涓存椂鏂囦欢鍚�
+ string tempFileName = $"{Path.GetFileNameWithoutExtension(fileName)}_{Guid.NewGuid():N}{Path.GetExtension(fileName)}";
+ string tempFilePath = Path.Combine(Path.GetTempPath(), tempFileName);
+
+ try
+ {
+ // 灏濊瘯澶嶅埗鏂囦欢鍒颁复鏃朵綅缃紙浣跨敤閲嶈瘯鏈哄埗锛�
+ bool copySuccess = false;
+ for (int attempt = 0; attempt < MAX_RETRY_COUNT; attempt++)
+ {
+ try
+ {
+ //Directory.GetFiles.Copy(filePath, tempFilePath, false);
+ copySuccess = true;
+ break;
+ }
+ catch (IOException) when (attempt < MAX_RETRY_COUNT - 1)
+ {
+ await Task.Delay(RETRY_DELAY_MS * (attempt + 1));
+ }
+ }
+
+ if (!copySuccess)
+ {
+ return StatusCode(500, "鏃犳硶澶嶅埗鏂囦欢锛屽彲鑳借鍏朵粬杩涚▼鍗犵敤");
+ }
+
+ // 浠庝复鏃舵枃浠惰鍙�
+ byte[] fileBytes;
+ using (FileStream tempStream = new FileStream(tempFilePath, FileMode.Open, FileAccess.Read, FileShare.Read))
+ {
+ using (MemoryStream memoryStream = new MemoryStream())
+ {
+ await tempStream.CopyToAsync(memoryStream);
+ fileBytes = memoryStream.ToArray();
+ }
+ }
+
+ string extension = Path.GetExtension(fileName).ToLowerInvariant();
+ string contentType = GetContentType(extension);
+
+ // 杩斿洖鏂囦欢鍚庢竻鐞嗕复鏃舵枃浠�
+ var result = File(fileBytes, contentType, fileName);
+
+ // 寮傛娓呯悊涓存椂鏂囦欢
+ _ = Task.Run(() =>
+ {
+ try
+ {
+ Directory.Delete(tempFilePath);
+ }
+ catch
+ {
+ // 蹇界暐鍒犻櫎澶辫触
+ }
+ });
+
+ return result;
+ }
+ finally
+ {
+ // 纭繚涓存椂鏂囦欢琚竻鐞�
+ if (Directory.Exists(tempFilePath))
+ {
+ try
+ {
+ Directory.Delete(tempFilePath);
+ }
+ catch
+ {
+ // 蹇界暐鍒犻櫎澶辫触
+ }
+ }
+ }
+ }
+ catch (Exception ex)
+ {
+ return StatusCode(500, $"鏈嶅姟鍣ㄥ唴閮ㄩ敊璇�: {ex.Message}");
+ }
+ }
}
-}
+}
\ No newline at end of file
diff --git "a/\351\241\271\347\233\256\350\265\204\346\226\231/\346\225\260\346\215\256\345\272\223\345\255\227\345\205\270/ALD_20251212105252.pdf" "b/\351\241\271\347\233\256\350\265\204\346\226\231/\346\225\260\346\215\256\345\272\223\345\255\227\345\205\270/ALD_20251212105252.pdf"
new file mode 100644
index 0000000..87a9c8e
--- /dev/null
+++ "b/\351\241\271\347\233\256\350\265\204\346\226\231/\346\225\260\346\215\256\345\272\223\345\255\227\345\205\270/ALD_20251212105252.pdf"
Binary files differ
diff --git "a/\351\241\271\347\233\256\350\265\204\346\226\231/\346\225\260\346\215\256\345\272\223\345\255\227\345\205\270/WIDESEAWMS_ALDZhongRui.sql" "b/\351\241\271\347\233\256\350\265\204\346\226\231/\346\225\260\346\215\256\345\272\223\345\255\227\345\205\270/WIDESEAWMS_ALDZhongRui.sql"
new file mode 100644
index 0000000..ce7350c
--- /dev/null
+++ "b/\351\241\271\347\233\256\350\265\204\346\226\231/\346\225\260\346\215\256\345\272\223\345\255\227\345\205\270/WIDESEAWMS_ALDZhongRui.sql"
Binary files differ
--
Gitblit v1.9.3