浏览代码

提交订单页面和详情页面 20230619

xiaobai 1 年之前
父节点
当前提交
42a7aec0b5

+ 1 - 1
.env.dev

@@ -1,5 +1,5 @@
 # 开发环境
-NODE_ENV=production
+NODE_ENV=development
 
 VITE_DEV=false
 

+ 90 - 49
src/api/mall/trade/order/type/orderType.ts

@@ -1,24 +1,24 @@
 export interface TradeOrderPageItemRespVO {
   // 订单编号
-  id: number
+  id?: number
   // 订单流水号
-  no: string
+  no?: string
   // 下单时间
-  createTime: Date
+  createTime?: Date
   // 订单类型
-  type: number
+  type?: number
   // 订单来源
-  terminal: number
+  terminal?: number
   // 用户编号
-  userId: number
+  userId?: number
   // 用户 IP
-  userIp: string
+  userIp?: string
   // 用户备注
-  userRemark: string
+  userRemark?: string
   // 订单状态
-  status: number
+  status?: number
   // 购买的商品数量
-  productCount: number
+  productCount?: number
   // 订单完成时间
   finishTime?: Date
   // 订单取消时间
@@ -30,23 +30,23 @@ export interface TradeOrderPageItemRespVO {
   // 支付订单编号
   payOrderId: number
   // 是否已支付
-  payed: boolean
+  payed?: boolean
   // 付款时间
   payTime?: Date
   // 支付渠道
-  payChannelCode: string
+  payChannelCode?: string
   // 商品原价(总)
-  originalPrice: number
+  originalPrice?: number
   // 订单原价(总)
-  orderPrice: number
+  orderPrice?: number
   // 订单优惠(总)
-  discountPrice: number
+  discountPrice?: number
   // 运费金额
-  deliveryPrice: number
+  deliveryPrice?: number
   // 订单调价(总)
-  adjustPrice: number
+  adjustPrice?: number
   // 应付金额(总)
-  payPrice: number
+  payPrice?: number
   // 配送模板编号
   deliveryTemplateId?: number
   // 发货物流公司编号
@@ -54,35 +54,37 @@ export interface TradeOrderPageItemRespVO {
   // 发货物流单号
   logisticsNo?: string
   // 发货状态
-  deliveryStatus: number
+  deliveryStatus?: number
   // 发货时间
   deliveryTime?: Date
   // 收货时间
   receiveTime?: Date
   // 收件人名称
-  receiverName: string
+  receiverName?: string
   // 收件人手机
-  receiverMobile: string
+  receiverMobile?: string
   // 收件人地区编号
-  receiverAreaId: number
+  receiverAreaId?: number
   // 收件人邮编
-  receiverPostCode: number
+  receiverPostCode?: number
   // 收件人详细地址
-  receiverDetailAddress: string
+  receiverDetailAddress?: string
   // 售后状态
   afterSaleStatus?: number
   // 退款金额
-  refundPrice: number
+  refundPrice?: number
   // 优惠劵编号
   couponId?: number
   // 优惠劵减免金额
-  couponPrice: number
+  couponPrice?: number
   // 积分抵扣的金额
-  pointPrice: number
+  pointPrice?: number
   //收件人地区名字
-  receiverAreaName: string
+  receiverAreaName?: string
   // 订单项列表
-  items: TradeOrderItemBaseVO[]
+  items?: TradeOrderItemBaseVO[]
+  //用户信息
+  user?: MemberUserRespDTO
 }
 
 /**
@@ -94,70 +96,70 @@ export interface TradeOrderItemBaseVO {
   /**
    * 编号
    */
-  id: number
+  id?: number
   /**
    * 用户编号
    */
-  userId: number
+  userId?: number
   /**
    * 订单编号
    */
-  orderId: number
+  orderId?: number
   // ========== 商品基本信息 ==========
   /**
    * 商品 SPU 编号
    */
-  spuId: number
+  spuId?: number
   /**
    * 商品 SPU 名称
    */
-  spuName: string
+  spuName?: string
   /**
    * 商品 SKU 编号
    */
-  skuId: number
+  skuId?: number
   /**
    * 商品图片
    */
-  picUrl: string
+  picUrl?: string
   /**
    * 购买数量
    */
-  count: number
+  count?: number
   // ========== 价格 + 支付基本信息 ==========
   /**
    * 商品原价(总)
    */
-  originalPrice: number
+  originalPrice?: number
   /**
    * 商品原价(单)
    */
-  originalUnitPrice: number
+  originalUnitPrice?: number
   /**
    * 商品优惠(总)
    */
-  discountPrice: number
+  discountPrice?: number
   /**
    * 商品实付金额(总)
    */
-  payPrice: number
+  payPrice?: number
   /**
    * 子订单分摊金额(总)
    */
-  orderPartPrice: number
+  orderPartPrice?: number
   /**
    * 分摊后子订单实付金额(总)
    */
-  orderDividePrice: number
+  orderDividePrice?: number
   // ========== 营销基本信息 ==========
   // TODO 芋艿:在捉摸一下
   // ========== 售后基本信息 ==========
   /**
    * 售后状态
    */
-  afterSaleStatus: number
+  afterSaleStatus?: number
   //属性数组
-  properties: ProductPropertyValueDetailRespVO[]
+  properties?: ProductPropertyValueDetailRespVO[]
 }
 
 /**
@@ -167,17 +169,56 @@ export interface ProductPropertyValueDetailRespVO {
   /**
    * 属性的编号
    */
-  propertyId: number
+  propertyId?: number
   /**
    * 属性的名称
    */
-  propertyName: string
+  propertyName?: string
   /**
    * 属性值的编号
    */
-  valueId: number
+  valueId?: number
   /**
    * 属性值的名称
    */
-  valueName: string
+  valueName?: string
+}
+
+/**
+ * 订单详情查询 请求
+ */
+export interface TradeOrderPageReqVO {
+  pageNo: number
+  pageSize: number
+  no?: string
+  userId?: string
+  userNickname?: string
+  userMobile?: string
+  receiverName?: string
+  receiverMobile?: string
+  terminal?: string
+  type?: number
+  status?: number
+  payChannelCode?: string
+  createTime?: [Date, Date]
+  spuName?: string
+  itemCount?: string
+  all?: string
+}
+
+//用户信息
+export interface MemberUserRespDTO {
+  id?: number
+  nickname?: string
+  status?: number
+  avatar?: string
+  mobile?: string
+}
+//订单详情选中type
+export interface SelectType {
+  queryParams: TradeOrderPageReqVO
+  selectTotal: number //选中的数量
+  selectAllFlag: boolean //全选标识
+  selectData: Map<number, Set<string>> //存放涉及选中得页面以及每页选中得数据订单号  全选时根据条件查询 排除取消的list订单
+  unSelectList: Set<string> //登记取消的list 全选标识为true 时登记单独取消的list,再次选中时排除, 全选标识为false 时清空list
 }

