|
|
@@ -1,14 +1,60 @@
|
|
|
<template>
|
|
|
<div class="app-container">
|
|
|
<el-form :model="queryParams" ref="queryForm" :inline="true" v-show="showSearch" label-width="68px">
|
|
|
- <el-form-item label="订单编号" prop="orderCode">
|
|
|
- <el-input
|
|
|
- v-model="queryParams.orderCode"
|
|
|
- placeholder="请输入订单编号"
|
|
|
- clearable
|
|
|
- size="small"
|
|
|
- @keyup.enter.native="handleQuery"
|
|
|
- />
|
|
|
+ <el-form-item label="订单编号" prop="orderCodes">
|
|
|
+ <div class="tag-input-container">
|
|
|
+ <!-- 标签显示区域 -->
|
|
|
+ <div class="tags-wrapper" @click="focusInput">
|
|
|
+ <!-- 已添加的订单号标签 -->
|
|
|
+ <el-tag
|
|
|
+ v-for="(code, index) in queryParams.orderCodes"
|
|
|
+ :key="index"
|
|
|
+ closable
|
|
|
+ size="small"
|
|
|
+ @close="removeOrderCode(index)"
|
|
|
+ class="order-tag"
|
|
|
+ :class="{ 'tag-error': false }"
|
|
|
+ >
|
|
|
+ {{ code }}
|
|
|
+ </el-tag>
|
|
|
+
|
|
|
+ <!-- 输入框 -->
|
|
|
+ <el-input
|
|
|
+ ref="tagInput"
|
|
|
+ v-model="currentInput"
|
|
|
+ v-show="inputVisible || queryParams.orderCodes.length === 0"
|
|
|
+ :placeholder="queryParams.orderCodes.length === 0 ? '请输入订单号,按回车或逗号分隔' : '继续输入...'"
|
|
|
+ size="small"
|
|
|
+ class="tag-input"
|
|
|
+ @keydown.native="handleKeyDown"
|
|
|
+ @keyup.native="handleKeyUp"
|
|
|
+ @blur="handleInputConfirm"
|
|
|
+ @focus="inputVisible = true"
|
|
|
+ clearable
|
|
|
+ />
|
|
|
+
|
|
|
+ <!-- 添加按钮(当没有输入时显示) -->
|
|
|
+ <el-button
|
|
|
+ v-if="!inputVisible && queryParams.orderCodes.length > 0"
|
|
|
+ class="button-new-tag"
|
|
|
+ size="small"
|
|
|
+ @click="showInput"
|
|
|
+ icon="el-icon-plus"
|
|
|
+ type="text"
|
|
|
+ >
|
|
|
+ 添加订单号
|
|
|
+ </el-button>
|
|
|
+ </div>
|
|
|
+
|
|
|
+ <!-- 输入提示 -->
|
|
|
+ <div class="input-tips">
|
|
|
+ <span class="tip-text">
|
|
|
+ 支持:回车、逗号、空格分隔 |
|
|
|
+ 已添加 {{ queryParams.orderCodes.length }} 个订单号
|
|
|
+ <span v-if="maxOrderCodes > 0"> (最多{{ maxOrderCodes }}个)</span>
|
|
|
+ </span>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
</el-form-item>
|
|
|
<el-form-item label="用户名称" prop="userName">
|
|
|
<el-input
|
|
|
@@ -174,6 +220,20 @@
|
|
|
<el-table-column label="ERP账号" align="center" prop="loginAccount" />
|
|
|
<el-table-column label="ERP电话" align="center" prop="erpPhone" />
|
|
|
<el-table-column label="订单编号" align="center" prop="orderCode" />
|
|
|
+ <el-table-column label="商品名称" align="center" width="200">
|
|
|
+ <template slot-scope="scope">
|
|
|
+ <div style="display: flex; align-items: center; justify-content: center;">
|
|
|
+ <span>{{ scope.row.goodsName }}</span>
|
|
|
+ <el-image
|
|
|
+ v-if="scope.row.goodsImage"
|
|
|
+ :src="scope.row.goodsImage"
|
|
|
+ style="width: 40px; height: 40px; margin-left: 8px;"
|
|
|
+ fit="cover"
|
|
|
+ :preview-src-list="[scope.row.goodsImage]"
|
|
|
+ />
|
|
|
+ </div>
|
|
|
+ </template>
|
|
|
+ </el-table-column>
|
|
|
<el-table-column label="用户名称" align="center" prop="userName" />
|
|
|
<el-table-column label="用户电话" align="center" prop="userPhone" />
|
|
|
<el-table-column label="用户地址" align="center" prop="userAddress" show-overflow-tooltip />
|
|
|
@@ -528,6 +588,7 @@ export default {
|
|
|
pageNum: 1,
|
|
|
pageSize: 10,
|
|
|
orderCode: null,
|
|
|
+ orderCodes: [], // 添加订单号数组
|
|
|
userName: null,
|
|
|
userPhone: null,
|
|
|
integral: null,
|
|
|
@@ -541,6 +602,15 @@ export default {
|
|
|
companyId:null,
|
|
|
loginAccount: null // 添加ERP账号筛选字段
|
|
|
},
|
|
|
+ // 最大订单号数量限制
|
|
|
+ maxOrderCodes: {
|
|
|
+ type: Number,
|
|
|
+ default: 50
|
|
|
+ },
|
|
|
+ // 输入框是否可见
|
|
|
+ inputVisible: false,
|
|
|
+ // 当前输入值
|
|
|
+ currentInput: '',
|
|
|
createTime:null,
|
|
|
qwCompanyList:[],
|
|
|
companyUserNameList:[],
|
|
|
@@ -691,10 +761,57 @@ export default {
|
|
|
/** 查询积分商品订单列表 */
|
|
|
getList() {
|
|
|
this.loading = true;
|
|
|
+
|
|
|
+ // 直接传递订单编号数组给后端
|
|
|
listIntegralOrder(this.queryParams).then(response => {
|
|
|
- this.integralOrderList = response.rows;
|
|
|
+ // 解析itemJson字段,提取goodsName和图片
|
|
|
+ const processedData = response.rows.map(item => {
|
|
|
+ let goodsName = '';
|
|
|
+ let goodsImage = '';
|
|
|
+ try {
|
|
|
+ if (item.itemJson) {
|
|
|
+ const itemData = JSON.parse(item.itemJson);
|
|
|
+ // 如果itemJson是数组格式,取第一个商品的名称和图片
|
|
|
+ if (Array.isArray(itemData) && itemData.length > 0) {
|
|
|
+ goodsName = itemData[0].goodsName || '';
|
|
|
+ // 提取图片,优先使用imgUrl,如果没有则使用images的第一张
|
|
|
+ if (itemData[0].imgUrl) {
|
|
|
+ goodsImage = itemData[0].imgUrl;
|
|
|
+ } else if (itemData[0].images && itemData[0].images.split(',').length > 0) {
|
|
|
+ goodsImage = itemData[0].images.split(',')[0];
|
|
|
+ }
|
|
|
+ }
|
|
|
+ // 如果itemJson是对象格式,直接取goodsName和图片
|
|
|
+ else if (itemData.goodsName) {
|
|
|
+ goodsName = itemData.goodsName;
|
|
|
+ // 提取图片,优先使用imgUrl,如果没有则使用images的第一张
|
|
|
+ if (itemData.imgUrl) {
|
|
|
+ goodsImage = itemData.imgUrl;
|
|
|
+ } else if (itemData.images && itemData.images.split(',').length > 0) {
|
|
|
+ goodsImage = itemData.images.split(',')[0];
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ } catch (error) {
|
|
|
+ console.error('解析itemJson失败:', error);
|
|
|
+ goodsName = '';
|
|
|
+ goodsImage = '';
|
|
|
+ }
|
|
|
+
|
|
|
+ return {
|
|
|
+ ...item,
|
|
|
+ goodsName: goodsName,
|
|
|
+ goodsImage: goodsImage
|
|
|
+ };
|
|
|
+ });
|
|
|
+
|
|
|
+ this.integralOrderList = processedData;
|
|
|
this.total = response.total;
|
|
|
this.loading = false;
|
|
|
+ }).catch(error => {
|
|
|
+ console.error('查询订单列表失败:', error);
|
|
|
+ this.loading = false;
|
|
|
+ this.$message.error('查询订单列表失败');
|
|
|
});
|
|
|
},
|
|
|
// 取消按钮
|
|
|
@@ -739,6 +856,12 @@ export default {
|
|
|
this.queryParams.qwUserId=null;
|
|
|
this.queryParams.companyId=null;
|
|
|
this.queryParams.companyUserId=null;
|
|
|
+
|
|
|
+ // 清除订单号标签
|
|
|
+ this.queryParams.orderCodes = [];
|
|
|
+ this.currentInput = '';
|
|
|
+ this.inputVisible = false;
|
|
|
+
|
|
|
this.handleQuery();
|
|
|
|
|
|
},
|
|
|
@@ -1093,6 +1216,159 @@ export default {
|
|
|
submitOrderStatusFileForm(){
|
|
|
this.$refs.uploadStatus.submit();
|
|
|
},
|
|
|
+ // 处理键盘按下事件
|
|
|
+ handleKeyDown(event) {
|
|
|
+ const { key, target } = event
|
|
|
+
|
|
|
+ // 处理退格键删除标签
|
|
|
+ if (key === 'Backspace' && !target.value && this.queryParams.orderCodes.length > 0) {
|
|
|
+ event.preventDefault()
|
|
|
+ this.removeOrderCode(this.queryParams.orderCodes.length - 1)
|
|
|
+ }
|
|
|
+
|
|
|
+ // 处理分隔符
|
|
|
+ if ([',', ',', ' ', 'Enter'].includes(key)) {
|
|
|
+ event.preventDefault()
|
|
|
+ this.handleInputConfirm()
|
|
|
+ }
|
|
|
+ },
|
|
|
+
|
|
|
+ // 处理键盘抬起事件(实时分割输入)
|
|
|
+ handleKeyUp(event) {
|
|
|
+ const value = event.target.value
|
|
|
+
|
|
|
+ // 检查是否包含分隔符
|
|
|
+ if (/[,,\s]/.test(value)) {
|
|
|
+ this.handleInputConfirm()
|
|
|
+ }
|
|
|
+ },
|
|
|
+
|
|
|
+ // 确认输入
|
|
|
+ handleInputConfirm() {
|
|
|
+ const inputValue = this.currentInput.trim()
|
|
|
+
|
|
|
+ if (inputValue) {
|
|
|
+ // 分割多个订单号
|
|
|
+ const codes = inputValue.split(/[,,\s]+/).filter(code => code.trim())
|
|
|
+
|
|
|
+ codes.forEach(code => {
|
|
|
+ this.addOrderCode(code.trim())
|
|
|
+ })
|
|
|
+ }
|
|
|
+
|
|
|
+ this.currentInput = ''
|
|
|
+ },
|
|
|
+
|
|
|
+ // 添加订单号
|
|
|
+ addOrderCode(code) {
|
|
|
+ if (!code) return
|
|
|
+
|
|
|
+ // 检查数量限制
|
|
|
+ if (this.maxOrderCodes > 0 && this.queryParams.orderCodes.length >= this.maxOrderCodes) {
|
|
|
+ this.$message.warning(`最多只能添加 ${this.maxOrderCodes} 个订单号`)
|
|
|
+ return
|
|
|
+ }
|
|
|
+
|
|
|
+ // 检查重复
|
|
|
+ if (this.queryParams.orderCodes.includes(code)) {
|
|
|
+ this.$message.warning(`订单号 "${code}" 已存在`)
|
|
|
+ return
|
|
|
+ }
|
|
|
+
|
|
|
+ // 添加到列表
|
|
|
+ this.queryParams.orderCodes.push(code)
|
|
|
+ },
|
|
|
+
|
|
|
+ // 删除订单号
|
|
|
+ removeOrderCode(index) {
|
|
|
+ this.queryParams.orderCodes.splice(index, 1)
|
|
|
+ },
|
|
|
+
|
|
|
+ // 显示输入框
|
|
|
+ showInput() {
|
|
|
+ this.inputVisible = true
|
|
|
+ this.$nextTick(() => {
|
|
|
+ this.$refs.tagInput.focus()
|
|
|
+ })
|
|
|
+ },
|
|
|
+ // 聚焦输入框
|
|
|
+ focusInput() {
|
|
|
+ if (!this.inputVisible) {
|
|
|
+ this.showInput()
|
|
|
+ }
|
|
|
+ },
|
|
|
}
|
|
|
};
|
|
|
</script>
|
|
|
+
|
|
|
+<style scoped>
|
|
|
+.tag-input-container {
|
|
|
+ min-width: 445px;
|
|
|
+}
|
|
|
+
|
|
|
+.tags-wrapper {
|
|
|
+ min-height: 32px;
|
|
|
+ padding: 4px 8px;
|
|
|
+ border: 1px solid #dcdfe6;
|
|
|
+ border-radius: 4px;
|
|
|
+ cursor: text;
|
|
|
+ display: flex;
|
|
|
+ flex-wrap: wrap;
|
|
|
+ align-items: center;
|
|
|
+ gap: 4px;
|
|
|
+ transition: border-color 0.2s;
|
|
|
+}
|
|
|
+
|
|
|
+.tags-wrapper:hover {
|
|
|
+ border-color: #c0c4cc;
|
|
|
+}
|
|
|
+
|
|
|
+.tags-wrapper:focus-within {
|
|
|
+ border-color: #409eff;
|
|
|
+ box-shadow: 0 0 0 2px rgba(64, 158, 255, 0.2);
|
|
|
+}
|
|
|
+
|
|
|
+.order-tag {
|
|
|
+ margin: 2px;
|
|
|
+ flex-shrink: 0;
|
|
|
+}
|
|
|
+
|
|
|
+.tag-error {
|
|
|
+ background-color: #fef0f0;
|
|
|
+ border-color: #fbc4c4;
|
|
|
+ color: #f56c6c;
|
|
|
+}
|
|
|
+
|
|
|
+.tag-input {
|
|
|
+ border: none;
|
|
|
+ outline: none;
|
|
|
+ flex: 1;
|
|
|
+ min-width: 120px;
|
|
|
+}
|
|
|
+
|
|
|
+.tag-input >>> .el-input__inner {
|
|
|
+ border: none;
|
|
|
+ padding: 0;
|
|
|
+ height: 24px;
|
|
|
+ line-height: 24px;
|
|
|
+}
|
|
|
+
|
|
|
+.button-new-tag {
|
|
|
+ height: 24px;
|
|
|
+ line-height: 22px;
|
|
|
+ padding: 0 8px;
|
|
|
+ margin: 2px;
|
|
|
+}
|
|
|
+
|
|
|
+.input-tips {
|
|
|
+ margin-top: 4px;
|
|
|
+ font-size: 12px;
|
|
|
+ color: #909399;
|
|
|
+}
|
|
|
+
|
|
|
+.tip-text {
|
|
|
+ display: flex;
|
|
|
+ align-items: center;
|
|
|
+ gap: 8px;
|
|
|
+}
|
|
|
+</style>
|