dxq 2 недель назад
Родитель
Сommit
5ff132fb07

+ 250
- 0
src/views/sto/components/PopupBatchEdit.vue Просмотреть файл

@@ -0,0 +1,250 @@
1
+<template>
2
+  <el-dialog
3
+    v-model="dialogVisible"
4
+    title="批量修改信息明细"
5
+    width="600px"
6
+    :close-on-click-modal="false"
7
+    destroy-on-close
8
+    @close="handleClose"
9
+  >
10
+    <el-form :model="form" label-width="120px" label-position="right">
11
+      <el-form-item label="新客户名称">
12
+        <el-select
13
+          v-model="form.customerCompany"
14
+          clearable
15
+          filterable
16
+          placeholder="请选择客户名称"
17
+          style="width: 100%;"
18
+        >
19
+          <el-option
20
+            v-for="item in customerCompanyOptions"
21
+            :key="item.value"
22
+            :label="item.label"
23
+            :value="item.value"
24
+          />
25
+        </el-select>
26
+      </el-form-item>
27
+
28
+      <el-form-item label="新货权单位">
29
+        <el-select
30
+          v-model="form.ownerCompany"
31
+          clearable
32
+          filterable
33
+          placeholder="请选择货权单位"
34
+          style="width: 100%;"
35
+        >
36
+          <el-option
37
+            v-for="item in ownerCompanyOptions"
38
+            :key="item.value"
39
+            :label="item.label"
40
+            :value="item.value"
41
+          />
42
+        </el-select>
43
+      </el-form-item>
44
+
45
+      <el-form-item label="新订单号">
46
+        <el-input v-model="form.orderNo" placeholder="请输入新订单号" />
47
+      </el-form-item>
48
+
49
+      <el-form-item label="新合约号">
50
+        <el-input v-model="form.contractNo" placeholder="请输入新合约号" />
51
+      </el-form-item>
52
+
53
+      <el-form-item label="新收货地址">
54
+        <el-input v-model="form.deliveryAddress" placeholder="请输入新收货地址" />
55
+      </el-form-item>
56
+
57
+      <el-form-item label="新产地">
58
+        <el-input v-model="form.prodPlace" placeholder="请输入新产地" />
59
+      </el-form-item>
60
+
61
+      <el-form-item label="新捆包号">
62
+        <el-input v-model="form.bundleNo" placeholder="请输入新捆包号" />
63
+      </el-form-item>
64
+    </el-form>
65
+
66
+    <template #footer>
67
+      <div class="dialog-footer">
68
+        <el-button type="success" @click="handleConfirm">确定</el-button>
69
+        <el-button type="danger" @click="handleCancel">取消</el-button>
70
+      </div>
71
+    </template>
72
+  </el-dialog>
73
+</template>
74
+
75
+<script setup>
76
+import { ref, getCurrentInstance } from 'vue'
77
+import { ElMessage } from 'element-plus'
78
+
79
+const { proxy } = getCurrentInstance()
80
+
81
+const dialogVisible = ref(false)
82
+const customerCompanyOptions = ref([])
83
+const ownerCompanyOptions = ref([])
84
+const selectedRows = ref([])
85
+
86
+const form = ref({
87
+  customerCompany: '',
88
+  ownerCompany: '',
89
+  orderNo: '',
90
+  contractNo: '',
91
+  deliveryAddress: '',
92
+  prodPlace: '',
93
+  bundleNo: ''
94
+})
95
+
96
+// 获取客户名称选项
97
+const fetchCustomerOptions = async () => {
98
+  try {
99
+    const response = await proxy.$axios.get('sto/Customer/querySelect', {})
100
+    if (response.data.code === 0 || response.data.code === '0') {
101
+      const options = response.data.data || []
102
+      customerCompanyOptions.value = options.map(item => ({
103
+        label: item.label || item.name || item.value || '',
104
+        value: item.value || item.id || item.code || item.label || ''
105
+      })).filter(item => item.label && item.value)
106
+    }
107
+  } catch (error) {
108
+    console.error('获取客户名称选项失败:', error)
109
+  }
110
+}
111
+
112
+// 获取货权单位选项
113
+const fetchOwnerCompanyOptions = async () => {
114
+  try {
115
+    const response = await proxy.$axios.get('sto/Customer/querySelect', {})
116
+    if (response.data.code === 0 || response.data.code === '0') {
117
+      const options = response.data.data || []
118
+      ownerCompanyOptions.value = options.map(item => ({
119
+        label: item.label || item.name || item.value || '',
120
+        value: item.value || item.id || item.code || item.label || ''
121
+      })).filter(item => item.label && item.value)
122
+    }
123
+  } catch (error) {
124
+    console.error('获取货权单位选项失败:', error)
125
+  }
126
+}
127
+
128
+// 打开弹窗
129
+const open = (rows) => {
130
+  if (!rows || rows.length === 0) {
131
+    ElMessage.warning('请先选择要批量修改的数据')
132
+    return
133
+  }
134
+  
135
+  selectedRows.value = rows
136
+  
137
+  // 重置表单
138
+  form.value = {
139
+    customerCompany: '',
140
+    ownerCompany: '',
141
+    orderNo: '',
142
+    contractNo: '',
143
+    deliveryAddress: '',
144
+    prodPlace: '',
145
+    bundleNo: ''
146
+  }
147
+  
148
+  // 获取选项数据
149
+  fetchCustomerOptions()
150
+  fetchOwnerCompanyOptions()
151
+  
152
+  dialogVisible.value = true
153
+}
154
+
155
+// 关闭弹窗
156
+const handleClose = () => {
157
+  dialogVisible.value = false
158
+  selectedRows.value = []
159
+  form.value = {
160
+    customerCompany: '',
161
+    ownerCompany: '',
162
+    orderNo: '',
163
+    contractNo: '',
164
+    deliveryAddress: '',
165
+    prodPlace: '',
166
+    bundleNo: ''
167
+  }
168
+}
169
+
170
+// 确定
171
+const handleConfirm = async () => {
172
+  // 检查是否至少填写了一个字段
173
+  const hasValue = Object.values(form.value).some(val => val && val.toString().trim() !== '')
174
+  
175
+  if (!hasValue) {
176
+    ElMessage.warning('请至少填写一个要修改的字段')
177
+    return
178
+  }
179
+  
180
+  try {
181
+    // 构建批量修改的数据
182
+    const updateData = {
183
+      ids: selectedRows.value.map(row => row.id || row.inProdNo).filter(id => id),
184
+      updateFields: {}
185
+    }
186
+    
187
+    // 只包含有值的字段
188
+    if (form.value.customerCompany) {
189
+      updateData.updateFields.customerCompany = form.value.customerCompany
190
+    }
191
+    if (form.value.ownerCompany) {
192
+      updateData.updateFields.ownerCompany = form.value.ownerCompany
193
+    }
194
+    if (form.value.orderNo) {
195
+      updateData.updateFields.orderNo = form.value.orderNo
196
+    }
197
+    if (form.value.contractNo) {
198
+      updateData.updateFields.contractNo = form.value.contractNo
199
+    }
200
+    if (form.value.deliveryAddress) {
201
+      updateData.updateFields.deliveryAddress = form.value.deliveryAddress
202
+    }
203
+    if (form.value.prodPlace) {
204
+      updateData.updateFields.prodPlace = form.value.prodPlace
205
+    }
206
+    if (form.value.bundleNo) {
207
+      updateData.updateFields.bundleNo = form.value.bundleNo
208
+    }
209
+    
210
+    // TODO: 根据实际API调整接口地址和参数格式
211
+    const url = 'sto/OutRecord/batchUpdate' // 需要根据实际API调整
212
+    const param = {
213
+      json: JSON.stringify(updateData),
214
+      jsonList: JSON.stringify(selectedRows.value)
215
+    }
216
+    
217
+    const response = await proxy.$axios.post(url, param)
218
+    
219
+    if (response.data.code === 0 || response.data.code === '0') {
220
+      ElMessage.success('批量修改成功')
221
+      handleClose()
222
+      emit('success')
223
+    } else {
224
+      ElMessage.error(`批量修改失败:${response.data.msg || ''}`)
225
+    }
226
+  } catch (error) {
227
+    ElMessage.error(`批量修改失败:${error.message || ''}`)
228
+  }
229
+}
230
+
231
+// 取消
232
+const handleCancel = () => {
233
+  handleClose()
234
+}
235
+
236
+const emit = defineEmits(['success'])
237
+
238
+defineExpose({
239
+  open
240
+})
241
+</script>
242
+
243
+<style scoped>
244
+.dialog-footer {
245
+  text-align: right;
246
+}
247
+</style>
248
+
249
+
250
+

+ 164
- 0
src/views/sto/components/PopupBatchMove.vue Просмотреть файл

@@ -0,0 +1,164 @@
1
+<template>
2
+  <el-dialog
3
+    v-model="dialogVisible"
4
+    title="批量垛位"
5
+    width="500px"
6
+    :close-on-click-modal="false"
7
+    destroy-on-close
8
+    @close="handleClose"
9
+  >
10
+    <el-form :model="form" label-width="100px" label-position="right">
11
+      <el-form-item label="库房名称">
12
+        <el-select
13
+          v-model="form.wareId"
14
+          clearable
15
+          filterable
16
+          placeholder="请选择"
17
+          style="width: 100%;"
18
+        >
19
+          <el-option
20
+            v-for="item in wareOptions"
21
+            :key="item.value"
22
+            :label="item.label"
23
+            :value="item.value"
24
+          />
25
+        </el-select>
26
+      </el-form-item>
27
+
28
+      <el-form-item label="新垛位">
29
+        <el-input v-model="form.stackName" placeholder="请输入新垛位" />
30
+      </el-form-item>
31
+    </el-form>
32
+
33
+    <template #footer>
34
+      <div class="dialog-footer">
35
+        <el-button type="success" @click="handleSave">保存</el-button>
36
+        <el-button type="danger" @click="handleCancel">取消</el-button>
37
+      </div>
38
+    </template>
39
+  </el-dialog>
40
+</template>
41
+
42
+<script setup>
43
+import { ref, getCurrentInstance } from 'vue'
44
+import { ElMessage } from 'element-plus'
45
+
46
+const { proxy } = getCurrentInstance()
47
+
48
+const dialogVisible = ref(false)
49
+const wareOptions = ref([])
50
+const selectedRows = ref([])
51
+
52
+const form = ref({
53
+  wareId: '',
54
+  stackName: ''
55
+})
56
+
57
+// 获取库房选项
58
+const fetchWareOptions = async () => {
59
+  try {
60
+    const response = await proxy.$axios.get('sto/Ware/options', {})
61
+    if (response.data.code === 0 || response.data.code === '0') {
62
+      const options = response.data.data || []
63
+      wareOptions.value = options.map(item => ({
64
+        label: item.label || item.name || item.value || '',
65
+        value: item.value || item.id || item.code || item.label || ''
66
+      })).filter(item => item.label && item.value)
67
+    }
68
+  } catch (error) {
69
+    console.error('获取库房选项失败:', error)
70
+  }
71
+}
72
+
73
+// 打开弹窗
74
+const open = (rows) => {
75
+  if (!rows || rows.length === 0) {
76
+    ElMessage.warning('请先选择要批量倒垛的数据')
77
+    return
78
+  }
79
+  
80
+  selectedRows.value = rows
81
+  
82
+  // 重置表单
83
+  form.value = {
84
+    wareId: '',
85
+    stackName: ''
86
+  }
87
+  
88
+  // 获取库房选项
89
+  fetchWareOptions()
90
+  
91
+  dialogVisible.value = true
92
+}
93
+
94
+// 关闭弹窗
95
+const handleClose = () => {
96
+  dialogVisible.value = false
97
+  selectedRows.value = []
98
+  form.value = {
99
+    wareId: '',
100
+    stackName: ''
101
+  }
102
+}
103
+
104
+// 保存
105
+const handleSave = async () => {
106
+  if (!form.value.wareId) {
107
+    ElMessage.warning('请选择库房名称')
108
+    return
109
+  }
110
+  
111
+  if (!form.value.stackName || form.value.stackName.trim() === '') {
112
+    ElMessage.warning('请输入新垛位')
113
+    return
114
+  }
115
+  
116
+  try {
117
+    // 构建批量倒垛的数据
118
+    const moveData = {
119
+      wareId: form.value.wareId,
120
+      stackName: form.value.stackName.trim(),
121
+      ids: selectedRows.value.map(row => row.id || row.inProdNo).filter(id => id)
122
+    }
123
+    
124
+    // TODO: 根据实际API调整接口地址和参数格式
125
+    const url = 'sto/OutRecord/batchMove' // 需要根据实际API调整
126
+    const param = {
127
+      json: JSON.stringify(moveData),
128
+      jsonList: JSON.stringify(selectedRows.value)
129
+    }
130
+    
131
+    const response = await proxy.$axios.post(url, param)
132
+    
133
+    if (response.data.code === 0 || response.data.code === '0') {
134
+      ElMessage.success('批量倒垛成功')
135
+      handleClose()
136
+      emit('success')
137
+    } else {
138
+      ElMessage.error(`批量倒垛失败:${response.data.msg || ''}`)
139
+    }
140
+  } catch (error) {
141
+    ElMessage.error(`批量倒垛失败:${error.message || ''}`)
142
+  }
143
+}
144
+
145
+// 取消
146
+const handleCancel = () => {
147
+  handleClose()
148
+}
149
+
150
+const emit = defineEmits(['success'])
151
+
152
+defineExpose({
153
+  open
154
+})
155
+</script>
156
+
157
+<style scoped>
158
+.dialog-footer {
159
+  text-align: right;
160
+}
161
+</style>
162
+
163
+
164
+