+ 273 - 170
src/views/mall/trade/order/index.vue

@@ -45,7 +45,7 @@
         />
       </el-form-item>
       <el-form-item label="订单来源" prop="terminal">
-        <el-select class="!w-280px" v-model="queryParams.terminal" clearable placeholder="全部TODO">
+        <el-select class="!w-280px" v-model="queryParams.terminal" clearable placeholder="全部">
           <el-option
             v-for="dict in getStrDictOptions(DICT_TYPE.TERMINAL)"
             :key="dict.value"
@@ -65,46 +65,37 @@
         </el-select>
       </el-form-item>
 
-      <el-form-item label="订单搜索" prop="searchValue">
-        <!-- 双item绑定2个变量用于reset时没法重置 -->
-        <el-form-item class="!w-280px" prop="searchType">
-          <el-input
-            class="!w-280px"
-            v-model="queryParams.searchValue"
-            clearable
-            placeholder="请输入TODO"
-          >
-            <template #prepend>
-              <el-select
-                style="width: 100px"
-                v-model="queryParams.searchType"
-                clearable
-                placeholder="全部"
-              >
-                <el-option
-                  v-for="dict in searchList"
-                  :key="dict.value"
-                  :label="dict.label"
-                  :value="dict.value"
-                />
-              </el-select>
-            </template>
-          </el-input>
-        </el-form-item>
+      <el-form-item label="订单搜索">
+        <el-input
+          v-show="true"
+          class="!w-280px"
+          v-model="queryType.v"
+          clearable
+          placeholder="请输入"
+        >
+          <template #prepend>
+            <el-select style="width: 110px" v-model="queryType.k" clearable placeholder="全部">
+              <el-option
+                v-for="dict in searchList"
+                :key="dict.value"
+                :label="dict.label"
+                :value="dict.value"
+              />
+            </el-select>
+          </template>
+        </el-input>
       </el-form-item>
       <el-form-item>
-        <el-button @click="handleQuery">
+        <el-button @click="handleQuery" v-hasPermi="['trade:order:query']">
           <Icon class="mr-5px" icon="ep:search" />
           搜索
         </el-button>
-        <el-button @click="resetQuery">
+        <el-button @click="resetQuery" v-hasPermi="['trade:order:query']">
           <Icon class="mr-5px" icon="ep:refresh" />
           重置
         </el-button>
-        <!-- v-hasPermi="['trade:order:export']"
-           需要将选中的数据存入orderSelect.multipleSelection中 
-          需要考虑全选时数据如何处理-->
         <el-button type="success" plain @click="handleExport" :loading="exportLoading">
+          <!--           v-hasPermi="['trade:order:export']"        -->
           <Icon icon="ep:download" class="mr-5px" /> 导出TODO
         </el-button>
       </el-form-item>
@@ -118,7 +109,9 @@
         <template #default="scope">
           <el-descriptions class="mx-40">
             <el-descriptions-item label="商品原价(总): ">{{
-              '¥ ' + parseFloat(scope.row.originalPrice / 100).toFixed(2) + ' 元'
+              '¥ ' +
+              parseFloat((scope.row.originalPrice / 100) as unknown as string).toFixed(2) +
+              ' 元'
             }}</el-descriptions-item>
             <el-descriptions-item label="下单时间: ">
               {{ formatDate(scope.row.createTime) }}</el-descriptions-item
@@ -131,11 +124,10 @@
           </el-descriptions>
         </template>
       </el-table-column>
-      <!-- <el-table-column label="全选" type="selection" width="55" fixed="left">x</el-table-column> -->
       <el-table-column width="100" fixed="left">
         <template #header>
           <el-dropdown icon="eq:search" @command="handleDropType">
-            <el-button link type="primary">全选({{ orderSelect.checkTotal }}) </el-button>
+            <el-button link type="primary">全选({{ orderSelect.selectTotal }}) </el-button>
 
             <template #dropdown>
               <el-dropdown-menu>
@@ -162,7 +154,20 @@
           <dict-tag :type="DICT_TYPE.TRADE_ORDER_TYPE" :value="scope.row.type" />
         </template>
       </el-table-column>
-
+      <el-table-column label="用户信息" align="center" min-width="100">
+        <template #default="scope">
+          <el-button link type="primary" @click="goUserDetail(scope.row)"
+            >{{ scope.row.userId }}{{ '[' + scope.row.user.nickname + ']' }}</el-button
+          >
+        </template>
+      </el-table-column>
+      <el-table-column
+        :formatter="dateFormatter"
+        align="center"
+        label="创建时间"
+        prop="createTime"
+        min-width="180"
+      />
       <el-table-column label="订单来源" align="center" min-width="100">
         <template #default="scope">
           <dict-tag
@@ -174,13 +179,6 @@
         </template>
       </el-table-column>
 
-      <el-table-column label="用户信息(id)" align="center" min-width="100">
-        <template #default="scope">
-          <el-button link type="primary" @click="goUserDetail(scope.row)">{{
-            scope.row.userId
-          }}</el-button>
-        </template>
-      </el-table-column>
       <el-table-column label="商品信息" align="left" min-width="200" prop="items">
         <template #default="scope">
           <el-popover
@@ -208,7 +206,10 @@
               <div>
                 <p>{{ item.spuName }}</p>
                 <p>{{
-                  '¥ ' + parseFloat(item.payPrice / 100).toFixed(2) + '元 x ' + item.count
+                  '¥ ' +
+                  parseFloat((item.payPrice / 100) as unknown as string).toFixed(2) +
+                  '元 x ' +
+                  item.count
                 }}</p>
               </div>
             </div>
