fix: 修改独立窗口样式
This commit is contained in:
@@ -11,6 +11,7 @@
|
||||
"dev": "vite --mode env.local",
|
||||
"dev-server": "vite --mode dev",
|
||||
"ts:check": "vue-tsc --noEmit",
|
||||
"build": "node --max_old_space_size=4096 ./node_modules/vite/bin/vite.js build",
|
||||
"build:local": "node --max_old_space_size=4096 ./node_modules/vite/bin/vite.js build",
|
||||
"build:dev": "node --max_old_space_size=4096 ./node_modules/vite/bin/vite.js build --mode dev",
|
||||
"build:test": "node --max_old_space_size=4096 ./node_modules/vite/bin/vite.js build --mode test",
|
||||
|
||||
@@ -2,12 +2,12 @@
|
||||
"$schema": "https://schema.tauri.app/config/2",
|
||||
"productName": "teacher-end",
|
||||
"version": "0.1.0",
|
||||
"identifier": "com.tauri.dev",
|
||||
"identifier": "com.pengcheng.teacherend",
|
||||
"build": {
|
||||
"frontendDist": "../dist",
|
||||
"devUrl": "http://localhost:5173",
|
||||
"beforeDevCommand": "pnpm dev",
|
||||
"beforeBuildCommand": "pnpm build"
|
||||
"beforeDevCommand": "yarn dev",
|
||||
"beforeBuildCommand": "yarn build"
|
||||
},
|
||||
"app": {
|
||||
"windows": [
|
||||
|
||||
@@ -14,8 +14,6 @@ export const getQuestionlistAnswer = (params: QuestionQueryVO) => {
|
||||
return request.get({ url: '/exam/question/listAnswer', params })
|
||||
}
|
||||
|
||||
|
||||
|
||||
export const getQuestionSendList = (params: QuestionQueryVO) => {
|
||||
return request.get({ url: '/exam/question/sendList', params })
|
||||
}
|
||||
@@ -24,21 +22,20 @@ export const getQuestionAuditList = (params: QuestionQueryVO) => {
|
||||
return request.get({ url: '/exam/question/auditList', params })
|
||||
}
|
||||
|
||||
|
||||
export async function auditQuestion(data) {
|
||||
return await request.post({ url: '/rabbitmq/sendAudio' ,data })
|
||||
return await request.post({ url: '/rabbitmq/sendAudio', data })
|
||||
}
|
||||
export async function auditQuestionTrue(data) {
|
||||
return await request.post({ url: '/exam/question/auditQuestion' ,data })
|
||||
return await request.post({ url: '/exam/question/auditQuestion', data })
|
||||
}
|
||||
export async function rabbitmqConnect() {
|
||||
return await request.post({ url: '/rabbitmq/connect' })
|
||||
}
|
||||
export async function changePaperQu(data) {
|
||||
return await request.post({ url: '/exam/qu/changePaperQu',data })
|
||||
return await request.post({ url: '/exam/qu/changePaperQu', data })
|
||||
}
|
||||
export async function changePaperQuRandom(data) {
|
||||
return await request.post({ url: '/exam/qu/changePaperQuRandom',data })
|
||||
return await request.post({ url: '/exam/qu/changePaperQuRandom', data })
|
||||
}
|
||||
|
||||
// 获取试题详情
|
||||
@@ -49,7 +46,6 @@ export const getQuestionnotId = (id: number) => {
|
||||
return request.get({ url: '/exam/question/notId/' + id })
|
||||
}
|
||||
|
||||
|
||||
// 获取题库列表
|
||||
export const getBankList = () => {
|
||||
return request.get({ url: '/exam/bank/list' })
|
||||
@@ -57,7 +53,7 @@ export const getBankList = () => {
|
||||
|
||||
// 删除试题
|
||||
export const removeQuestions = (ids) => {
|
||||
return request.delete({ url: '/exam/question/' + ids})
|
||||
return request.delete({ url: '/exam/question/' + ids })
|
||||
}
|
||||
export async function removeQuestion(id) {
|
||||
return await request.delete({ url: '/exam/question/' + id })
|
||||
@@ -65,41 +61,40 @@ export async function removeQuestion(id) {
|
||||
|
||||
// 新增试题
|
||||
export function addQuestion(data: any) {
|
||||
return request.post({url: '/exam/question', data});
|
||||
return request.post({ url: '/exam/question', data })
|
||||
}
|
||||
|
||||
// 修改试题
|
||||
export function editQuestion(data: any) {
|
||||
return request.put({url: '/exam/question', data});
|
||||
return request.put({ url: '/exam/question', data })
|
||||
}
|
||||
|
||||
export function editQuestionNoAudit(data: any) {
|
||||
return request.put({url: '/exam/question/NoAudit', data});
|
||||
return request.put({ url: '/exam/question/NoAudit', data })
|
||||
}
|
||||
|
||||
|
||||
// 更改状态
|
||||
export async function updateQuStatus(quId: string, status: number) {
|
||||
return await request.put({
|
||||
return await request.put({
|
||||
url: '/exam/question/updateQuStatus',
|
||||
data: { quId, status } // 使用data
|
||||
})
|
||||
}
|
||||
|
||||
export const getQuestionExamineList = (params: QuestionQueryVO) => {
|
||||
return request.get({ url: '/exam/question/auditList', params })
|
||||
return request.get({ url: '/exam/question/auditList', params })
|
||||
}
|
||||
|
||||
export const getSchoolName = (params) => {
|
||||
return request.get({ url: '/exam/question/getSchoolName',params })
|
||||
return request.get({ url: '/exam/question/getSchoolName', params })
|
||||
}
|
||||
|
||||
export const getSchoolNameNopage = () => {
|
||||
return request.get({ url: '/exam/question/getSchoolNameNopage' })
|
||||
return request.get({ url: '/exam/question/getSchoolNameNopage' })
|
||||
}
|
||||
|
||||
export const receiveAll = () => {
|
||||
return request.get({ url: '/rabbitmq/receiveAll' })
|
||||
return request.get({ url: '/rabbitmq/receiveAll' })
|
||||
}
|
||||
export const syncUniversities = (ids: string[]) => {
|
||||
return request.post({
|
||||
@@ -112,10 +107,9 @@ export const doPush = (data) => {
|
||||
return request.post({
|
||||
url: '/rabbitmq/doPush',
|
||||
data: data
|
||||
});
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
export const connectSchoolAll = (ids: string[]) => {
|
||||
return request.post({
|
||||
url: '/rabbitmq/connectSchoolAll',
|
||||
@@ -123,7 +117,6 @@ export const connectSchoolAll = (ids: string[]) => {
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
export const auditQue = (ids: string[]) => {
|
||||
return request.post({
|
||||
url: '/exam/question/auditQue',
|
||||
@@ -147,36 +140,33 @@ export const getListByQuId = (id) => {
|
||||
}
|
||||
|
||||
export const getMysqlPoint = (data) => {
|
||||
return request.post({ url: `/exam/getPoints/get_mysql_point`,data })
|
||||
return request.post({ url: `/exam/getPoints/get_mysql_point`, data })
|
||||
}
|
||||
//设置mysql考点
|
||||
export const saveSelectedKaodian = (data) => {
|
||||
return request.post({ url: `/exam/getPoints/update_mysql_point`,data })
|
||||
return request.post({ url: `/exam/getPoints/update_mysql_point`, data })
|
||||
}
|
||||
//设置浏览器考点
|
||||
export const setBrowserPoint = (data) => {
|
||||
return request.post({ url: `/exam/getPoints/set_browser_point`,data })
|
||||
export const setBrowserPoint = (data) => {
|
||||
return request.post({ url: `/exam/getPoints/set_browser_point`, data })
|
||||
}
|
||||
|
||||
export const getFilePoint = (data) => {
|
||||
return request.post({ url: `/exam/getPoints/get_filePoint`,data })
|
||||
return request.post({ url: `/exam/getPoints/get_filePoint`, data })
|
||||
}
|
||||
|
||||
export const getPsPoint = (data) => {
|
||||
return request.post({ url: `/exam/getPoints/get_ps_point`,data })
|
||||
return request.post({ url: `/exam/getPoints/get_ps_point`, data })
|
||||
}
|
||||
|
||||
export const setPsPoint = (data) => {
|
||||
return request.post({ url: `/exam/getPoints/set_ps_point`,data })
|
||||
return request.post({ url: `/exam/getPoints/set_ps_point`, data })
|
||||
}
|
||||
|
||||
|
||||
export const getPsPointByQuId = (id) => {
|
||||
return request.get({ url: `/exam/getPoints/getPsPointById/${id}` })
|
||||
}
|
||||
|
||||
export const previewQuestion = (data) => {
|
||||
return request.upload(
|
||||
{ url: `/exam/question/previewQuestion`, data }
|
||||
)
|
||||
return request.upload({ url: `/exam/question/previewQuestion`, data })
|
||||
}
|
||||
|
||||
@@ -44,7 +44,7 @@ const loginOut = async () => {
|
||||
})
|
||||
await userStore.loginOut()
|
||||
tagsViewStore.delAllViews()
|
||||
replace('/login?redirect=/index')
|
||||
replace('/login') // 退出后直接跳转到登录页,不带重定向参数
|
||||
} catch {}
|
||||
}
|
||||
const toProfile = async () => {
|
||||
|
||||
@@ -66,7 +66,7 @@ router.beforeEach(async (to, from, next) => {
|
||||
loadStart()
|
||||
if (getAccessToken()) {
|
||||
if (to.path === '/login') {
|
||||
next({ path: '/' })
|
||||
next({ path: '/dashboard' }) // 已登录时访问登录页,重定向到首页
|
||||
} else {
|
||||
// 获取所有字典
|
||||
const dictStore = useDictStoreWithOut()
|
||||
@@ -105,10 +105,22 @@ router.beforeEach(async (to, from, next) => {
|
||||
// 修复跳转时不带参数的问题
|
||||
const redirect = decodeURIComponent(redirectPath as string)
|
||||
const { paramsObject: query } = parseURL(redirect)
|
||||
const nextData = to.path === redirect ? { ...to, replace: true } : { path: redirect, query }
|
||||
|
||||
// 如果重定向路径是根路径或不存在的路径,改为首页
|
||||
const finalRedirect = (redirect === '/' || redirect === '/index') ? '/dashboard' : redirect
|
||||
console.log('Permission guard - first time setting user, redirecting to:', finalRedirect) // 调试日志
|
||||
const nextData = to.path === finalRedirect ? { ...to, replace: true } : { path: finalRedirect, query }
|
||||
next(nextData)
|
||||
} else {
|
||||
next()
|
||||
// 即使用户信息已设置,也要检查是否需要重定向到首页
|
||||
if (to.path === '/' || (to.path === '/login' && from.query.redirect)) {
|
||||
// 从登录页跳转过来,或者访问根路径,重定向到首页
|
||||
console.log('Permission guard - redirecting to dashboard from:', to.path) // 调试日志
|
||||
next({ path: '/dashboard', replace: true })
|
||||
} else {
|
||||
console.log('Permission guard - allowing navigation to:', to.path) // 调试日志
|
||||
next()
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
|
||||
@@ -36,13 +36,18 @@ const remainingRouter: AppRouteRecordRaw[] = [
|
||||
{
|
||||
path: '/redirect',
|
||||
component: Layout,
|
||||
name: 'Redirect',
|
||||
name: 'Home',
|
||||
children: [
|
||||
{
|
||||
path: '/redirect/:path(.*)',
|
||||
name: 'Redirect',
|
||||
component: () => import('@/views/Redirect/Redirect.vue'),
|
||||
meta: {}
|
||||
path: 'dashboard',
|
||||
component: () => import('@/views/dashboard/index.vue'),
|
||||
name: 'Dashboard',
|
||||
meta: {
|
||||
title: t('router.home'),
|
||||
icon: 'ep:home-filled',
|
||||
noCache: false,
|
||||
affix: true
|
||||
}
|
||||
}
|
||||
],
|
||||
meta: {
|
||||
@@ -767,6 +772,107 @@ const remainingRouter: AppRouteRecordRaw[] = [
|
||||
hidden: true,
|
||||
noTagsView: true
|
||||
}
|
||||
},
|
||||
{
|
||||
path: '/wps-word-independent',
|
||||
name: 'WpsWordIndependent',
|
||||
component: () => import('@/views/wps/word-independent.vue'),
|
||||
meta: {
|
||||
title: 'Word题独立窗口',
|
||||
hidden: true,
|
||||
noTagsView: true
|
||||
}
|
||||
},
|
||||
{
|
||||
path: '/wps-pptx-independent',
|
||||
name: 'WpsPptxIndependent',
|
||||
component: () => import('@/views/wps/pptx-independent.vue'),
|
||||
meta: {
|
||||
title: 'PPT题独立窗口',
|
||||
hidden: true,
|
||||
noTagsView: true
|
||||
}
|
||||
},
|
||||
{
|
||||
path: '/wps-xlsx-independent',
|
||||
name: 'WpsXlsxIndependent',
|
||||
component: () => import('@/views/wps/xlsx-independent.vue'),
|
||||
meta: {
|
||||
title: 'Excel题独立窗口',
|
||||
hidden: true,
|
||||
noTagsView: true
|
||||
}
|
||||
},
|
||||
// 新增的问题类型独立窗口路由
|
||||
{
|
||||
path: '/choice-independent',
|
||||
name: 'ChoiceIndependent',
|
||||
component: () => import('@/views/paper/question/independent/choice.vue'),
|
||||
meta: {
|
||||
title: '选择题独立窗口',
|
||||
hidden: true,
|
||||
noTagsView: true
|
||||
}
|
||||
},
|
||||
{
|
||||
path: '/mysql-independent',
|
||||
name: 'MysqlIndependent',
|
||||
component: () => import('@/views/paper/question/independent/mysql.vue'),
|
||||
meta: {
|
||||
title: '程序设计题独立窗口',
|
||||
hidden: true,
|
||||
noTagsView: true
|
||||
}
|
||||
},
|
||||
{
|
||||
path: '/brower-independent',
|
||||
name: 'BrowerIndependent',
|
||||
component: () => import('@/views/paper/question/independent/brower.vue'),
|
||||
meta: {
|
||||
title: '网络题独立窗口',
|
||||
hidden: true,
|
||||
noTagsView: true
|
||||
}
|
||||
},
|
||||
{
|
||||
path: '/file-independent',
|
||||
name: 'FileIndependent',
|
||||
component: () => import('@/views/paper/question/independent/file.vue'),
|
||||
meta: {
|
||||
title: '文件处理题独立窗口',
|
||||
hidden: true,
|
||||
noTagsView: true
|
||||
}
|
||||
},
|
||||
{
|
||||
path: '/setting-independent',
|
||||
name: 'SettingIndependent',
|
||||
component: () => import('@/views/paper/question/independent/setting.vue'),
|
||||
meta: {
|
||||
title: 'Windows网络设置题独立窗口',
|
||||
hidden: true,
|
||||
noTagsView: true
|
||||
}
|
||||
},
|
||||
{
|
||||
path: '/email-independent',
|
||||
name: 'EmailIndependent',
|
||||
component: () => import('@/views/paper/question/independent/email.vue'),
|
||||
meta: {
|
||||
title: '邮箱题独立窗口',
|
||||
hidden: true,
|
||||
noTagsView: true
|
||||
}
|
||||
},
|
||||
{
|
||||
path: '/ps-independent',
|
||||
name: 'PsIndependent',
|
||||
component: () => import('@/views/paper/question/independent/ps.vue'),
|
||||
meta: {
|
||||
title: '图像处理题独立窗口',
|
||||
hidden: true,
|
||||
noTagsView: true
|
||||
}
|
||||
}
|
||||
]
|
||||
|
||||
|
||||
@@ -89,64 +89,64 @@
|
||||
mode="pop"
|
||||
@success="handleLogin"
|
||||
/>
|
||||
<!-- <el-col :span="24" style="padding-right: 10px; padding-left: 10px">-->
|
||||
<!-- <el-form-item>-->
|
||||
<!-- <el-row :gutter="5" justify="space-between" style="width: 100%">-->
|
||||
<!-- <el-col :span="8">-->
|
||||
<!-- <XButton-->
|
||||
<!-- :title="t('login.btnMobile')"-->
|
||||
<!-- class="w-[100%]"-->
|
||||
<!-- @click="setLoginState(LoginStateEnum.MOBILE)"-->
|
||||
<!-- />-->
|
||||
<!-- </el-col>-->
|
||||
<!-- <el-col :span="8">-->
|
||||
<!-- <XButton-->
|
||||
<!-- :title="t('login.btnQRCode')"-->
|
||||
<!-- class="w-[100%]"-->
|
||||
<!-- @click="setLoginState(LoginStateEnum.QR_CODE)"-->
|
||||
<!-- />-->
|
||||
<!-- </el-col>-->
|
||||
<!-- <el-col :span="8">-->
|
||||
<!-- <XButton-->
|
||||
<!-- :title="t('login.btnRegister')"-->
|
||||
<!-- class="w-[100%]"-->
|
||||
<!-- @click="setLoginState(LoginStateEnum.REGISTER)"-->
|
||||
<!-- />-->
|
||||
<!-- </el-col>-->
|
||||
<!-- </el-row>-->
|
||||
<!-- </el-form-item>-->
|
||||
<!-- </el-col>-->
|
||||
<!-- <el-divider content-position="center">{{ t('login.otherLogin') }}</el-divider>-->
|
||||
<!-- <el-col :span="24" style="padding-right: 10px; padding-left: 10px">-->
|
||||
<!-- <el-form-item>-->
|
||||
<!-- <div class="w-[100%] flex justify-between">-->
|
||||
<!-- <Icon-->
|
||||
<!-- v-for="(item, key) in socialList"-->
|
||||
<!-- :key="key"-->
|
||||
<!-- :icon="item.icon"-->
|
||||
<!-- :size="30"-->
|
||||
<!-- class="anticon cursor-pointer"-->
|
||||
<!-- color="#999"-->
|
||||
<!-- @click="doSocialLogin(item.type)"-->
|
||||
<!-- />-->
|
||||
<!-- </div>-->
|
||||
<!-- </el-form-item>-->
|
||||
<!-- </el-col>-->
|
||||
<!-- <el-divider content-position="center">萌新必读</el-divider>-->
|
||||
<!-- <el-col :span="24" style="padding-right: 10px; padding-left: 10px">-->
|
||||
<!-- <el-form-item>-->
|
||||
<!-- <div class="w-[100%] flex justify-between">-->
|
||||
<!-- <el-link href="https://doc.iocoder.cn/" target="_blank">📚开发指南</el-link>-->
|
||||
<!-- <el-link href="https://doc.iocoder.cn/video/" target="_blank">🔥视频教程</el-link>-->
|
||||
<!-- <el-link href="https://www.iocoder.cn/Interview/good-collection/" target="_blank">-->
|
||||
<!-- ⚡面试手册-->
|
||||
<!-- </el-link>-->
|
||||
<!-- <el-link href="http://static.yudao.iocoder.cn/mp/Aix9975.jpeg" target="_blank">-->
|
||||
<!-- 🤝外包咨询-->
|
||||
<!-- </el-link>-->
|
||||
<!-- </div>-->
|
||||
<!-- </el-form-item>-->
|
||||
<!-- </el-col>-->
|
||||
<!-- <el-col :span="24" style="padding-right: 10px; padding-left: 10px">-->
|
||||
<!-- <el-form-item>-->
|
||||
<!-- <el-row :gutter="5" justify="space-between" style="width: 100%">-->
|
||||
<!-- <el-col :span="8">-->
|
||||
<!-- <XButton-->
|
||||
<!-- :title="t('login.btnMobile')"-->
|
||||
<!-- class="w-[100%]"-->
|
||||
<!-- @click="setLoginState(LoginStateEnum.MOBILE)"-->
|
||||
<!-- />-->
|
||||
<!-- </el-col>-->
|
||||
<!-- <el-col :span="8">-->
|
||||
<!-- <XButton-->
|
||||
<!-- :title="t('login.btnQRCode')"-->
|
||||
<!-- class="w-[100%]"-->
|
||||
<!-- @click="setLoginState(LoginStateEnum.QR_CODE)"-->
|
||||
<!-- />-->
|
||||
<!-- </el-col>-->
|
||||
<!-- <el-col :span="8">-->
|
||||
<!-- <XButton-->
|
||||
<!-- :title="t('login.btnRegister')"-->
|
||||
<!-- class="w-[100%]"-->
|
||||
<!-- @click="setLoginState(LoginStateEnum.REGISTER)"-->
|
||||
<!-- />-->
|
||||
<!-- </el-col>-->
|
||||
<!-- </el-row>-->
|
||||
<!-- </el-form-item>-->
|
||||
<!-- </el-col>-->
|
||||
<!-- <el-divider content-position="center">{{ t('login.otherLogin') }}</el-divider>-->
|
||||
<!-- <el-col :span="24" style="padding-right: 10px; padding-left: 10px">-->
|
||||
<!-- <el-form-item>-->
|
||||
<!-- <div class="w-[100%] flex justify-between">-->
|
||||
<!-- <Icon-->
|
||||
<!-- v-for="(item, key) in socialList"-->
|
||||
<!-- :key="key"-->
|
||||
<!-- :icon="item.icon"-->
|
||||
<!-- :size="30"-->
|
||||
<!-- class="anticon cursor-pointer"-->
|
||||
<!-- color="#999"-->
|
||||
<!-- @click="doSocialLogin(item.type)"-->
|
||||
<!-- />-->
|
||||
<!-- </div>-->
|
||||
<!-- </el-form-item>-->
|
||||
<!-- </el-col>-->
|
||||
<!-- <el-divider content-position="center">萌新必读</el-divider>-->
|
||||
<!-- <el-col :span="24" style="padding-right: 10px; padding-left: 10px">-->
|
||||
<!-- <el-form-item>-->
|
||||
<!-- <div class="w-[100%] flex justify-between">-->
|
||||
<!-- <el-link href="https://doc.iocoder.cn/" target="_blank">📚开发指南</el-link>-->
|
||||
<!-- <el-link href="https://doc.iocoder.cn/video/" target="_blank">🔥视频教程</el-link>-->
|
||||
<!-- <el-link href="https://www.iocoder.cn/Interview/good-collection/" target="_blank">-->
|
||||
<!-- ⚡面试手册-->
|
||||
<!-- </el-link>-->
|
||||
<!-- <el-link href="http://static.yudao.iocoder.cn/mp/Aix9975.jpeg" target="_blank">-->
|
||||
<!-- 🤝外包咨询-->
|
||||
<!-- </el-link>-->
|
||||
<!-- </div>-->
|
||||
<!-- </el-form-item>-->
|
||||
<!-- </el-col>-->
|
||||
</el-row>
|
||||
</el-form>
|
||||
</template>
|
||||
@@ -275,14 +275,26 @@ const handleLogin = async (params: any) => {
|
||||
authUtil.removeLoginForm()
|
||||
}
|
||||
authUtil.setToken(res)
|
||||
if (!redirect.value) {
|
||||
redirect.value = '/'
|
||||
|
||||
// 登录成功后,确保跳转逻辑
|
||||
if (!redirect.value || redirect.value === '/') {
|
||||
redirect.value = '/dashboard' // 默认跳转到首页
|
||||
}
|
||||
|
||||
// 判断是否为SSO登录
|
||||
if (redirect.value.indexOf('sso') !== -1) {
|
||||
window.location.href = window.location.href.replace('/login?redirect=', '')
|
||||
} else {
|
||||
await push({ path: redirect.value || permissionStore.addRouters[0].path })
|
||||
// 强制跳转到首页,除非有特殊的重定向需求
|
||||
const targetPath =
|
||||
redirect.value === '/'
|
||||
? '/dashboard'
|
||||
: redirect.value === '/login'
|
||||
? '/dashboard'
|
||||
: redirect.value
|
||||
|
||||
console.log('Login redirect to:', targetPath) // 调试日志
|
||||
await push({ path: targetPath, replace: true })
|
||||
}
|
||||
} finally {
|
||||
loginLoading.value = false
|
||||
@@ -329,6 +341,7 @@ watch(
|
||||
() => currentRoute.value,
|
||||
(route: RouteLocationNormalizedLoaded) => {
|
||||
redirect.value = route?.query?.redirect as string
|
||||
console.log('LoginForm - route changed, redirect:', redirect.value) // 调试日志
|
||||
},
|
||||
{
|
||||
immediate: true
|
||||
|
||||
@@ -108,7 +108,7 @@
|
||||
<template #image>
|
||||
<Icon icon="ep:menu" :size="60" color="#dcdfe6" />
|
||||
</template>
|
||||
<el-button type="primary" @click="$router.push('/profile')">前往个人中心</el-button>
|
||||
<el-button type="primary" @click="$router.push('/user/profile')">前往个人中心</el-button>
|
||||
</el-empty>
|
||||
</div>
|
||||
</el-card>
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -62,10 +62,15 @@
|
||||
/>
|
||||
</el-form-item>
|
||||
<el-form-item label="课程">
|
||||
<el-input v-model="formData.courseName" placeholder="请输入课程" disabled />
|
||||
<el-input v-model="formData.courseName" placeholder="" disabled />
|
||||
</el-form-item>
|
||||
<el-form-item label="题型难度">
|
||||
<el-select v-model="formData.quLevel" placeholder="请选择题型难度" clearable>
|
||||
<el-select
|
||||
v-model="formData.quLevel"
|
||||
placeholder="请选择题型难度"
|
||||
clearable
|
||||
style="width: 200px"
|
||||
>
|
||||
<el-option
|
||||
v-for="dict in getIntDictOptions(DICT_TYPE.EXAM_QUE_DIFF)"
|
||||
:key="dict.value"
|
||||
@@ -110,7 +115,8 @@
|
||||
<CodeEditor
|
||||
ref="textareaRef"
|
||||
v-model="referenceAnswer"
|
||||
:rows="10"
|
||||
:rows="codeEditorRows"
|
||||
:style="{ height: codeEditorHeight + 'px' }"
|
||||
:key="`reference-editor-${formType}`"
|
||||
/>
|
||||
<div class="btn-line">
|
||||
@@ -410,7 +416,8 @@
|
||||
<div class="block">
|
||||
<CodeEditor
|
||||
v-model="formData.analysis"
|
||||
:rows="10"
|
||||
:rows="codeEditorRows"
|
||||
:style="{ height: codeEditorHeight + 'px' }"
|
||||
:key="`analysis-editor-${formType}`"
|
||||
/>
|
||||
</div>
|
||||
@@ -542,7 +549,7 @@
|
||||
<FileForm ref="FileRef" @success="handleUploadSuccess" />
|
||||
</template>
|
||||
<script lang="ts" setup>
|
||||
import { ref, reactive, onMounted, watch } from 'vue'
|
||||
import { ref, reactive, onMounted, watch, computed } from 'vue'
|
||||
import * as QuestionApi from '@/api/paper/question'
|
||||
import { DICT_TYPE, getIntDictOptions } from '@/utils/dict'
|
||||
import CodeEditor from './components/CodeEditor.vue'
|
||||
@@ -569,6 +576,38 @@ const props = withDefaults(defineProps<Props>(), {
|
||||
const { t } = useI18n() // 国际化
|
||||
const message = useMessage() // 消息弹窗
|
||||
|
||||
// 响应式高度计算
|
||||
const containerHeight = ref(0)
|
||||
const codeEditorHeight = computed(() => {
|
||||
// 计算可视区域高度
|
||||
const viewportHeight = window.innerHeight
|
||||
// 计算每个代码编辑器的高度(五五开,减去一些边距和其他元素高度)
|
||||
const availableHeight = Math.max(200, Math.min(viewportHeight - 300, 500)) // 最小200px,最大500px
|
||||
const singleEditorHeight = Math.floor(availableHeight / 2) - 10 // 减去间距,五五开
|
||||
return Math.max(100, singleEditorHeight) // 最小100px
|
||||
})
|
||||
|
||||
// 计算代码编辑器的行数(基于高度)
|
||||
const codeEditorRows = computed(() => {
|
||||
// 假设每行大约20px高度
|
||||
return Math.max(5, Math.floor(codeEditorHeight.value / 20))
|
||||
})
|
||||
|
||||
// 监听窗口大小变化
|
||||
onMounted(() => {
|
||||
const updateHeight = () => {
|
||||
containerHeight.value = window.innerHeight
|
||||
}
|
||||
|
||||
updateHeight()
|
||||
window.addEventListener('resize', updateHeight)
|
||||
|
||||
// 组件卸载时移除监听器
|
||||
return () => {
|
||||
window.removeEventListener('resize', updateHeight)
|
||||
}
|
||||
})
|
||||
|
||||
const dialogVisible = ref(false) // 弹窗的是否展示
|
||||
const dialogTitle = ref('') // 弹窗的标题
|
||||
const formLoading = ref(false) // 表单的加载中
|
||||
@@ -580,7 +619,7 @@ const content = ref('')
|
||||
const inputText = ref('')
|
||||
|
||||
const handleClick = (tab: any) => {
|
||||
activeName.value = tab.paneName
|
||||
activeName.value = tab.paneNam
|
||||
}
|
||||
|
||||
/** 取消操作 */
|
||||
@@ -780,7 +819,15 @@ const open = async (queryParams: any, type: string, id?: number) => {
|
||||
formLoading.value = true
|
||||
try {
|
||||
const res = await QuestionApi.getQuestion(id)
|
||||
res.keywords = Array.isArray(res.keywords) ? res.keywords : []
|
||||
// 处理keywords字段:如果是字符串,转换为对象数组
|
||||
if (typeof res.keywords === 'string' && res.keywords) {
|
||||
res.keywords = res.keywords
|
||||
.split(',')
|
||||
.filter((k) => k && k.trim() !== '')
|
||||
.map((k) => ({ keyword: k.trim() }))
|
||||
} else if (!Array.isArray(res.keywords)) {
|
||||
res.keywords = []
|
||||
}
|
||||
res.questionKeywords = Array.isArray(res.questionKeywords) ? res.questionKeywords : []
|
||||
res.answerList = Array.isArray(res.answerList) ? res.answerList : []
|
||||
res.fileUploads = Array.isArray(res.fileUploads)
|
||||
@@ -1104,8 +1151,15 @@ const submitForm = async () => {
|
||||
dataToSubmit.answer = dataToSubmit.answer || ''
|
||||
dataToSubmit.resourceValue = dataToSubmit.resourceValue || ''
|
||||
|
||||
// 确保数组字段
|
||||
dataToSubmit.keywords = Array.isArray(dataToSubmit.keywords) ? dataToSubmit.keywords : []
|
||||
// 处理keywords字段:将对象数组转换为逗号分隔的字符串
|
||||
if (Array.isArray(dataToSubmit.keywords)) {
|
||||
dataToSubmit.keywords = dataToSubmit.keywords
|
||||
.map((item) => (typeof item === 'object' && item.keyword ? item.keyword : String(item)))
|
||||
.filter(Boolean)
|
||||
.join(',')
|
||||
} else {
|
||||
dataToSubmit.keywords = dataToSubmit.keywords || ''
|
||||
}
|
||||
dataToSubmit.questionKeywords = Array.isArray(dataToSubmit.questionKeywords)
|
||||
? dataToSubmit.questionKeywords
|
||||
: []
|
||||
@@ -1471,14 +1525,13 @@ const lightenColor = (color: string, amount: number) => {
|
||||
flex: 1;
|
||||
overflow: hidden;
|
||||
background: var(--el-bg-color);
|
||||
margin: 16px;
|
||||
margin: 16px 16px 0 16px;
|
||||
border-radius: 8px;
|
||||
box-shadow: var(--el-box-shadow);
|
||||
|
||||
.program-edit {
|
||||
height: 100%;
|
||||
padding: 20px;
|
||||
|
||||
.main {
|
||||
height: 100%;
|
||||
position: relative;
|
||||
@@ -1594,40 +1647,58 @@ const lightenColor = (color: string, amount: number) => {
|
||||
}
|
||||
|
||||
.independent-footer {
|
||||
background: var(--el-bg-color);
|
||||
border-top: 1px solid var(--el-border-color);
|
||||
padding: 16px 24px;
|
||||
display: flex;
|
||||
justify-content: flex-end;
|
||||
gap: 12px;
|
||||
box-shadow: var(--el-box-shadow-light);
|
||||
background: #ffffff !important;
|
||||
border-top: 1px solid #e4e7ed !important;
|
||||
margin: 0 16px 16px 16px !important;
|
||||
padding: 16px 24px !important;
|
||||
display: flex !important;
|
||||
justify-content: flex-end !important;
|
||||
gap: 12px !important;
|
||||
box-shadow: 0 -2px 4px rgba(0, 0, 0, 0.1) !important;
|
||||
z-index: 1000 !important;
|
||||
border-radius: 0 0 8px 8px !important;
|
||||
|
||||
.el-button {
|
||||
border-radius: 6px;
|
||||
font-weight: 500;
|
||||
padding: 8px 16px;
|
||||
border-radius: 6px !important;
|
||||
font-weight: 500 !important;
|
||||
padding: 10px 20px !important;
|
||||
font-size: 14px !important;
|
||||
transition: all 0.3s !important;
|
||||
min-width: 80px !important;
|
||||
height: 36px !important;
|
||||
|
||||
&.el-button--primary {
|
||||
background: var(--el-color-primary);
|
||||
border-color: var(--el-color-primary);
|
||||
&:first-child {
|
||||
background: #409eff !important;
|
||||
border-color: #409eff !important;
|
||||
color: #ffffff !important;
|
||||
|
||||
&:hover {
|
||||
background: var(--el-color-primary-light-3);
|
||||
border-color: var(--el-color-primary-light-3);
|
||||
background: #66b1ff !important;
|
||||
border-color: #66b1ff !important;
|
||||
color: #ffffff !important;
|
||||
}
|
||||
|
||||
&:active {
|
||||
background: #3a8ee6 !important;
|
||||
border-color: #3a8ee6 !important;
|
||||
}
|
||||
}
|
||||
|
||||
&.el-button--default {
|
||||
background: #ffffff;
|
||||
border-color: var(--el-border-color);
|
||||
color: var(--el-text-color-primary);
|
||||
&:last-child {
|
||||
background: #ffffff !important;
|
||||
border: 1px solid #dcdfe6 !important;
|
||||
color: #606266 !important;
|
||||
|
||||
&:hover {
|
||||
background: var(--el-fill-color-lighter);
|
||||
border-color: var(--el-color-primary);
|
||||
color: var(--el-color-primary);
|
||||
background: #ecf5ff !important;
|
||||
border-color: #409eff !important;
|
||||
color: #409eff !important;
|
||||
}
|
||||
|
||||
&:active {
|
||||
background: #e6f7ff !important;
|
||||
border-color: #3a8ee6 !important;
|
||||
color: #3a8ee6 !important;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1833,6 +1904,15 @@ const lightenColor = (color: string, amount: number) => {
|
||||
}
|
||||
|
||||
:deep(.el-tabs) {
|
||||
.el-tabs__header {
|
||||
position: sticky;
|
||||
top: 0;
|
||||
z-index: 100;
|
||||
background: var(--el-bg-color);
|
||||
border-bottom: 1px solid var(--el-border-color-lighter);
|
||||
margin-bottom: 0;
|
||||
}
|
||||
|
||||
.el-tabs__item {
|
||||
padding: 0 20px;
|
||||
height: 40px;
|
||||
@@ -1849,6 +1929,10 @@ const lightenColor = (color: string, amount: number) => {
|
||||
height: 3px;
|
||||
border-radius: 2px;
|
||||
}
|
||||
|
||||
.el-tabs__content {
|
||||
padding-top: 20px;
|
||||
}
|
||||
}
|
||||
|
||||
:deep(.el-checkbox) {
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,29 +1,53 @@
|
||||
<template>
|
||||
<div class="head-container">
|
||||
<el-input v-model="deptName" class="mb-20px" clearable placeholder="请输入知识点">
|
||||
<template #prefix>
|
||||
<Icon icon="ep:search" />
|
||||
</template>
|
||||
</el-input>
|
||||
</div>
|
||||
<div class="head-container " >
|
||||
<el-tree
|
||||
ref="treeRef"
|
||||
:data="deptList"
|
||||
:expand-on-click-node="false"
|
||||
:filter-node-method="filterNode"
|
||||
:props="defaultProps"
|
||||
default-expand-all
|
||||
highlight-current
|
||||
node-key="id"
|
||||
@node-click="handleNodeClick"
|
||||
/>
|
||||
<div style="height: 100%; display: flex; flex-direction: column">
|
||||
<!-- 搜索框固定在顶部 -->
|
||||
<div style="flex-shrink: 0; margin-bottom: 16px">
|
||||
<el-input
|
||||
v-model="deptName"
|
||||
clearable
|
||||
placeholder="搜索知识点..."
|
||||
style="
|
||||
--el-input-border-radius: 20px;
|
||||
--el-input-bg-color: #f8f9fa;
|
||||
--el-input-border-color: transparent;
|
||||
"
|
||||
size="default"
|
||||
>
|
||||
<template #prefix>
|
||||
<el-icon style="color: #67c23a">
|
||||
<Search />
|
||||
</el-icon>
|
||||
</template>
|
||||
</el-input>
|
||||
</div>
|
||||
<!-- 树形内容区域可滚动 -->
|
||||
<div
|
||||
style="flex: 1; overflow: auto; margin: -2px; padding: 2px 8px 8px 2px; border-radius: 6px"
|
||||
>
|
||||
<el-tree
|
||||
ref="treeRef"
|
||||
:data="deptList"
|
||||
:expand-on-click-node="false"
|
||||
:filter-node-method="filterNode"
|
||||
:props="defaultProps"
|
||||
default-expand-all
|
||||
highlight-current
|
||||
node-key="id"
|
||||
@node-click="handleNodeClick"
|
||||
style="
|
||||
--el-tree-node-hover-bg-color: #f0f9ff;
|
||||
--el-tree-node-content-height: auto;
|
||||
padding-bottom: 8px;
|
||||
"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import { ref, watch } from 'vue'
|
||||
import { ElTree } from 'element-plus'
|
||||
import * as DeptApi from '@/api/system/dept'
|
||||
import { Search } from '@element-plus/icons-vue'
|
||||
import { defaultProps, handleTree } from '@/utils/tree'
|
||||
import * as SpecialtyApi from '@/api/points'
|
||||
|
||||
@@ -62,3 +86,66 @@ onMounted(async () => {
|
||||
await getTree()
|
||||
})
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
/* 树节点内容样式 - 彻底解决长文本显示问题 */
|
||||
:deep(.el-tree-node__content) {
|
||||
height: auto !important;
|
||||
min-height: 32px !important;
|
||||
padding: 6px 20px 6px 0 !important;
|
||||
white-space: normal !important;
|
||||
word-wrap: break-word !important;
|
||||
word-break: break-all !important;
|
||||
line-height: 1.4 !important;
|
||||
display: flex !important;
|
||||
align-items: flex-start !important;
|
||||
}
|
||||
|
||||
/* 树节点标签样式 */
|
||||
:deep(.el-tree-node__label) {
|
||||
white-space: normal !important;
|
||||
word-wrap: break-word !important;
|
||||
word-break: break-all !important;
|
||||
line-height: 1.4 !important;
|
||||
flex: 1 !important;
|
||||
padding-top: 2px;
|
||||
}
|
||||
|
||||
/* 展开/收起图标对齐 */
|
||||
:deep(.el-tree-node__expand-icon) {
|
||||
margin-top: 6px !important;
|
||||
flex-shrink: 0 !important;
|
||||
}
|
||||
|
||||
/* 为不同层级的节点设置不同的样式 */
|
||||
:deep(.el-tree-node[data-level='1'] .el-tree-node__content) {
|
||||
font-weight: 600;
|
||||
color: #303133;
|
||||
}
|
||||
|
||||
:deep(.el-tree-node[data-level='2'] .el-tree-node__content) {
|
||||
font-weight: 500;
|
||||
color: #606266;
|
||||
}
|
||||
|
||||
:deep(.el-tree-node[data-level='3'] .el-tree-node__content) {
|
||||
font-weight: 400;
|
||||
color: #909399;
|
||||
}
|
||||
|
||||
/* 悬停效果 */
|
||||
:deep(.el-tree-node__content:hover) {
|
||||
background-color: #f0f9ff !important;
|
||||
}
|
||||
|
||||
/* 选中状态 */
|
||||
:deep(.el-tree-node.is-current > .el-tree-node__content) {
|
||||
background-color: #e1f5fe !important;
|
||||
color: #409eff !important;
|
||||
}
|
||||
|
||||
/* 滚动条样式 */
|
||||
:deep(.el-tree) {
|
||||
padding-bottom: 12px;
|
||||
}
|
||||
</style>
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -1,28 +1,53 @@
|
||||
<template>
|
||||
<div class="head-container">
|
||||
<el-input v-model="deptName" class="mb-20px" clearable placeholder="请输入专业名称">
|
||||
<template #prefix>
|
||||
<Icon icon="ep:search" />
|
||||
</template>
|
||||
</el-input>
|
||||
</div>
|
||||
<div class="head-container ">
|
||||
<el-tree
|
||||
ref="treeRef"
|
||||
:data="specialtyList"
|
||||
:expand-on-click-node="false"
|
||||
:filter-node-method="filterNode"
|
||||
:props="defaultProps"
|
||||
default-expand-all
|
||||
highlight-current
|
||||
node-key="id"
|
||||
@node-click="handleNodeClick"
|
||||
/>
|
||||
<div style="height: 100%; display: flex; flex-direction: column">
|
||||
<!-- 搜索框固定在顶部 -->
|
||||
<div style="flex-shrink: 0; margin-bottom: 16px">
|
||||
<el-input
|
||||
v-model="deptName"
|
||||
clearable
|
||||
placeholder="搜索专业名称..."
|
||||
style="
|
||||
--el-input-border-radius: 20px;
|
||||
--el-input-bg-color: #f8f9fa;
|
||||
--el-input-border-color: transparent;
|
||||
"
|
||||
size="default"
|
||||
>
|
||||
<template #prefix>
|
||||
<el-icon style="color: #409eff">
|
||||
<Search />
|
||||
</el-icon>
|
||||
</template>
|
||||
</el-input>
|
||||
</div>
|
||||
<!-- 树形内容区域可滚动 -->
|
||||
<div
|
||||
style="flex: 1; overflow: auto; margin: -2px; padding: 2px 8px 8px 2px; border-radius: 6px"
|
||||
>
|
||||
<el-tree
|
||||
ref="treeRef"
|
||||
:data="specialtyList"
|
||||
:expand-on-click-node="false"
|
||||
:filter-node-method="filterNode"
|
||||
:props="defaultProps"
|
||||
default-expand-all
|
||||
highlight-current
|
||||
node-key="id"
|
||||
@node-click="handleNodeClick"
|
||||
style="
|
||||
--el-tree-node-hover-bg-color: #f0f9ff;
|
||||
--el-tree-node-content-height: auto;
|
||||
padding-bottom: 8px;
|
||||
"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import { ref, watch } from 'vue'
|
||||
import { ElTree } from 'element-plus'
|
||||
import { Search } from '@element-plus/icons-vue'
|
||||
import * as UserApi from '@/api/system/user'
|
||||
import { defaultProps, handleTree } from '@/utils/tree'
|
||||
|
||||
@@ -60,3 +85,66 @@ onMounted(async () => {
|
||||
await getTree()
|
||||
})
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
/* 树节点内容样式 - 彻底解决长文本显示问题 */
|
||||
:deep(.el-tree-node__content) {
|
||||
height: auto !important;
|
||||
min-height: 32px !important;
|
||||
padding: 6px 20px 6px 0 !important;
|
||||
white-space: normal !important;
|
||||
word-wrap: break-word !important;
|
||||
word-break: break-all !important;
|
||||
line-height: 1.4 !important;
|
||||
display: flex !important;
|
||||
align-items: flex-start !important;
|
||||
}
|
||||
|
||||
/* 树节点标签样式 */
|
||||
:deep(.el-tree-node__label) {
|
||||
white-space: normal !important;
|
||||
word-wrap: break-word !important;
|
||||
word-break: break-all !important;
|
||||
line-height: 1.4 !important;
|
||||
flex: 1 !important;
|
||||
padding-top: 2px;
|
||||
}
|
||||
|
||||
/* 展开/收起图标对齐 */
|
||||
:deep(.el-tree-node__expand-icon) {
|
||||
margin-top: 6px !important;
|
||||
flex-shrink: 0 !important;
|
||||
}
|
||||
|
||||
/* 为不同层级的节点设置不同的样式 */
|
||||
:deep(.el-tree-node[data-level='1'] .el-tree-node__content) {
|
||||
font-weight: 600;
|
||||
color: #303133;
|
||||
}
|
||||
|
||||
:deep(.el-tree-node[data-level='2'] .el-tree-node__content) {
|
||||
font-weight: 500;
|
||||
color: #606266;
|
||||
}
|
||||
|
||||
:deep(.el-tree-node[data-level='3'] .el-tree-node__content) {
|
||||
font-weight: 400;
|
||||
color: #909399;
|
||||
}
|
||||
|
||||
/* 悬停效果 */
|
||||
:deep(.el-tree-node__content:hover) {
|
||||
background-color: #f0f9ff !important;
|
||||
}
|
||||
|
||||
/* 选中状态 */
|
||||
:deep(.el-tree-node.is-current > .el-tree-node__content) {
|
||||
background-color: #e1f5fe !important;
|
||||
color: #409eff !important;
|
||||
}
|
||||
|
||||
/* 滚动条样式 */
|
||||
:deep(.el-tree) {
|
||||
padding-bottom: 12px;
|
||||
}
|
||||
</style>
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
49
src/views/paper/question/independent/brower.vue
Normal file
49
src/views/paper/question/independent/brower.vue
Normal file
@@ -0,0 +1,49 @@
|
||||
<template>
|
||||
<div class="independent-window">
|
||||
<BrowerForm ref="formRef" :isIndependent="true" />
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import { ref, onMounted } from 'vue'
|
||||
import { listen } from '@tauri-apps/api/event'
|
||||
import { getCurrentWindow } from '@tauri-apps/api/window'
|
||||
import BrowerForm from '@/views/paper/question/BrowerForm.vue'
|
||||
|
||||
defineOptions({ name: 'BrowerIndependent' })
|
||||
|
||||
const formRef = ref()
|
||||
|
||||
onMounted(async () => {
|
||||
console.log('BrowerIndependent mounted, sending ready signal...')
|
||||
|
||||
// 发送窗口准备就绪信号
|
||||
try {
|
||||
const { emit } = await import('@tauri-apps/api/event')
|
||||
await emit('brower-window-ready', { timestamp: Date.now() })
|
||||
console.log('Sent brower-window-ready event')
|
||||
} catch (error) {
|
||||
console.error('Failed to send ready signal:', error)
|
||||
}
|
||||
|
||||
// 监听表单提交成功事件,关闭窗口
|
||||
await listen('brower-form-success', async () => {
|
||||
const appWindow = getCurrentWindow()
|
||||
await appWindow.close()
|
||||
})
|
||||
|
||||
// 监听表单取消事件,关闭窗口
|
||||
await listen('brower-form-cancel', async () => {
|
||||
const appWindow = getCurrentWindow()
|
||||
await appWindow.close()
|
||||
})
|
||||
})
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.independent-window {
|
||||
width: 100vw;
|
||||
height: 100vh;
|
||||
overflow: hidden;
|
||||
}
|
||||
</style>
|
||||
49
src/views/paper/question/independent/choice.vue
Normal file
49
src/views/paper/question/independent/choice.vue
Normal file
@@ -0,0 +1,49 @@
|
||||
<template>
|
||||
<div class="independent-window">
|
||||
<ChoiceForm ref="formRef" :isIndependent="true" />
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import { ref, onMounted } from 'vue'
|
||||
import { listen } from '@tauri-apps/api/event'
|
||||
import { getCurrentWindow } from '@tauri-apps/api/window'
|
||||
import ChoiceForm from '@/views/paper/question/ChoiceForm.vue'
|
||||
|
||||
defineOptions({ name: 'ChoiceIndependent' })
|
||||
|
||||
const formRef = ref()
|
||||
|
||||
onMounted(async () => {
|
||||
console.log('ChoiceIndependent mounted, sending ready signal...')
|
||||
|
||||
// 发送窗口准备就绪信号
|
||||
try {
|
||||
const { emit } = await import('@tauri-apps/api/event')
|
||||
await emit('choice-window-ready', { timestamp: Date.now() })
|
||||
console.log('Sent choice-window-ready event')
|
||||
} catch (error) {
|
||||
console.error('Failed to send ready signal:', error)
|
||||
}
|
||||
|
||||
// 监听表单提交成功事件,关闭窗口
|
||||
await listen('choice-form-success', async () => {
|
||||
const appWindow = getCurrentWindow()
|
||||
await appWindow.close()
|
||||
})
|
||||
|
||||
// 监听表单取消事件,关闭窗口
|
||||
await listen('choice-form-cancel', async () => {
|
||||
const appWindow = getCurrentWindow()
|
||||
await appWindow.close()
|
||||
})
|
||||
})
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.independent-window {
|
||||
width: 100vw;
|
||||
height: 100vh;
|
||||
overflow: hidden;
|
||||
}
|
||||
</style>
|
||||
49
src/views/paper/question/independent/email.vue
Normal file
49
src/views/paper/question/independent/email.vue
Normal file
@@ -0,0 +1,49 @@
|
||||
<template>
|
||||
<div class="independent-window">
|
||||
<EmailForm ref="formRef" :isIndependent="true" />
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import { ref, onMounted } from 'vue'
|
||||
import { listen } from '@tauri-apps/api/event'
|
||||
import { getCurrentWindow } from '@tauri-apps/api/window'
|
||||
import EmailForm from '@/views/paper/question/EmailForm.vue'
|
||||
|
||||
defineOptions({ name: 'EmailIndependent' })
|
||||
|
||||
const formRef = ref()
|
||||
|
||||
onMounted(async () => {
|
||||
console.log('EmailIndependent mounted, sending ready signal...')
|
||||
|
||||
// 发送窗口准备就绪信号
|
||||
try {
|
||||
const { emit } = await import('@tauri-apps/api/event')
|
||||
await emit('email-window-ready', { timestamp: Date.now() })
|
||||
console.log('Sent email-window-ready event')
|
||||
} catch (error) {
|
||||
console.error('Failed to send ready signal:', error)
|
||||
}
|
||||
|
||||
// 监听表单提交成功事件,关闭窗口
|
||||
await listen('email-form-success', async () => {
|
||||
const appWindow = getCurrentWindow()
|
||||
await appWindow.close()
|
||||
})
|
||||
|
||||
// 监听表单取消事件,关闭窗口
|
||||
await listen('email-form-cancel', async () => {
|
||||
const appWindow = getCurrentWindow()
|
||||
await appWindow.close()
|
||||
})
|
||||
})
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.independent-window {
|
||||
width: 100vw;
|
||||
height: 100vh;
|
||||
overflow: hidden;
|
||||
}
|
||||
</style>
|
||||
49
src/views/paper/question/independent/file.vue
Normal file
49
src/views/paper/question/independent/file.vue
Normal file
@@ -0,0 +1,49 @@
|
||||
<template>
|
||||
<div class="independent-window">
|
||||
<FileForm ref="formRef" :isIndependent="true" />
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import { ref, onMounted } from 'vue'
|
||||
import { listen } from '@tauri-apps/api/event'
|
||||
import { getCurrentWindow } from '@tauri-apps/api/window'
|
||||
import FileForm from '@/views/paper/question/FileForm.vue'
|
||||
|
||||
defineOptions({ name: 'FileIndependent' })
|
||||
|
||||
const formRef = ref()
|
||||
|
||||
onMounted(async () => {
|
||||
console.log('FileIndependent mounted, sending ready signal...')
|
||||
|
||||
// 发送窗口准备就绪信号
|
||||
try {
|
||||
const { emit } = await import('@tauri-apps/api/event')
|
||||
await emit('file-window-ready', { timestamp: Date.now() })
|
||||
console.log('Sent file-window-ready event')
|
||||
} catch (error) {
|
||||
console.error('Failed to send ready signal:', error)
|
||||
}
|
||||
|
||||
// 监听表单提交成功事件,关闭窗口
|
||||
await listen('file-form-success', async () => {
|
||||
const appWindow = getCurrentWindow()
|
||||
await appWindow.close()
|
||||
})
|
||||
|
||||
// 监听表单取消事件,关闭窗口
|
||||
await listen('file-form-cancel', async () => {
|
||||
const appWindow = getCurrentWindow()
|
||||
await appWindow.close()
|
||||
})
|
||||
})
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.independent-window {
|
||||
width: 100vw;
|
||||
height: 100vh;
|
||||
overflow: hidden;
|
||||
}
|
||||
</style>
|
||||
49
src/views/paper/question/independent/mysql.vue
Normal file
49
src/views/paper/question/independent/mysql.vue
Normal file
@@ -0,0 +1,49 @@
|
||||
<template>
|
||||
<div class="independent-window">
|
||||
<MysqlForm ref="formRef" :isIndependent="true" />
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import { ref, onMounted } from 'vue'
|
||||
import { listen } from '@tauri-apps/api/event'
|
||||
import { getCurrentWindow } from '@tauri-apps/api/window'
|
||||
import MysqlForm from '@/views/paper/question/MysqlForm.vue'
|
||||
|
||||
defineOptions({ name: 'MysqlIndependent' })
|
||||
|
||||
const formRef = ref()
|
||||
|
||||
onMounted(async () => {
|
||||
console.log('MysqlIndependent mounted, sending ready signal...')
|
||||
|
||||
// 发送窗口准备就绪信号
|
||||
try {
|
||||
const { emit } = await import('@tauri-apps/api/event')
|
||||
await emit('mysql-window-ready', { timestamp: Date.now() })
|
||||
console.log('Sent mysql-window-ready event')
|
||||
} catch (error) {
|
||||
console.error('Failed to send ready signal:', error)
|
||||
}
|
||||
|
||||
// 监听表单提交成功事件,关闭窗口
|
||||
await listen('mysql-form-success', async () => {
|
||||
const appWindow = getCurrentWindow()
|
||||
await appWindow.close()
|
||||
})
|
||||
|
||||
// 监听表单取消事件,关闭窗口
|
||||
await listen('mysql-form-cancel', async () => {
|
||||
const appWindow = getCurrentWindow()
|
||||
await appWindow.close()
|
||||
})
|
||||
})
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.independent-window {
|
||||
width: 100vw;
|
||||
height: 100vh;
|
||||
overflow: hidden;
|
||||
}
|
||||
</style>
|
||||
49
src/views/paper/question/independent/ps.vue
Normal file
49
src/views/paper/question/independent/ps.vue
Normal file
@@ -0,0 +1,49 @@
|
||||
<template>
|
||||
<div class="independent-window">
|
||||
<PsForm ref="formRef" :isIndependent="true" />
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import { ref, onMounted } from 'vue'
|
||||
import { listen } from '@tauri-apps/api/event'
|
||||
import { getCurrentWindow } from '@tauri-apps/api/window'
|
||||
import PsForm from '@/views/paper/question/PsForm.vue'
|
||||
|
||||
defineOptions({ name: 'PsIndependent' })
|
||||
|
||||
const formRef = ref()
|
||||
|
||||
onMounted(async () => {
|
||||
console.log('PsIndependent mounted, sending ready signal...')
|
||||
|
||||
// 发送窗口准备就绪信号
|
||||
try {
|
||||
const { emit } = await import('@tauri-apps/api/event')
|
||||
await emit('ps-window-ready', { timestamp: Date.now() })
|
||||
console.log('Sent ps-window-ready event')
|
||||
} catch (error) {
|
||||
console.error('Failed to send ready signal:', error)
|
||||
}
|
||||
|
||||
// 监听表单提交成功事件,关闭窗口
|
||||
await listen('ps-form-success', async () => {
|
||||
const appWindow = getCurrentWindow()
|
||||
await appWindow.close()
|
||||
})
|
||||
|
||||
// 监听表单取消事件,关闭窗口
|
||||
await listen('ps-form-cancel', async () => {
|
||||
const appWindow = getCurrentWindow()
|
||||
await appWindow.close()
|
||||
})
|
||||
})
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.independent-window {
|
||||
width: 100vw;
|
||||
height: 100vh;
|
||||
overflow: hidden;
|
||||
}
|
||||
</style>
|
||||
49
src/views/paper/question/independent/setting.vue
Normal file
49
src/views/paper/question/independent/setting.vue
Normal file
@@ -0,0 +1,49 @@
|
||||
<template>
|
||||
<div class="independent-window">
|
||||
<SettingForm ref="formRef" :isIndependent="true" />
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import { ref, onMounted } from 'vue'
|
||||
import { listen } from '@tauri-apps/api/event'
|
||||
import { getCurrentWindow } from '@tauri-apps/api/window'
|
||||
import SettingForm from '@/views/paper/question/SettingForm.vue'
|
||||
|
||||
defineOptions({ name: 'SettingIndependent' })
|
||||
|
||||
const formRef = ref()
|
||||
|
||||
onMounted(async () => {
|
||||
console.log('SettingIndependent mounted, sending ready signal...')
|
||||
|
||||
// 发送窗口准备就绪信号
|
||||
try {
|
||||
const { emit } = await import('@tauri-apps/api/event')
|
||||
await emit('setting-window-ready', { timestamp: Date.now() })
|
||||
console.log('Sent setting-window-ready event')
|
||||
} catch (error) {
|
||||
console.error('Failed to send ready signal:', error)
|
||||
}
|
||||
|
||||
// 监听表单提交成功事件,关闭窗口
|
||||
await listen('setting-form-success', async () => {
|
||||
const appWindow = getCurrentWindow()
|
||||
await appWindow.close()
|
||||
})
|
||||
|
||||
// 监听表单取消事件,关闭窗口
|
||||
await listen('setting-form-cancel', async () => {
|
||||
const appWindow = getCurrentWindow()
|
||||
await appWindow.close()
|
||||
})
|
||||
})
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.independent-window {
|
||||
width: 100vw;
|
||||
height: 100vh;
|
||||
overflow: hidden;
|
||||
}
|
||||
</style>
|
||||
File diff suppressed because it is too large
Load Diff
49
src/views/wps/pptx-independent.vue
Normal file
49
src/views/wps/pptx-independent.vue
Normal file
@@ -0,0 +1,49 @@
|
||||
<template>
|
||||
<div class="independent-window">
|
||||
<WpsPptxForm ref="formRef" :isIndependent="true" />
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import { ref, onMounted } from 'vue'
|
||||
import { listen } from '@tauri-apps/api/event'
|
||||
import { getCurrentWindow } from '@tauri-apps/api/window'
|
||||
import WpsPptxForm from '@/views/paper/question/WpsPptxForm.vue'
|
||||
|
||||
defineOptions({ name: 'WpsPptxIndependent' })
|
||||
|
||||
const formRef = ref()
|
||||
|
||||
onMounted(async () => {
|
||||
console.log('WpsPptxIndependent mounted, sending ready signal...')
|
||||
|
||||
// 发送窗口准备就绪信号
|
||||
try {
|
||||
const { emit } = await import('@tauri-apps/api/event')
|
||||
await emit('wps-pptx-window-ready', { timestamp: Date.now() })
|
||||
console.log('Sent wps-pptx-window-ready event')
|
||||
} catch (error) {
|
||||
console.error('Failed to send ready signal:', error)
|
||||
}
|
||||
|
||||
// 监听表单提交成功事件,关闭窗口
|
||||
await listen('wps-pptx-form-success', async () => {
|
||||
const appWindow = getCurrentWindow()
|
||||
await appWindow.close()
|
||||
})
|
||||
|
||||
// 监听表单取消事件,关闭窗口
|
||||
await listen('wps-pptx-form-cancel', async () => {
|
||||
const appWindow = getCurrentWindow()
|
||||
await appWindow.close()
|
||||
})
|
||||
})
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.independent-window {
|
||||
width: 100vw;
|
||||
height: 100vh;
|
||||
overflow: hidden;
|
||||
}
|
||||
</style>
|
||||
49
src/views/wps/word-independent.vue
Normal file
49
src/views/wps/word-independent.vue
Normal file
@@ -0,0 +1,49 @@
|
||||
<template>
|
||||
<div class="independent-window">
|
||||
<WpsWordForm ref="formRef" :isIndependent="true" />
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import { ref, onMounted } from 'vue'
|
||||
import { listen } from '@tauri-apps/api/event'
|
||||
import { getCurrentWindow } from '@tauri-apps/api/window'
|
||||
import WpsWordForm from '@/views/paper/question/WpsWordForm.vue'
|
||||
|
||||
defineOptions({ name: 'WpsWordIndependent' })
|
||||
|
||||
const formRef = ref()
|
||||
|
||||
onMounted(async () => {
|
||||
console.log('WpsWordIndependent mounted, sending ready signal...')
|
||||
|
||||
// 发送窗口准备就绪信号
|
||||
try {
|
||||
const { emit } = await import('@tauri-apps/api/event')
|
||||
await emit('wps-word-window-ready', { timestamp: Date.now() })
|
||||
console.log('Sent wps-word-window-ready event')
|
||||
} catch (error) {
|
||||
console.error('Failed to send ready signal:', error)
|
||||
}
|
||||
|
||||
// 监听表单提交成功事件,关闭窗口
|
||||
await listen('wps-word-form-success', async () => {
|
||||
const appWindow = getCurrentWindow()
|
||||
await appWindow.close()
|
||||
})
|
||||
|
||||
// 监听表单取消事件,关闭窗口
|
||||
await listen('wps-word-form-cancel', async () => {
|
||||
const appWindow = getCurrentWindow()
|
||||
await appWindow.close()
|
||||
})
|
||||
})
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.independent-window {
|
||||
width: 100vw;
|
||||
height: 100vh;
|
||||
overflow: hidden;
|
||||
}
|
||||
</style>
|
||||
49
src/views/wps/xlsx-independent.vue
Normal file
49
src/views/wps/xlsx-independent.vue
Normal file
@@ -0,0 +1,49 @@
|
||||
<template>
|
||||
<div class="independent-window">
|
||||
<WpsXlsxForm ref="formRef" :isIndependent="true" />
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import { ref, onMounted } from 'vue'
|
||||
import { listen } from '@tauri-apps/api/event'
|
||||
import { getCurrentWindow } from '@tauri-apps/api/window'
|
||||
import WpsXlsxForm from '@/views/paper/question/WpsXlsxForm.vue'
|
||||
|
||||
defineOptions({ name: 'WpsXlsxIndependent' })
|
||||
|
||||
const formRef = ref()
|
||||
|
||||
onMounted(async () => {
|
||||
console.log('WpsXlsxIndependent mounted, sending ready signal...')
|
||||
|
||||
// 发送窗口准备就绪信号
|
||||
try {
|
||||
const { emit } = await import('@tauri-apps/api/event')
|
||||
await emit('wps-xlsx-window-ready', { timestamp: Date.now() })
|
||||
console.log('Sent wps-xlsx-window-ready event')
|
||||
} catch (error) {
|
||||
console.error('Failed to send ready signal:', error)
|
||||
}
|
||||
|
||||
// 监听表单提交成功事件,关闭窗口
|
||||
await listen('wps-xlsx-form-success', async () => {
|
||||
const appWindow = getCurrentWindow()
|
||||
await appWindow.close()
|
||||
})
|
||||
|
||||
// 监听表单取消事件,关闭窗口
|
||||
await listen('wps-xlsx-form-cancel', async () => {
|
||||
const appWindow = getCurrentWindow()
|
||||
await appWindow.close()
|
||||
})
|
||||
})
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.independent-window {
|
||||
width: 100vw;
|
||||
height: 100vh;
|
||||
overflow: hidden;
|
||||
}
|
||||
</style>
|
||||
@@ -9,7 +9,11 @@
|
||||
label-width="110px"
|
||||
>
|
||||
<el-form-item>
|
||||
<el-button type="primary" plain @click="openForm('create')">
|
||||
<el-button
|
||||
type="primary"
|
||||
plain
|
||||
@click="openForm('create')"
|
||||
>
|
||||
<Icon icon="ep:plus" class="mr-5px" /> 新增
|
||||
</el-button>
|
||||
<el-button type="danger" plain @click="toggleExpandAll">
|
||||
@@ -29,16 +33,26 @@
|
||||
v-if="refreshTable"
|
||||
>
|
||||
<el-table-column prop="name" label="名称" />
|
||||
<el-table-column prop="title" label="标签名称" />
|
||||
<el-table-column prop="title" label="标签名称" />
|
||||
<el-table-column prop="functions" label="方法名称" />
|
||||
<el-table-column prop="parameter" label="方法参数" />
|
||||
<el-table-column prop="chineseName" label="中文描述" />
|
||||
<el-table-column label="操作" align="center" width="200">
|
||||
<el-table-column label="操作" align="center" width="150">
|
||||
<template #default="scope">
|
||||
<el-button link type="primary" @click="openIndependentWindow(scope.row)">
|
||||
<el-button
|
||||
link
|
||||
type="primary"
|
||||
@click="openForm('update', scope.row.id)"
|
||||
>
|
||||
修改
|
||||
</el-button>
|
||||
<el-button link type="danger" @click="handleDelete(scope.row.id)"> 删除 </el-button>
|
||||
<el-button
|
||||
link
|
||||
type="danger"
|
||||
@click="handleDelete(scope.row.id)"
|
||||
>
|
||||
删除
|
||||
</el-button>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
@@ -49,10 +63,12 @@
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import { DICT_TYPE, getIntDictOptions } from '@/utils/dict'
|
||||
import { dateFormatter } from '@/utils/formatTime'
|
||||
import { handleTree } from '@/utils/tree'
|
||||
import * as XlsxApi from '@/api/wps/xlsx'
|
||||
import XlsxForm from './XlsxForm.vue'
|
||||
import { newWindow } from '@/utils/tauriWindow'
|
||||
|
||||
|
||||
defineOptions({ name: 'WpsXlsx' })
|
||||
|
||||
@@ -122,27 +138,6 @@ const handleDelete = async (id: number) => {
|
||||
} catch {}
|
||||
}
|
||||
|
||||
/** 打开独立窗口 */
|
||||
const openIndependentWindow = async (row: any) => {
|
||||
try {
|
||||
// 直接使用 newWindow 方法创建独立窗口
|
||||
await newWindow(`excel-edit-${row.id}`, {
|
||||
url: `/xlsx-independent?id=${row.id}&mode=edit&name=${encodeURIComponent(row.name)}`,
|
||||
title: `编辑 Excel - ${row.name}`,
|
||||
width: 900,
|
||||
height: 650,
|
||||
resizable: true,
|
||||
decorations: true,
|
||||
center: true,
|
||||
visible: true
|
||||
})
|
||||
message.success(`独立窗口已打开: ${row.name}`)
|
||||
} catch (error) {
|
||||
console.error('打开独立窗口失败:', error)
|
||||
message.error('打开独立窗口失败')
|
||||
}
|
||||
}
|
||||
|
||||
/** 初始化 **/
|
||||
onMounted(async () => {
|
||||
await getList()
|
||||
|
||||
Reference in New Issue
Block a user