+ 331
- 0
src/views/sto/components/PopupDistribution.vue Просмотреть файл

@@ -0,0 +1,331 @@
1
+<template>
2
+  <el-dialog
3
+    v-model="dialogVisible"
4
+    title="配车"
5
+    width="1000px"
6
+    :close-on-click-modal="false"
7
+    destroy-on-close
8
+    @close="handleClose"
9
+  >
10
+    <el-form :model="form" label-width="100px" label-position="right">
11
+      <el-row :gutter="20">
12
+        <el-col :span="8">
13
+				<el-form-item label="车号">
14
+            <el-select
15
+              v-model="form.truckNo"
16
+              clearable
17
+              filterable
18
+              allow-create
19
+              default-first-option
20
+              placeholder="请选择"
21
+              style="width: 100%;"
22
+              @change="handleTruckChange"
23
+            >
24
+              <el-option
25
+                v-for="item in truckOptions"
26
+                :key="item.value"
27
+                :label="item.label"
28
+                :value="item.value"
29
+              />
30
+					</el-select>
31
+				</el-form-item>
32
+        </el-col>
33
+        <el-col :span="8">
34
+				<el-form-item label="司机姓名">
35
+            <el-input v-model="form.driverName" placeholder="司机姓名" />
36
+				</el-form-item>
37
+        </el-col>
38
+        <el-col :span="8">
39
+				<el-form-item label="联系方式">
40
+            <el-input v-model="form.driverPhone" placeholder="联系方式" />
41
+				</el-form-item>
42
+        </el-col>
43
+      </el-row>
44
+
45
+      <el-row :gutter="20">
46
+        <el-col :span="8">
47
+          <el-form-item label="总重量">
48
+            <el-input :value="totalWeight" placeholder="总重量" readonly />
49
+          </el-form-item>
50
+        </el-col>
51
+        <el-col :span="8">
52
+          <el-form-item label="总数量">
53
+            <el-input :value="totalQuantity" placeholder="总数量" readonly />
54
+          </el-form-item>
55
+        </el-col>
56
+        <el-col :span="8">
57
+          <el-form-item label="提货单位">
58
+            <el-input v-model="form.deliveryCompany" placeholder="提货单位" />
59
+				</el-form-item>
60
+        </el-col>
61
+      </el-row>
62
+
63
+      <el-row :gutter="20">
64
+        <el-col :span="24">
65
+				<el-form-item label=" ">
66
+            <el-button type="success" @click="handleConfirm">确定</el-button>
67
+            <el-button type="success" @click="handleCancel">取消</el-button>
68
+            <el-button type="primary" @click="handlePrint">打印配车单</el-button>
69
+				</el-form-item>
70
+        </el-col>
71
+      </el-row>
72
+			</el-form>
73
+
74
+    <el-table
75
+      :data="tableData"
76
+      border
77
+      style="width: 100%; margin-top: 20px;"
78
+      max-height="400"
79
+    >
80
+      <el-table-column
81
+        type="selection"
82
+        width="55"
83
+        header-align="center"
84
+        align="center"
85
+      />
86
+      <el-table-column
87
+        prop="layerNo"
88
+        label="层数"
89
+        width="80"
90
+        header-align="center"
91
+        align="center"
92
+        show-overflow-tooltip
93
+      >
94
+        <template #default="{ row }">
95
+          {{ row.outLayerNo ?? row.layerNo ?? '-' }}
96
+        </template>
97
+				</el-table-column>
98
+      <el-table-column
99
+        label="垛位"
100
+        width="120"
101
+        header-align="center"
102
+        align="center"
103
+        show-overflow-tooltip
104
+      >
105
+        <template #default="{ row }">
106
+          {{ row.outStackName ?? row.stackName ?? '-' }}
107
+        </template>
108
+				</el-table-column>
109
+      <el-table-column
110
+        label="物料"
111
+        min-width="140"
112
+        header-align="center"
113
+        align="center"
114
+        show-overflow-tooltip
115
+      >
116
+        <template #default="{ row }">
117
+          {{ row.materialName ?? '-' }}
118
+        </template>
119
+				</el-table-column>
120
+      <el-table-column
121
+        label="钢种"
122
+        width="120"
123
+        header-align="center"
124
+        align="center"
125
+        show-overflow-tooltip
126
+      >
127
+        <template #default="{ row }">
128
+          {{ row.ST_GRADE ?? row.stGrade ?? '-' }}
129
+        </template>
130
+				</el-table-column>
131
+      <el-table-column
132
+        prop="inProdNo"
133
+        label="钢板号"
134
+        min-width="160"
135
+        header-align="center"
136
+        align="center"
137
+        show-overflow-tooltip
138
+      />
139
+      <el-table-column
140
+        prop="materialStandard"
141
+        label="规格型号"
142
+        min-width="140"
143
+        header-align="center"
144
+        align="center"
145
+        show-overflow-tooltip
146
+      />
147
+      <el-table-column
148
+        label="数量"
149
+        width="100"
150
+        header-align="center"
151
+        align="right"
152
+        show-overflow-tooltip
153
+      >
154
+        <template #default="{ row }">
155
+          {{ row.outQuantity ?? row.OUT_QUANTITY ?? '-' }}
156
+        </template>
157
+				</el-table-column>
158
+      <el-table-column
159
+        label="重量"
160
+        width="100"
161
+        header-align="center"
162
+        align="right"
163
+        show-overflow-tooltip
164
+      >
165
+        <template #default="{ row }">
166
+          {{ row.outWeight ?? row.OUT_WEIGHT ?? '-' }}
167
+        </template>
168
+				</el-table-column>
169
+			</el-table>
170
+		</el-dialog>
171
+</template>
172
+
173
+<script setup>
174
+import { ref, computed, watch, getCurrentInstance } from 'vue'
175
+import { ElMessage } from 'element-plus'
176
+
177
+const { proxy } = getCurrentInstance()
178
+
179
+const dialogVisible = ref(false)
180
+const truckOptions = ref([])
181
+const tableData = ref([])
182
+
183
+const form = ref({
184
+					truckNo: '',
185
+					driverName: '',
186
+					driverPhone: '',
187
+  deliveryCompany: ''
188
+})
189
+
190
+// 计算总重量和总数量
191
+const totalWeight = computed(() => {
192
+  const total = tableData.value.reduce((sum, row) => {
193
+    const weight = parseFloat(row.outWeight ?? row.OUT_WEIGHT ?? 0) || 0
194
+    return sum + weight
195
+  }, 0)
196
+  return total.toFixed(3)
197
+})
198
+
199
+const totalQuantity = computed(() => {
200
+  const total = tableData.value.reduce((sum, row) => {
201
+    const quantity = parseFloat(row.outQuantity ?? row.OUT_QUANTITY ?? 0) || 0
202
+    return sum + quantity
203
+  }, 0)
204
+  return total.toFixed(0)
205
+})
206
+
207
+// 获取车辆列表
208
+const fetchTrucks = async () => {
209
+  try {
210
+    const response = await proxy.$axios.get('WareDistribution/queryWaitTrucks.do', {})
211
+    if (response.data.code === 0 || response.data.code === '0') {
212
+      const trucks = response.data.data || []
213
+      truckOptions.value = trucks.map(item => ({
214
+        label: item.truckNo || item.label || '',
215
+        value: item.truckNo || item.value || ''
216
+      })).filter(item => item.label && item.value)
217
+    }
218
+  } catch (error) {
219
+    console.error('获取车辆列表失败:', error)
220
+  }
221
+}
222
+
223
+// 车号选择变化
224
+const handleTruckChange = (val) => {
225
+  if (val) {
226
+    const truck = truckOptions.value.find(item => item.value === val)
227
+    if (truck && truck.originalData) {
228
+      form.value.driverName = truck.originalData.driverName || ''
229
+      form.value.driverPhone = truck.originalData.driverPhone || ''
230
+    }
231
+  }
232
+}
233
+
234
+// 打开弹窗
235
+const open = (selectedRows) => {
236
+  if (!selectedRows || selectedRows.length === 0) {
237
+    ElMessage.warning('请先选择要配货的数据')
238
+    return
239
+  }
240
+  
241
+  // 重置表单
242
+  form.value = {
243
+    truckNo: '',
244
+    driverName: '',
245
+    driverPhone: '',
246
+    deliveryCompany: ''
247
+  }
248
+  
249
+  // 设置表格数据为选中的行
250
+  tableData.value = selectedRows.map(row => ({ ...row }))
251
+  
252
+  // 获取车辆列表
253
+  fetchTrucks()
254
+  
255
+  dialogVisible.value = true
256
+}
257
+
258
+// 关闭弹窗
259
+const handleClose = () => {
260
+  dialogVisible.value = false
261
+  tableData.value = []
262
+  form.value = {
263
+					truckNo: '',
264
+					driverName: '',
265
+					driverPhone: '',
266
+    deliveryCompany: ''
267
+  }
268
+}
269
+
270
+// 确定
271
+const handleConfirm = async () => {
272
+  if (!form.value.truckNo) {
273
+    ElMessage.warning('请选择车号')
274
+					return
275
+				}
276
+  
277
+  try {
278
+    const distribution = {
279
+      truckNo: form.value.truckNo,
280
+      driverName: form.value.driverName,
281
+      driverPhone: form.value.driverPhone,
282
+      sumWeight: totalWeight.value,
283
+      sumCount: totalQuantity.value,
284
+      deliveryCompany: form.value.deliveryCompany,
285
+      listDetail: tableData.value
286
+    }
287
+    
288
+    const param = {
289
+      json: JSON.stringify(distribution),
290
+      jsonList: JSON.stringify(tableData.value)
291
+    }
292
+    
293
+    const response = await proxy.$axios.post('WareDistribution/save.do', param)
294
+    
295
+    if (response.data.code === 0 || response.data.code === '0') {
296
+      ElMessage.success('配货成功')
297
+      handleClose()
298
+      emit('success')
299
+    } else {
300
+      ElMessage.error(`配货失败:${response.data.msg || ''}`)
301
+    }
302
+  } catch (error) {
303
+    ElMessage.error(`配货失败:${error.message || ''}`)
304
+  }
305
+}
306
+
307
+// 取消
308
+const handleCancel = () => {
309
+  handleClose()
310
+}
311
+
312
+// 打印配车单
313
+const handlePrint = () => {
314
+  if (!form.value.truckNo) {
315
+    ElMessage.warning('请选择车号')
316
+    return
317
+  }
318
+  
319
+  // TODO: 实现打印逻辑
320
+  ElMessage.info('打印功能待实现')
321
+}
322
+
323
+const emit = defineEmits(['success'])
324
+
325
+defineExpose({
326
+  open
327
+})
328
+</script>
329
+
330
+<style scoped>
331
+</style>

