feat: 展播模式优化与排课表修复
- 展播模式:空状态/错误状态添加返回上课按钮 - 展播模式:退出时自动跳转回上课页面或关闭标签页 - 数据库:lesson表id添加AUTO_INCREMENT,修复预约上课报错 Made-with: Cursor
This commit is contained in:
parent
50efe68f62
commit
709e59e142
13
reading-platform-frontend/src/components.d.ts
vendored
13
reading-platform-frontend/src/components.d.ts
vendored
@ -11,11 +11,16 @@ declare module 'vue' {
|
|||||||
AAvatar: typeof import('ant-design-vue/es')['Avatar']
|
AAvatar: typeof import('ant-design-vue/es')['Avatar']
|
||||||
ABadge: typeof import('ant-design-vue/es')['Badge']
|
ABadge: typeof import('ant-design-vue/es')['Badge']
|
||||||
AButton: typeof import('ant-design-vue/es')['Button']
|
AButton: typeof import('ant-design-vue/es')['Button']
|
||||||
|
AButtonGroup: typeof import('ant-design-vue/es')['ButtonGroup']
|
||||||
ACard: typeof import('ant-design-vue/es')['Card']
|
ACard: typeof import('ant-design-vue/es')['Card']
|
||||||
ACheckbox: typeof import('ant-design-vue/es')['Checkbox']
|
ACheckbox: typeof import('ant-design-vue/es')['Checkbox']
|
||||||
ACheckboxGroup: typeof import('ant-design-vue/es')['CheckboxGroup']
|
ACheckboxGroup: typeof import('ant-design-vue/es')['CheckboxGroup']
|
||||||
ACol: typeof import('ant-design-vue/es')['Col']
|
ACol: typeof import('ant-design-vue/es')['Col']
|
||||||
|
ADatePicker: typeof import('ant-design-vue/es')['DatePicker']
|
||||||
|
ADescriptions: typeof import('ant-design-vue/es')['Descriptions']
|
||||||
|
ADescriptionsItem: typeof import('ant-design-vue/es')['DescriptionsItem']
|
||||||
ADivider: typeof import('ant-design-vue/es')['Divider']
|
ADivider: typeof import('ant-design-vue/es')['Divider']
|
||||||
|
ADrawer: typeof import('ant-design-vue/es')['Drawer']
|
||||||
ADropdown: typeof import('ant-design-vue/es')['Dropdown']
|
ADropdown: typeof import('ant-design-vue/es')['Dropdown']
|
||||||
AEmpty: typeof import('ant-design-vue/es')['Empty']
|
AEmpty: typeof import('ant-design-vue/es')['Empty']
|
||||||
AForm: typeof import('ant-design-vue/es')['Form']
|
AForm: typeof import('ant-design-vue/es')['Form']
|
||||||
@ -34,25 +39,33 @@ declare module 'vue' {
|
|||||||
AMenuItem: typeof import('ant-design-vue/es')['MenuItem']
|
AMenuItem: typeof import('ant-design-vue/es')['MenuItem']
|
||||||
AModal: typeof import('ant-design-vue/es')['Modal']
|
AModal: typeof import('ant-design-vue/es')['Modal']
|
||||||
APageHeader: typeof import('ant-design-vue/es')['PageHeader']
|
APageHeader: typeof import('ant-design-vue/es')['PageHeader']
|
||||||
|
APagination: typeof import('ant-design-vue/es')['Pagination']
|
||||||
APopconfirm: typeof import('ant-design-vue/es')['Popconfirm']
|
APopconfirm: typeof import('ant-design-vue/es')['Popconfirm']
|
||||||
AProgress: typeof import('ant-design-vue/es')['Progress']
|
AProgress: typeof import('ant-design-vue/es')['Progress']
|
||||||
ARadio: typeof import('ant-design-vue/es')['Radio']
|
ARadio: typeof import('ant-design-vue/es')['Radio']
|
||||||
ARadioGroup: typeof import('ant-design-vue/es')['RadioGroup']
|
ARadioGroup: typeof import('ant-design-vue/es')['RadioGroup']
|
||||||
|
ARangePicker: typeof import('ant-design-vue/es')['RangePicker']
|
||||||
|
ARate: typeof import('ant-design-vue/es')['Rate']
|
||||||
ARow: typeof import('ant-design-vue/es')['Row']
|
ARow: typeof import('ant-design-vue/es')['Row']
|
||||||
ASelect: typeof import('ant-design-vue/es')['Select']
|
ASelect: typeof import('ant-design-vue/es')['Select']
|
||||||
ASelectOptGroup: typeof import('ant-design-vue/es')['SelectOptGroup']
|
ASelectOptGroup: typeof import('ant-design-vue/es')['SelectOptGroup']
|
||||||
ASelectOption: typeof import('ant-design-vue/es')['SelectOption']
|
ASelectOption: typeof import('ant-design-vue/es')['SelectOption']
|
||||||
|
ASkeleton: typeof import('ant-design-vue/es')['Skeleton']
|
||||||
ASpace: typeof import('ant-design-vue/es')['Space']
|
ASpace: typeof import('ant-design-vue/es')['Space']
|
||||||
ASpin: typeof import('ant-design-vue/es')['Spin']
|
ASpin: typeof import('ant-design-vue/es')['Spin']
|
||||||
|
AStatistic: typeof import('ant-design-vue/es')['Statistic']
|
||||||
AStep: typeof import('ant-design-vue/es')['Step']
|
AStep: typeof import('ant-design-vue/es')['Step']
|
||||||
ASteps: typeof import('ant-design-vue/es')['Steps']
|
ASteps: typeof import('ant-design-vue/es')['Steps']
|
||||||
|
ASubMenu: typeof import('ant-design-vue/es')['SubMenu']
|
||||||
ASwitch: typeof import('ant-design-vue/es')['Switch']
|
ASwitch: typeof import('ant-design-vue/es')['Switch']
|
||||||
ATable: typeof import('ant-design-vue/es')['Table']
|
ATable: typeof import('ant-design-vue/es')['Table']
|
||||||
ATabPane: typeof import('ant-design-vue/es')['TabPane']
|
ATabPane: typeof import('ant-design-vue/es')['TabPane']
|
||||||
ATabs: typeof import('ant-design-vue/es')['Tabs']
|
ATabs: typeof import('ant-design-vue/es')['Tabs']
|
||||||
ATag: typeof import('ant-design-vue/es')['Tag']
|
ATag: typeof import('ant-design-vue/es')['Tag']
|
||||||
ATextarea: typeof import('ant-design-vue/es')['Textarea']
|
ATextarea: typeof import('ant-design-vue/es')['Textarea']
|
||||||
|
ATimeRangePicker: typeof import('ant-design-vue/es')['TimeRangePicker']
|
||||||
ATooltip: typeof import('ant-design-vue/es')['Tooltip']
|
ATooltip: typeof import('ant-design-vue/es')['Tooltip']
|
||||||
|
ATypographyText: typeof import('ant-design-vue/es')['TypographyText']
|
||||||
AUpload: typeof import('ant-design-vue/es')['Upload']
|
AUpload: typeof import('ant-design-vue/es')['Upload']
|
||||||
FilePreviewModal: typeof import('./components/FilePreviewModal.vue')['default']
|
FilePreviewModal: typeof import('./components/FilePreviewModal.vue')['default']
|
||||||
FileUploader: typeof import('./components/course/FileUploader.vue')['default']
|
FileUploader: typeof import('./components/course/FileUploader.vue')['default']
|
||||||
|
|||||||
@ -10,7 +10,10 @@
|
|||||||
<div v-else-if="error" class="error-container">
|
<div v-else-if="error" class="error-container">
|
||||||
<ExclamationCircleOutlined style="font-size: 48px; color: #ff4d4f;" />
|
<ExclamationCircleOutlined style="font-size: 48px; color: #ff4d4f;" />
|
||||||
<p>{{ error }}</p>
|
<p>{{ error }}</p>
|
||||||
<a-button type="primary" @click="loadData">重新加载</a-button>
|
<a-space>
|
||||||
|
<a-button type="primary" @click="loadData">重新加载</a-button>
|
||||||
|
<a-button @click="goBackToLesson">返回上课</a-button>
|
||||||
|
</a-space>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- 展播内容 -->
|
<!-- 展播内容 -->
|
||||||
@ -30,19 +33,22 @@
|
|||||||
<div v-else class="empty-container">
|
<div v-else class="empty-container">
|
||||||
<InboxOutlined style="font-size: 48px; color: #ccc;" />
|
<InboxOutlined style="font-size: 48px; color: #ccc;" />
|
||||||
<p>暂无展播内容</p>
|
<p>暂无展播内容</p>
|
||||||
|
<p class="empty-hint">请先在上课页面选择教学环节,或确认课程已配置教学流程</p>
|
||||||
|
<a-button type="primary" @click="goBackToLesson">返回上课</a-button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import { ref, computed, onMounted, onUnmounted } from 'vue';
|
import { ref, computed, onMounted, onUnmounted } from 'vue';
|
||||||
import { useRoute } from 'vue-router';
|
import { useRoute, useRouter } from 'vue-router';
|
||||||
import { ExclamationCircleOutlined, InboxOutlined } from '@ant-design/icons-vue';
|
import { ExclamationCircleOutlined, InboxOutlined } from '@ant-design/icons-vue';
|
||||||
import { message } from 'ant-design-vue';
|
import { message } from 'ant-design-vue';
|
||||||
import KidsMode from './components/KidsMode.vue';
|
import KidsMode from './components/KidsMode.vue';
|
||||||
import * as teacherApi from '@/api/teacher';
|
import * as teacherApi from '@/api/teacher';
|
||||||
|
|
||||||
const route = useRoute();
|
const route = useRoute();
|
||||||
|
const router = useRouter();
|
||||||
|
|
||||||
// 状态
|
// 状态
|
||||||
const loading = ref(true);
|
const loading = ref(true);
|
||||||
@ -273,9 +279,24 @@ const loadData = async () => {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
// 处理退出
|
// 返回上课页面
|
||||||
|
const goBackToLesson = () => {
|
||||||
|
if (lessonId) {
|
||||||
|
router.push(`/teacher/lessons/${lessonId}`);
|
||||||
|
} else {
|
||||||
|
router.push('/teacher/lessons');
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// 处理退出:跳转回上课页面
|
||||||
const handleExit = () => {
|
const handleExit = () => {
|
||||||
message.info('展播模式已关闭,您可以关闭此标签页');
|
// 优先尝试关闭标签页并聚焦 opener(从上课页新开时)
|
||||||
|
if (window.opener && !window.opener.closed) {
|
||||||
|
window.opener.focus();
|
||||||
|
window.close();
|
||||||
|
} else {
|
||||||
|
goBackToLesson();
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
// 处理环节切换
|
// 处理环节切换
|
||||||
@ -358,6 +379,12 @@ onUnmounted(() => {
|
|||||||
font-size: 18px;
|
font-size: 18px;
|
||||||
opacity: 0.8;
|
opacity: 0.8;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.empty-hint {
|
||||||
|
font-size: 14px !important;
|
||||||
|
opacity: 0.6;
|
||||||
|
margin: 0;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.error-container {
|
.error-container {
|
||||||
|
|||||||
@ -0,0 +1,9 @@
|
|||||||
|
-- =====================================================
|
||||||
|
-- 幼儿园阅读平台数据库迁移脚本
|
||||||
|
-- 版本:V12
|
||||||
|
-- 描述:为 lesson 表(排课表)添加 id 自增,修复预约上课报错
|
||||||
|
-- =====================================================
|
||||||
|
-- 说明:V11 迁移遗漏了 lesson 表,导致插入时 "Field 'id' doesn't have a default value"
|
||||||
|
|
||||||
|
ALTER TABLE `lesson`
|
||||||
|
MODIFY COLUMN `id` BIGINT NOT NULL AUTO_INCREMENT COMMENT '主键 ID';
|
||||||
Loading…
Reference in New Issue
Block a user