@@ -218,7 +219,7 @@
 
       <el-table-column label="实际支付(元)" align="center" prop="payPrice" min-width="100">
         <template #default="scope">
-          {{ '¥ ' + parseFloat(scope.row.payPrice / 100).toFixed(2) }}
+          {{ '¥ ' + parseFloat((scope.row.payPrice / 100) as unknown as string).toFixed(2) }}
         </template>
       </el-table-column>
       <el-table-column
@@ -240,7 +241,7 @@
       <el-table-column label="订单状态" align="center" prop="status" min-width="100">
         <template #default="scope">
           <dict-tag
-            v-if="scope.row.status == ''"
+            v-if="scope.row.status !== ''"
             :type="DICT_TYPE.TRADE_ORDER_STATUS"
             :value="scope.row.status"
           />
@@ -249,9 +250,8 @@
       </el-table-column>
       <el-table-column label="操作" align="center" fixed="right" min-width="150">
         <template #default="scope">
-          <el-button v-if="scope.row.status == '0'" link type="primary" @click="sendXX(scope.row)"
-            >待支付</el-button
-          >
+          <!-- <el-button v-if="scope.row.status == '0'" link type="primary" @click="sendXX(scope.row)"
+            >待支付</el-button> -->
           <el-button v-if="scope.row.status == '10'" link type="primary" @click="sendXX(scope.row)"
             >发货</el-button
           >
@@ -277,135 +277,136 @@
 <script setup lang="ts" name="OrderList">
 import { DICT_TYPE, getStrDictOptions } from '@/utils/dict'
 import * as TradeOrderApi from '@/api/mall/trade/order'
+import {
+  TradeOrderPageReqVO,
+  SelectType,
+  TradeOrderPageItemRespVO
+} from '@/api/mall/trade/order/type/orderType'
 import { dateFormatter, formatDate } from '@/utils/formatTime'
 import download from '@/utils/download'
-// import TradeOrderDetail from './tradeOrderDetail.vue'
-interface CurrentType {
-  checkTotal: number //选中的数量
-  currentType: string //页面选中类型, 0-noPage无选中页面 1-currentPage 当前页面 2-allPage所有页面
-  selectAll: boolean //全选标识
-  multipleSelection: [] // 选中的数据  暂未记录,需考虑全选时数据应该如何处理 ,部分选中可以使用该数据,需要登记
-  pageNoList: [] //当前页面选中的页号 如果再次选中当前页将取消本页面的选中数据 全选时 将所有的页面list 都放进去 再次全选时 全部清空
-}
-const orderSelect: CurrentType = reactive({
-  checkTotal: 0,
-  currentType: '0',
-  selectAll: false,
-  multipleSelection: [],
-  pageNoList: []
-})
 
 const message = useMessage()
-
 const { push } = useRouter()
