提交 7a650bb3 authored 作者: 王鹏飞's avatar 王鹏飞

chore: add vite-plugin-checker; fix eslint error

上级 3f09fdd0
/* eslint-env node */
require('@rushstack/eslint-patch/modern-module-resolution')
module.exports = {
root: true,
extends: [
'plugin:vue/vue3-essential',
'eslint:recommended',
'@vue/eslint-config-typescript/recommended',
'./.eslintrc-auto-import.json'
],
rules: {
'vue/multi-word-component-names': 'off',
'@typescript-eslint/no-explicit-any': 'off'
}
}
import pluginVue from 'eslint-plugin-vue'
import vueTsEslintConfig from '@vue/eslint-config-typescript'
import AutoImportJson from './.eslintrc-auto-import.json' with { type: 'json' }
export default [
{
name: 'app/files-to-lint',
files: ['**/*.{ts,mts,tsx,vue}'],
},
{
name: 'app/files-to-ignore',
ignores: ['**/dist/**', '**/dist-ssr/**', '**/coverage/**', '**/lib/**'],
},
...pluginVue.configs['flat/essential'],
...vueTsEslintConfig(),
{
languageOptions: {
...AutoImportJson,
},
rules: {
'vue/block-lang': 'off',
'vue/multi-word-component-names': 'off',
'@typescript-eslint/no-explicit-any': 'off',
'@typescript-eslint/no-unused-expressions': 'off',
},
},
]
This source diff could not be displayed because it is too large. You can view the blob instead.
...@@ -9,7 +9,7 @@ ...@@ -9,7 +9,7 @@
"build:pre": "vue-tsc --noEmit && vite build --mode pre", "build:pre": "vue-tsc --noEmit && vite build --mode pre",
"preview": "vite preview --port 4173", "preview": "vite preview --port 4173",
"typecheck": "vue-tsc --noEmit", "typecheck": "vue-tsc --noEmit",
"lint": "eslint . --ext .vue,.js,.jsx,.cjs,.mjs,.ts,.tsx,.cts,.mts --fix --ignore-path .gitignore", "lint": "eslint . --fix",
"deploy": "node ./deploy.js", "deploy": "node ./deploy.js",
"cert": "node ./cert.js" "cert": "node ./cert.js"
}, },
...@@ -43,7 +43,6 @@ ...@@ -43,7 +43,6 @@
"vuedraggable": "^4.1.0" "vuedraggable": "^4.1.0"
}, },
"devDependencies": { "devDependencies": {
"@rushstack/eslint-patch": "^1.2.0",
"@tsconfig/node20": "^20.1.4", "@tsconfig/node20": "^20.1.4",
"@types/ali-oss": "^6.16.8", "@types/ali-oss": "^6.16.8",
"@types/blueimp-md5": "^2.18.0", "@types/blueimp-md5": "^2.18.0",
...@@ -53,18 +52,18 @@ ...@@ -53,18 +52,18 @@
"@types/ua-parser-js": "^0.7.36", "@types/ua-parser-js": "^0.7.36",
"@types/video.js": "^7.3.52", "@types/video.js": "^7.3.52",
"@vitejs/plugin-vue": "^5.1.4", "@vitejs/plugin-vue": "^5.1.4",
"@vue-macros/reactivity-transform": "^1.1.2", "@vue-macros/reactivity-transform": "^1.1.3",
"@vue/eslint-config-typescript": "^12.0.0", "@vue/eslint-config-typescript": "^14.1.3",
"@vue/tsconfig": "^0.5.1", "@vue/tsconfig": "^0.6.0",
"chalk": "^5.2.0", "chalk": "^5.2.0",
"eslint": "^8.57.0", "eslint": "^9.14.0",
"eslint-plugin-vue": "^9.25.0", "eslint-plugin-vue": "^9.30.0",
"sass": "^1.58.3", "sass": "^1.58.3",
"typescript": "~5.4.5", "typescript": "~5.6.3",
"unplugin-auto-import": "^0.17.8", "unplugin-auto-import": "^0.17.8",
"vite": "^5.4.9", "vite": "^5.4.10",
"vite-plugin-checker": "^0.6.4", "vite-plugin-checker": "^0.8.0",
"vite-plugin-mkcert": "^1.17.6", "vite-plugin-mkcert": "^1.17.6",
"vue-tsc": "^1.8.27" "vue-tsc": "^2.1.10"
} }
} }
...@@ -5,7 +5,7 @@ const emit = defineEmits<{ ...@@ -5,7 +5,7 @@ const emit = defineEmits<{
(e: 'resize'): void (e: 'resize'): void
}>() }>()
const props = defineProps<{ isLeftShow?: number }>() defineProps<{ isLeftShow?: number }>()
const leftPanelVisible = $ref<boolean>(true) const leftPanelVisible = $ref<boolean>(true)
const leftPanelWidth = useStorage('leftPanelWidth', 400) const leftPanelWidth = useStorage('leftPanelWidth', 400)
...@@ -19,10 +19,10 @@ let dragFlag = $ref(false) ...@@ -19,10 +19,10 @@ let dragFlag = $ref(false)
function useDrag() { function useDrag() {
const dragDom = document.getElementById('panel-resize') const dragDom = document.getElementById('panel-resize')
if (dragDom) { if (dragDom) {
dragDom.addEventListener('mousedown', e => { dragDom.addEventListener('mousedown', (e) => {
e.preventDefault() e.preventDefault()
dragFlag = true dragFlag = true
document.onmousemove = e => { document.onmousemove = (e) => {
leftPanelWidth.value = e.clientX leftPanelWidth.value = e.clientX
} }
document.onmouseup = () => { document.onmouseup = () => {
...@@ -52,14 +52,12 @@ onMounted(() => { ...@@ -52,14 +52,12 @@ onMounted(() => {
<path <path
class="path-wapper" class="path-wapper"
d="M0 0l14.12 8.825A4 4 0 0116 12.217v61.566a4 4 0 01-1.88 3.392L0 86V0z" d="M0 0l14.12 8.825A4 4 0 0116 12.217v61.566a4 4 0 01-1.88 3.392L0 86V0z"
fill="#e1e4eb" fill="#e1e4eb"></path>
></path>
<path <path
class="path-arrow" class="path-arrow"
d="M10.758 48.766a.778.778 0 000-1.127L6.996 43l3.762-4.639a.778.778 0 000-1.127.85.85 0 00-1.172 0l-4.344 5.202a.78.78 0 000 1.128l4.344 5.202a.85.85 0 001.172 0z" d="M10.758 48.766a.778.778 0 000-1.127L6.996 43l3.762-4.639a.778.778 0 000-1.127.85.85 0 00-1.172 0l-4.344 5.202a.78.78 0 000 1.128l4.344 5.202a.85.85 0 001.172 0z"
fill="#8D9EA7" fill="#8D9EA7"
fill-rule="nonzero" fill-rule="nonzero"></path>
></path>
</g> </g>
</svg> </svg>
</div> </div>
......
...@@ -3,7 +3,7 @@ const appConfigList = [ ...@@ -3,7 +3,7 @@ const appConfigList = [
system: 'default', system: 'default',
title: '商业数据分析实验室', title: '商业数据分析实验室',
logo: 'https://webapp-pub.ezijing.com/website/base/logo.svg', logo: 'https://webapp-pub.ezijing.com/website/base/logo.svg',
hosts: ['saas-lab'] hosts: ['saas-lab'],
}, },
{ {
system: 'x', system: 'x',
...@@ -13,7 +13,7 @@ const appConfigList = [ ...@@ -13,7 +13,7 @@ const appConfigList = [
studentMenus: [ studentMenus: [
{ name: '首页', path: '/' }, { name: '首页', path: '/' },
{ name: '我的实验', path: '/student/lab' }, { name: '我的实验', path: '/student/lab' },
{ name: '理论学习', path: import.meta.env.VITE_SAAS_LEARN_URL } { name: '理论学习', path: import.meta.env.VITE_SAAS_LEARN_URL },
], ],
adminMenus: [ adminMenus: [
{ name: '首页', path: '/' }, { name: '首页', path: '/' },
...@@ -27,22 +27,22 @@ const appConfigList = [ ...@@ -27,22 +27,22 @@ const appConfigList = [
{ name: '实验指导书管理', path: '/admin/lab/book', tag: 'v1-teacher-book' }, { name: '实验指导书管理', path: '/admin/lab/book', tag: 'v1-teacher-book' },
{ name: '实验操作视频管理', path: '/admin/lab/video', tag: 'v1-teacher-video' }, { name: '实验操作视频管理', path: '/admin/lab/video', tag: 'v1-teacher-video' },
{ name: '实验讨论交流', path: '/admin/lab/discuss', tag: 'v1-teacher-discussion' }, { name: '实验讨论交流', path: '/admin/lab/discuss', tag: 'v1-teacher-discussion' },
{ name: '实验成绩管理', path: '/admin/lab/score', tag: 'v1-teacher-record' } { name: '实验成绩管理', path: '/admin/lab/score', tag: 'v1-teacher-record' },
] ],
} },
] ],
}, },
{ {
system: 'game', system: 'game',
title: '商业数据分析竞赛平台', title: '商业数据分析竞赛平台',
hosts: ['saas-game'] hosts: ['saas-game'],
}, },
{ {
system: 'dml', system: 'dml',
title: '数智营销实践教学平台', title: '数智营销实践教学平台',
logo: 'https://webapp-pub.ezijing.com/website/base/logo.svg', logo: 'https://webapp-pub.ezijing.com/website/base/logo.svg',
hosts: ['saas-dml-web'], hosts: ['saas-dml-web'],
dmlURL: import.meta.env.VITE_DML_PRO_URL dmlURL: import.meta.env.VITE_DML_PRO_URL,
}, },
{ {
system: 'swsjfxs', system: 'swsjfxs',
...@@ -53,13 +53,13 @@ const appConfigList = [ ...@@ -53,13 +53,13 @@ const appConfigList = [
studentMenus: [ studentMenus: [
{ name: '首页', path: '/' }, { name: '首页', path: '/' },
{ name: '我的大赛', path: '/student/contest' }, { name: '我的大赛', path: '/student/contest' },
{ name: '大赛成绩查询', path: '/student/contest/score' } { name: '大赛成绩查询', path: '/student/contest/score' },
], ],
xTrainLabel: '商务数据分析理论训练', xTrainLabel: '商务数据分析理论训练',
labTrainLabel: '商务数据分析实操训练', labTrainLabel: '商务数据分析实操训练',
xExamLabel: '商务数据分析理论考试', xExamLabel: '商务数据分析理论考试',
labExamLabel: '商务数据分析实操考试', labExamLabel: '商务数据分析实操考试',
loginURL: import.meta.env.VITE_SWSJFXS_LOGIN_URL loginURL: import.meta.env.VITE_SWSJFXS_LOGIN_URL,
}, },
{ {
system: 'swsjfxs', system: 'swsjfxs',
...@@ -70,7 +70,7 @@ const appConfigList = [ ...@@ -70,7 +70,7 @@ const appConfigList = [
studentMenus: [ studentMenus: [
{ name: '首页', path: '/' }, { name: '首页', path: '/' },
{ name: '我的大赛', path: '/student/contest' }, { name: '我的大赛', path: '/student/contest' },
{ name: '大赛成绩查询', path: '/student/contest/score' } { name: '大赛成绩查询', path: '/student/contest/score' },
], ],
xTrainLabel: '理论训练', xTrainLabel: '理论训练',
labTrainLabel: '实操训练', labTrainLabel: '实操训练',
...@@ -79,7 +79,7 @@ const appConfigList = [ ...@@ -79,7 +79,7 @@ const appConfigList = [
loginURL: import.meta.env.VITE_SWSJFXS_LOGIN_URL, loginURL: import.meta.env.VITE_SWSJFXS_LOGIN_URL,
hideAvailableEvents: true, // 隐藏可参与赛项 hideAvailableEvents: true, // 隐藏可参与赛项
hidePracticalTestPaper: true, // 隐藏实操试卷 hidePracticalTestPaper: true, // 隐藏实操试卷
hideContestToolbar: true // 隐藏大赛工具栏 hideContestToolbar: true, // 隐藏大赛工具栏
}, },
{ {
system: 'amo', system: 'amo',
...@@ -90,7 +90,7 @@ const appConfigList = [ ...@@ -90,7 +90,7 @@ const appConfigList = [
studentMenus: [ studentMenus: [
{ name: '首页', path: '/' }, { name: '首页', path: '/' },
{ name: '我的大赛', path: '/student/contest' }, { name: '我的大赛', path: '/student/contest' },
{ name: '大赛成绩查询', path: '/student/contest/score' } { name: '大赛成绩查询', path: '/student/contest/score' },
], ],
xTrainLabel: '理论训练', xTrainLabel: '理论训练',
labTrainLabel: '实操训练', labTrainLabel: '实操训练',
...@@ -99,7 +99,7 @@ const appConfigList = [ ...@@ -99,7 +99,7 @@ const appConfigList = [
loginURL: import.meta.env.VITE_SWSJFXS_LOGIN_URL, loginURL: import.meta.env.VITE_SWSJFXS_LOGIN_URL,
hideAvailableEvents: true, // 隐藏可参与赛项 hideAvailableEvents: true, // 隐藏可参与赛项
hidePracticalTestPaper: true, // 隐藏实操试卷 hidePracticalTestPaper: true, // 隐藏实操试卷
hideContestToolbar: true // 隐藏大赛工具栏 hideContestToolbar: true, // 隐藏大赛工具栏
}, },
{ {
system: 'default', system: 'default',
...@@ -110,7 +110,7 @@ const appConfigList = [ ...@@ -110,7 +110,7 @@ const appConfigList = [
hosts: ['saas-lab-bda2'], hosts: ['saas-lab-bda2'],
studentMenus: [ studentMenus: [
{ name: '首页', path: '/' }, { name: '首页', path: '/' },
{ name: '我的大赛', path: '/student/contest' } { name: '我的大赛', path: '/student/contest' },
// { name: '大赛成绩查询', path: '/student/contest/score' } // { name: '大赛成绩查询', path: '/student/contest/score' }
], ],
xTrainLabel: '理论训练', xTrainLabel: '理论训练',
...@@ -120,7 +120,7 @@ const appConfigList = [ ...@@ -120,7 +120,7 @@ const appConfigList = [
// loginURL: import.meta.env.VITE_SWSJFXS_LOGIN_URL, // loginURL: import.meta.env.VITE_SWSJFXS_LOGIN_URL,
hideAvailableEvents: true, // 隐藏可参与赛项 hideAvailableEvents: true, // 隐藏可参与赛项
hidePracticalTestPaper: true, // 隐藏实操试卷 hidePracticalTestPaper: true, // 隐藏实操试卷
hideContestToolbar: true // 隐藏大赛工具栏 hideContestToolbar: true, // 隐藏大赛工具栏
}, },
{ {
system: 'nac', system: 'nac',
...@@ -131,7 +131,7 @@ const appConfigList = [ ...@@ -131,7 +131,7 @@ const appConfigList = [
hosts: ['saas-lab-nac'], hosts: ['saas-lab-nac'],
studentMenus: [ studentMenus: [
{ name: '首页', path: '/' }, { name: '首页', path: '/' },
{ name: '我的大赛', path: '/student/contest' } { name: '我的大赛', path: '/student/contest' },
// { name: '大赛成绩查询', path: '/student/contest/score' } // { name: '大赛成绩查询', path: '/student/contest/score' }
], ],
xTrainLabel: '理论训练', xTrainLabel: '理论训练',
...@@ -141,16 +141,16 @@ const appConfigList = [ ...@@ -141,16 +141,16 @@ const appConfigList = [
// loginURL: import.meta.env.VITE_SWSJFXS_LOGIN_URL, // loginURL: import.meta.env.VITE_SWSJFXS_LOGIN_URL,
hideAvailableEvents: true, // 隐藏可参与赛项 hideAvailableEvents: true, // 隐藏可参与赛项
hidePracticalTestPaper: true, // 隐藏实操试卷 hidePracticalTestPaper: true, // 隐藏实操试卷
hideContestToolbar: true // 隐藏大赛工具栏 hideContestToolbar: true, // 隐藏大赛工具栏
} },
] ]
export function useAppConfig() { export function useAppConfig() {
const found = appConfigList.find(item => { const found = appConfigList.find((item) => {
return item.hosts.find(host => location.host.split('.').includes(host)) return item.hosts.find((host) => location.host.split('.').includes(host))
}) })
const appConfig = found || appConfigList[8] const appConfig = found || appConfigList[0]
return { ...appConfig } return { ...appConfig }
} }
...@@ -32,7 +32,7 @@ onMounted(() => { ...@@ -32,7 +32,7 @@ onMounted(() => {
const platformKey = ref('career_data_analysis') const platformKey = ref('career_data_analysis')
const platformKeys = ref([ const platformKeys = ref([
{ platform_key: 'career_data_analysis', name: '商业数据分析实验' }, { platform_key: 'career_data_analysis', name: '商业数据分析实验' },
{ platform_key: 'data_marketing', name: '数据营销实操' } { platform_key: 'data_marketing', name: '数据营销实操' },
]) ])
// async function fetchPlatformKeys(competition_id: string) { // async function fetchPlatformKeys(competition_id: string) {
// const res = await getPlatformKeys({ competition_id }) // const res = await getPlatformKeys({ competition_id })
...@@ -59,7 +59,11 @@ onUnmounted(() => { ...@@ -59,7 +59,11 @@ onUnmounted(() => {
timer && clearInterval(timer) timer && clearInterval(timer)
}) })
const statistics = reactive({ competitor_count: 0, complete_answer_competitor_count: 0, starting_answer_competitor_count: 0 }) const statistics = reactive({
competitor_count: 0,
complete_answer_competitor_count: 0,
starting_answer_competitor_count: 0,
})
async function fetchStatistics(competition_id: string, platform_key = 'career_data_analysis') { async function fetchStatistics(competition_id: string, platform_key = 'career_data_analysis') {
const res = await getCompetitionStatistics({ competition_id, platform_key }) const res = await getCompetitionStatistics({ competition_id, platform_key })
Object.assign(statistics, res.data.detail) Object.assign(statistics, res.data.detail)
...@@ -93,8 +97,8 @@ const submittedListOptions = { ...@@ -93,8 +97,8 @@ const submittedListOptions = {
{ label: '所在专业', prop: 'student.specialty_name' }, { label: '所在专业', prop: 'student.specialty_name' },
{ label: '所在班级', prop: 'student.class_name' }, { label: '所在班级', prop: 'student.class_name' },
{ label: '提交时间', prop: 'commit_time' }, { label: '提交时间', prop: 'commit_time' },
{ label: '作答用时', prop: 'answer_time' } { label: '作答用时', prop: 'answer_time' },
] ],
} }
const submittedLis = computed(() => { const submittedLis = computed(() => {
return competitorsTableData.value.filter((item: any) => item.commit_status == 3) return competitorsTableData.value.filter((item: any) => item.commit_status == 3)
...@@ -110,9 +114,9 @@ const answeringListOptions = { ...@@ -110,9 +114,9 @@ const answeringListOptions = {
{ label: '所在班级', prop: 'student.class_name' }, { label: '所在班级', prop: 'student.class_name' },
{ {
label: '作答用时', label: '作答用时',
prop: 'answer_time' prop: 'answer_time',
} },
] ],
} }
const answeringList = computed(() => { const answeringList = computed(() => {
return competitorsTableData.value.filter((item: any) => item.commit_status == 2 || item.commit_status == 4) return competitorsTableData.value.filter((item: any) => item.commit_status == 2 || item.commit_status == 4)
...@@ -133,44 +137,44 @@ const listOptions = { ...@@ -133,44 +137,44 @@ const listOptions = {
prop: 'module_1', prop: 'module_1',
computed({ row }: { row: any }) { computed({ row }: { row: any }) {
return getModuleStatus(row, 0) return getModuleStatus(row, 0)
} },
}, },
{ {
label: '模块二', label: '模块二',
prop: 'module_2', prop: 'module_2',
computed({ row }: { row: any }) { computed({ row }: { row: any }) {
return getModuleStatus(row, 1) return getModuleStatus(row, 1)
} },
}, },
{ {
label: '模块三', label: '模块三',
prop: 'module_3', prop: 'module_3',
computed({ row }: { row: any }) { computed({ row }: { row: any }) {
return getModuleStatus(row, 2) return getModuleStatus(row, 2)
} },
}, },
{ {
label: '模块四', label: '模块四',
prop: 'module_4', prop: 'module_4',
computed({ row }: { row: any }) { computed({ row }: { row: any }) {
return getModuleStatus(row, 3) return getModuleStatus(row, 3)
} },
}, },
{ {
label: '模块五', label: '模块五',
prop: 'module_5', prop: 'module_5',
computed({ row }: { row: any }) { computed({ row }: { row: any }) {
return getModuleStatus(row, 4) return getModuleStatus(row, 4)
} },
}, },
{ {
label: '模块六', label: '模块六',
prop: 'module_6', prop: 'module_6',
computed({ row }: { row: any }) { computed({ row }: { row: any }) {
return getModuleStatus(row, 5) return getModuleStatus(row, 5)
} },
} },
] ],
} }
function getModuleStatus(row: any, index: number) { function getModuleStatus(row: any, index: number) {
try { try {
...@@ -182,7 +186,7 @@ function getModuleStatus(row: any, index: number) { ...@@ -182,7 +186,7 @@ function getModuleStatus(row: any, index: number) {
if (status == 3) return '<span class="is-completed2">部分完成</span>' if (status == 3) return '<span class="is-completed2">部分完成</span>'
if (status == 4) return '<span class="is-completed">全部完成</span>' if (status == 4) return '<span class="is-completed">全部完成</span>'
} catch (error) { } catch (error) {
// console.log(error) console.log(error)
} }
return '<span class="not-started">未开始</span>' return '<span class="not-started">未开始</span>'
} }
...@@ -198,7 +202,11 @@ function getModuleStatus(row: any, index: number) { ...@@ -198,7 +202,11 @@ function getModuleStatus(row: any, index: number) {
<el-option v-for="item in competitionList" :key="item.id" :value="item" :label="item.name"></el-option> <el-option v-for="item in competitionList" :key="item.id" :value="item" :label="item.name"></el-option>
</el-select> </el-select>
<el-select v-model="platformKey" size="large"> <el-select v-model="platformKey" size="large">
<el-option v-for="item in platformKeys" :key="item.platform_key" :value="item.platform_key" :label="item.name"></el-option> <el-option
v-for="item in platformKeys"
:key="item.platform_key"
:value="item.platform_key"
:label="item.name"></el-option>
</el-select> </el-select>
</el-row> </el-row>
<ul class="statistics"> <ul class="statistics">
......
...@@ -188,10 +188,10 @@ const title = $computed(() => { ...@@ -188,10 +188,10 @@ const title = $computed(() => {
return isUpdate ? '编辑赛项' : '新增赛项' return isUpdate ? '编辑赛项' : '新增赛项'
}) })
// 是否禁用赛项周期 // 是否禁用赛项周期
const disabledRange = $computed(() => { // const disabledRange = $computed(() => {
const [firstDate, secondDate] = form.dateRange || [] // const [firstDate, secondDate] = form.dateRange || []
return isUpdate && dayjs().isBetween(firstDate, secondDate, 'date', '[]') // return isUpdate && dayjs().isBetween(firstDate, secondDate, 'date', '[]')
}) // })
// 提交 // 提交
function handleSubmit() { function handleSubmit() {
formRef?.validate().then(() => { formRef?.validate().then(() => {
......
...@@ -25,11 +25,11 @@ const form = reactive<any>({ ...@@ -25,11 +25,11 @@ const form = reactive<any>({
is_show: '1', is_show: '1',
// rule_list: [{ name: '实验报告', type: 1, percent: 100, rule_mode: 1 }], // rule_list: [{ name: '实验报告', type: 1, percent: 100, rule_mode: 1 }],
rule_list: [], rule_list: [],
exam_rules: [] exam_rules: [],
}) })
function fetchInfo() { function fetchInfo() {
getExperimentGradeRule({ experiment_id: props.data.id }).then(res => { getExperimentGradeRule({ experiment_id: props.data.id }).then((res) => {
const { detail } = res.data const { detail } = res.data
if (!detail.id) return if (!detail.id) return
let ruleList = [] let ruleList = []
...@@ -139,12 +139,12 @@ function handleSubmit(call?: any) { ...@@ -139,12 +139,12 @@ function handleSubmit(call?: any) {
// 当前评分方法 // 当前评分方法
function currentRuleNames(value: number) { function currentRuleNames(value: number) {
const typeList = form.rule_list.map((item: any) => item.type) const typeList = form.rule_list.map((item: any) => item.type)
const tempList = gradeRuleList.filter(item => { const tempList = gradeRuleList.filter((item) => {
return item.value === value || item.value === 5 || !typeList.includes(item.value) return item.value === value || item.value === 5 || !typeList.includes(item.value)
}) })
if (props.data.type === '4') { if (props.data.type === '4') {
// 数字营销实验 // 数字营销实验
return tempList.filter(item => [1, 5, 6, 7, 8, 9, 10].includes(item.value as number)) return tempList.filter((item) => [1, 5, 6, 7, 8, 9, 10].includes(item.value as number))
} else { } else {
return tempList.filter((item: any) => item.value <= 5) return tempList.filter((item: any) => item.value <= 5)
} }
...@@ -209,7 +209,7 @@ const marketingType = { ...@@ -209,7 +209,7 @@ const marketingType = {
'5': '5、用户精准分群', '5': '5、用户精准分群',
'6': '6、自动化营销旅程', '6': '6、自动化营销旅程',
'7': '7、营销物料设计', '7': '7、营销物料设计',
'8': '8、营销策划报告' '8': '8、营销策划报告',
} }
let marketingForm = $ref({ let marketingForm = $ref({
percent: 0, percent: 0,
...@@ -222,8 +222,8 @@ let marketingForm = $ref({ ...@@ -222,8 +222,8 @@ let marketingForm = $ref({
{ type: '5', percent: 15 }, { type: '5', percent: 15 },
{ type: '6', percent: 15 }, { type: '6', percent: 15 },
{ type: '7', percent: 15 }, { type: '7', percent: 15 },
{ type: '8', percent: 5 } { type: '8', percent: 5 },
] ],
}) })
let marketingShow = $ref(false) let marketingShow = $ref(false)
const handleMarketingAdd = function () { const handleMarketingAdd = function () {
...@@ -263,8 +263,7 @@ onMounted(() => { ...@@ -263,8 +263,7 @@ onMounted(() => {
title="编辑实验成绩规则" title="编辑实验成绩规则"
:close-on-click-modal="false" :close-on-click-modal="false"
width="800px" width="800px"
@update:modelValue="value => $emit('update:modelValue', value)" @update:modelValue="(value) => $emit('update:modelValue', value)">
>
<el-form ref="formRef" :model="form" label-suffix=":"> <el-form ref="formRef" :model="form" label-suffix=":">
<el-form-item label="实验名称">{{ data?.name }}</el-form-item> <el-form-item label="实验名称">{{ data?.name }}</el-form-item>
<el-row> <el-row>
...@@ -340,8 +339,7 @@ onMounted(() => { ...@@ -340,8 +339,7 @@ onMounted(() => {
:disabled="row.type === 1" :disabled="row.type === 1"
style="width: 100%" style="width: 100%"
@change="handleTypeChange(row)" @change="handleTypeChange(row)"
v-else v-else>
>
<el-option v-for="item in currentRuleNames(row.type)" :key="item.value" v-bind="item"></el-option> <el-option v-for="item in currentRuleNames(row.type)" :key="item.value" v-bind="item"></el-option>
</el-select> </el-select>
</template> </template>
...@@ -393,27 +391,26 @@ onMounted(() => { ...@@ -393,27 +391,26 @@ onMounted(() => {
<el-input-number <el-input-number
@change="handlePercentChange(marketingForm, 1, 3)" @change="handlePercentChange(marketingForm, 1, 3)"
v-model="marketingForm.percent" v-model="marketingForm.percent"
:min="0" :min="0" />
/>
% %
</el-form-item> </el-form-item>
<el-button <el-button
style="margin-left: 20px" style="margin-left: 20px"
type="primary" type="primary"
:icon="!marketingShow ? Plus : Minus" :icon="!marketingShow ? Plus : Minus"
@click="handleMarketingAdd" @click="handleMarketingAdd"></el-button>
></el-button>
</div> </div>
<el-divider></el-divider> <el-divider></el-divider>
<el-form-item <template v-if="marketingShow">
v-if="marketingShow" <el-form-item
style="margin-bottom: 10px" style="margin-bottom: 10px"
label-width="150px" label-width="150px"
:label="marketingType[item.type as '1']" :label="marketingType[item.type as '1']"
v-for="(item, index) in marketingForm.details" v-for="(item, index) in marketingForm.details"
> :key="index">
<el-input-number @change="handleMarketingChildChange(item, index)" v-model="item.percent" :min="0" /> % <el-input-number @change="handleMarketingChildChange(item, index)" v-model="item.percent" :min="0" /> %
</el-form-item> </el-form-item>
</template>
<div class="total-c" v-if="marketingShow"> <div class="total-c" v-if="marketingShow">
<p>营销策划小计:{{ marketingTotal }}%</p> <p>营销策划小计:{{ marketingTotal }}%</p>
</div> </div>
......
<script setup lang="ts"> <script setup lang="ts">
import type { FormInstance } from 'element-plus' import type { FormInstance } from 'element-plus'
import { Document, CircleCheck, CircleClose, CircleCloseFilled } from '@element-plus/icons-vue' import { CircleCloseFilled } from '@element-plus/icons-vue'
import type { UploadFile } from 'element-plus'
const route = useRoute()
const modelValue: any = defineModel() const modelValue: any = defineModel()
const ruleFormRef = ref<FormInstance>() const ruleFormRef = ref<FormInstance>()
// 移除上传文件
const handleRemove = (file: UploadFile) => {
if (file) {
modelValue.value.forEach((item: any) => {
const index = item.files.findIndex((cItem: { url: string }) => cItem.url === file.url)
item.files.splice(index, 1)
})
}
}
const removeQuestion = (index: number) => { const removeQuestion = (index: number) => {
modelValue.value.splice(index, 1) modelValue.value.splice(index, 1)
} }
......
...@@ -2,11 +2,8 @@ ...@@ -2,11 +2,8 @@
import type { FormInstance } from 'element-plus' import type { FormInstance } from 'element-plus'
import { Document, CircleCheck, CircleClose, CircleCloseFilled } from '@element-plus/icons-vue' import { Document, CircleCheck, CircleClose, CircleCloseFilled } from '@element-plus/icons-vue'
import AppUpload from '@/components/base/AppUpload.vue' import AppUpload from '@/components/base/AppUpload.vue'
import { getQuestionTags } from '../../api'
import type { UploadFile } from 'element-plus' import type { UploadFile } from 'element-plus'
const route = useRoute()
const modelValue: any = defineModel() const modelValue: any = defineModel()
const ruleFormRef = ref<FormInstance>() const ruleFormRef = ref<FormInstance>()
...@@ -42,7 +39,7 @@ const options = $ref<{ id: number; name: string }[]>([ ...@@ -42,7 +39,7 @@ const options = $ref<{ id: number; name: string }[]>([
{ id: 405, name: 'H5资料' }, { id: 405, name: 'H5资料' },
{ id: 406, name: '二维码资料' }, { id: 406, name: '二维码资料' },
{ id: 407, name: '小程序资料' }, { id: 407, name: '小程序资料' },
{ id: 408, name: '卡券资料' } { id: 408, name: '卡券资料' },
]) ])
onMounted(() => { onMounted(() => {
const dom: any = document.querySelectorAll('.app-main')[0] const dom: any = document.querySelectorAll('.app-main')[0]
...@@ -57,7 +54,7 @@ const getTips = function (n: number) { ...@@ -57,7 +54,7 @@ const getTips = function (n: number) {
405: '试题文件支持格式包含:png jpg jpeg ,大小不超过5M', 405: '试题文件支持格式包含:png jpg jpeg ,大小不超过5M',
406: '试题文件支持格式包含:png jpg jpeg ,大小不超过5M', 406: '试题文件支持格式包含:png jpg jpeg ,大小不超过5M',
407: '试题文件支持格式包含:png jpg jpeg ,大小不超过5M', 407: '试题文件支持格式包含:png jpg jpeg ,大小不超过5M',
508: '试题文件支持格式包含:png jpg jpeg ,大小不超过5M' 508: '试题文件支持格式包含:png jpg jpeg ,大小不超过5M',
} }
return tipText[n] return tipText[n]
} }
...@@ -111,8 +108,7 @@ const getTips = function (n: number) { ...@@ -111,8 +108,7 @@ const getTips = function (n: number) {
@change="handleDownload(file)" @change="handleDownload(file)"
v-model="file.is_download" v-model="file.is_download"
size="large" size="large"
active-text="能否下载" active-text="能否下载" />
/>
</div> </div>
</template> </template>
</AppUpload> </AppUpload>
......
...@@ -10,16 +10,18 @@ onMounted(() => { ...@@ -10,16 +10,18 @@ onMounted(() => {
// 获取题 // 获取题
let list: any = $ref() let list: any = $ref()
const getCurrentQuestions = function () { const getCurrentQuestions = function () {
getQuestions({ experiment_id: route.query.id }).then(res => { getQuestions({ experiment_id: route.query.id }).then((res) => {
list = res.data.items list = res.data.items
}) })
} }
const selectAnswer = ['302', '202']
</script> </script>
<template> <template>
<el-dialog title="2023商业数据分析大赛决赛试题" :close-on-click-modal="false" width="50%" @update:modelValue="value => $emit('update:modelValue', value)"> <el-dialog
title="2023商业数据分析大赛决赛试题"
:close-on-click-modal="false"
width="50%"
@update:modelValue="(value) => $emit('update:modelValue', value)">
<el-card class="box-card" v-for="(item, index) in list" :key="item.id"> <el-card class="box-card" v-for="(item, index) in list" :key="item.id">
<template #header> <template #header>
<div class="card-header"> <div class="card-header">
...@@ -27,7 +29,9 @@ const selectAnswer = ['302', '202'] ...@@ -27,7 +29,9 @@ const selectAnswer = ['302', '202']
<el-form-item label="本题分值" style="margin: 0"> {{ item.score }} </el-form-item> <el-form-item label="本题分值" style="margin: 0"> {{ item.score }} </el-form-item>
</div> </div>
</template> </template>
<div class="text item">正确答案:{{ ['302', '202'].includes(item.type) ? item.answer_info?.name : item?.answer || '上传成功' }}</div> <div class="text item">
正确答案:{{ ['302', '202'].includes(item.type) ? item.answer_info?.name : item?.answer || '上传成功' }}
</div>
</el-card> </el-card>
</el-dialog> </el-dialog>
</template> </template>
......
<script setup lang="ts"> <script setup lang="ts">
import type { FormInstance, FormRules } from 'element-plus' import type { FormInstance, FormRules } from 'element-plus'
import { ElMessage } from 'element-plus' // import { ElMessage } from 'element-plus'
import AppUpload from '@/components/base/AppUpload.vue' import AppUpload from '@/components/base/AppUpload.vue'
import { useCountdown } from '@/composables/useCountdown' // import { useCountdown } from '@/composables/useCountdown'
import { joinContest2, sendApplySMS } from '../api' import {
joinContest2,
// sendApplySMS
} from '../api'
const { second, disabled, start } = useCountdown() // const { second, disabled, start } = useCountdown()
const countdownText = $computed(() => { // const countdownText = $computed(() => {
return disabled.value ? `(${second.value})秒` : '点击获取' // return disabled.value ? `(${second.value})秒` : '点击获取'
}) // })
// 发送验证码 // 发送验证码
function sendSMS() { // function sendSMS() {
if (form.mobile) { // if (form.mobile) {
start() // start()
sendApplySMS({ competition_id: form.competition_id, mobile: form.mobile }).catch(() => { // sendApplySMS({ competition_id: form.competition_id, mobile: form.mobile }).catch(() => {
stop() // stop()
}) // })
} else { // } else {
ElMessage({ // ElMessage({
showClose: true, // showClose: true,
message: '请输入手机号', // message: '请输入手机号',
type: 'warning' // type: 'warning'
}) // })
new Error('请输入手机号') // new Error('请输入手机号')
} // }
} // }
const router = useRouter() const router = useRouter()
const formRef = $ref<FormInstance>() const formRef = $ref<FormInstance>()
...@@ -45,7 +48,7 @@ const form = reactive({ ...@@ -45,7 +48,7 @@ const form = reactive({
photo: '', photo: '',
// code: '', // code: '',
protocol: false, protocol: false,
team_name: '' team_name: '',
}) })
const checkProtocol = (rule: any, value: any, callback: any) => { const checkProtocol = (rule: any, value: any, callback: any) => {
if (!value) { if (!value) {
...@@ -68,7 +71,7 @@ const rules = ref<FormRules>({ ...@@ -68,7 +71,7 @@ const rules = ref<FormRules>({
teacher_name: [{ required: true, message: '请输入指导教师' }], teacher_name: [{ required: true, message: '请输入指导教师' }],
photo: [{ required: true, message: '请上传证件照' }], photo: [{ required: true, message: '请上传证件照' }],
code: [{ required: true, message: '请输入验证码' }], code: [{ required: true, message: '请输入验证码' }],
protocol: [{ validator: checkProtocol, trigger: 'change' }] protocol: [{ validator: checkProtocol, trigger: 'change' }],
}) })
let dialogVisible = $ref(false) let dialogVisible = $ref(false)
......
...@@ -108,7 +108,7 @@ function uploadPicture(url: string) { ...@@ -108,7 +108,7 @@ function uploadPicture(url: string) {
screenshotLoading = false screenshotLoading = false
}) })
} }
let resizeKey = $ref(0) // let resizeKey = $ref(0)
function handleResize() { function handleResize() {
resizeKey = Date.now() resizeKey = Date.now()
} }
......
{
"extends": "@vue/tsconfig/tsconfig.dom.json",
"include": ["auto-imports.d.ts", "env.d.ts", "src/**/*", "src/**/*.vue"],
"compilerOptions": {
"composite": true,
"tsBuildInfoFile": "./node_modules/.tmp/tsconfig.app.tsbuildinfo",
"allowJs": true,
"baseUrl": ".",
"paths": {
"@/*": ["./src/*"]
},
"types": ["element-plus/global", "@vue-macros/reactivity-transform/macros-global"]
}
}
{ {
"extends": "@vue/tsconfig/tsconfig.json", "files": [],
"include": ["auto-imports.d.ts", "env.d.ts", "src/**/*", "src/**/*.vue"],
"compilerOptions": {
"allowJs": true,
"baseUrl": ".",
"paths": {
"@/*": ["./src/*"]
},
"types": ["element-plus/global", "@vue-macros/reactivity-transform/macros-global"]
},
"references": [ "references": [
{ {
"path": "./tsconfig.config.json" "path": "./tsconfig.node.json"
},
{
"path": "./tsconfig.app.json"
} }
] ]
} }
...@@ -3,6 +3,11 @@ ...@@ -3,6 +3,11 @@
"include": ["vite.config.*", "vitest.config.*", "cypress.config.*", "playwright.config.*"], "include": ["vite.config.*", "vitest.config.*", "cypress.config.*", "playwright.config.*"],
"compilerOptions": { "compilerOptions": {
"composite": true, "composite": true,
"noEmit": true,
"tsBuildInfoFile": "./node_modules/.tmp/tsconfig.node.tsbuildinfo",
"module": "ESNext",
"moduleResolution": "Bundler",
"types": ["node"] "types": ["node"]
} }
} }
...@@ -4,7 +4,7 @@ import { fileURLToPath, URL } from 'node:url' ...@@ -4,7 +4,7 @@ import { fileURLToPath, URL } from 'node:url'
import { defineConfig } from 'vite' import { defineConfig } from 'vite'
import vue from '@vitejs/plugin-vue' import vue from '@vitejs/plugin-vue'
// import checker from 'vite-plugin-checker' import checker from 'vite-plugin-checker'
import AutoImport from 'unplugin-auto-import/vite' import AutoImport from 'unplugin-auto-import/vite'
import ReactivityTransform from '@vue-macros/reactivity-transform/vite' import ReactivityTransform from '@vue-macros/reactivity-transform/vite'
import mkcert from 'vite-plugin-mkcert' import mkcert from 'vite-plugin-mkcert'
...@@ -12,15 +12,15 @@ import mkcert from 'vite-plugin-mkcert' ...@@ -12,15 +12,15 @@ import mkcert from 'vite-plugin-mkcert'
export default defineConfig(({ mode }) => ({ export default defineConfig(({ mode }) => ({
base: mode === 'prod' ? 'https://webapp-pub.ezijing.com/website/prod/saas-lab/' : '/', base: mode === 'prod' ? 'https://webapp-pub.ezijing.com/website/prod/saas-lab/' : '/',
plugins: [ plugins: [
mkcert(),
vue(), vue(),
AutoImport({ AutoImport({
imports: ['vue', 'vue-router', '@vueuse/core', '@vueuse/math'], imports: ['vue', 'vue-router', '@vueuse/core', '@vueuse/math'],
dts: true, dts: true,
eslintrc: { enabled: true } eslintrc: { enabled: true },
}), }),
ReactivityTransform(), ReactivityTransform(),
mkcert() checker({ vueTsc: true, eslint: { useFlatConfig: true, lintCommand: 'eslint "./src/**/*.{vue,js,jsx,ts,tsx}"' } }),
// checker({ vueTsc: true, eslint: { lintCommand: 'eslint "./src/**/*.{vue,js,jsx,ts,tsx}"' } })
], ],
server: { server: {
open: true, open: true,
...@@ -30,7 +30,7 @@ export default defineConfig(({ mode }) => ({ ...@@ -30,7 +30,7 @@ export default defineConfig(({ mode }) => ({
// cert: fs.readFileSync(path.join(__dirname, './https/ezijing.com.pem')) // cert: fs.readFileSync(path.join(__dirname, './https/ezijing.com.pem'))
// }, // },
proxy: { proxy: {
'/api': 'https://saas-lab.ezijing.com' '/api': 'https://saas-lab.ezijing.com',
// '/api/resource': { // '/api/resource': {
// target: 'http://com-resource-admin-test.ezijing.com', // target: 'http://com-resource-admin-test.ezijing.com',
// changeOrigin: true, // changeOrigin: true,
...@@ -41,11 +41,11 @@ export default defineConfig(({ mode }) => ({ ...@@ -41,11 +41,11 @@ export default defineConfig(({ mode }) => ({
// changeOrigin: true, // changeOrigin: true,
// rewrite: path => path.replace(/^\/api\/lab/, '') // rewrite: path => path.replace(/^\/api\/lab/, '')
// } // }
} },
}, },
resolve: { resolve: {
alias: { alias: {
'@': fileURLToPath(new URL('./src', import.meta.url)) '@': fileURLToPath(new URL('./src', import.meta.url)),
} },
} },
})) }))
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论