+ 286
- 0
src/views/sto/components/PopupEdit.vue Просмотреть файл

@@ -0,0 +1,286 @@
1
+<template>
2
+  <el-dialog
3
+    v-model="dialogVisible"
4
+    title="修改材料信息"
5
+    width="900px"
6
+    top="5vh"
7
+    :close-on-click-modal="false"
8
+    destroy-on-close
9
+    @close="handleClose"
10
+  >
11
+    <el-form
12
+      :model="form"
13
+      label-width="90px"
14
+      label-position="right"
15
+    >
16
+      <el-row :gutter="20">
17
+        <el-col :span="12">
18
+          <el-form-item label="材料编号">
19
+            <el-input v-model="form.materialNo" disabled />
20
+          </el-form-item>
21
+        </el-col>
22
+        <el-col :span="12">
23
+          <el-form-item label="规格型号">
24
+            <el-input v-model="form.materialStandard" disabled />
25
+          </el-form-item>
26
+        </el-col>
27
+      </el-row>
28
+
29
+      <el-row :gutter="20">
30
+        <el-col :span="12">
31
+          <el-form-item label="品名">
32
+            <el-input v-model="form.materialName" disabled />
33
+          </el-form-item>
34
+        </el-col>
35
+        <el-col :span="12">
36
+          <el-form-item label="钢种">
37
+            <el-input v-model="form.stGrade" disabled />
38
+          </el-form-item>
39
+        </el-col>
40
+      </el-row>
41
+
42
+      <el-row :gutter="20">
43
+        <el-col :span="12">
44
+          <el-form-item label="数量">
45
+            <el-input v-model="form.outQuantity" />
46
+          </el-form-item>
47
+        </el-col>
48
+        <el-col :span="12">
49
+          <el-form-item label="重量">
50
+            <el-input v-model="form.outWeight" />
51
+          </el-form-item>
52
+        </el-col>
53
+      </el-row>
54
+
55
+      <el-row :gutter="20">
56
+        <el-col :span="12">
57
+          <el-form-item label="订单号">
58
+            <el-input v-model="form.orderNo" />
59
+          </el-form-item>
60
+        </el-col>
61
+        <el-col :span="12">
62
+          <el-form-item label="合约号">
63
+            <el-input v-model="form.contractNo" />
64
+          </el-form-item>
65
+        </el-col>
66
+      </el-row>
67
+
68
+      <el-row :gutter="20">
69
+        <el-col :span="12">
70
+          <el-form-item label="捆包号">
71
+            <el-input v-model="form.bundleNo" />
72
+          </el-form-item>
73
+        </el-col>
74
+        <el-col :span="12">
75
+          <el-form-item label="产地">
76
+            <el-input v-model="form.prodPlace" />
77
+          </el-form-item>
78
+        </el-col>
79
+      </el-row>
80
+
81
+      <el-row :gutter="20">
82
+        <el-col :span="12">
83
+          <el-form-item label="货权单位">
84
+            <el-select
85
+              v-model="form.ownerCompany"
86
+              clearable
87
+              filterable
88
+              placeholder="请选择货权单位"
89
+              style="width: 100%;"
90
+            >
91
+              <el-option
92
+                v-for="item in ownerCompanyOptions"
93
+                :key="item.value"
94
+                :label="item.label"
95
+                :value="item.value"
96
+              />
97
+            </el-select>
98
+          </el-form-item>
99
+        </el-col>
100
+        <el-col :span="12">
101
+          <el-form-item label="客户名称">
102
+            <el-select
103
+              v-model="form.customerCompany"
104
+              clearable
105
+              filterable
106
+              placeholder="请选择客户名称"
107
+              style="width: 100%;"
108
+            >
109
+              <el-option
110
+                v-for="item in customerCompanyOptions"
111
+                :key="item.value"
112
+                :label="item.label"
113
+                :value="item.value"
114
+              />
115
+            </el-select>
116
+          </el-form-item>
117
+        </el-col>
118
+      </el-row>
119
+
120
+      <el-row :gutter="20">
121
+        <el-col :span="24">
122
+          <el-form-item label="收货地址">
123
+            <el-input v-model="form.deliveryAddress" />
124
+          </el-form-item>
125
+        </el-col>
126
+      </el-row>
127
+
128
+      <el-row :gutter="20">
129
+        <el-col :span="24">
130
+          <el-form-item label="备注">
131
+            <el-input v-model="form.remark" type="textarea" :rows="2" />
132
+          </el-form-item>
133
+        </el-col>
134
+      </el-row>
135
+    </el-form>
136
+
137
+    <template #footer>
138
+      <div class="dialog-footer">
139
+        <el-button type="primary" @click="handleConfirm">确定</el-button>
140
+        <el-button @click="handleCancel">取消</el-button>
141
+      </div>
142
+    </template>
143
+  </el-dialog>
144
+</template>
145
+
146
+<script setup>
147
+import { ref, reactive, getCurrentInstance } from 'vue'
148
+import { ElMessage } from 'element-plus'
149
+
150
+const { proxy } = getCurrentInstance()
151
+
152
+const dialogVisible = ref(false)
153
+const customerCompanyOptions = ref([])
154
+const ownerCompanyOptions = ref([])
155
+
156
+const createEmptyForm = () => ({
157
+  materialNo: '',
158
+  materialStandard: '',
159
+  materialName: '',
160
+  stGrade: '',
161
+  outQuantity: '',
162
+  outWeight: '',
163
+  orderNo: '',
164
+  contractNo: '',
165
+  bundleNo: '',
166
+  prodPlace: '',
167
+  ownerCompany: '',
168
+  customerCompany: '',
169
+  deliveryAddress: '',
170
+  remark: ''
171
+})
172
+
173
+const form = reactive(createEmptyForm())
174
+
175
+// 获取客户名称选项
176
+const fetchCustomerOptions = async () => {
177
+  try {
178
+    const response = await proxy.$axios.get('sto/Customer/querySelect', {})
179
+    if (response.data.code === 0 || response.data.code === '0') {
180
+      const options = response.data.data || []
181
+      customerCompanyOptions.value = options.map(item => ({
182
+        label: item.label || item.name || item.value || '',
183
+        value: item.value || item.id || item.code || item.label || ''
184
+      })).filter(item => item.label && item.value)
185
+    }
186
+  } catch (error) {
187
+    console.error('获取客户名称选项失败:', error)
188
+  }
189
+}
190
+
191
+// 获取货权单位选项
192
+const fetchOwnerCompanyOptions = async () => {
193
+  try {
194
+    const response = await proxy.$axios.get('sto/Customer/querySelect', {})
195
+    if (response.data.code === 0 || response.data.code === '0') {
196
+      const options = response.data.data || []
197
+      ownerCompanyOptions.value = options.map(item => ({
198
+        label: item.label || item.name || item.value || '',
199
+        value: item.value || item.id || item.code || item.label || ''
200
+      })).filter(item => item.label && item.value)
201
+    }
202
+  } catch (error) {
203
+    console.error('获取货权单位选项失败:', error)
204
+  }
205
+}
206
+
207
+// 打开弹窗
208
+const open = (row) => {
209
+  if (!row) {
210
+    ElMessage.warning('请选择要编辑的数据')
211
+    return
212
+  }
213
+  
214
+  // 重置表单并回填当前行数据
215
+  Object.assign(form, createEmptyForm(), {
216
+    materialNo: row.inProdNo ?? '',
217
+    materialStandard: row.materialStandard ?? '',
218
+    materialName: row.materialName ?? '',
219
+    stGrade: row.ST_GRADE ?? row.stGrade ?? '',
220
+    outQuantity: row.outQuantity ?? row.OUT_QUANTITY ?? '',
221
+    outWeight: row.outWeight ?? row.OUT_WEIGHT ?? '',
222
+    orderNo: row.orderNo ?? '',
223
+    contractNo: row.contractNo ?? '',
224
+    bundleNo: row.bundleNo ?? '',
225
+    prodPlace: row.prodPlace ?? '',
226
+    ownerCompany: row.ownerCompany ?? '',
227
+    customerCompany: row.customerCompany ?? row.CustomerCompany ?? '',
228
+    deliveryAddress: row.deliveryAddress ?? '',
229
+    remark: row.remark ?? ''
230
+  })
231
+  
232
+  // 获取选项数据
233
+  fetchCustomerOptions()
234
+  fetchOwnerCompanyOptions()
235
+  
236
+  dialogVisible.value = true
237
+}
238
+
239
+// 关闭弹窗
240
+const handleClose = () => {
241
+  dialogVisible.value = false
242
+  Object.assign(form, createEmptyForm())
243
+}
244
+
245
+// 确定
246
+const handleConfirm = async () => {
247
+  try {
248
+    // TODO: 根据实际API调整接口地址和参数格式
249
+    const url = 'sto/OutRecord/update' // 需要根据实际API调整
250
+    const param = {
251
+      json: JSON.stringify(form)
252
+    }
253
+    
254
+    const response = await proxy.$axios.post(url, param)
255
+    
256
+    if (response.data.code === 0 || response.data.code === '0') {
257
+      ElMessage.success('修改成功')
258
+      handleClose()
259
+      emit('success')
260
+    } else {
261
+      ElMessage.error(`修改失败:${response.data.msg || ''}`)
262
+    }
263
+  } catch (error) {
264
+    ElMessage.error(`修改失败:${error.message || ''}`)
265
+  }
266
+}
267
+
268
+// 取消
269
+const handleCancel = () => {
270
+  handleClose()
271
+}
272
+
273
+const emit = defineEmits(['success'])
274
+
275
+defineExpose({
276
+  open
277
+})
278
+</script>
279
+
280
+<style scoped>
281
+.dialog-footer {
282
+  text-align: right;
283
+}
284
+</style>
285
+
286
+