-const queryFormRef = ref() //表单搜索
-const queryParams = ref({
+const imgViewVisible = ref(false) // 商品图预览
+const imageViewerList = ref<string[]>([]) // 商品图预览列表
+const queryFormRef = ref()
+const loading = ref(false)
+const exportLoading = ref(false)
+const total = ref(0) // 总记录数
+const list = ref<Array<TradeOrderPageItemRespVO | any>>([]) //表数据
+
+//选中状态选中处理
+const orderSelect: SelectType = reactive({
+  queryParams: {} as TradeOrderPageReqVO,
+  selectTotal: 0,
+  selectAllFlag: false,
+  selectData: new Map<number, Set<string>>(),
+  unSelectList: new Set<string>()
+})
+
+//表单搜索
+const queryParams: TradeOrderPageReqVO = reactive({
   pageNo: 1, //首页
-  pageSize: 10, //页面大小
-  tabIndex: 0 //详情页面数据
+  pageSize: 10 //页面大小
 })
 
-const loading = ref(false)
-const exportLoading = ref(false)
-// 总记录数
-const total = ref(0)
+const queryType = reactive({ k: '', v: '' }) // 订单搜索类型kv
 
-//表数据
-const list = ref<any>([])
-//订单搜索
+/*
+ * 订单搜索
+ * 商品名称  商品件数 全部  需要后端支持TODO
+ */
 const searchList = ref([
-  {
-    value: 'orderNo',
-    label: '订单号'
-  },
-  {
-    value: 'userId',
-    label: '用户UID'
-  },
-  {
-    value: 'userName',
-    label: '用户姓名'
-  },
-  {
-    value: 'userTel',
-    label: '用户电话'
-  },
-  {
-    value: 'itemName',
-    label: '商品名称'
-  },
-  {
-    value: 'itemCount',
-    label: '商品件数'
-  }
+  { value: 'no', label: '订单号' },
+  { value: 'userId', label: '用户UID' },
+  { value: 'userNickname', label: '用户昵称' },
+  { value: 'userMobile', label: '用户电话' },
+  { value: 'spuName', label: '商品名称TODO' },
+  { value: 'itemCount', label: '商品件数TODO' }
 ])
 
-const imgViewVisible = ref(false) // 商品图预览
-
-const imageViewerList = ref<string[]>([]) // 商品图预览列表
+/**
 
-/**当前页 所有页  暂不考虑数据本地化 会导致选中当前页 从后台重新拉取数据时出现数据不一致*/
+ 当前页/? 如果pageNo存在,则将但前数据全部按照单个选中模式取消 ,不存在,则新增全页 增加 Map.pageNo Map.roderNoList
+ 单个选中  如果pagelist存在,订单号选中状态取反,并对总数按选中状态加减。如果pagelist不存在,订单号选中状态取反,并对总数按选中状态加减,增加 Map.pageNo,
+ 如果当前Map.pageNo 所对应list 为空 ,清除pageNo
+ * @param command ===1 当前页 选中 ===2 所有页面选中
+ */
 const handleDropType = (command: string) => {
-  orderSelect.currentType = command
   let i = 0
+  //当前页按钮
   if (command === '1') {
-    // pageNoList 当前页面选中的页号 如果再次选中当前页将取消本页面的选中数据
-    //取消本页面记录
-    var index = orderSelect.pageNoList.indexOf(queryParams.value.pageNo)
-    if (index > -1) {
-      for (i; i < list.value.length; i++) {
-        if (list.value[i]['itemSelect'] === true) {
-          list.value[i]['itemSelect'] = false
-          orderSelect.checkTotal = orderSelect.checkTotal - 1
+    //如果该页面有选中数据 则选中事件触发时 取消该页面
+    if (orderSelect.selectData && orderSelect.selectData.has(queryParams.pageNo)) {
+      for (i = 0; i < list.value.length; i++) {
+        if (orderSelect.selectData.get(queryParams.pageNo)!.has(list.value[i].id)) {
+          //选中数量减少
+          orderSelect.selectTotal -= 1
+          //考虑全选中,针对某一页面选中当前页时 会将所有数据中去掉该页面, 需要登记到 orderSelect.unSelectList
+          unSelectListRecord(list.value[i].id, 'add')
         }
+        list.value[i]['itemSelect'] = false
       }
-      orderSelect.pageNoList.splice(index, 1)
+      orderSelect.selectData.delete(queryParams.pageNo) //移除该页面
     } else {
-      for (i; i < list.value.length; i++) {
-        if (list.value[i]['itemSelect'] === false) {
-          list.value[i]['itemSelect'] = true
-          orderSelect.checkTotal = orderSelect.checkTotal + 1
-        }
+      //当前页选中状态中 默认全选中
+      orderSelect.selectData.set(queryParams.pageNo, new Set<string>())
+      for (i = 0; i < list.value.length; i++) {
+        list.value[i]['itemSelect'] = true
+        orderSelect.selectData.get(queryParams.pageNo)!.add(list.value[i].id)
+        //选中数量增加
+        orderSelect.selectTotal += 1
+        //对于登记过取消状态中的数据排除
+        unSelectListRecord(list.value[i].id, 'del')
       }
-      orderSelect.pageNoList.splice(0, 0, queryParams.value.pageNo)
     }
   }
+  //所有页按钮
   if (command === '2') {
-    orderSelect.selectAll = !orderSelect.selectAll
-    //全选时 将所有的页面list 都放进去 再次全选时 全部清空
-    if (orderSelect.selectAll) {
-      //打勾勾
-      for (i; i < list.value.length; i++) {
+    initSelect() //重置之前选中的类容清空
+    orderSelect.selectAllFlag = !orderSelect.selectAllFlag
+
+    if (orderSelect.selectAllFlag) {
+      //打勾勾 //全选
+      orderSelect.selectData?.set(queryParams.pageNo, new Set<string>())
+      for (i = 0; i < list.value.length; i++) {
         list.value[i]['itemSelect'] = true
+        orderSelect.selectData?.get(queryParams.pageNo)?.add(list.value[i].id) //id是主键不重复
       }
-      // 初始化页面数组
-      const array1: [] = Array.from(
-        { length: total.value / queryParams.value.pageSize + 1 },
-        (item, idx) => idx + 1
-      )
-      orderSelect.pageNoList = [] //清空原有的
-      orderSelect.pageNoList = [].concat(array1)
-      orderSelect.checkTotal = total.value
+      orderSelect.selectTotal = total.value
     } else {
       //取消勾勾
       for (i; i < list.value.length; i++) {
         list.value[i]['itemSelect'] = false
       }
-      orderSelect.pageNoList = [] //清空
-      orderSelect.checkTotal = 0
     }
   }
 }
+
+//对全选状态中的 单选或者当前页面单选时登记取消的数据
+const unSelectListRecord = (id: string, op: string) => {
+  if (!orderSelect.selectAllFlag) {
+    return
+  }
+  if (op == 'add') {
+    orderSelect.unSelectList.add(id)
+  } else {
+    orderSelect.unSelectList.delete(id)
+  }
+}
 /***复选框选中 */
 const handcheckclick = (row: any) => {
-  //选中增加1
-  if (!row.itemSelect) {
-    // 取消 -1
-    orderSelect.checkTotal = orderSelect.checkTotal - 1
-    //
+  if (row.itemSelect) {
+    orderSelect.selectTotal += 1
+    if (!orderSelect.selectData.has(queryParams.pageNo)) {
+      orderSelect.selectData?.set(queryParams.pageNo, new Set<string>())
+    }
+    orderSelect.selectData?.get(queryParams.pageNo)?.add(row.id)
+    unSelectListRecord(row.id, 'del')
   } else {
-    //选中 +1
-    orderSelect.checkTotal = orderSelect.checkTotal + 1
+    orderSelect.selectTotal -= 1
+    orderSelect.selectData.get(queryParams.pageNo)?.delete(row.id)
+    unSelectListRecord(row.id, 'add')
   }
 }
 /**
@@ -416,10 +417,15 @@ const handleExport = async () => {
   try {
     // 导出的二次确认
     await message.exportConfirm()
+    //增加查询条件 用于全选时后台查询数据
+    orderSelect.queryParams = queryParams
+
     // 发起导出
     exportLoading.value = true
-    //TODO导出的数据是后台导出还是从前端中获取数据(全选时数据怎么打印?)
-    download.excel(orderSelect.multipleSelection as any, '订单信息.xls') //
+    //全选时 根据上送的条件查询所有数据,在排除unseleectList 数据,
+    //非全选时, 根据上送的selectData 直接查询数据 后台实现导出数据接口即可
+    console.log(orderSelect)
+    download.excel(orderSelect as any, '订单信息.xls') //?
   } catch {
   } finally {
     exportLoading.value = false
@@ -430,49 +436,57 @@ const handleExport = async () => {
 
 /** 搜索按钮操作 */
 const handleQuery = () => {
-  //选中状态初始化
-  orderSelect.checkTotal = 0
-  orderSelect.currentType = '0'
-  orderSelect.multipleSelection = []
-  orderSelect.pageNoList = []
-  orderSelect.selectAll = false
-
   getList()
 }
 
 /** 重置按钮操作 */
 const resetQuery = () => {
-  //选中状态初始化
-  orderSelect.checkTotal = 0
-  orderSelect.currentType = '0'
-  orderSelect.multipleSelection = []
-  orderSelect.pageNoList = []
-  orderSelect.selectAll = false
-
   queryFormRef.value.resetFields()
-  handleQuery()
+  queryType.v = '' //重置
+  queryType.k = ''
+  //休眠0.1s 等待watch响应
+  setTimeout(() => {
+    initSelect() //重置对选中设置恢复初始状态
+    handleQuery()
+  }, 100)
+}
+
+/**选中状态初始化**/
+const initSelect = () => {
+  orderSelect.queryParams = {} as TradeOrderPageReqVO
+  orderSelect.selectTotal = 0
+  orderSelect.selectAllFlag = false
+  orderSelect.selectData?.clear()
+  orderSelect.unSelectList?.clear()
 }
 
 const getList = async () => {
   loading.value = true
   try {
-    const data = await TradeOrderApi.getOrderList(queryParams.value)
+    const data = await TradeOrderApi.getOrderList(queryParams)
     list.value = data.list
     total.value = data.total
-
     let i = 0
-    //给数组添加选中属性 itemSelect 默认为false 当前状态如果时全选 则新加载的页面都为选中状态
-    if (
-      orderSelect.currentType === '2' || //全选状态加载状态设置为选中
-      orderSelect.pageNoList.indexOf(queryParams.value.pageNo) > -1 //已选择页面加载状态设置为默认选中,会存在选中当前页面后手动取消该页面部分数据,再重新加载该页面时设置为选中状态,但是没有增加选中的数量
-    ) {
-      for (i; i < list.value.length; i++) {
+    if (orderSelect.selectData && orderSelect.selectData.has(queryParams.pageNo)) {
+      //该页面已经加载过了。直接按照之前状态设置选中状态值
+      for (i = 0; i < list.value.length; i++) {
+        if (orderSelect.selectData.get(queryParams.pageNo)!.has(list.value[i].id)) {
+          list.value[i]['itemSelect'] = true //之前已经选取过了
+        } else {
+          list.value[i]['itemSelect'] = false
+        }
+      }
+    } else if (orderSelect.selectAllFlag) {
+      //全选状态中 首次加载页面 默认全部选中
+      orderSelect.selectData.set(queryParams.pageNo, new Set<string>())
+      for (i = 0; i < list.value.length; i++) {
         list.value[i]['itemSelect'] = true
+        orderSelect.selectData.get(queryParams.pageNo)!.add(list.value[i].id)
       }
     } else {
-      //还需要判断当前页面是否已经选中了? 而且还要出来选中的数据是否后来手动一行行取消了处理
+      //非全选状态中  首次加载默认非选中状态
       for (i; i < list.value.length; i++) {
-        list.value[i]['itemSelect'] = false //暂定为未选中状态, 实际情况需要考虑已选中状态,后期优化
+        list.value[i]['itemSelect'] = false //设置状态为未选中状态
       }
     }
   } finally {
@@ -480,11 +494,58 @@ const getList = async () => {
   }
 }
 
+// const getList = async () => {
+//   loading.value = true
+//   try {
+//     const data = await TradeOrderApi.getOrderList(queryParams)
+//     list.value = data.list
+//     total.value = data.total
+//     let i = 0
+//     //给数组添加选中属性 itemSelect 默认为false 当前状态如果时全选 则新加载的页面都为选中状态
+
+//     if (orderSelect.selectAllFlag) {
+//       if (orderSelect.selectData && orderSelect.selectData.has(queryParams.pageNo)) {
+//         //页面已经加载过了
+//         for (i = 0; i < list.value.length; i++) {
+//           if (orderSelect.selectData.get(queryParams.pageNo)!.has(list.value[i].id)) {
+//             list.value[i]['itemSelect'] = true //之前已经选取过了
+//           } else {
+//             list.value[i]['itemSelect'] = false
+//           }
+//         }
+//       } else {
+//         //首次加载页面 默认全部选中
+//         orderSelect.selectData.set(queryParams.pageNo, new Set<string>())
+//         for (i = 0; i < list.value.length; i++) {
+//           list.value[i]['itemSelect'] = true
+//           orderSelect.selectData.get(queryParams.pageNo)!.add(list.value[i].id)
+//         }
+//       }
+//     } else {
+//       if (orderSelect.selectData && orderSelect.selectData.has(queryParams.pageNo)) {
+//         //页面已经加载过了
+//         for (i = 0; i < list.value.length; i++) {
+//           if (orderSelect.selectData.get(queryParams.pageNo)!.has(list.value[i].id)) {
+//             list.value[i]['itemSelect'] = true //之前已经选取过了
+//           } else {
+//             list.value[i]['itemSelect'] = false
+//           }
+//         }
+//       } else {
+//         for (i; i < list.value.length; i++) {
+//           list.value[i]['itemSelect'] = false //设置状态为未选中状态
+//         }
+//       }
+//     }
+//   } finally {
+//     loading.value = false
+//   }
+// }
+
 /**
  * 跳转订单详情
  */
 const showOrderDetail = (row: any) => {
-  console.log('TODO Order Detail: ' + row.id)
   push({ name: 'TradeOrderDetail', query: { id: row.id } })
 }
 
@@ -510,8 +571,50 @@ const imagePreview = (imgUrl: string) => {
   imgViewVisible.value = true
 }
 
+//针对订单搜索类型和值进行调整 使用监听器
+watch(
+  () => [queryType.k, queryType.v],
+  ([newK, newV], [oldK]) => {
+    //重置oldK对应得value
+    if (oldK != newK) {
+      if (oldK == 'no' && queryParams.no != '') {
+        queryParams.no = ''
+      } else if (oldK == 'userId' && queryParams.userId != '') {
+        queryParams.userId = ''
+      } else if (oldK == 'userNickname' && queryParams.userNickname != '') {
+        queryParams.userNickname = ''
+      } else if (oldK == 'userMobile' && queryParams.userMobile !== '') {
+        queryParams.userMobile = ''
+      } else if (oldK == 'spuName' && queryParams.spuName !== '') {
+        queryParams.spuName = ''
+      } else if (oldK == 'itemCount' && queryParams.itemCount !== '') {
+        queryParams.itemCount = ''
+      } else if (oldK == '' && queryParams.all !== '') {
+        queryParams.all = ''
+      }
+    }
+    // 根据选中得k设置Value
+    if (newK == 'no') {
+      queryParams.no = newV
+    } else if (newK == 'userId') {
+      queryParams.userId = newV
+    } else if (newK == 'userNickname') {
+      queryParams.userNickname = newV
+    } else if (newK == 'userMobile') {
+      queryParams.userMobile = newV
+    } else if (newK == 'spuName') {
+      queryParams.spuName = newV
+    } else if (newK == 'itemCount') {
+      queryParams.itemCount = newV
+    } else if (newK == '') {
+      queryParams.all = newV
+    }
+  }
+)
+
 /** 初始化 **/
 onMounted(() => {
+  initSelect()
   getList()
 })
 </script>

+ 0 - 141
src/views/mall/trade/order/tradeOrderDetail-crmeb.vue

@@ -1,141 +0,0 @@
-<template>
-  <el-drawer v-model="drawerVisiable" width="50%">
-    <el-form inline="true">
-      <el-form-item>
-        <div>
-          <span text="普通订单:">普通订单:</span>
-          <span text="订单号: ">1111112546</span>
-        </div>
-      </el-form-item>
-      <el-form-item> <el-button type="primary" icon="search">发送货</el-button></el-form-item>
-      <el-form-item><el-button type="success" icon="search">小票打印</el-button> </el-form-item>
-      <el-form-item>
-        <el-dropdown @command="handleCommand">
-          <el-button> ... </el-button>
-          <template #dropdown>
-            <el-dropdown-menu>
-              <el-dropdown-item command="remark">订单备注</el-dropdown-item>
-              <el-dropdown-item command="b">立即退款</el-dropdown-item>
-              <el-dropdown-item command="print">打印配货单</el-dropdown-item>
-            </el-dropdown-menu>
-          </template>
-        </el-dropdown>
-      </el-form-item>
-    </el-form>
-
-    <el-descriptions class="m-10" direction="vertical" column="4">
-      <el-descriptions-item label="订单状态">未发货TODO</el-descriptions-item>
-      <el-descriptions-item label="实际支付">1000 元 TODO</el-descriptions-item>
-      <el-descriptions-item label="支付方式">手机支付</el-descriptions-item>
-      <el-descriptions-item label="支付时间"> {{ formatDate(Date()) }}</el-descriptions-item>
-    </el-descriptions>
-    <el-tabs @tab-click="handleClick">
-      <el-tab-pane label="订单信息">
-        <el-descriptions title="订单信息">
-          <el-descriptions-item label="用户UID: ">kooriookami</el-descriptions-item>
-          <el-descriptions-item label="用户昵称: ">18100000000</el-descriptions-item>
-          <el-descriptions-item label="绑定电话: ">Suzhou</el-descriptions-item>
-        </el-descriptions>
-        <el-divider border-style="dashed" />
-        <el-descriptions title="收货信息" column="1">
-          <el-descriptions-item label="收货人: ">kooriookami</el-descriptions-item>
-          <el-descriptions-item label="收货电话: ">18100000000</el-descriptions-item>
-          <el-descriptions-item label="收货地址: ">{{ detailData }}</el-descriptions-item>
-        </el-descriptions>
-        <el-divider border-style="dashed" />
-        <el-descriptions title="供应商信息">
-          <el-descriptions-item label="供应商: ">kooriookami</el-descriptions-item>
-          <el-descriptions-item label="供应商姓名: ">18100000000</el-descriptions-item>
-          <el-descriptions-item label="联系方式: ">Suzhou</el-descriptions-item>
-          <el-descriptions-item label="供应商邮箱: ">Suzhou</el-descriptions-item>
-        </el-descriptions>
-        <el-divider border-style="dashed" />
-        <el-descriptions title="订单信息">
-          <el-descriptions-item label="创建时间: "> {{ formatDate(Date()) }} </el-descriptions-item>
-          <el-descriptions-item label="商品总数: ">18100000000</el-descriptions-item>
-          <el-descriptions-item label="商品总价: ¥">200.00 元</el-descriptions-item>
-          <el-descriptions-item label="优惠券金额: ¥">200.00 元</el-descriptions-item>
-          <el-descriptions-item label="积分抵扣: ">200.00</el-descriptions-item>
-          <el-descriptions-item label="支付邮费: ¥">200.00 元</el-descriptions-item>
-          <el-descriptions-item label="会员商品优惠: ¥">200.00 元</el-descriptions-item>
-          <el-descriptions-item label="推广人: ¥">200.00 元</el-descriptions-item>
-          <el-descriptions-item label="支付时间: "> {{ formatDate(Date()) }} </el-descriptions-item>
-          <el-descriptions-item label="支付方式: ¥">200.00 元</el-descriptions-item>
-        </el-descriptions>
-        <el-divider v-if="true" border-style="dashed" />
-        <el-descriptions v-if="true" title="订单备注">
-          <el-descriptions-item label="备注: ">TODO</el-descriptions-item>
-        </el-descriptions>
-      </el-tab-pane>
-      <el-tab-pane label="商品信息">
-        <el-descriptions title="商品信息">
-          <el-descriptions-item label="用户UID: ">kooriookami</el-descriptions-item>
-          <el-descriptions-item label="用户昵称: ">18100000000</el-descriptions-item>
-          <el-descriptions-item label="绑定电话: ">Suzhou</el-descriptions-item>
-        </el-descriptions>
-      </el-tab-pane>
-      <el-tab-pane label="订单记录">
-        <el-descriptions title="订单记录">
-          <el-descriptions-item label="用户UID: ">kooriookami</el-descriptions-item>
-          <el-descriptions-item label="用户昵称: ">18100000000</el-descriptions-item>
-          <el-descriptions-item label="绑定电话: ">Suzhou</el-descriptions-item>
-        </el-descriptions>
-      </el-tab-pane>
-      <el-tab-pane label="发货记录">
-        <el-descriptions title="发货记录">
-          <el-descriptions-item label="用户UID: ">kooriookami</el-descriptions-item>
-          <el-descriptions-item label="用户昵称: ">18100000000</el-descriptions-item>
-          <el-descriptions-item label="绑定电话: ">Suzhou</el-descriptions-item>
-        </el-descriptions>
-      </el-tab-pane>
-    </el-tabs>
-  </el-drawer>
-</template>
-<script lang="ts" name="tradeOrderDetail-crmeb" setup>
-import { formatDate } from '@/utils/formatTime'
-import * as TradeOrderApi from '@/api/mall/trade/order'
-const message = useMessage() // 消息弹窗
-
-const drawerVisiable = ref(false)
-let detailData = reactive<any>({
-  items: [],
-  user: {}
-}) //详情数据
-
-const handleClick = () => {}
-
-const handleCommand = (command: string) => {
-  console.log(command)
-}
-//暂考虑一次性加载详情页面所有数据
-const queryDetail = async (no: string) => {
-  try {
-    const res = await TradeOrderApi.getOrderDetail(no)
-    console.log(res)
-    detailData.value = res
-    console.log(detailData.value)
-  } catch {
-    message.error('获取详情数据失败')
-  }
-}
-
-//显示详情
-const show = async (no: string) => {
-  drawerVisiable.value = true
-  try {
-    queryDetail(no)
-  } finally {
-  }
-}
-
-defineExpose({ show }) //显示详情方法
-</script>
-<style>
-.el-dropdown-link {
-  cursor: pointer;
-  color: #409eff;
-}
-.el-icon-arrow-down {
-  font-size: 12px;
-}
-</style>

+ 87 - 90
src/views/mall/trade/order/tradeOrderDetail.vue

@@ -21,10 +21,10 @@
       <el-descriptions-item label="付款方式: ">
         <dict-tag :type="DICT_TYPE.PAY_CHANNEL_CODE_TYPE" :value="order.payChannelCode" />
       </el-descriptions-item>
-      <el-descriptions-item label="买家: ">{{ order.user.nickname }}</el-descriptions-item>
+      <!-- <el-descriptions-item label="买家: ">{{ order.user.nickname }}</el-descriptions-item> -->
       <!-- TODO 芋艿:待实现:跳转会员 -->
       <el-descriptions-item label="收货地址: ">
-        {{ order.receiverAreaName }} " "{{ order.receiverDetailAddress }} " "
+        {{ order.receiverAreaName }} {{ order.receiverDetailAddress }}
         <el-link
           v-clipboard:copy="order.receiverAreaName + ' ' + order.receiverDetailAddress"
           v-clipboard:success="clipboardSuccess"
@@ -37,7 +37,11 @@
     <!-- 订单状态 -->
     <el-descriptions title="订单状态" :column="1">
       <el-descriptions-item label="订单状态: ">
-        <dict-tag :type="DICT_TYPE.TRADE_ORDER_STATUS" :value="order.status" />
+        <dict-tag
+          v-if="order.status !== ''"
+          :type="DICT_TYPE.TRADE_ORDER_STATUS"
+          :value="order.status"
+        />
       </el-descriptions-item>
       <el-descriptions-item label-class-name="no-colon">
         <el-button type="primary" size="small">调整价格</el-button>
@@ -68,12 +72,12 @@
     <!-- 物流信息 TODO -->
 
     <!-- 商品信息 -->
-    <el-descriptions title="商品信息" column="6">
+    <el-descriptions title="商品信息">
       <el-descriptions-item labelClassName="no-colon">
         <el-row :gutter="20">
-          <el-col :span="10">
+          <el-col :span="15">
             <el-table :data="order.items" border>
-              <el-table-column prop="spuName" label="商品" width="400">
+              <el-table-column prop="spuName" label="商品" width="auto">
                 <template #default="{ row }">
                   {{ row.spuName }}
                   <el-tag
@@ -81,22 +85,18 @@
                     v-for="property in row.properties"
                     :key="property.propertyId"
                   >
-                    {{ property.propertyName }}{{ property.valueName }}</el-tag
+                    {{ property.propertyName }}: {{ property.valueName }}</el-tag
                   >
                 </template>
               </el-table-column>
-              <el-table-column prop="originalUnitPrice" label="单价(元)" width="180">
-                <template #default="{ row }">
-                  ¥{{ (row.originalUnitPrice / 100.0).toFixed(2) }}
-                </template>
+              <el-table-column prop="price" label="商品原价(元)" width="150">
+                <template #default="{ row }"> ¥{{ (row.price / 100.0).toFixed(2) }} </template>
               </el-table-column>
               <el-table-column prop="count" label="数量" width="100" />
-              <el-table-column prop="originalPrice" label="小计(元)" width="100">
-                <template #default="{ row }">
-                  ¥{{ (row.originalPrice / 100.0).toFixed(2) }}
-                </template>
+              <el-table-column prop="payPrice" label="合计(元)" width="150">
+                <template #default="{ row }"> ¥{{ (row.payPrice / 100.0).toFixed(2) }} </template>
               </el-table-column>
-              <el-table-column prop="afterSaleStatus" label="退款状态">
+              <el-table-column prop="afterSaleStatus" label="售后状态" width="auto">
                 <template #default="{ row }">
                   <dict-tag
                     :type="DICT_TYPE.TRADE_ORDER_ITEM_AFTER_SALE_STATUS"
@@ -113,26 +113,31 @@
       <!-- <el-descriptions-item v-for="item in 5" label-class-name="no-colon" :key="item" /> -->
     </el-descriptions>
     <el-descriptions column="6">
-      <el-descriptions-item label="商品总额: "
-        >¥{{ (order.originalPrice / 100.0).toFixed(2) }}</el-descriptions-item
-      >
-      <el-descriptions-item label="运费金额: "
-        >¥{{ (order.deliveryPrice / 100.0).toFixed(2) }}</el-descriptions-item
-      >
-      <el-descriptions-item label="订单调价: "
-        >¥{{ (order.adjustPrice / 100.0).toFixed(2) }}</el-descriptions-item
+      <el-descriptions-item label="商品总额: ">
+        ¥{{ parseFloat((order.totalPrice / 100.0) as unknown as string).toFixed(2) }}
+      </el-descriptions-item>
+      <el-descriptions-item label="运费金额: ">
+        ¥{{ parseFloat((order.deliveryPrice / 100.0) as unknown as string).toFixed(2) }}
+      </el-descriptions-item>
+      <el-descriptions-item label="订单调价: ">
+        ¥{{
+          parseFloat((order.adjustPrice / 100.0) as unknown as string).toFixed(2)
+        }}</el-descriptions-item
       >
       <el-descriptions-item>
         <template #label><span style="color: red">商品优惠: </span></template>
-        ¥{{ ((order.originalPrice - order.originalPrice) / 100.0).toFixed(2) }}
+        <!-- 没理解TODO  order.totalPrice - order.totalPrice -->
+        ¥{{
+          parseFloat((order.totalPrice - order.totalPrice / 100.0) as unknown as string).toFixed(2)
+        }}
       </el-descriptions-item>
       <el-descriptions-item>
         <template #label><span style="color: red">订单优惠: </span></template>
-        ¥{{ (order.discountPrice / 100.0).toFixed(2) }}
+        ¥{{ parseFloat((order.discountPrice / 100.0) as unknown as string).toFixed(2) }}
       </el-descriptions-item>
       <el-descriptions-item>
         <template #label><span style="color: red">积分抵扣: </span></template>
-        ¥{{ (order.pointPrice / 100.0).toFixed(2) }}
+        ¥{{ parseFloat((order.pointPrice / 100.0) as unknown as string).toFixed(2) }}
       </el-descriptions-item>
 
       <el-descriptions-item v-for="item in 5" label-class-name="no-colon" :key="item" />
@@ -159,66 +164,58 @@
 
         <!-- 物流信息 -->
         <el-descriptions-item v-if="group.key === 'expressInfo'" labelClassName="no-colon">
-          <el-tabs type="card">
-            <!-- 循环包裹物流信息 -->
-            <el-tab-pane
-              v-for="pkgInfo in detailInfo[group.key]"
-              :key="pkgInfo.label"
-              :label="pkgInfo.label"
-            >
-              <!-- 包裹详情 -->
-              <el-descriptions>
-                <el-descriptions-item
-                  v-for="(pkgChild, pkgCIdx) in group.children"
-                  v-bind="pkgChild.childProps"
-                  :key="`pkgChild_${pkgCIdx}`"
-                  :label="pkgChild.label"
-                >
-                  <!-- 包裹商品列表 -->
-                  <template v-if="pkgChild.valueKey === 'goodsList' && pkgInfo[pkgChild.valueKey]">
-                    <div
-                      v-for="(goodInfo, goodInfoIdx) in pkgInfo[pkgChild.valueKey]"
-                      :key="`goodInfo_${goodInfoIdx}`"
-                      style="display: flex"
-                    >
-                      <el-image
-                        style="width: 100px; height: 100px; flex: none"
-                        :src="goodInfo.imgUrl"
-                      />
-                      <el-descriptions :column="1">
-                        <el-descriptions-item labelClassName="no-colon">{{
-                          goodInfo.name
-                        }}</el-descriptions-item>
-                        <el-descriptions-item label="数量">{{
-                          goodInfo.count
-                        }}</el-descriptions-item>
-                      </el-descriptions>
-                    </div>
-                  </template>
+          <!-- 循环包裹物流信息 -->
+          <div v-show="(pkgInfo = detailInfo[group.key]) !== null" style="border: 1px dashed">
+            <!-- 包裹详情 -->
+            <el-descriptions class="m-5">
+              <el-descriptions-item
+                v-for="(pkgChild, pkgCIdx) in group.children"
+                v-bind="pkgChild.childProps"
+                :key="`pkgChild_${pkgCIdx}`"
+                :label="pkgChild.label"
+              >
+                <!-- 包裹商品列表 -->
+                <template v-if="pkgChild.valueKey === 'goodsList' && pkgInfo[pkgChild.valueKey]">
+                  <div
+                    v-for="(goodInfo, goodInfoIdx) in pkgInfo[pkgChild.valueKey]"
+                    :key="`goodInfo_${goodInfoIdx}`"
+                    style="display: flex"
+                  >
+                    <el-image
+                      style="width: 100px; height: 100px; flex: none"
+                      :src="goodInfo.imgUrl"
+                    />
+                    <el-descriptions :column="1">
+                      <el-descriptions-item labelClassName="no-colon">{{
+                        goodInfo.name
+                      }}</el-descriptions-item>
+                      <el-descriptions-item label="数量">{{ goodInfo.count }}</el-descriptions-item>
+                    </el-descriptions>
+                  </div>
+                </template>
 
-                  <!-- 包裹物流详情 -->
-                  <template v-else-if="pkgChild.valueKey === 'wlxq'">
-                    <el-row :gutter="10">
-                      <el-col :span="6" :offset="1">
-                        <el-timeline>
-                          <el-timeline-item
-                            v-for="(activity, index) in pkgInfo[pkgChild.valueKey]"
-                            :key="index"
-                            :timestamp="activity.timestamp"
-                          >
-                            {{ activity.content }}
-                          </el-timeline-item>
-                        </el-timeline>
-                      </el-col>
-                    </el-row>
-                  </template>
-                  <template v-else>
-                    {{ pkgInfo[pkgChild.valueKey] }}
-                  </template>
-                </el-descriptions-item>
-              </el-descriptions>
-            </el-tab-pane>
-          </el-tabs>
+                <!-- 包裹物流详情 -->
+                <template v-else-if="pkgChild.valueKey === 'wlxq'">
+                  <el-row :gutter="10">
+                    <el-col :span="6" :offset="1">
+                      <el-timeline>
+                        <el-timeline-item
+                          v-for="(activity, index) in pkgInfo[pkgChild.valueKey]"
+                          :key="index"
+                          :timestamp="activity.timestamp"
+                        >
+                          {{ activity.content }}
+                        </el-timeline-item>
+                      </el-timeline>
+                    </el-col>
+                  </el-row>
+                </template>
+                <template v-else>
+                  {{ pkgInfo[pkgChild.valueKey] }}
+                </template>
+              </el-descriptions-item>
+            </el-descriptions>
+          </div>
         </el-descriptions-item>
       </el-descriptions>
     </div>
@@ -259,7 +256,7 @@ const detailGroups = ref([
 ])
 
 const detailInfo = ref({
-  expressInfo: [
+  expressInfo:
     // 物流信息
     {
       label: '包裹1',
@@ -290,8 +287,7 @@ const detailInfo = ref({
           timestamp: '2018-04-11 12:55:52'
         }
       ]
-    }
-  ],
+    },
   orderLog: [
     // 订单操作日志
     {
@@ -310,8 +306,9 @@ const getlist = async () => {
   dialogVisible.value = true
   loading.value = true
   try {
-    const res = await TradeOrderApi.getOrderDetail(queryParams.id)
+    const res = await TradeOrderApi.getOrderDetail(queryParams.id as unknown as number)
     order.value = res
+    console.log(order)
   } catch {
     message.error('获取详情数据失败')
   } finally {