|
|
@@ -0,0 +1,258 @@
|
|
|
+<template>
|
|
|
+ <div class="assessment-orders admin-page">
|
|
|
+ <el-card>
|
|
|
+ <div slot="header" class="admin-page-header">
|
|
|
+ <span class="admin-page-title">测评预约管理</span>
|
|
|
+ <div class="filter-bar">
|
|
|
+ <el-input
|
|
|
+ v-model="keyword"
|
|
|
+ placeholder="搜索用户/规划师..."
|
|
|
+ prefix-icon="el-icon-search"
|
|
|
+ clearable
|
|
|
+ style="width: 200px; margin-right: 10px;"
|
|
|
+ @keyup.enter.native="handleSearch"
|
|
|
+ @clear="handleSearch"
|
|
|
+ />
|
|
|
+ <el-select v-model="statusFilter" placeholder="预约状态" clearable @change="handleSearch" style="width: 140px; margin-right: 10px;">
|
|
|
+ <el-option label="全部状态" value="" />
|
|
|
+ <el-option label="待确认" :value="0" />
|
|
|
+ <el-option label="已确认" :value="1" />
|
|
|
+ <el-option label="已完成" :value="2" />
|
|
|
+ <el-option label="已取消" :value="3" />
|
|
|
+ <el-option label="未到" :value="4" />
|
|
|
+ </el-select>
|
|
|
+ <el-button type="primary" icon="el-icon-search" @click="handleSearch">搜索</el-button>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+
|
|
|
+ <el-table :max-height="tableHeight" :data="list" v-loading="loading" border stripe empty-text="暂无测评预约">
|
|
|
+ <el-table-column label="用户" width="110">
|
|
|
+ <template slot-scope="{ row }">{{ row.userName || '-' }}</template>
|
|
|
+ </el-table-column>
|
|
|
+ <el-table-column label="孩子" width="100">
|
|
|
+ <template slot-scope="{ row }">{{ row.childName || '-' }}</template>
|
|
|
+ </el-table-column>
|
|
|
+ <el-table-column label="测评方案" min-width="140" show-overflow-tooltip>
|
|
|
+ <template slot-scope="{ row }">{{ row.packageName || '-' }}</template>
|
|
|
+ </el-table-column>
|
|
|
+ <el-table-column label="当前规划师" width="120">
|
|
|
+ <template slot-scope="{ row }">
|
|
|
+ <span v-if="row.guideName">{{ row.guideName }}</span>
|
|
|
+ <el-tag v-else size="mini" type="info">未分配</el-tag>
|
|
|
+ </template>
|
|
|
+ </el-table-column>
|
|
|
+ <el-table-column label="预约日期" width="120">
|
|
|
+ <template slot-scope="{ row }">{{ row.appointmentDate || '-' }}</template>
|
|
|
+ </el-table-column>
|
|
|
+ <el-table-column label="预约时间" width="100">
|
|
|
+ <template slot-scope="{ row }">{{ row.appointmentTime || '-' }}</template>
|
|
|
+ </el-table-column>
|
|
|
+ <el-table-column label="预约类型" width="100">
|
|
|
+ <template slot-scope="{ row }">{{ row.appointmentType || '-' }}</template>
|
|
|
+ </el-table-column>
|
|
|
+ <el-table-column label="状态" width="100">
|
|
|
+ <template slot-scope="{ row }">
|
|
|
+ <el-tag :type="statusType(row.status)" size="mini">{{ statusLabel(row.status) }}</el-tag>
|
|
|
+ </template>
|
|
|
+ </el-table-column>
|
|
|
+ <el-table-column label="创建时间" width="155">
|
|
|
+ <template slot-scope="{ row }">{{ formatTime(row.createdAt) }}</template>
|
|
|
+ </el-table-column>
|
|
|
+ <el-table-column label="操作" width="130" fixed="right">
|
|
|
+ <template slot-scope="{ row }">
|
|
|
+ <el-button
|
|
|
+ size="mini"
|
|
|
+ type="primary"
|
|
|
+ plain
|
|
|
+ @click="openChangeGuideDialog(row)"
|
|
|
+ :disabled="row.status === 3"
|
|
|
+ >修改规划师</el-button>
|
|
|
+ </template>
|
|
|
+ </el-table-column>
|
|
|
+ </el-table>
|
|
|
+
|
|
|
+ <el-pagination
|
|
|
+ @size-change="handleSizeChange"
|
|
|
+ @current-change="handleCurrentChange"
|
|
|
+ :current-page="page"
|
|
|
+ :page-sizes="[10, 20, 50]"
|
|
|
+ :page-size="size"
|
|
|
+ :total="total"
|
|
|
+ layout="total, sizes, prev, pager, next, jumper"
|
|
|
+ class="pagination-wrap"
|
|
|
+ />
|
|
|
+ </el-card>
|
|
|
+
|
|
|
+ <!-- 修改规划师 Dialog -->
|
|
|
+ <el-dialog title="修改规划师" :visible.sync="changeGuideDialogVisible" width="500px">
|
|
|
+ <div v-if="currentOrder" v-loading="guidesLoading">
|
|
|
+ <el-descriptions :column="1" border size="small" style="margin-bottom: 20px;">
|
|
|
+ <el-descriptions-item label="用户">{{ currentOrder.userName }}</el-descriptions-item>
|
|
|
+ <el-descriptions-item label="孩子">{{ currentOrder.childName }}</el-descriptions-item>
|
|
|
+ <el-descriptions-item label="测评方案">{{ currentOrder.packageName || '-' }}</el-descriptions-item>
|
|
|
+ <el-descriptions-item label="预约日期">{{ currentOrder.appointmentDate || '-' }}</el-descriptions-item>
|
|
|
+ <el-descriptions-item label="当前规划师">
|
|
|
+ <span v-if="currentOrder.guideName">{{ currentOrder.guideName }}</span>
|
|
|
+ <span v-else style="color: #999;">未分配</span>
|
|
|
+ </el-descriptions-item>
|
|
|
+ </el-descriptions>
|
|
|
+
|
|
|
+ <el-form label-width="100px">
|
|
|
+ <el-form-item label="新规划师">
|
|
|
+ <el-select
|
|
|
+ v-model="selectedGuideId"
|
|
|
+ placeholder="请选择规划师"
|
|
|
+ style="width: 100%;"
|
|
|
+ filterable
|
|
|
+ >
|
|
|
+ <el-option
|
|
|
+ v-for="g in guides"
|
|
|
+ :key="g.id"
|
|
|
+ :label="g.nickname + (g.realName ? ' (' + g.realName + ')' : '') + (g.teacherNo ? ' - ' + g.teacherNo : '')"
|
|
|
+ :value="g.id"
|
|
|
+ />
|
|
|
+ </el-select>
|
|
|
+ </el-form-item>
|
|
|
+ </el-form>
|
|
|
+ </div>
|
|
|
+ <div slot="footer">
|
|
|
+ <el-button @click="changeGuideDialogVisible = false">取消</el-button>
|
|
|
+ <el-button type="primary" @click="confirmChangeGuide" :loading="changing">确认修改</el-button>
|
|
|
+ </div>
|
|
|
+ </el-dialog>
|
|
|
+ </div>
|
|
|
+</template>
|
|
|
+
|
|
|
+<script>
|
|
|
+import { getAssessmentOrderList, changeAssessmentGuide, getAvailableGuides } from '@/api/admin'
|
|
|
+
|
|
|
+export default {
|
|
|
+ name: 'AssessmentOrders',
|
|
|
+ computed: {
|
|
|
+ tableHeight() {
|
|
|
+ return window.innerHeight - 320
|
|
|
+ }
|
|
|
+ },
|
|
|
+ data() {
|
|
|
+ return {
|
|
|
+ loading: false,
|
|
|
+ list: [],
|
|
|
+ page: 1,
|
|
|
+ size: 20,
|
|
|
+ total: 0,
|
|
|
+ keyword: '',
|
|
|
+ statusFilter: '',
|
|
|
+ // 修改规划师
|
|
|
+ changeGuideDialogVisible: false,
|
|
|
+ currentOrder: null,
|
|
|
+ selectedGuideId: null,
|
|
|
+ guides: [],
|
|
|
+ guidesLoading: false,
|
|
|
+ changing: false
|
|
|
+ }
|
|
|
+ },
|
|
|
+ mounted() {
|
|
|
+ this.loadList()
|
|
|
+ },
|
|
|
+ methods: {
|
|
|
+ handleSearch() {
|
|
|
+ this.page = 1
|
|
|
+ this.loadList()
|
|
|
+ },
|
|
|
+ async loadList() {
|
|
|
+ this.loading = true
|
|
|
+ try {
|
|
|
+ var params = { page: this.page, size: this.size }
|
|
|
+ if (this.statusFilter) {
|
|
|
+ params.status = this.statusFilter
|
|
|
+ }
|
|
|
+ if (this.keyword) {
|
|
|
+ params.keyword = this.keyword
|
|
|
+ }
|
|
|
+ var res = await getAssessmentOrderList(params)
|
|
|
+ this.list = res.data.records || []
|
|
|
+ this.total = res.data.total || 0
|
|
|
+ } catch (e) {
|
|
|
+ this.$message.error(e.message || '加载测评订单失败')
|
|
|
+ } finally {
|
|
|
+ this.loading = false
|
|
|
+ }
|
|
|
+ },
|
|
|
+ handleSizeChange(val) {
|
|
|
+ this.size = val
|
|
|
+ this.page = 1
|
|
|
+ this.loadList()
|
|
|
+ },
|
|
|
+ handleCurrentChange(val) {
|
|
|
+ this.page = val
|
|
|
+ this.loadList()
|
|
|
+ },
|
|
|
+ async openChangeGuideDialog(row) {
|
|
|
+ this.currentOrder = row
|
|
|
+ this.selectedGuideId = row.guideId || null
|
|
|
+ this.changeGuideDialogVisible = true
|
|
|
+
|
|
|
+ this.guidesLoading = true
|
|
|
+ try {
|
|
|
+ var res = await getAvailableGuides()
|
|
|
+ this.guides = res.data || []
|
|
|
+ } catch (e) {
|
|
|
+ this.$message.error(e.message || '加载规划师列表失败')
|
|
|
+ } finally {
|
|
|
+ this.guidesLoading = false
|
|
|
+ }
|
|
|
+ },
|
|
|
+ async confirmChangeGuide() {
|
|
|
+ if (!this.selectedGuideId) {
|
|
|
+ this.$message.warning('请选择规划师')
|
|
|
+ return
|
|
|
+ }
|
|
|
+ if (this.currentOrder.guideId === this.selectedGuideId) {
|
|
|
+ this.$message.warning('新规划师与当前规划师相同')
|
|
|
+ return
|
|
|
+ }
|
|
|
+ this.changing = true
|
|
|
+ try {
|
|
|
+ await changeAssessmentGuide(this.currentOrder.id, this.selectedGuideId)
|
|
|
+ this.$message.success('规划师修改成功')
|
|
|
+ this.changeGuideDialogVisible = false
|
|
|
+ this.loadList()
|
|
|
+ } catch (e) {
|
|
|
+ this.$message.error(e.message || '修改规划师失败')
|
|
|
+ } finally {
|
|
|
+ this.changing = false
|
|
|
+ }
|
|
|
+ },
|
|
|
+ statusType(status) {
|
|
|
+ var map = { 0: 'warning', 1: 'primary', 2: 'success', 3: 'info', 4: 'danger' }
|
|
|
+ return map[status] !== undefined ? map[status] : 'info'
|
|
|
+ },
|
|
|
+ statusLabel(status) {
|
|
|
+ var map = { 0: '待确认', 1: '已确认', 2: '已完成', 3: '已取消', 4: '未到' }
|
|
|
+ return map[status] !== undefined ? map[status] : (status !== null && status !== undefined ? status : '-')
|
|
|
+ },
|
|
|
+ formatTime(t) {
|
|
|
+ if (!t) return '-'
|
|
|
+ return t.replace ? t.replace('T', ' ').substring(0, 19) : t
|
|
|
+ }
|
|
|
+ }
|
|
|
+}
|
|
|
+</script>
|
|
|
+
|
|
|
+<style scoped>
|
|
|
+.assessment-orders .admin-page-header {
|
|
|
+ display: flex;
|
|
|
+ justify-content: space-between;
|
|
|
+ align-items: center;
|
|
|
+ flex-wrap: wrap;
|
|
|
+ gap: 10px;
|
|
|
+}
|
|
|
+.filter-bar {
|
|
|
+ display: flex;
|
|
|
+ align-items: center;
|
|
|
+}
|
|
|
+.pagination-wrap {
|
|
|
+ margin-top: 20px;
|
|
|
+ text-align: right;
|
|
|
+}
|
|
|
+</style>
|