+ 381
- 0
src/views/sto/components/PopupOutStock.vue Просмотреть файл

@@ -0,0 +1,381 @@
1
+<template>
2
+  <el-dialog
3
+    v-model="dialogVisible"
4
+    title="客户"
5
+    width="1000px"
6
+    :close-on-click-modal="false"
7
+    destroy-on-close
8
+    @close="handleClose"
9
+  >
10
+    <el-form :model="form" label-width="100px" label-position="right">
11
+      <el-row :gutter="20">
12
+        <el-col :span="8">
13
+          <el-form-item label="车号">
14
+            <el-select
15
+              v-model="form.truckNo"
16
+              clearable
17
+              filterable
18
+              allow-create
19
+              default-first-option
20
+              placeholder="请选择"
21
+              style="width: 100%;"
22
+              @change="handleTruckChange"
23
+            >
24
+              <el-option
25
+                v-for="item in truckOptions"
26
+                :key="item.value"
27
+                :label="item.label"
28
+                :value="item.value"
29
+              />
30
+            </el-select>
31
+          </el-form-item>
32
+        </el-col>
33
+        <el-col :span="8">
34
+          <el-form-item label="司机姓名">
35
+            <el-input v-model="form.driverName" placeholder="司机姓名" />
36
+          </el-form-item>
37
+        </el-col>
38
+        <el-col :span="8">
39
+          <el-form-item label="联系方式">
40
+            <el-input v-model="form.driverPhone" placeholder="联系方式" />
41
+          </el-form-item>
42
+        </el-col>
43
+      </el-row>
44
+
45
+      <el-row :gutter="20">
46
+        <el-col :span="8">
47
+          <el-form-item label="总重量">
48
+            <el-input :value="totalWeight" placeholder="总重量" readonly />
49
+          </el-form-item>
50
+        </el-col>
51
+        <el-col :span="8">
52
+          <el-form-item label="总数量">
53
+            <el-input :value="totalQuantity" placeholder="总数量" readonly />
54
+          </el-form-item>
55
+        </el-col>
56
+        <el-col :span="8">
57
+          <el-form-item label="过磅重量">
58
+            <el-input v-model="form.suttle" placeholder="过磅重量" />
59
+          </el-form-item>
60
+        </el-col>
61
+      </el-row>
62
+
63
+      <el-row :gutter="20">
64
+        <el-col :span="8">
65
+          <el-form-item label="理货人员">
66
+            <el-select
67
+              v-model="form.tallyPeople"
68
+              clearable
69
+              filterable
70
+              placeholder="理货人员"
71
+              style="width: 100%;"
72
+            >
73
+              <el-option
74
+                v-for="item in tallyPeopleOptions"
75
+                :key="item.value"
76
+                :label="item.label"
77
+                :value="item.value"
78
+              />
79
+            </el-select>
80
+          </el-form-item>
81
+        </el-col>
82
+        <el-col :span="8">
83
+          <el-form-item label=" ">
84
+            <el-button type="success" @click="handleOutStock">出库</el-button>
85
+          </el-form-item>
86
+        </el-col>
87
+        <el-col :span="4">
88
+          <el-form-item label="是否打印地址">
89
+            <el-switch v-model="form.printAddress" active-color="#13ce66" inactive-color="#ff4949" />
90
+          </el-form-item>
91
+        </el-col>
92
+        <el-col :span="4">
93
+          <el-form-item label="是否打印备注">
94
+            <el-switch v-model="form.printRemark" active-color="#13ce66" inactive-color="#ff4949" />
95
+          </el-form-item>
96
+        </el-col>
97
+      </el-row>
98
+    </el-form>
99
+
100
+    <el-table
101
+      :data="tableData"
102
+      border
103
+      style="width: 100%; margin-top: 20px;"
104
+      max-height="400"
105
+    >
106
+      <el-table-column
107
+        prop="layerNo"
108
+        label="层数"
109
+        width="80"
110
+        header-align="center"
111
+        align="center"
112
+        show-overflow-tooltip
113
+      >
114
+        <template #default="{ row }">
115
+          {{ row.outLayerNo ?? row.layerNo ?? '-' }}
116
+        </template>
117
+      </el-table-column>
118
+      <el-table-column
119
+        label="垛位"
120
+        width="120"
121
+        header-align="center"
122
+        align="center"
123
+        show-overflow-tooltip
124
+      >
125
+        <template #default="{ row }">
126
+          {{ row.outStackName ?? row.stackName ?? '-' }}
127
+        </template>
128
+      </el-table-column>
129
+      <el-table-column
130
+        label="物料"
131
+        min-width="140"
132
+        header-align="center"
133
+        align="center"
134
+        show-overflow-tooltip
135
+      >
136
+        <template #default="{ row }">
137
+          {{ row.materialName ?? '-' }}
138
+        </template>
139
+      </el-table-column>
140
+      <el-table-column
141
+        label="钢种"
142
+        width="120"
143
+        header-align="center"
144
+        align="center"
145
+        show-overflow-tooltip
146
+      >
147
+        <template #default="{ row }">
148
+          {{ row.ST_GRADE ?? row.stGrade ?? '-' }}
149
+        </template>
150
+      </el-table-column>
151
+      <el-table-column
152
+        prop="inProdNo"
153
+        label="钢板号"
154
+        min-width="160"
155
+        header-align="center"
156
+        align="center"
157
+        show-overflow-tooltip
158
+      />
159
+      <el-table-column
160
+        prop="materialStandard"
161
+        label="规格型号"
162
+        min-width="140"
163
+        header-align="center"
164
+        align="center"
165
+        show-overflow-tooltip
166
+      />
167
+      <el-table-column
168
+        label="数量"
169
+        width="100"
170
+        header-align="center"
171
+        align="right"
172
+        show-overflow-tooltip
173
+      >
174
+        <template #default="{ row }">
175
+          {{ row.outQuantity ?? row.OUT_QUANTITY ?? '-' }}
176
+        </template>
177
+      </el-table-column>
178
+      <el-table-column
179
+        label="重量"
180
+        width="100"
181
+        header-align="center"
182
+        align="right"
183
+        show-overflow-tooltip
184
+      >
185
+        <template #default="{ row }">
186
+          {{ row.outWeight ?? row.OUT_WEIGHT ?? '-' }}
187
+        </template>
188
+      </el-table-column>
189
+    </el-table>
190
+  </el-dialog>
191
+</template>
192
+
193
+<script setup>
194
+import { ref, computed, getCurrentInstance } from 'vue'
195
+import { ElMessage, ElMessageBox } from 'element-plus'
196
+
197
+const { proxy } = getCurrentInstance()
198
+
199
+const dialogVisible = ref(false)
200
+const truckOptions = ref([])
201
+const tallyPeopleOptions = ref([])
202
+const tableData = ref([])
203
+
204
+const form = ref({
205
+  truckNo: '',
206
+  driverName: '',
207
+  driverPhone: '',
208
+  suttle: '',
209
+  tallyPeople: '',
210
+  printAddress: true,
211
+  printRemark: true
212
+})
213
+
214
+// 计算总重量和总数量
215
+const totalWeight = computed(() => {
216
+  const total = tableData.value.reduce((sum, row) => {
217
+    const weight = parseFloat(row.outWeight ?? row.OUT_WEIGHT ?? 0) || 0
218
+    return sum + weight
219
+  }, 0)
220
+  return total.toFixed(3)
221
+})
222
+
223
+const totalQuantity = computed(() => {
224
+  const total = tableData.value.reduce((sum, row) => {
225
+    const quantity = parseFloat(row.outQuantity ?? row.OUT_QUANTITY ?? 0) || 0
226
+    return sum + quantity
227
+  }, 0)
228
+  return total.toFixed(0)
229
+})
230
+
231
+// 获取车辆列表
232
+const fetchTrucks = async () => {
233
+  try {
234
+    const response = await proxy.$axios.get('WareDistribution/queryWaitTrucks.do', {})
235
+    if (response.data.code === 0 || response.data.code === '0') {
236
+      const trucks = response.data.data || []
237
+      truckOptions.value = trucks.map(item => ({
238
+        label: item.truckNo || item.label || '',
239
+        value: item.truckNo || item.value || ''
240
+      })).filter(item => item.label && item.value)
241
+    }
242
+  } catch (error) {
243
+    console.error('获取车辆列表失败:', error)
244
+  }
245
+}
246
+
247
+// 获取理货人员选项
248
+const fetchTallyPeopleOptions = async () => {
249
+  try {
250
+    const response = await proxy.$axios.get('Common/querySelector.do', {
251
+      type: 'TALLY_PEOPLE'
252
+    })
253
+    if (response.data.code === 0 || response.data.code === '0') {
254
+      const options = response.data.data || []
255
+      tallyPeopleOptions.value = options.map(item => ({
256
+        label: item.dicName || item.label || '',
257
+        value: item.dicCode || item.value || ''
258
+      })).filter(item => item.label && item.value)
259
+    }
260
+  } catch (error) {
261
+    console.error('获取理货人员选项失败:', error)
262
+  }
263
+}
264
+
265
+// 车号选择变化
266
+const handleTruckChange = (val) => {
267
+  if (val) {
268
+    const truck = truckOptions.value.find(item => item.value === val)
269
+    if (truck && truck.originalData) {
270
+      form.value.driverName = truck.originalData.driverName || ''
271
+      form.value.driverPhone = truck.originalData.driverPhone || ''
272
+    }
273
+  }
274
+}
275
+
276
+// 打开弹窗
277
+const open = (selectedRows) => {
278
+  if (!selectedRows || selectedRows.length === 0) {
279
+    ElMessage.warning('请先选择要出库的数据')
280
+    return
281
+  }
282
+  
283
+  // 重置表单
284
+  form.value = {
285
+    truckNo: '',
286
+    driverName: '',
287
+    driverPhone: '',
288
+    suttle: '',
289
+    tallyPeople: '',
290
+    printAddress: true,
291
+    printRemark: true
292
+  }
293
+  
294
+  // 设置表格数据为选中的行
295
+  tableData.value = selectedRows.map(row => ({ ...row }))
296
+  
297
+  // 获取车辆列表和理货人员选项
298
+  fetchTrucks()
299
+  fetchTallyPeopleOptions()
300
+  
301
+  dialogVisible.value = true
302
+}
303
+
304
+// 关闭弹窗
305
+const handleClose = () => {
306
+  dialogVisible.value = false
307
+  tableData.value = []
308
+  form.value = {
309
+    truckNo: '',
310
+    driverName: '',
311
+    driverPhone: '',
312
+    suttle: '',
313
+    tallyPeople: '',
314
+    printAddress: true,
315
+    printRemark: true
316
+  }
317
+}
318
+
319
+// 出库
320
+const handleOutStock = async () => {
321
+  if (!form.value.truckNo) {
322
+    ElMessage.warning('请选择车号')
323
+    return
324
+  }
325
+  
326
+  try {
327
+    const distribution = {
328
+      truckNo: form.value.truckNo,
329
+      driverName: form.value.driverName,
330
+      driverPhone: form.value.driverPhone,
331
+      sumWeight: totalWeight.value,
332
+      sumCount: totalQuantity.value,
333
+      suttle: form.value.suttle || 0,
334
+      tallyPeople: form.value.tallyPeople,
335
+      printAddress: form.value.printAddress,
336
+      printRemark: form.value.printRemark,
337
+      listDetail: tableData.value
338
+    }
339
+    
340
+    const param = {
341
+      json: JSON.stringify(distribution)
342
+    }
343
+    
344
+    const response = await proxy.$axios.post('WareOut/outByDistribution.do', param)
345
+    
346
+    if (response.data.code === 0 || response.data.code === '0') {
347
+      // 如果存在现金支付方式,显示警告
348
+      if (response.data.payWay === '现金') {
349
+        await ElMessageBox.alert(
350
+          `存在支付方式为现金的材料,价格为${response.data.InvoicePrice},请在出库界面确认价格`,
351
+          '警告',
352
+          {
353
+            confirmButtonText: '确定',
354
+            type: 'warning'
355
+          }
356
+        )
357
+      }
358
+      
359
+      ElMessage.success('出库成功')
360
+      handleClose()
361
+      emit('success')
362
+    } else {
363
+      ElMessage.error(`出库失败:${response.data.msg || ''}`)
364
+    }
365
+  } catch (error) {
366
+    ElMessage.error(`出库失败:${error.message || ''}`)
367
+  }
368
+}
369
+
370
+const emit = defineEmits(['success'])
371
+
372
+defineExpose({
373
+  open
374
+})
375
+</script>
376
+
377
+<style scoped>
378
+</style>
379
+
380
+
381
+

