| | |
| | | import { computed, nextTick, onMounted, onUnmounted, ref, watch } from 'vue' |
| | | import { useRoute, useRouter } from 'vue-router' |
| | | import { useTabStore } from '@/store' |
| | | import SearchPanel from '@/components/custom/SearchPanel.vue' |
| | | import SelectPointModal from '@/views/testDemo/specialPointManagement/components/SelectPointModal.vue' |
| | | import VehicleSelectModal from '@/views/assetManagement/fleetManagement/components/VehicleSelectModal.vue' |
| | | import type { DataTableColumns } from 'naive-ui' |
| | |
| | | const testPointTableScrollX = 960 |
| | | const testPointColumns = computed<DataTableColumns<TestPoint>>(() => [ |
| | | { |
| | | title: '排序', |
| | | title: '序号', |
| | | key: 'index', |
| | | width: 60, |
| | | align: 'left', |
| | |
| | | width: 280, |
| | | align: 'left', |
| | | render: (_row, index) => ( |
| | | <n-space size={8}> |
| | | <n-space size={12}> |
| | | <n-button |
| | | text |
| | | type="primary" |
| | |
| | | <span style="color: #ff4d4f">*</span>计划名称 |
| | | </div> |
| | | <n-input |
| | | v-model:value="planName" |
| | | class="flex-1" |
| | | placeholder="请输入" |
| | | clearable |
| | | style="width: 400px" |
| | | maxlength="30" |
| | | show-count |
| | | :disabled="isReadOnly" |
| | | v-model:value="planName" class="flex-1" placeholder="请输入" clearable style="width: 400px" maxlength="30" |
| | | show-count :disabled="isReadOnly" |
| | | /> |
| | | </div> |
| | | </n-card> |
| | | |
| | | <n-card style="border-radius: 6px" content-style="padding: 24px;"> |
| | | <div class="mb-4 flex items-center"> |
| | | <div class="mr-2 bg-blue-500" style="width: 3px; height: 14px" /> |
| | | <span class="font-bold" style="font-size: 16px">测试车辆</span> |
| | | </div> |
| | | <div class="mb-4 flex items-center gap-2"> |
| | | <div class="text-sm"> |
| | | <div class="mb-4 flex items-center justify-between gap-2"> |
| | | <!-- <div class="text-sm"> |
| | | 测试车辆 |
| | | </div> --> |
| | | <div class=" flex items-center"> |
| | | <div class="mr-2 bg-blue-500" style="width: 3px; height: 14px" /> |
| | | <span class="font-bold" style="font-size: 16px">测试车辆</span> |
| | | </div> |
| | | <div class="flex gap-2"> |
| | | <n-button |
| | | style=" |
| | | height: 28px; |
| | | border: 1px solid #7abdff; |
| | | background-color: #e6f4ff; |
| | | color: #0068ff; |
| | | " |
| | | :disabled="isReadOnly" |
| | | @click="handleSelectVehicle" |
| | | > |
| | | 选择 |
| | | </n-button> |
| | | <n-button style="height: 28px" :disabled="isReadOnly" @click="handleResetVehicles"> |
| | | <n-button style="width: 84px;" :disabled="isReadOnly" @click="handleResetVehicles"> |
| | | 重置 |
| | | </n-button> |
| | | <n-button style="width: 84px;" type="primary" secondary :disabled="isReadOnly" @click="handleSelectVehicle"> |
| | | 选择 |
| | | </n-button> |
| | | </div> |
| | | </div> |
| | | |
| | | <n-data-table |
| | | :columns="vehicleColumns" |
| | | :data="vehicles" |
| | | :bordered="false" |
| | | :scroll-x="vehicleTableScrollX" |
| | | :header-height="18" |
| | | :row-height="18" |
| | | :row-key="row => row.id" |
| | | /> |
| | | :columns="vehicleColumns" :data="vehicles" :bordered="false" :scroll-x="vehicleTableScrollX" |
| | | :header-height="18" :row-height="18" :row-key="row => row.id" |
| | | > |
| | | <template #empty> |
| | | <div class="flex-center"> |
| | | <img :src="noDataImg" style="width:123px;height:125px"> |
| | | </div> |
| | | </template> |
| | | </n-data-table> |
| | | </n-card> |
| | | |
| | | <n-card style="border-radius: 6px" content-style="padding: 24px;"> |
| | |
| | | <span class="font-bold" style="font-size: 16px">测试点位信息</span> |
| | | </div> |
| | | <n-button |
| | | style=" |
| | | height: 28px; |
| | | border: 1px solid #7abdff; |
| | | background-color: #e6f4ff; |
| | | color: #0068ff; |
| | | " |
| | | :disabled="isReadOnly" |
| | | @click="handleAddPoint" |
| | | style="width: 84px;" type="primary" secondary :disabled="isReadOnly" @click="handleAddPoint" |
| | | > |
| | | 添加 |
| | | </n-button> |
| | | </div> |
| | | |
| | | <n-data-table |
| | | :columns="testPointColumns" |
| | | :data="testPoints" |
| | | :bordered="false" |
| | | :scroll-x="testPointTableScrollX" |
| | | :header-height="18" |
| | | :row-height="18" |
| | | :row-key="row => row.id" |
| | | /> |
| | | :columns="testPointColumns" :data="testPoints" :bordered="false" :scroll-x="testPointTableScrollX" |
| | | :header-height="18" :row-height="18" :row-key="row => row.id" |
| | | > |
| | | <template #empty> |
| | | <div class="flex-center"> |
| | | <img :src="noDataImg" style="width:123px;height:125px"> |
| | | </div> |
| | | </template> |
| | | </n-data-table> |
| | | </n-card> |
| | | |
| | | <n-card |
| | |
| | | <span class="font-bold" style="font-size: 16px">订单列表</span> |
| | | </div> |
| | | |
| | | <div class="mb-4 flex flex-wrap gap-4"> |
| | | <div class="flex items-center gap-2"> |
| | | <div class="text-sm" style="width: 70px"> |
| | | 订单号 |
| | | </div> |
| | | <n-input |
| | | v-model:value="orderSearchModel.orderNumber" |
| | | placeholder="请输入订单号" |
| | | clearable |
| | | style="width: 200px" |
| | | /> |
| | | </div> |
| | | <div class="flex items-center gap-2"> |
| | | <div class="text-sm" style="width: 70px"> |
| | | 车辆 |
| | | </div> |
| | | <n-input |
| | | v-model:value="orderSearchModel.plateNumber" |
| | | placeholder="请输入车辆" |
| | | clearable |
| | | style="width: 200px" |
| | | /> |
| | | </div> |
| | | <div class="flex items-center gap-2"> |
| | | <div class="text-sm" style="width: 70px"> |
| | | 订单状态 |
| | | </div> |
| | | <n-select |
| | | v-model:value="orderSearchModel.status" |
| | | placeholder="请选择订单状态" |
| | | clearable |
| | | style="width: 150px" |
| | | :options="orderStatusOptions" |
| | | @update:show="(val) => isOrderStatusOpen = val" |
| | | > |
| | | <template #arrow> |
| | | <img |
| | | src="https://huishou-1323682843.cos.ap-nanjing.myqcloud.com/images/e120f81c-9f15-4e1a-9938-22252898edf9.png" |
| | | class="arrow-icon" :class="[isOrderStatusOpen ? 'arrow-icon--open' : '']" |
| | | style="width: 16px; height: 16px" |
| | | alt="arrow" |
| | | <n-form |
| | | :model="orderSearchModel" |
| | | label-placement="left" |
| | | inline |
| | | :show-feedback="false" |
| | | class="mb-4" |
| | | > |
| | | <SearchPanel :default-collapsed="false"> |
| | | <n-gi> |
| | | <n-form-item label="订单号" path="orderNumber"> |
| | | <n-input |
| | | v-model:value="orderSearchModel.orderNumber" |
| | | placeholder="请输入订单号" |
| | | clearable |
| | | /> |
| | | </n-form-item> |
| | | </n-gi> |
| | | <n-gi> |
| | | <n-form-item label="车辆" path="plateNumber"> |
| | | <n-input |
| | | v-model:value="orderSearchModel.plateNumber" |
| | | placeholder="请输入车辆" |
| | | clearable |
| | | /> |
| | | </n-form-item> |
| | | </n-gi> |
| | | <n-gi> |
| | | <n-form-item label="订单状态" path="status"> |
| | | <n-select |
| | | v-model:value="orderSearchModel.status" |
| | | placeholder="请选择订单状态" |
| | | clearable |
| | | :options="orderStatusOptions" |
| | | @update:show="(val) => isOrderStatusOpen = val" |
| | | > |
| | | </template> |
| | | <template #empty> |
| | | <div class="flex-center"> |
| | | <img |
| | | :src="noDataImg" |
| | | style="width: 50%" |
| | | alt="no-data" |
| | | > |
| | | </div> |
| | | </template> |
| | | </n-select> |
| | | </div> |
| | | <div class="flex items-center gap-2"> |
| | | <div class="text-sm" style="width: 70px"> |
| | | 下单时间 |
| | | </div> |
| | | <n-date-picker |
| | | v-model:value="orderSearchModel.orderTimeRange" |
| | | format="yyyy/MM/dd" |
| | | type="daterange" |
| | | clearable |
| | | :actions="[]" |
| | | :close-on-select="true" |
| | | start-placeholder="开始时间" |
| | | end-placeholder="结束时间" |
| | | style="width: 300px" |
| | | /> |
| | | </div> |
| | | <div class="flex gap-2"> |
| | | <n-button type="primary" @click="handleSearchOrders"> |
| | | 查询 |
| | | </n-button> |
| | | <n-button @click="handleResetOrderSearch"> |
| | | 重置 |
| | | </n-button> |
| | | </div> |
| | | </div> |
| | | <template #arrow> |
| | | <img |
| | | src="https://huishou-1323682843.cos.ap-nanjing.myqcloud.com/images/e120f81c-9f15-4e1a-9938-22252898edf9.png" |
| | | class="arrow-icon" |
| | | :class="[isOrderStatusOpen ? 'arrow-icon--open' : '']" |
| | | style="width: 16px; height: 16px" |
| | | alt="arrow" |
| | | > |
| | | </template> |
| | | <template #empty> |
| | | <div class="flex-center"> |
| | | <img :src="noDataImg" style="width: 50%" alt="no-data"> |
| | | </div> |
| | | </template> |
| | | </n-select> |
| | | </n-form-item> |
| | | </n-gi> |
| | | <n-gi> |
| | | <n-form-item label="下单时间" path="orderTimeRange"> |
| | | <n-date-picker |
| | | v-model:value="orderSearchModel.orderTimeRange" |
| | | format="yyyy/MM/dd" |
| | | type="daterange" |
| | | clearable |
| | | :actions="[]" |
| | | :close-on-select="true" |
| | | start-placeholder="开始时间" |
| | | end-placeholder="结束时间" |
| | | separator="-" |
| | | /> |
| | | </n-form-item> |
| | | </n-gi> |
| | | <template #action> |
| | | <n-button style="width: 84px;" @click="handleResetOrderSearch"> |
| | | 重置 |
| | | </n-button> |
| | | <n-button style="width: 84px;" type="primary" @click="handleSearchOrders"> |
| | | 查询 |
| | | </n-button> |
| | | </template> |
| | | </SearchPanel> |
| | | </n-form> |
| | | |
| | | <div class="flex-1 overflow-auto"> |
| | | <n-data-table |
| | | :columns="orderColumns" |
| | | :data="orders" |
| | | :bordered="false" |
| | | :scroll-x="orderTableScrollX" |
| | | :header-height="18" |
| | | :row-height="18" |
| | | :loading="orderLoading" |
| | | :columns="orderColumns" :data="orders" :bordered="false" :scroll-x="orderTableScrollX" |
| | | :header-height="18" :row-height="18" :loading="orderLoading" |
| | | > |
| | | <template #empty> |
| | | <div class="flex-center"> |
| | |
| | | </n-data-table> |
| | | </div> |
| | | <Pagination |
| | | :count="orderCount" |
| | | :page="orderPageParams.pageNum" |
| | | :page-size="orderPageParams.pageSize" |
| | | class="robotaxi-pagination mt-12px" |
| | | @change="changeOrderPage" |
| | | :count="orderCount" :page="orderPageParams.pageNum" :page-size="orderPageParams.pageSize" |
| | | class="robotaxi-pagination mt-12px" @change="changeOrderPage" |
| | | /> |
| | | </n-card> |
| | | |
| | |
| | | <div class="flex items-center gap-2"> |
| | | <span class="text-sm">圈数:</span> |
| | | <n-input-number |
| | | v-model:value="lapCount" |
| | | :min="1" |
| | | :max="100" |
| | | style="width: 100px" |
| | | v-model:value="lapCount" :min="1" :max="100" style="width: 100px" |
| | | :disabled="isBatchRunning" |
| | | /> |
| | | </div> |
| | | <n-button |
| | | type="primary" |
| | | :disabled="isBatchRunning" |
| | | @click="handleBatchStart" |
| | | > |
| | | <n-button type="primary" :disabled="isBatchRunning" @click="handleBatchStart"> |
| | | 启动批量测试 |
| | | </n-button> |
| | | <n-button |
| | | :disabled="!batchProgress || batchProgress.errorCount === 0" |
| | | @click="handleBatchRetry" |
| | | > |
| | | <n-button :disabled="!batchProgress || batchProgress.errorCount === 0" @click="handleBatchRetry"> |
| | | 重试失败 |
| | | </n-button> |
| | | <n-button |
| | | type="error" |
| | | :disabled="!isBatchRunning" |
| | | @click="handleBatchCancel" |
| | | > |
| | | <n-button type="error" :disabled="!isBatchRunning" @click="handleBatchCancel"> |
| | | 取消 |
| | | </n-button> |
| | | </div> |
| | |
| | | </span> |
| | | </div> |
| | | <n-progress |
| | | type="line" |
| | | :percentage="batchProgressPercent" |
| | | type="line" :percentage="batchProgressPercent" |
| | | :status="batchProgress.status === 'FAILED' ? 'error' : batchProgress.status === 'SUCCESS' ? 'success' : 'default'" |
| | | :height="20" |
| | | :show-indicator="true" |
| | | class="mb-4" |
| | | :height="20" :show-indicator="true" class="mb-4" |
| | | /> |
| | | <div class="flex gap-8 text-sm"> |
| | | <div>总订单数:<span class="font-bold">{{ batchProgress.totalCount || 0 }}</span></div> |
| | | <div>已创建:<span class="font-bold text-blue-600">{{ batchProgress.createdCount || 0 }}</span></div> |
| | | <div>已完成:<span class="font-bold text-green-600">{{ batchProgress.completedCount || 0 }}</span></div> |
| | | <div>异常数:<span class="font-bold" :class="batchProgress.errorCount > 0 ? 'text-red-600' : ''">{{ batchProgress.errorCount || 0 }}</span></div> |
| | | <div> |
| | | 异常数:<span class="font-bold" :class="batchProgress.errorCount > 0 ? 'text-red-600' : ''">{{ |
| | | batchProgress.errorCount || 0 }}</span> |
| | | </div> |
| | | </div> |
| | | </n-card> |
| | | |
| | |
| | | <span class="font-bold" style="font-size: 16px">车辆进度</span> |
| | | </div> |
| | | <n-data-table |
| | | :columns="vehicleProgressColumns" |
| | | :data="vehicleProgressList" |
| | | :bordered="false" |
| | | :scroll-x="vehicleProgressTableScrollX" |
| | | :header-height="18" |
| | | :row-height="18" |
| | | :columns="vehicleProgressColumns" :data="vehicleProgressList" :bordered="false" |
| | | :scroll-x="vehicleProgressTableScrollX" :header-height="18" :row-height="18" |
| | | > |
| | | <template #empty> |
| | | <div class="flex-center"> |
| | |
| | | <n-button style="width: 84px; height: 32px" @click="handleCancel"> |
| | | {{ isDetail ? "返回" : "取消" }} |
| | | </n-button> |
| | | <n-button |
| | | v-if="!isDetail" |
| | | type="primary" |
| | | style="width: 84px; height: 32px" |
| | | @click="handleSave" |
| | | > |
| | | <n-button v-if="!isDetail" type="primary" style="width: 84px; height: 32px" @click="handleSave"> |
| | | 保存 |
| | | </n-button> |
| | | </div> |
| | | |
| | | <SelectPointModal |
| | | v-model:show="showPointSelectModal" |
| | | :existing-points="existingPointsForPointModal" |
| | | v-model:show="showPointSelectModal" :existing-points="existingPointsForPointModal" |
| | | @confirm="handleConfirmPointSelect" |
| | | /> |
| | | <VehicleSelectModal |
| | | v-model:visible="showVehicleModal" |
| | | :existing-vehicles="vehicles" |
| | | v-model:visible="showVehicleModal" :existing-vehicles="vehicles" |
| | | @confirm="handleConfirmVehicleSelect" |
| | | /> |
| | | |
| | | <n-modal |
| | | v-model:show="showOrderModal" |
| | | title="生成订单" |
| | | preset="card" |
| | | size="small" |
| | | style="width: 400px" |
| | | :segmented="{ |
| | | v-model:show="showOrderModal" title="生成订单" preset="card" size="small" style="width: 400px" :segmented="{ |
| | | content: true, |
| | | action: true, |
| | | }" |
| | | :mask-closable="false" |
| | | }" :mask-closable="false" |
| | | > |
| | | <div class="p-4"> |
| | | <div class="mb-4"> |
| | |
| | | <div class="text-sm mb-2"> |
| | | 是否停车: |
| | | </div> |
| | | <n-radio-group |
| | | v-model:value="orderModalData.isPark" |
| | | :disabled="orderModalData.orderType === '测试订单'" |
| | | > |
| | | <n-radio-group v-model:value="orderModalData.isPark" :disabled="orderModalData.orderType === '测试订单'"> |
| | | <n-radio :value="true"> |
| | | 是 |
| | | </n-radio> |
| | |
| | | 否 |
| | | </n-radio> |
| | | </n-radio-group> |
| | | <div |
| | | v-if="orderModalData.orderType === '测试订单'" |
| | | class="text-12px text-red-500 mt-1" |
| | | > |
| | | <div v-if="orderModalData.orderType === '测试订单'" class="text-12px text-red-500 mt-1"> |
| | | 测试订单默认停车,不可修改 |
| | | </div> |
| | | </div> |
| | |
| | | </n-modal> |
| | | |
| | | <n-modal |
| | | v-model:show="showChangeAmountModal" |
| | | title="订单改价" |
| | | preset="card" |
| | | size="small" |
| | | style="width: 400px" |
| | | v-model:show="showChangeAmountModal" title="订单改价" preset="card" size="small" style="width: 400px" |
| | | :segmented="{ |
| | | content: true, |
| | | action: true, |
| | | }" |
| | | :bordered="false" |
| | | :mask-closable="false" |
| | | }" :bordered="false" :mask-closable="false" |
| | | > |
| | | <div class="p-4"> |
| | | <div class="text-sm mb-2"> |
| | | 订单金额: |
| | | </div> |
| | | <n-input-number |
| | | v-model:value="changeAmountForm.amount" |
| | | :precision="2" |
| | | min="0" |
| | | placeholder="请输入金额" |
| | | v-model:value="changeAmountForm.amount" :precision="2" min="0" placeholder="请输入金额" |
| | | style="width: 100%" |
| | | /> |
| | | </div> |
| | |
| | | </n-modal> |
| | | |
| | | <n-modal |
| | | v-model:show="showReassignModal" |
| | | title="改派订单" |
| | | preset="card" |
| | | size="small" |
| | | style="width: 400px" |
| | | :segmented="{ |
| | | v-model:show="showReassignModal" title="改派订单" preset="card" size="small" style="width: 400px" :segmented="{ |
| | | content: true, |
| | | action: true, |
| | | }" |
| | | :bordered="false" |
| | | :mask-closable="false" |
| | | }" :bordered="false" :mask-closable="false" |
| | | > |
| | | <div class="p-4"> |
| | | <div class="text-sm mb-2"> |
| | | 改派车辆: |
| | | </div> |
| | | <n-select |
| | | v-model:value="reassignForm.vehicleId" |
| | | placeholder="请选择改派车辆" |
| | | :options="reassignVehicleOptions" |
| | | clearable |
| | | style="width: 100%" |
| | | @update:show="(val) => isReassignVehicleOpen = val" |
| | | v-model:value="reassignForm.vehicleId" placeholder="请选择改派车辆" :options="reassignVehicleOptions" |
| | | clearable style="width: 100%" @update:show="(val) => isReassignVehicleOpen = val" |
| | | > |
| | | <template #arrow> |
| | | <img |
| | | src="https://huishou-1323682843.cos.ap-nanjing.myqcloud.com/images/e120f81c-9f15-4e1a-9938-22252898edf9.png" |
| | | class="arrow-icon" :class="[isReassignVehicleOpen ? 'arrow-icon--open' : '']" |
| | | style="width: 16px; height: 16px" |
| | | alt="arrow" |
| | | style="width: 16px; height: 16px" alt="arrow" |
| | | > |
| | | </template> |
| | | <template #empty> |
| | | <div class="flex-center"> |
| | | <img |
| | | :src="noDataImg" |
| | | style="width: 50%" |
| | | alt="no-data" |
| | | > |
| | | <img :src="noDataImg" style="width: 50%" alt="no-data"> |
| | | </div> |
| | | </template> |
| | | </n-select> |
| | |
| | | 改派原因: |
| | | </div> |
| | | <n-input |
| | | v-model:value="reassignForm.reassignReason" |
| | | type="textarea" |
| | | placeholder="请输入改派原因" |
| | | maxlength="200" |
| | | v-model:value="reassignForm.reassignReason" type="textarea" placeholder="请输入改派原因" maxlength="200" |
| | | show-count |
| | | /> |
| | | </div> |
| | |
| | | </div> |
| | | </template> |
| | | |
| | | <style scoped></style> |
| | | <style scoped> |
| | | .n-button--secondary { |
| | | box-sizing: border-box; |
| | | color: #0068FF; |
| | | border: 1px solid #7ABDFF; |
| | | background-color: #E6F4FF; |
| | | } |
| | | </style> |