+ 214
- 0
src/views/sto/components/PopupTransferOwnership.vue Просмотреть файл

@@ -0,0 +1,214 @@
1
+<template>
2
+  <el-dialog
3
+    v-model="dialogVisible"
4
+    title="货权转移"
5
+    width="600px"
6
+    :close-on-click-modal="false"
7
+    destroy-on-close
8
+    @close="handleClose"
9
+  >
10
+    <el-form :model="form" label-width="100px" label-position="right">
11
+      <el-form-item label="新客户">
12
+        <el-select
13
+          v-model="form.customerCompany"
14
+          clearable
15
+          filterable
16
+          placeholder="请选择客户名称"
17
+          style="width: 100%;"
18
+        >
19
+          <el-option
20
+            v-for="item in customerCompanyOptions"
21
+            :key="item.value"
22
+            :label="item.label"
23
+            :value="item.value"
24
+          />
25
+        </el-select>
26
+      </el-form-item>
27
+
28
+      <el-form-item label="新货主">
29
+        <el-select
30
+          v-model="form.ownerCompany"
31
+          clearable
32
+          filterable
33
+          placeholder="请选择货权单位"
34
+          style="width: 100%;"
35
+        >
36
+          <el-option
37
+            v-for="item in ownerCompanyOptions"
38
+            :key="item.value"
39
+            :label="item.label"
40
+            :value="item.value"
41
+          />
42
+        </el-select>
43
+      </el-form-item>
44
+
45
+      <el-form-item label="修改地址">
46
+        <el-input
47
+          v-model="form.deliveryAddress"
48
+          type="textarea"
49
+          :rows="3"
50
+          placeholder="请输入地址"
51
+        />
52
+      </el-form-item>
53
+    </el-form>
54
+
55
+    <template #footer>
56
+      <div class="dialog-footer">
57
+        <el-button type="success" @click="handleSave">保存</el-button>
58
+        <el-button type="danger" @click="handleCancel">取消</el-button>
59
+      </div>
60
+    </template>
61
+  </el-dialog>
62
+</template>
63
+
64
+<script setup>
65
+import { ref, getCurrentInstance } from 'vue'
66
+import { ElMessage } from 'element-plus'
67
+
68
+const { proxy } = getCurrentInstance()
69
+
70
+const dialogVisible = ref(false)
71
+const customerCompanyOptions = ref([])
72
+const ownerCompanyOptions = ref([])
73
+const selectedRows = ref([])
74
+
75
+const form = ref({
76
+  customerCompany: '',
77
+  ownerCompany: '',
78
+  deliveryAddress: ''
79
+})
80
+
81
+// 获取客户名称选项
82
+const fetchCustomerOptions = async () => {
83
+  try {
84
+    const response = await proxy.$axios.get('sto/Customer/querySelect', {})
85
+    if (response.data.code === 0 || response.data.code === '0') {
86
+      const options = response.data.data || []
87
+      customerCompanyOptions.value = options.map(item => ({
88
+        label: item.label || item.name || item.value || '',
89
+        value: item.value || item.id || item.code || item.label || ''
90
+      })).filter(item => item.label && item.value)
91
+    }
92
+  } catch (error) {
93
+    console.error('获取客户名称选项失败:', error)
94
+  }
95
+}
96
+
97
+// 获取货权单位选项
98
+const fetchOwnerCompanyOptions = async () => {
99
+  try {
100
+    const response = await proxy.$axios.get('sto/Customer/querySelect', {})
101
+    if (response.data.code === 0 || response.data.code === '0') {
102
+      const options = response.data.data || []
103
+      ownerCompanyOptions.value = options.map(item => ({
104
+        label: item.label || item.name || item.value || '',
105
+        value: item.value || item.id || item.code || item.label || ''
106
+      })).filter(item => item.label && item.value)
107
+    }
108
+  } catch (error) {
109
+    console.error('获取货权单位选项失败:', error)
110
+  }
111
+}
112
+
113
+// 打开弹窗
114
+const open = (rows) => {
115
+  if (!rows || rows.length === 0) {
116
+    ElMessage.warning('请先选择要转移货权的数据')
117
+    return
118
+  }
119
+  
120
+  selectedRows.value = rows
121
+  
122
+  // 重置表单
123
+  form.value = {
124
+    customerCompany: '',
125
+    ownerCompany: '',
126
+    deliveryAddress: ''
127
+  }
128
+  
129
+  // 获取选项数据
130
+  fetchCustomerOptions()
131
+  fetchOwnerCompanyOptions()
132
+  
133
+  dialogVisible.value = true
134
+}
135
+
136
+// 关闭弹窗
137
+const handleClose = () => {
138
+  dialogVisible.value = false
139
+  selectedRows.value = []
140
+  form.value = {
141
+    customerCompany: '',
142
+    ownerCompany: '',
143
+    deliveryAddress: ''
144
+  }
145
+}
146
+
147
+// 保存
148
+const handleSave = async () => {
149
+  // 检查是否至少填写了一个字段
150
+  const hasValue = form.value.customerCompany || form.value.ownerCompany || (form.value.deliveryAddress && form.value.deliveryAddress.trim() !== '')
151
+  
152
+  if (!hasValue) {
153
+    ElMessage.warning('请至少填写一个要修改的字段')
154
+    return
155
+  }
156
+  
157
+  try {
158
+    // 构建货权转移的数据
159
+    const transferData = {
160
+      ids: selectedRows.value.map(row => row.id || row.inProdNo).filter(id => id),
161
+      updateFields: {}
162
+    }
163
+    
164
+    // 只包含有值的字段
165
+    if (form.value.customerCompany) {
166
+      transferData.updateFields.customerCompany = form.value.customerCompany
167
+    }
168
+    if (form.value.ownerCompany) {
169
+      transferData.updateFields.ownerCompany = form.value.ownerCompany
170
+    }
171
+    if (form.value.deliveryAddress && form.value.deliveryAddress.trim() !== '') {
172
+      transferData.updateFields.deliveryAddress = form.value.deliveryAddress.trim()
173
+    }
174
+    
175
+    // TODO: 根据实际API调整接口地址和参数格式
176
+    const url = 'sto/OutRecord/transferOwnership' // 需要根据实际API调整
177
+    const param = {
178
+      json: JSON.stringify(transferData),
179
+      jsonList: JSON.stringify(selectedRows.value)
180
+    }
181
+    
182
+    const response = await proxy.$axios.post(url, param)
183
+    
184
+    if (response.data.code === 0 || response.data.code === '0') {
185
+      ElMessage.success('货权转移成功')
186
+      handleClose()
187
+      emit('success')
188
+    } else {
189
+      ElMessage.error(`货权转移失败:${response.data.msg || ''}`)
190
+    }
191
+  } catch (error) {
192
+    ElMessage.error(`货权转移失败:${error.message || ''}`)
193
+  }
194
+}
195
+
196
+// 取消
197
+const handleCancel = () => {
198
+  handleClose()
199
+}
200
+
201
+const emit = defineEmits(['success'])
202
+
203
+defineExpose({
204
+  open
205
+})
206
+</script>
207
+
208
+<style scoped>
209
+.dialog-footer {
210
+  text-align: right;
211
+}
212
+</style>
213
+
214
+

+ 976
- 0
src/views/sto/ware/storeChange.vue Просмотреть файл

@@ -0,0 +1,976 @@
1
+<template>
2
+  <div>
3
+    <el-card :body-style="cardBodyStyle">
4
+      <el-form :model="query" label-width="90px" label-position="right">
5
+        <el-row :gutter="10">
6
+          <el-col :span="6">
7
+            <el-form-item label="库房名称">
8
+              <el-select
9
+                v-model="query.wareId"
10
+                clearable
11
+                filterable
12
+                placeholder="请选择库房"
13
+                style="width: 100%;"
14
+                @visible-change="handleWareVisible"
15
+              >
16
+                <el-option
17
+                  v-for="item in wareOptions"
18
+                  :key="item.value"
19
+                  :label="item.label"
20
+                  :value="item.value"
21
+                />
22
+              </el-select>
23
+            </el-form-item>
24
+          </el-col>
25
+          <el-col :span="6">
26
+            <el-form-item label="垛位名称">
27
+              <el-input v-model="query.stackName" clearable placeholder="请输入垛位名称" />
28
+            </el-form-item>
29
+          </el-col>
30
+          <el-col :span="6">
31
+            <el-form-item label="品名">
32
+              <el-input v-model="query.materialName" clearable placeholder="请输入品名" />
33
+            </el-form-item>
34
+          </el-col>
35
+          <el-col :span="6">
36
+            <el-form-item label="钢种">
37
+              <el-input v-model="query.stGrade" clearable placeholder="请输入钢种" />
38
+            </el-form-item>
39
+          </el-col>
40
+        </el-row>
41
+
42
+        <el-row :gutter="10">
43
+          <el-col :span="6">
44
+            <el-form-item label="规格型号">
45
+              <el-input v-model="query.materialStandard" clearable placeholder="请输入规格型号" />
46
+            </el-form-item>
47
+          </el-col>
48
+          <el-col :span="6">
49
+            <el-form-item label="捆包号">
50
+              <el-input v-model="query.bundleNo" clearable placeholder="请输入捆包号" />
51
+            </el-form-item>
52
+          </el-col>
53
+          <el-col :span="6">
54
+            <el-form-item label="材料号">
55
+              <el-input v-model="query.inProdNo" clearable placeholder="请输入材料号" />
56
+            </el-form-item>
57
+          </el-col>
58
+          <el-col :span="6">
59
+            <el-form-item label="订单号">
60
+              <el-input v-model="query.orderNo" clearable placeholder="请输入订单号" />
61
+            </el-form-item>
62
+          </el-col>
63
+        </el-row>
64
+
65
+        <el-row :gutter="10">
66
+          <el-col :span="6">
67
+            <el-form-item label="合约号">
68
+              <el-input v-model="query.contractNo" clearable placeholder="请输入合约号" />
69
+            </el-form-item>
70
+          </el-col>
71
+          <el-col :span="6">
72
+            <el-form-item label="货权单位">
73
+              <el-select
74
+                v-model="query.ownerCompany"
75
+                clearable
76
+                filterable
77
+                placeholder="请选择货权单位"
78
+                style="width: 100%;"
79
+                @visible-change="handleOwnerVisible"
80
+              >
81
+                <el-option
82
+                  v-for="item in ownerCompanyOptions"
83
+                  :key="item.value"
84
+                  :label="item.label"
85
+                  :value="item.value"
86
+                />
87
+              </el-select>
88
+            </el-form-item>
89
+          </el-col>
90
+          <el-col :span="6">
91
+            <el-form-item label="客户名称">
92
+              <el-select
93
+                v-model="query.customerCompany"
94
+                clearable
95
+                filterable
96
+                placeholder="请选择客户名称"
97
+                style="width: 100%;"
98
+                @visible-change="handleCustomerVisible"
99
+              >
100
+                <el-option
101
+                  v-for="item in customerCompanyOptions"
102
+                  :key="item.value"
103
+                  :label="item.label"
104
+                  :value="item.value"
105
+                />
106
+              </el-select>
107
+            </el-form-item>
108
+          </el-col>
109
+<!--          <el-col :span="6">-->
110
+<!--            <el-form-item label="出库车号">-->
111
+<!--              <el-input v-model="query.outTruckNo" clearable placeholder="请输入出库车号" />-->
112
+<!--            </el-form-item>-->
113
+<!--          </el-col>-->
114
+        </el-row>
115
+
116
+        <el-row :gutter="10">
117
+          <el-col :span="8">
118
+            <el-form-item label="入库时间">
119
+              <el-date-picker
120
+                v-model="query.outDtmRange"
121
+                type="datetimerange"
122
+                range-separator="至"
123
+                start-placeholder="开始时间"
124
+                end-placeholder="结束时间"
125
+                :default-time="defaultRangeTime"
126
+                style="width: 100%;"
127
+              />
128
+            </el-form-item>
129
+          </el-col>
130
+          <el-col :span="16">
131
+            <el-form-item label=" ">
132
+              <el-button type="primary" @click="handleSearch">查询</el-button>
133
+              <el-button @click="handleReset">重置</el-button>
134
+              <el-button type="primary" @click="handleTransferOwnership">货权转移</el-button>
135
+              <el-button type="primary" @click="handleAllocate">配货</el-button>
136
+              <el-button type="primary" @click="handleOutStock">出库</el-button>
137
+              <el-button @click="handleExport">导出记录</el-button>
138
+
139
+              <el-dropdown @command="handleOtherCommand">
140
+                <el-button>
141
+                  其他操作
142
+                  <i class="el-icon-arrow-down el-icon--right" />
143
+                </el-button>
144
+                <template #dropdown>
145
+                  <el-dropdown-menu>
146
+                    <el-dropdown-item command="cancelIn">取消入库</el-dropdown-item>
147
+                    <el-dropdown-item command="batchEdit">批量修改</el-dropdown-item>
148
+                    <el-dropdown-item command="batchMove">批量倒垛</el-dropdown-item>
149
+                  </el-dropdown-menu>
150
+                </template>
151
+              </el-dropdown>
152
+
153
+              <el-dropdown @command="handleLockCommand">
154
+                <el-button type="danger">
155
+                  封锁出仓
156
+                  <i class="el-icon-arrow-down el-icon--right" />
157
+                </el-button>
158
+                <template #dropdown>
159
+                  <el-dropdown-menu>
160
+                    <el-dropdown-item command="lock">封锁</el-dropdown-item>
161
+                    <el-dropdown-item command="unlock">取消封锁</el-dropdown-item>
162
+                    <el-dropdown-item command="inStock">入仓</el-dropdown-item>
163
+                  </el-dropdown-menu>
164
+                </template>
165
+              </el-dropdown>
166
+            </el-form-item>
167
+          </el-col>
168
+        </el-row>
169
+      </el-form>
170
+    </el-card>
171
+
172
+    <el-card :body-style="cardBodyStyle" class="summary-card">
173
+      <el-row :gutter="20">
174
+        <el-col :span="6">
175
+          <div class="summary-item">
176
+            <span class="summary-label">数量统计:</span>
177
+            <span class="summary-value">{{ statistics.totalQuantity ?? '-' }}</span>
178
+          </div>
179
+        </el-col>
180
+        <el-col :span="6">
181
+          <div class="summary-item">
182
+            <span class="summary-label">重量统计:</span>
183
+            <span class="summary-value">{{ statistics.totalWeight ?? '-' }}</span>
184
+          </div>
185
+        </el-col>
186
+      </el-row>
187
+    </el-card>
188
+
189
+    <el-card :body-style="cardBodyStyle">
190
+      <el-table
191
+        ref="tableRef"
192
+        v-loading="tableLoading"
193
+        :data="tableData"
194
+        border
195
+        highlight-current-row
196
+        @selection-change="handleSelectionChange"
197
+      >
198
+        <el-table-column
199
+            type="selection"
200
+            width="55"
201
+            header-align="center"
202
+            align="center"
203
+            fixed="left"
204
+        />
205
+        <el-table-column
206
+          label="操作"
207
+          width="100"
208
+          header-align="center"
209
+          align="center"
210
+          fixed="left"
211
+        >
212
+          <template #default="{ row }">
213
+            <el-button type="text" size="small" @click="handleEdit(row)">编辑</el-button>
214
+          </template>
215
+        </el-table-column>
216
+
217
+        <el-table-column label="仓库名称" min-width="140" header-align="center" align="center">
218
+          <template #default="{ row }">
219
+            {{ row.outWareName ?? row.wareName ?? '-' }}
220
+          </template>
221
+        </el-table-column>
222
+        <el-table-column label="垛位名称" min-width="140" header-align="center" align="center">
223
+          <template #default="{ row }">
224
+            {{ row.outStackName ?? row.stackName ?? '-' }}
225
+          </template>
226
+        </el-table-column>
227
+        <el-table-column label="层号" width="100" header-align="center" align="center">
228
+          <template #default="{ row }">
229
+            {{ row.outLayerNo ?? row.layerNo ?? '-' }}
230
+          </template>
231
+        </el-table-column>
232
+        <el-table-column label="物料名称" min-width="160" header-align="center" align="center">
233
+          <template #default="{ row }">
234
+            {{ row.materialName ?? '-' }}
235
+          </template>
236
+        </el-table-column>
237
+        <el-table-column label="钢种" width="140" header-align="center" align="center">
238
+          <template #default="{ row }">
239
+            {{ row.ST_GRADE ?? row.stGrade ?? '-' }}
240
+          </template>
241
+        </el-table-column>
242
+        <el-table-column prop="inDtm" label="入库时间" min-width="180" header-align="center" align="center" show-overflow-tooltip />
243
+        <el-table-column prop="ownerCompany" label="货权公司" min-width="160" header-align="center" align="center" show-overflow-tooltip />
244
+        <el-table-column prop="receivingCompany" label="收货公司" min-width="160" header-align="center" align="center" show-overflow-tooltip />
245
+        <el-table-column label="最终客户公司" min-width="180" header-align="center" align="center" show-overflow-tooltip>
246
+          <template #default="{ row }">
247
+            {{ row.customerCompany ?? row.CustomerCompany ?? '-' }}
248
+          </template>
249
+        </el-table-column>
250
+        <el-table-column prop="inProdNo" label="材料号" min-width="140" header-align="center" align="center" show-overflow-tooltip />
251
+        <el-table-column label="出库车号" min-width="140" header-align="center" align="center" show-overflow-tooltip>
252
+          <template #default="{ row }">
253
+            {{ row.outTruckNo ?? row.carNo ?? '-' }}
254
+          </template>
255
+        </el-table-column>
256
+        <el-table-column prop="orderNo" label="订单号" min-width="160" header-align="center" align="center" show-overflow-tooltip />
257
+        <el-table-column prop="contractNo" label="合约号" min-width="160" header-align="center" align="center" show-overflow-tooltip />
258
+        <el-table-column label="出库重量" min-width="140" header-align="center" align="right" show-overflow-tooltip>
259
+          <template #default="{ row }">
260
+            {{ row.outWeight ?? row.OUT_WEIGHT ?? '-' }}
261
+          </template>
262
+        </el-table-column>
263
+        <el-table-column label="出库数量" min-width="140" header-align="center" align="right" show-overflow-tooltip>
264
+          <template #default="{ row }">
265
+            {{ row.outQuantity ?? row.OUT_QUANTITY ?? '-' }}
266
+          </template>
267
+        </el-table-column>
268
+        <el-table-column label="出库标记" width="140" header-align="center" align="center">
269
+          <template #default="{ row }">
270
+            <el-tag :type="flagTagType(row.outFlag)" effect="plain">
271
+              {{ flagLabel(row.outFlag) }}
272
+            </el-tag>
273
+          </template>
274
+        </el-table-column>
275
+        <el-table-column prop="deliveryAddress" label="收货地址" min-width="200" header-align="center" align="center" show-overflow-tooltip />
276
+<!--        <el-table-column prop="outDtm" label="出库时间" min-width="180" header-align="center" align="center" show-overflow-tooltip />-->
277
+      </el-table>
278
+    </el-card>
279
+
280
+    <el-card :body-style="cardBodyStyle">
281
+      <el-pagination
282
+        :current-page="currentPage"
283
+        :page-size="pageSize"
284
+        :page-sizes="pageSizes"
285
+        :total="totalRows"
286
+        background="background"
287
+        layout="total, sizes, prev, pager, next, jumper"
288
+        @size-change="handleSizeChange"
289
+        @current-change="handleCurrentChange"
290
+      />
291
+    </el-card>
292
+
293
+    <!-- 编辑弹窗 -->
294
+    <PopupEdit ref="popupEditRef" @success="handleEditSuccess" />
295
+
296
+    <!-- 配货弹窗 -->
297
+    <PopupDistribution ref="popupDistributionRef" @success="handleDistributionSuccess" />
298
+
299
+    <!-- 出库弹窗 -->
300
+    <PopupOutStock ref="popupOutStockRef" @success="handleOutStockSuccess" />
301
+
302
+    <!-- 批量修改弹窗 -->
303
+    <PopupBatchEdit ref="popupBatchEditRef" @success="handleBatchEditSuccess" />
304
+
305
+    <!-- 批量倒垛弹窗 -->
306
+    <PopupBatchMove ref="popupBatchMoveRef" @success="handleBatchMoveSuccess" />
307
+
308
+    <!-- 货权转移弹窗 -->
309
+    <PopupTransferOwnership ref="popupTransferOwnershipRef" @success="handleTransferOwnershipSuccess" />
310
+  </div>
311
+</template>
312
+
313
+<script setup>
314
+import {getCurrentInstance, onMounted, reactive, ref} from 'vue'
315
+import {ElMessage, ElMessageBox} from 'element-plus'
316
+import tools from '@/tools'
317
+import PopupDistribution from '../components/PopupDistribution.vue'
318
+import PopupOutStock from '../components/PopupOutStock.vue'
319
+import PopupBatchEdit from '../components/PopupBatchEdit.vue'
320
+import PopupBatchMove from '../components/PopupBatchMove.vue'
321
+import PopupTransferOwnership from '../components/PopupTransferOwnership.vue'
322
+import PopupEdit from '../components/PopupEdit.vue'
323
+
324
+const {proxy} = getCurrentInstance()
325
+
326
+const cardBodyStyle = ref(tools.style.card)
327
+const tableLoading = ref(false)
328
+const tableData = ref([])
329
+const currentPage = ref(1)
330
+const totalRows = ref(0)
331
+const pageSizes = ref([10, 20, 50, 100])
332
+const pageSize = ref(10)
333
+const tableRef = ref(null)
334
+const popupDistributionRef = ref(null)
335
+const popupOutStockRef = ref(null)
336
+const popupBatchEditRef = ref(null)
337
+const popupBatchMoveRef = ref(null)
338
+const popupTransferOwnershipRef = ref(null)
339
+const popupEditRef = ref(null)
340
+const multipleSelection = ref([])
341
+
342
+const listUrl = ref('sto/WareStore/query')
343
+const statisticsUrl = ref('sto//WareStore/statistics')
344
+
345
+const wareOptions = ref([])
346
+const ownerCompanyOptions = ref([])
347
+const customerCompanyOptions = ref([])
348
+const statistics = reactive({
349
+  totalQuantity: 0,
350
+  totalWeight: 0
351
+})
352
+const defaultRangeTime = [
353
+  new Date(0, 0, 0, 0, 0, 0),
354
+  new Date(0, 0, 0, 23, 59, 59)
355
+]
356
+
357
+const toOptions = (list, labelKey, valueKey) =>
358
+  (list || []).map((item) => {
359
+    if (typeof item === 'string') {
360
+      return {
361
+        label: item,
362
+        value: item
363
+      }
364
+    }
365
+    return {
366
+      label: item?.[labelKey] ?? item?.label ?? item?.name ?? item?.value ?? '',
367
+      value: item?.[valueKey] ?? item?.value ?? item?.id ?? item?.code ?? item?.label ?? ''
368
+    }
369
+  }).filter((item) => item.label !== '' && item.value !== '')
370
+
371
+const createDefaultQuery = () => {
372
+  const today = new Date()
373
+  const start = new Date(today.getFullYear(), today.getMonth(), today.getDate())
374
+  const end = new Date(today.getFullYear(), today.getMonth(), today.getDate(), 23, 59, 59, 999)
375
+  return {
376
+    wareId: '',
377
+  stackName: '',
378
+  materialName: '',
379
+    stGrade: '',
380
+  materialStandard: '',
381
+    bundleNo: '',
382
+    inProdNo: '',
383
+    orderNo: '',
384
+    contractNo: '',
385
+  ownerCompany: '',
386
+    customerCompany: '',
387
+    outTruckNo: '',
388
+    outFlag: '',
389
+    outDtmRange: [start, end]
390
+  }
391
+}
392
+const query = reactive(createDefaultQuery())
393
+
394
+const formatDateTime = (value, isEnd = false) => {
395
+  if (!value) return ''
396
+  const date = new Date(value)
397
+  if (Number.isNaN(date.getTime())) return ''
398
+  if (isEnd && date.getHours() === 0 && date.getMinutes() === 0 && date.getSeconds() === 0) {
399
+    date.setHours(23, 59, 59, 999)
400
+  }
401
+  const pad = (num) => String(num).padStart(2, '0')
402
+  const yyyy = date.getFullYear()
403
+  const mm = pad(date.getMonth() + 1)
404
+  const dd = pad(date.getDate())
405
+  const hh = pad(date.getHours())
406
+  const mi = pad(date.getMinutes())
407
+  const ss = pad(date.getSeconds())
408
+  return `${yyyy}-${mm}-${dd} ${hh}:${mi}:${ss}`
409
+}
410
+
411
+const buildQueryParams = () => {
412
+  const [startOut, endOut] = query.outDtmRange || []
413
+  return {
414
+    wareId: query.wareId,
415
+    stackName: query.stackName,
416
+    materialName: query.materialName,
417
+    stGrade: query.stGrade,
418
+    materialStandard: query.materialStandard,
419
+    bundleNo: query.bundleNo,
420
+    inProdNo: query.inProdNo,
421
+    orderNo: query.orderNo,
422
+    contractNo: query.contractNo,
423
+    ownerCompany: query.ownerCompany,
424
+    customerCompany: query.customerCompany,
425
+    outTruckNo: query.outTruckNo,
426
+    outFlag: query.outFlag,
427
+    startDtm: formatDateTime(startOut),
428
+    endDtm: formatDateTime(endOut, true)
429
+  }
430
+}
431
+
432
+const getTableData = () => {
433
+  tableLoading.value = true
434
+  const param = {
435
+    page: currentPage.value,
436
+    rows: pageSize.value,
437
+    params: JSON.stringify(buildQueryParams())
438
+  }
439
+  proxy.$axios.get(listUrl.value, param).then((response) => {
440
+    if (response.data.code === '0') {
441
+      tableData.value = response.data.data.records || []
442
+      totalRows.value = response.data.data.total || 0
443
+    } else {
444
+      ElMessage.error(`查询失败:${response.data.msg || ''}`)
445
+    }
446
+  }).catch((error) => {
447
+    ElMessage.error(`查询失败:${error.message || ''}`)
448
+  }).finally(() => {
449
+    tableLoading.value = false
450
+  })
451
+}
452
+
453
+const getStatistics = () => {
454
+  const param = {
455
+    params: JSON.stringify(buildQueryParams())
456
+  }
457
+  proxy.$axios
458
+    .get(statisticsUrl.value, param)
459
+    .then((response) => {
460
+      if (response.data.code === '0' || response.data.code === 0) {
461
+        const data = response.data.data || {}
462
+        statistics.totalQuantity =
463
+          data.totalQuantity ??
464
+          data.outQuantity ??
465
+          data.OUT_QUANTITY ??
466
+          data.totalQty ??
467
+          0
468
+        statistics.totalWeight =
469
+          data.totalWeight ??
470
+          data.outWeight ??
471
+          data.OUT_WEIGHT ??
472
+          data.totalWgt ??
473
+          0
474
+      } else {
475
+        ElMessage.error(`统计失败:${response.data.msg || ''}`)
476
+      }
477
+    })
478
+    .catch((error) => {
479
+      ElMessage.error(`统计失败:${error.message || ''}`)
480
+    })
481
+}
482
+
483
+const handleSearch = () => {
484
+  currentPage.value = 1
485
+  getTableData()
486
+  getStatistics()
487
+}
488
+
489
+const handleReset = () => {
490
+  Object.assign(query, createDefaultQuery())
491
+  handleSearch()
492
+}
493
+
494
+// 按钮操作区
495
+const handleTransferOwnership = () => {
496
+  if (multipleSelection.value.length === 0) {
497
+    ElMessage.warning('请先选择要转移货权的数据')
498
+    return
499
+  }
500
+  popupTransferOwnershipRef.value?.open(multipleSelection.value)
501
+}
502
+
503
+const handleTransferOwnershipSuccess = () => {
504
+  // 货权转移成功后刷新数据
505
+  getTableData()
506
+  getStatistics()
507
+  // 清空选中
508
+  if (tableRef.value) {
509
+    tableRef.value.clearSelection()
510
+  }
511
+}
512
+
513
+const handleAllocate = () => {
514
+  if (multipleSelection.value.length === 0) {
515
+    ElMessage.warning('请先选择要配货的数据')
516
+    return
517
+  }
518
+  popupDistributionRef.value?.open(multipleSelection.value)
519
+}
520
+
521
+const handleSelectionChange = (selection) => {
522
+  multipleSelection.value = selection
523
+}
524
+
525
+const handleDistributionSuccess = () => {
526
+  // 配货成功后刷新数据
527
+  getTableData()
528
+  getStatistics()
529
+  // 清空选中
530
+  if (tableRef.value) {
531
+    tableRef.value.clearSelection()
532
+  }
533
+}
534
+
535
+const handleOutStock = () => {
536
+  if (multipleSelection.value.length === 0) {
537
+    ElMessage.warning('请先选择要出库的数据')
538
+    return
539
+  }
540
+  popupOutStockRef.value?.open(multipleSelection.value)
541
+}
542
+
543
+const handleOutStockSuccess = () => {
544
+  // 出库成功后刷新数据
545
+  getTableData()
546
+  getStatistics()
547
+  // 清空选中
548
+  if (tableRef.value) {
549
+    tableRef.value.clearSelection()
550
+  }
551
+}
552
+
553
+const handleExport = () => {
554
+  // TODO 导出记录逻辑
555
+  console.log('导出记录', buildQueryParams())
556
+}
557
+
558
+const handleOtherCommand = (command) => {
559
+  // 其他操作下拉:取消入库、批量修改、批量倒垛
560
+  switch (command) {
561
+    case 'cancelIn':
562
+      handleCancelInbound()
563
+      break
564
+    case 'batchEdit':
565
+      handleBatchEdit()
566
+      break
567
+    case 'batchMove':
568
+      handleBatchMove()
569
+      break
570
+    default:
571
+      break
572
+  }
573
+}
574
+
575
+// 取消入库
576
+const handleCancelInbound = () => {
577
+  if (multipleSelection.value.length === 0) {
578
+    ElMessage.warning('请先选择要取消入库的数据')
579
+    return
580
+  }
581
+  
582
+  ElMessageBox.confirm(
583
+    '确认取消入库吗?',
584
+    '提示',
585
+    {
586
+      confirmButtonText: '确认',
587
+      cancelButtonText: '取消',
588
+      type: 'warning'
589
+    }
590
+  ).then(() => {
591
+    // 确认后执行取消入库
592
+    executeCancelInbound()
593
+  }).catch(() => {
594
+    // 取消操作
595
+    ElMessage.info('已取消操作')
596
+  })
597
+}
598
+
599
+// 批量修改
600
+const handleBatchEdit = () => {
601
+  if (multipleSelection.value.length === 0) {
602
+    ElMessage.warning('请先选择要批量修改的数据')
603
+    return
604
+  }
605
+  popupBatchEditRef.value?.open(multipleSelection.value)
606
+}
607
+
608
+const handleBatchEditSuccess = () => {
609
+  // 批量修改成功后刷新数据
610
+  getTableData()
611
+  getStatistics()
612
+  // 清空选中
613
+  if (tableRef.value) {
614
+    tableRef.value.clearSelection()
615
+  }
616
+}
617
+
618
+// 批量倒垛
619
+const handleBatchMove = () => {
620
+  if (multipleSelection.value.length === 0) {
621
+    ElMessage.warning('请先选择要批量倒垛的数据')
622
+    return
623
+  }
624
+  popupBatchMoveRef.value?.open(multipleSelection.value)
625
+}
626
+
627
+const handleBatchMoveSuccess = () => {
628
+  // 批量倒垛成功后刷新数据
629
+  getTableData()
630
+  getStatistics()
631
+  // 清空选中
632
+  if (tableRef.value) {
633
+    tableRef.value.clearSelection()
634
+  }
635
+}
636
+
637
+// 执行取消入库
638
+const executeCancelInbound = async () => {
639
+  try {
640
+    // 收集选中的行ID
641
+    const ids = multipleSelection.value.map(row => row.id || row.inProdNo).filter(id => id)
642
+    
643
+    if (ids.length === 0) {
644
+      ElMessage.warning('选中的数据中没有有效的ID')
645
+      return
646
+    }
647
+    
648
+    // TODO: 根据实际API调整接口地址和参数格式
649
+    const url = 'sto/InRecord/cancel' // 需要根据实际API调整
650
+    const param = {
651
+      ids: JSON.stringify(ids),
652
+      jsonList: JSON.stringify(multipleSelection.value)
653
+    }
654
+    
655
+    const response = await proxy.$axios.post(url, param)
656
+    
657
+    if (response.data.code === 0 || response.data.code === '0') {
658
+      ElMessage.success('取消入库成功')
659
+      // 刷新数据
660
+      getTableData()
661
+      getStatistics()
662
+      // 清空选中
663
+      if (tableRef.value) {
664
+        tableRef.value.clearSelection()
665
+      }
666
+    } else {
667
+      ElMessage.error(`取消入库失败:${response.data.msg || ''}`)
668
+    }
669
+  } catch (error) {
670
+    ElMessage.error(`取消入库失败:${error.message || ''}`)
671
+  }
672
+}
673
+
674
+const handleLockCommand = (command) => {
675
+  // 封锁出仓下拉:封锁、取消封锁、入仓
676
+  switch (command) {
677
+    case 'lock':
678
+      handleLock()
679
+      break
680
+    case 'unlock':
681
+      handleUnlock()
682
+      break
683
+    case 'inStock':
684
+      handleInStock()
685
+      break
686
+    default:
687
+      break
688
+  }
689
+}
690
+
691
+// 封锁
692
+const handleLock = () => {
693
+  if (multipleSelection.value.length === 0) {
694
+    ElMessage.warning('请先选择要封锁的材料')
695
+    return
696
+  }
697
+  
698
+  ElMessageBox.confirm(
699
+    '确认将选中的材料进行封锁吗?',
700
+    '提示',
701
+    {
702
+      confirmButtonText: '确认',
703
+      cancelButtonText: '取消',
704
+      type: 'warning'
705
+    }
706
+  ).then(() => {
707
+    // 确认后执行封锁
708
+    executeLock()
709
+  }).catch(() => {
710
+    // 取消操作
711
+    ElMessage.info('已取消操作')
712
+  })
713
+}
714
+
715
+// 执行封锁
716
+const executeLock = async () => {
717
+  try {
718
+    // 收集选中的行ID
719
+    const ids = multipleSelection.value.map(row => row.id || row.inProdNo).filter(id => id)
720
+    
721
+    if (ids.length === 0) {
722
+      ElMessage.warning('选中的数据中没有有效的ID')
723
+      return
724
+    }
725
+    
726
+    // TODO: 根据实际API调整接口地址和参数格式
727
+    const url = 'sto/OutRecord/lock' // 需要根据实际API调整
728
+    const param = {
729
+      ids: JSON.stringify(ids),
730
+      jsonList: JSON.stringify(multipleSelection.value)
731
+    }
732
+    
733
+    const response = await proxy.$axios.post(url, param)
734
+    
735
+    if (response.data.code === 0 || response.data.code === '0') {
736
+      ElMessage.success('封锁成功')
737
+      // 刷新数据
738
+      getTableData()
739
+      getStatistics()
740
+      // 清空选中
741
+      if (tableRef.value) {
742
+        tableRef.value.clearSelection()
743
+      }
744
+    } else {
745
+      ElMessage.error(`封锁失败:${response.data.msg || ''}`)
746
+    }
747
+  } catch (error) {
748
+    ElMessage.error(`封锁失败:${error.message || ''}`)
749
+  }
750
+}
751
+
752
+// 取消封锁
753
+const handleUnlock = () => {
754
+  if (multipleSelection.value.length === 0) {
755
+    ElMessage.warning('请先选择要取消封锁的材料')
756
+    return
757
+  }
758
+  
759
+  ElMessageBox.confirm(
760
+    '确认将选中的材料取消封锁吗?',
761
+    '提示',
762
+    {
763
+      confirmButtonText: '确认',
764
+      cancelButtonText: '取消',
765
+      type: 'warning'
766
+    }
767
+  ).then(() => {
768
+    // 确认后执行取消封锁
769
+    executeUnlock()
770
+  }).catch(() => {
771
+    // 取消操作
772
+    ElMessage.info('已取消操作')
773
+  })
774
+}
775
+
776
+// 执行取消封锁
777
+const executeUnlock = async () => {
778
+  try {
779
+    // 收集选中的行ID
780
+    const ids = multipleSelection.value.map(row => row.id || row.inProdNo).filter(id => id)
781
+    
782
+    if (ids.length === 0) {
783
+      ElMessage.warning('选中的数据中没有有效的ID')
784
+      return
785
+    }
786
+    
787
+    // TODO: 根据实际API调整接口地址和参数格式
788
+    const url = 'sto/OutRecord/unlock' // 需要根据实际API调整
789
+    const param = {
790
+      ids: JSON.stringify(ids),
791
+      jsonList: JSON.stringify(multipleSelection.value)
792
+    }
793
+    
794
+    const response = await proxy.$axios.post(url, param)
795
+    
796
+    if (response.data.code === 0 || response.data.code === '0') {
797
+      ElMessage.success('取消封锁成功')
798
+      // 刷新数据
799
+      getTableData()
800
+      getStatistics()
801
+      // 清空选中
802
+      if (tableRef.value) {
803
+        tableRef.value.clearSelection()
804
+      }
805
+    } else {
806
+      ElMessage.error(`取消封锁失败:${response.data.msg || ''}`)
807
+    }
808
+  } catch (error) {
809
+    ElMessage.error(`取消封锁失败:${error.message || ''}`)
810
+  }
811
+}
812
+
813
+// 入仓
814
+const handleInStock = () => {
815
+  if (multipleSelection.value.length === 0) {
816
+    ElMessage.warning('请先选择要入仓的材料')
817
+    return
818
+  }
819
+  
820
+  ElMessageBox.confirm(
821
+    '确认将选中的材料标记为入仓吗?',
822
+    '提示',
823
+    {
824
+      confirmButtonText: '确认',
825
+      cancelButtonText: '取消',
826
+      type: 'warning'
827
+    }
828
+  ).then(() => {
829
+    // 确认后执行入仓
830
+    executeInStock()
831
+  }).catch(() => {
832
+    // 取消操作
833
+    ElMessage.info('已取消操作')
834
+  })
835
+}
836
+
837
+// 执行入仓
838
+const executeInStock = async () => {
839
+  try {
840
+    // 收集选中的行ID
841
+    const ids = multipleSelection.value.map(row => row.id || row.inProdNo).filter(id => id)
842
+    
843
+    if (ids.length === 0) {
844
+      ElMessage.warning('选中的数据中没有有效的ID')
845
+      return
846
+    }
847
+    
848
+    // TODO: 根据实际API调整接口地址和参数格式
849
+    const url = 'sto/OutRecord/inStock' // 需要根据实际API调整
850
+    const param = {
851
+      ids: JSON.stringify(ids),
852
+      jsonList: JSON.stringify(multipleSelection.value)
853
+    }
854
+    
855
+    const response = await proxy.$axios.post(url, param)
856
+    
857
+    if (response.data.code === 0 || response.data.code === '0') {
858
+      ElMessage.success('入仓成功')
859
+      // 刷新数据
860
+      getTableData()
861
+      getStatistics()
862
+      // 清空选中
863
+      if (tableRef.value) {
864
+        tableRef.value.clearSelection()
865
+      }
866
+    } else {
867
+      ElMessage.error(`入仓失败:${response.data.msg || ''}`)
868
+    }
869
+  } catch (error) {
870
+    ElMessage.error(`入仓失败:${error.message || ''}`)
871
+  }
872
+}
873
+
874
+const handleSizeChange = (val) => {
875
+  pageSize.value = val
876
+  getTableData()
877
+}
878
+
879
+const handleCurrentChange = (val) => {
880
+  currentPage.value = val
881
+  getTableData()
882
+}
883
+
884
+// 编辑功能
885
+const handleEdit = (row) => {
886
+  popupEditRef.value?.open(row)
887
+}
888
+
889
+const handleEditSuccess = () => {
890
+  // 编辑成功后刷新数据
891
+  getTableData()
892
+  getStatistics()
893
+}
894
+
895
+const flagLabel = (val) => {
896
+  if (val === '1' || val === 1) return '正常'
897
+  if (val === '2' || val === 2) return '取消出库'
898
+  return val ?? '-'
899
+}
900
+const flagTagType = (val) => {
901
+  if (val === '1' || val === 1) return 'success'
902
+  if (val === '2' || val === 2) return 'danger'
903
+  return 'info'
904
+}
905
+
906
+const fetchWareOptions = () => {
907
+  proxy.$axios.get('sto/Ware/options', {}).then((response) => {
908
+    if (response.data.code === 0 || response.data.code === '0') {
909
+      wareOptions.value = toOptions(response.data.data, 'label', 'value')
910
+    }
911
+  })
912
+}
913
+
914
+const fetchOwnerCompanyOptions = () => {
915
+  proxy.$axios.get('sto/Customer/querySelect', {}).then((response) => {
916
+    if (response.data.code === 0 || response.data.code === '0') {
917
+      ownerCompanyOptions.value = toOptions(response.data.data, 'label', 'value')
918
+    }
919
+  })
920
+}
921
+
922
+const fetchCustomerOptions = () => {
923
+  proxy.$axios.get('sto/Customer/querySelect', {}).then((response) => {
924
+    if (response.data.code === 0 || response.data.code === '0') {
925
+      customerCompanyOptions.value = toOptions(response.data.data, 'label', 'value')
926
+    }
927
+  })
928
+}
929
+
930
+const handleWareVisible = (visible) => {
931
+  if (visible && wareOptions.value.length === 0) {
932
+    fetchWareOptions()
933
+  }
934
+}
935
+
936
+const handleOwnerVisible = (visible) => {
937
+  if (visible && ownerCompanyOptions.value.length === 0) {
938
+    fetchOwnerCompanyOptions()
939
+  }
940
+}
941
+
942
+const handleCustomerVisible = (visible) => {
943
+  if (visible && customerCompanyOptions.value.length === 0) {
944
+    fetchCustomerOptions()
945
+  }
946
+}
947
+
948
+onMounted(() => {
949
+  fetchWareOptions()
950
+  fetchOwnerCompanyOptions()
951
+  fetchCustomerOptions()
952
+  getTableData()
953
+  getStatistics()
954
+})
955
+</script>
956
+
957
+<style scoped>
958
+.summary-card {
959
+  margin-top: 10px;
960
+}
961
+.summary-item {
962
+  display: flex;
963
+  align-items: center;
964
+  height: 40px;
965
+}
966
+.summary-label {
967
+  color: #606266;
968
+  margin-right: 6px;
969
+  font-weight: 500;
970
+}
971
+.summary-value {
972
+  font-size: 18px;
973
+  font-weight: 600;
974
+  color: #303133;
975
+}
976
+</style>

Загрузка…
Отмена
Сохранить