提交 0555bcbc authored 作者: 王鹏飞's avatar 王鹏飞

chore: 适配移动端

上级 01d76ad6
-----BEGIN RSA PRIVATE KEY-----
MIIEpAIBAAKCAQEAucCbdPPyAp6vmnr5XObuPsctUhVLyXwqbIpgI5jWzjG7wmk8
V6z8WJKPO9KZM6D9ejtN/bbbd3j1cRiw7NSl8AUykiVHJWz9TXAflET2EpILLera
I1B2XAcBsc8dZBGGJD/LT97ZvNLYzuQOr7R1wytWH1uisAK5ClzgnSptMenXFyhw
5Xw0Lm3zoeeqYF/KMQ1McAYMGxgu6s6dxXKiA0BcgWQ31yZey0c4HhCt7T7sA/UN
ahUsxtCcSNSvdgXay5Pu/l3N88TwW2QzaCzrueILHWRFwkREhpqyrwjN3gkaa+1T
jLxzCsk/pTnPccxlFwc3YQ3hYLMl36NJ/OIpHwIDAQABAoIBACuMmaXYz6OHmroI
HNCIH9E+F0UIUyVg4/1gj9uoqKvdAx04WPphRyRo8AXhgSOWmfb/UnCqX1fqVvj2
BfzwehsEzO9wp/aBT/3IzM6RQHPoI5DXX98prSY0SlRqr4RXi3CSOFN4duoLMOOI
mlzdXUKttVpSvJixerqQPeT7HnC18NBKOydFMYPdXsgWcMXvu2BuvRClIzsjlXKM
VP00BNRY3Oje6T9yl8N051jIZh48YD3yyEAVFKPOWaJVzUU/RRPOOdTb2Y3A1bek
IbCdurdzoEQoJxkeTuColnuL1jj2mpxIBskKYhPAMV5arYS0pZ0VAtjoGGCyn7gT
l/bkTVkCgYEA6EB15hzRD2iTTIFMtDBqw0l3vJWcuWPvwFZl6zculO8Cdsvx0cDZ
VbEXByA0+CG3q47/UrVqETRhtyuVnxuKrceKU8/zib1dvvTMNjeYLKosjyG49xO6
gDx7nVBwYHmQN/iEuWTobLg1vtSNyd99WgG4cFHvqF7kIJb2W0IaGrsCgYEAzL70
VHn9BUP3CGecoU8Fnck9/7GWhvGgFU58Q/dU3Jr8g6lroeDas9zQU2tCnJN0e7cr
13thq2kQQHTYCY4J6EUtjO89sNVx4bO83xqQhobZBwZXkE5QDWIKCbiYGRLAb1+f
AAEwIEdPBgM88YFHOU5YbPTYH8TLkJfxyvMonu0CgYEArGWE3n3PdVeT1zs3O52g
8jrrpVGNF1QmWCgJ2VKJwkW0F4iFhMRYzzH3vPNcPj+Q/cjUn4lIJWMzkWrJ0mP4
ScyPUm1PApRNLPy7RRd5XtYm40wN52F+k8fRnlFiSUqTEejoZFGR8Xm/c1qFsS6y
9ofGZ6F6ewmM3uAQGGd1xxcCgYBFhjoVTW8bkJ6b3gMTy2+Oyr0gzD7fB8FiOsp7
kcrhNke0tZz01ROuq7aZ/Pwbiv6s2+ApRZ4+xGheWs7ZP8AhfQwgpUR/fZs0FwJ1
h+G3rKaZeg/V0qHgSYA7GNGdAf8SUpf9OmoLK+urkQHqyAlVbkMcjG+vKfYt3Uqf
rb4HaQKBgQCxm1oz9QrmxWKJ4eYKHSsD9UPu4QZhltBECH1btgvTwAEmwuXaCcta
RaFNhMe609sQ+YVIxa9fK0MXBiq7DG6nSLGvnLfVEYo4nGe6EvL9nQ7IFZywJjTb
/Fw4rTMwT59VSWJdv8BPznV7Gk7p17fcXM55iJxxu65r3ZuOXjQSGA==
-----END RSA PRIVATE KEY-----
\ No newline at end of file
MIIEpQIBAAKCAQEAwZGHX8Zg+EP5uwnEBWkQazq8DMnKz3QfcNRUjFsxsZjM/98r
oYYp+K6/i/b8JXAVMqjC9+X/ZajgbDPLTrgDJ4TQ70ajdusqG3swNqG0qLUogNgU
PcgVRKr2Pk+m79GD/nnxFgeaG6eBfLsb73G2cQUwsgi3bjf6mX6b9bjxjqzwX0PW
es27yyqdS9uQFzV5KLTA2FJJjGGbg54ZLxVc01aVXx2gG0eLnOFcDSmgXUN4hBmN
gYF4FYHhOVXdMl2+yGGp6IvtIIrt+cp2/TQePnxB2QYwrlDMajHrKp0x7LsqWwZT
jepPgGWWDssiSgTCYVaPx28ESbotpzR7D+LlHQIDAQABAoIBAQCCvXGrHcmXRgph
62mrodgGJQioto82aZ9mzPNCTcIVyzgDRtAoa/7jSdx0g+CwxLB8pAH0ADPtjQ/v
5VfXlnAC/DFGu/Zittmc8CqTa8si/CEcTVX2mLLMy5BAa/o8Fs5JTkGo+H99WDkc
byCiLLLmSXQne72xQzwO+rYKVN1K2JUfzch5wpv86IgfJm0gNEOOvtToeNeMbOWj
7AFfpqq7bRMIdZZZhm2n33duSCSnAO7/OuKHY2/RUkc6FvamAth/ME5S2eHrB7yb
KOMZTJH73xnZc3gmsBiIfC1BsqzV/37Ptd7ncTxuK5YZPXIyJ/BjnDTe712LAz+r
f3FEmtJdAoGBAOdPpbT1ylZKinxEIP4sUPUUrrlXqQxYn2xTOCSBz1dB7OpeqiD+
OBa6ur5Sh0+Ot/VRqV2MbXaGee/qqBiziFH23wKoFc6kxeH8RCv247y89yOHqpCP
SM4I7d10RpPh/POU0apGNOP4HOLOMY4V11u68em9hQDeN6oUBWKvDWTPAoGBANY6
mZ/EWKOFJSPfJNNtfXDO27P12ENsa9UvDv7f+FrcPqGkJq1qFBr3ySBjUE7hTv1e
jedRHtBg5Y038vj/MTofEPSaa5POFgzwfG5TPYCcrZkDoLosnuQ92yafMxZPAf16
Nt3vimpxV2Hwf1Nl3IAU/BavngdohWJkO+yOuupTAoGBAMxkTrJmdhJl75T6xoSS
OD83tWTFFvV34fdgWb24jrQ15tj6KS7aNEmxWo4Ocs5T+C1nqVamXZtcHKdpHHwn
OA/lKw435H0ikFCuDrcig/4ko+TbXlY6pkSZE0aaFjtad5/tIo9pVhcTCMNJG/TH
S/Mcb+LwunQX5+v7oP6gXB91AoGAFDbjWBgG5ScjIgdkSi8CrypVwN1p0rLgWfVe
zN4FaU1u+4GpxKNF0mWfLNcyNL893NqXOUSGS9NY1cJ5wtURqBJWXz5S+Fdx7Tak
ByUDoKcoGlAlUmvzckYD79kF0Q0Tev+VPcvkm7amMC+pVA1AiTVxtBJOLxTFwUsD
/IZbTNECgYEA5uwkBWpb/2yYk86cfuUWJjZ0k8jZPrdG4d9gTdD1Fj4abS3FniKM
x9eN8BcnH0j4raRo+MESzYf5hLbfHRG01oRtBQFZXEM0k/zkkRYdKWG1Ulg1+iZR
ZG/lblczYEUW/IOPYZKMX8c5nq7F6huLsioIvsYOdCGjLZbyRHjEPv8=
-----END RSA PRIVATE KEY-----
-----BEGIN CERTIFICATE-----
MIIGtjCCBZ6gAwIBAgIQDjUArTRdZ4P5wtQVmCqJGjANBgkqhkiG9w0BAQsFADBj
MIIGtDCCBZygAwIBAgIQJtN62MbxMBaLhLadTXD/LzANBgkqhkiG9w0BAQsFADBj
MQswCQYDVQQGEwJDTjE2MDQGA1UECgwtQmVpamluZyBYaW5jaGFjaGEgQ3JlZGl0
IE1hbmFnZW1lbnQgQ28uLCBMdGQuMRwwGgYDVQQDDBNYY2MgVHJ1c3QgT1YgU1NM
IENBMB4XDTIyMDgxODE0MDAzMVoXDTIzMDkxNzE0MDAzMFowgY4xCzAJBgNVBAYT
IENBMB4XDTIzMDkwNzA1NTM0MVoXDTI0MDkwNjA1NTM0MFowgY4xCzAJBgNVBAYT
AkNOMRIwEAYDVQQIDAnljJfkuqzluIIxEjAQBgNVBAcMCeWMl+S6rOW4gjE/MD0G
A1UECgw25riF5o6n57Sr6I2G77yI5YyX5Lqs77yJ5pWZ6IKy56eR5oqA6IKh5Lu9
5pyJ6ZmQ5YWs5Y+4MRYwFAYDVQQDDA0qLmV6aWppbmcuY29tMIIBIjANBgkqhkiG
9w0BAQEFAAOCAQ8AMIIBCgKCAQEAucCbdPPyAp6vmnr5XObuPsctUhVLyXwqbIpg
I5jWzjG7wmk8V6z8WJKPO9KZM6D9ejtN/bbbd3j1cRiw7NSl8AUykiVHJWz9TXAf
lET2EpILLeraI1B2XAcBsc8dZBGGJD/LT97ZvNLYzuQOr7R1wytWH1uisAK5Clzg
nSptMenXFyhw5Xw0Lm3zoeeqYF/KMQ1McAYMGxgu6s6dxXKiA0BcgWQ31yZey0c4
HhCt7T7sA/UNahUsxtCcSNSvdgXay5Pu/l3N88TwW2QzaCzrueILHWRFwkREhpqy
rwjN3gkaa+1TjLxzCsk/pTnPccxlFwc3YQ3hYLMl36NJ/OIpHwIDAQABo4IDODCC
AzQwDAYDVR0TAQH/BAIwADBDBgNVHR8EPDA6MDigNqA0hjJodHRwOi8veGluY2hh
9w0BAQEFAAOCAQ8AMIIBCgKCAQEAwZGHX8Zg+EP5uwnEBWkQazq8DMnKz3QfcNRU
jFsxsZjM/98roYYp+K6/i/b8JXAVMqjC9+X/ZajgbDPLTrgDJ4TQ70ajdusqG3sw
NqG0qLUogNgUPcgVRKr2Pk+m79GD/nnxFgeaG6eBfLsb73G2cQUwsgi3bjf6mX6b
9bjxjqzwX0PWes27yyqdS9uQFzV5KLTA2FJJjGGbg54ZLxVc01aVXx2gG0eLnOFc
DSmgXUN4hBmNgYF4FYHhOVXdMl2+yGGp6IvtIIrt+cp2/TQePnxB2QYwrlDMajHr
Kp0x7LsqWwZTjepPgGWWDssiSgTCYVaPx28ESbotpzR7D+LlHQIDAQABo4IDNjCC
AzIwDAYDVR0TAQH/BAIwADBDBgNVHR8EPDA6MDigNqA0hjJodHRwOi8veGluY2hh
Y2hhMm92LmNybC5jZXJ0dW0ucGwveGluY2hhY2hhMm92LmNybDB5BggrBgEFBQcB
AQRtMGswLwYIKwYBBQUHMAGGI2h0dHA6Ly94aW5jaGFjaGEyb3Yub2NzcC1jZXJ0
dW0uY29tMDgGCCsGAQUFBzAChixodHRwOi8vcmVwb3NpdG9yeS5jZXJ0dW0ucGwv
eGluY2hhY2hhMm92LmNlcjAfBgNVHSMEGDAWgBT6oMvCx12BtSCSByALtjtwOwkO
VTAdBgNVHQ4EFgQUEJufsd5nLNR+wqR2GsFWDn7qTn0wTAYDVR0gBEUwQzAIBgZn
VTAdBgNVHQ4EFgQUXm2TAFqEePvMkmcMN+bVXSvLTH8wTAYDVR0gBEUwQzAIBgZn
gQwBAgIwNwYMKoRoAYb2dwIFARYCMCcwJQYIKwYBBQUHAgEWGWh0dHBzOi8vd3d3
LmNlcnR1bS5wbC9DUFMwHQYDVR0lBBYwFAYIKwYBBQUHAwEGCCsGAQUFBwMCMA4G
A1UdDwEB/wQEAwIFoDAlBgNVHREEHjAcgg0qLmV6aWppbmcuY29tggtlemlqaW5n
LmNvbTCCAX4GCisGAQQB1nkCBAIEggFuBIIBagFoAHYAVYHUwhaQNgFK6gubVzxT
8MDkOHhwJQgXL6OqHQcT0wwAAAGCsUFwdgAABAMARzBFAiAc51lynft4sehXTgyw
tjQ83PAVmfZ3FC55eIpIETe2hgIhANvo5ZtGQpcZQ5HSGbRLy4Y9/MbUrS8dtkwP
l7I/lRj7AHYArfe++nz/EMiLnT2cHj4YarRnKV3PsQwkyoWGNOvcgooAAAGCsUFw
TwAABAMARzBFAiATnQDMw1wykBdnTIRfSSXPj7HZfDdRRq6VaiTbSpYKYQIhAMTp
V6K0W9gtdYGdeg4j6n17S1yMODYvLJxd3kAFFNDTAHYAejKMVNi3LbYg6jjgUh7p
hBZwMhOFTTvSK8E6V6NS61IAAAGCsUFwrQAABAMARzBFAiEAwWKXKxp6DcKG7R/d
rxmPUg8uNbUcdxysrpB3gOzkIlACICWpx7/+2ulDG2EC9m4RqGcXbts3VWu/yxpE
0pAYuAP8MA0GCSqGSIb3DQEBCwUAA4IBAQCf3AdKLO8EUntMjKaRa0lncwh/pBIQ
bcQfkJBfiTpo6tnRphR+DE50oYOX1TSQRm4cDgP2JURYiTK6Z2+ljqMbUx4mNLqe
+6yG+PGCUX6rX4BsJqlRP2W7WONE/I3/3S6MRfclKmakHSyrGFi8O/JJyNqm+5z9
8tnk8c1Cn7FboJZonhX0yszHkXLLeA93xm5+Etkw0+DvRcZGiEqKQivO3CnUh1gs
LZg27a8s3dtmAAHbb2icm5jloK9Jgpx/NkGL/cCoNZ8Ng2TZkRvo6GzIp43uS332
R07dQ6rNWZkPzdxKUdNcT0v3yJJyxD1H3Rk4/bxp78giw4JGHp52Df+U
LmNvbTCCAXwGCisGAQQB1nkCBAIEggFsBIIBaAFmAHUA7s3QZNXbGs7FXLedtM0T
ojKHRny87N7DUUhZRnEftZsAAAGKbjQU6wAABAMARjBEAiAMbEi/VFFT/mgWiXPw
WgVT5THVJCfr9j1oIcfiB5MFHgIgJ2nAv7xTmfoZfcO8sWoGigLdN8QtGksVUSI2
86Wg3O4AdgDatr9rP7W2Ip+bwrtca+hwkXFsu1GEhTS9pD0wSNf7qwAAAYpuNBUS
AAAEAwBHMEUCIDmQ1/B1s3jRr+0SvDSWEFN9/b4/W8QV5yULASXqQkYqAiEA0wKZ
lklUASXMM8mluAimD5e4qSXu76+148bfZA2d404AdQBIsONr2qZHNA/lagL6nTDr
HFIBy1bdLIHZu7+rOdiEcwAAAYpuNBefAAAEAwBGMEQCICyokQlEyxPTPYNBZzwv
W8AxbKUJl+I5TbJEJsiFECRUAiA8fA86Hof/yLHhMl4amx5AttDNhpDrCHDK1N7m
NYx9XjANBgkqhkiG9w0BAQsFAAOCAQEAq4Q2vW3Xh5TOYk/DofnV2uRiK08P5a5I
NRE5Tet3J5rp2WnNgXoSAOabqWGI6VrTyenTZxrmS/2Aq2A008WOj4Z7T3P9iDS/
MgJkPmc/REqHr15LIDnyRRfmn9+1ShVMwukYHSmZgPewAzSkKdGFN85t3uCEUnXz
kna3ZmSqgJrSWSO9n/3t/kICsVivjqSUuHtnCSbBa+DTSNxIkbkr1t1RJkF4KvSk
AKkvyojoKoeCd+WWEl2MBHY6TK4CzfyLN5qhQub0XqTOh6cG9TwALcLZ4MQeaeOO
ZkGv9DcyeOz7FwwzFa+vAyzhq2XlDPLlpZ4ELALbaqnq3x7HHpzlpw==
-----END CERTIFICATE-----
-----BEGIN CERTIFICATE-----
MIIEzzCCA7egAwIBAgIRAPJECC2rqQ2ljHLp8pqTQK4wDQYJKoZIhvcNAQELBQAw
......@@ -111,3 +111,4 @@ CjqTE5s7FCMTY5w/0YcneeVMUeMBrYVdGjux1XMQpNPyvG5k9VpWkKjHDkx0Dy5x
O/fIR/RpbxXyEV6DHpx8Uq79AtoSqFlnGNu8cN2bsWntgM6JQEhqDjXKKWYVIZQs
6GAqm4VKQPNriiTsBhYscw==
-----END CERTIFICATE-----
<script setup lang="ts">
import { useDevice } from '@/composables/useDevice'
const { mobile } = useDevice()
</script>
<template>
<RouterView />
<router-view :class="{ 'is-h5': mobile, 'is-pc': !mobile }" />
</template>
<style>
......
......@@ -67,7 +67,7 @@ button,
select,
textarea {
-webkit-tap-highlight-color: rgba(0, 0, 0, 0);
-webkit-appearance: none;
appearance: none;
border: 0;
border-radius: 0;
font: inherit;
......@@ -81,9 +81,8 @@ textarea:focus {
}
.el-tabs__item {
--el-font-size-base: 16px;
--el-font-size-base: .16rem;
padding: 0 20px !important;
min-width: 60px;
font-weight: 400;
text-align: center;
}
......@@ -98,6 +97,53 @@ textarea:focus {
height: 1px !important;
}
.is-h5 .el-tabs__item {
--el-font-size-base: 14px;
padding: 0 5px !important;
}
.is-h5 .el-tabs__active-bar {
padding: 0 5px;
margin-left: -5px;
}
body {
font-size: 14px;
}
html {
font-size: 100px;
}
@media (max-width: 767.98px) {
html {
font-size: 75px;
}
}
/*
@media (min-width: 768px) {
html {
font-size: 100px;
}
}
@media (min-width: 1920px) {
html {
font-size: 5.20833333vw;
}
}
.hidden {
display: none !important;
}
@media (max-width: 1023.5px) {
.hide_xs_sm {
display: none !important;
}
}
@media (max-width: 767.5px) {
.hide_xs {
display: none !important;
}
} */
......@@ -135,20 +135,9 @@ defineExpose({ refetch, tableRef })
</template>
<template v-else>
<!-- input -->
<el-input
v-model="params[item.prop]"
v-bind="item"
clearable
@change="search"
style="width: 200px"
v-if="item.type === 'input'" />
<el-input v-model="params[item.prop]" v-bind="item" clearable @change="search" style="width: 200px" v-if="item.type === 'input'" />
<!-- select -->
<el-select
v-model="params[item.prop]"
v-bind="item"
filterable
@change="search"
v-if="item.type === 'select'">
<el-select v-model="params[item.prop]" v-bind="item" filterable @change="search" v-if="item.type === 'select'">
<el-option
:label="option[item.labelKey] || option.label"
:value="option[item.valueKey] || option.value"
......@@ -171,13 +160,7 @@ defineExpose({ refetch, tableRef })
<!-- 主体 -->
<div class="table-list-bd">
<slot name="body" v-bind="{ data: dataList }">
<el-table
stripe
:header-cell-style="{ background: '#ededed' }"
:data="dataList"
v-loading="loading"
v-bind="$attrs"
ref="tableRef">
<el-table stripe :header-cell-style="{ background: '#ededed' }" :data="dataList" v-loading="loading" v-bind="$attrs" ref="tableRef">
<el-table-column align="center" v-bind="item || {}" v-for="item in columns" :key="item.prop">
<template #default="scope" v-if="item.slots || item.computed">
<slot :name="item.slots" v-bind="scope" v-if="item.slots"></slot>
......@@ -255,4 +238,11 @@ defineExpose({ refetch, tableRef })
margin: -8px -15px;
padding: 8px 15px;
}
.is-h5 {
.el-pagination__total,
.el-pagination__sizes,
.el-pagination__jump {
display: none !important;
}
}
</style>
......@@ -47,21 +47,13 @@ function handleClick(path: string) {
<template #title>
<el-icon><component :is="item.icon"></component></el-icon>{{ item.name }}
</template>
<el-menu-item
:index="subitem.path"
v-for="subitem in item.children"
:key="subitem.path"
@click="handleClick(subitem.path)"
>
<el-menu-item :index="subitem.path" v-for="subitem in item.children" :key="subitem.path" @click="handleClick(subitem.path)">
{{ subitem.name }}
</el-menu-item>
</el-sub-menu>
<el-menu-item :index="item.path" @click="handleClick(item.path)" v-else>
<el-icon>
<img
:src="item.iconImg"
v-if="item.path.slice(1, item.path.length) !== route.path.slice(1, route.path.length).split('/')[0]"
/>
<img :src="item.iconImg" v-if="item.path.slice(1, item.path.length) !== route.path.slice(1, route.path.length).split('/')[0]" />
<img :src="item.iconActiveImg" v-else /> </el-icon
>{{ item.name }}
</el-menu-item>
......@@ -118,4 +110,9 @@ function handleClick(path: string) {
}
}
}
.is-h5 {
.app-aside {
display: none;
}
}
</style>
......@@ -19,7 +19,12 @@ const logout = async () => {
<div class="logo">
<router-link to="/"><img src="https://zws-imgs-pub.ezijing.com/pc/base/ezijing-logo.svg" /></router-link>
</div>
<h1 class="app-name">产业学院</h1>
<h1 class="app-name">数字技能实训中心</h1>
</div>
<div class="app-header-center">
<a href="/" class="is-active">理论课程</a>
<a href="https://saas-lab.ezijing.com" target="_blank">商业数据分析</a>
<a href="https://saas-dml-web.ezijing.com" target="_blank">数字营销</a>
</div>
<div class="app-header-right">
<el-dropdown v-if="userInfo">
......@@ -60,23 +65,34 @@ const logout = async () => {
background-color: #fff;
border-bottom: 1px solid #e6e6e6;
.logo {
width: 120px;
width: 1.2rem;
}
}
.app-header-left {
display: flex;
align-items: center;
.app-name {
margin-left: 20px;
padding: 0 18px;
font-size: 24px;
margin-left: 0.2rem;
padding: 0 0.18rem;
font-size: 0.24rem;
font-weight: 400;
line-height: 1;
color: #333;
border-left: 1px solid #707070;
}
}
.app-header-center {
flex: 1;
margin: 0 10px;
a {
font-size: 20px;
color: #333333;
margin-left: 90px;
&.is-active {
color: var(--main-color);
}
}
}
.app-header-right {
display: flex;
......@@ -138,4 +154,9 @@ const logout = async () => {
.app-header-user-buttons {
padding-top: 16px;
}
.is-h5 {
.app-header-center {
display: none;
}
}
</style>
......@@ -14,7 +14,7 @@ export default { name: 'AppMain' }
.app-main {
position: relative;
flex: 1;
margin: 20px;
margin: 0.2rem;
overflow: hidden;
}
.app-main-inner {
......
export function useDevice() {
const navigator = window.navigator
const userAgent = ref(navigator.userAgent)
const mobile = computed(() => {
return /iphone/i.test(userAgent.value) || (/android/i.test(userAgent.value) && /mobile/i.test(userAgent.value))
})
const wechat = computed(() => {
return /micromessenger/i.test(userAgent.value)
})
const alipay = computed(() => {
return /alipayclient/i.test(userAgent.value)
})
addEventListener('resize', () => {
if (navigator) userAgent.value = navigator.userAgent
})
return { userAgent, mobile, wechat, alipay }
}
......@@ -100,13 +100,7 @@ function handleSubmit() {
<p class="discuss-item-form__title">回复本楼</p>
<el-form ref="formRef" :model="form" :rules="rules" hide-required-asterisk>
<el-form-item prop="content">
<el-input
type="textarea"
show-word-limit
:autosize="{ minRows: 6, maxRows: 6 }"
:maxlength="100"
v-model="form.content"
ref="inputRef" />
<el-input type="textarea" show-word-limit :autosize="{ minRows: 6, maxRows: 6 }" :maxlength="100" v-model="form.content" ref="inputRef" />
</el-form-item>
<el-row justify="end">
<el-button round type="primary" @click="handleSubmit">发表回复</el-button>
......@@ -125,8 +119,8 @@ function handleSubmit() {
}
.discuss-item__left {
position: relative;
width: 240px;
padding: 40px;
width: 2.4rem;
padding: 0.4rem;
text-align: center;
background-color: #f9f9fc;
box-sizing: border-box;
......@@ -135,8 +129,8 @@ function handleSubmit() {
position: absolute;
left: 0;
top: 0;
width: 60px;
height: 60px;
width: 0.6rem;
height: 0.6rem;
color: #fff;
background-color: var(--main-color);
z-index: 2000;
......@@ -158,8 +152,8 @@ function handleSubmit() {
padding: 5px 10px;
}
.discuss-item__avatar {
width: 100px;
height: 100px;
width: 1rem;
height: 1rem;
margin: 0 auto;
img {
width: 100%;
......@@ -175,7 +169,7 @@ function handleSubmit() {
}
.discuss-item__level {
img {
width: 40px;
width: 0.4rem;
}
p {
font-size: 10px;
......@@ -233,4 +227,20 @@ function handleSubmit() {
color: #333;
line-height: 40px;
}
.is-h5 {
.discuss-item__left {
width: 80px;
padding: 40px 20px;
}
.discuss-item__avatar {
width: 40px;
height: 40px;
}
.discuss-item__right {
padding: 10px;
.discuss-item__comment {
margin-right: 0;
}
}
}
</style>
......@@ -28,11 +28,7 @@ function handleClick(data: TopPostItem, event: Event) {
<template>
<section class="pined-post" v-if="list.length">
<section class="pined-post-item" v-for="item in list" :key="item.id">
<router-link
:to="`/bbs/${item.id}`"
target="_blank"
class="pined-post-item__inner"
@click="handleClick(item, $event)">
<router-link :to="`/bbs/${item.id}`" target="_blank" class="pined-post-item__inner" @click="handleClick(item, $event)">
<p class="t1">置顶</p>
<p class="t2">{{ item.title }}</p>
<p class="t3" v-if="!courseId">
......@@ -53,7 +49,7 @@ function handleClick(data: TopPostItem, event: Event) {
align-items: center;
}
.pined-post-item {
padding: 14px 0;
padding: 0.14rem 0;
&:hover {
.t2 {
color: var(--main-color);
......@@ -98,4 +94,12 @@ function handleClick(data: TopPostItem, event: Event) {
text-align: right;
}
}
.is-h5 {
.pined-post-item {
.t4 {
display: none;
}
}
}
</style>
......@@ -153,4 +153,13 @@ function handleBack() {
}
}
}
.is-h5 {
.el-backtop {
width: 40px;
height: 40px;
.t1 {
font-size: 12px;
}
}
}
</style>
......@@ -157,20 +157,13 @@ function genSubmitQuestion(questionList: PaperQuestionType[]) {
<div class="course-exam-card-bd">
<div class="course-exam-left">
<div class="course-exam-scroll">
<CourseExamQuestion
:question="currentQuestion"
:status="status"
:index="questionIndex + 1"
v-if="questionLength"
>
<CourseExamQuestion :question="currentQuestion" :status="status" :index="questionIndex + 1" v-if="questionLength">
<template #index>{{ questionIndex + 1 }}/{{ questionLength }}</template>
</CourseExamQuestion>
</div>
<div class="course-exam-buttons">
<el-button size="large" :disabled="questionIndex === 0" @click="handlePrev">上一题</el-button>
<el-button size="large" :disabled="questionIndex >= questionLength - 1" @click="handleNext">
下一题
</el-button>
<el-button size="large" :disabled="questionIndex >= questionLength - 1" @click="handleNext"> 下一题 </el-button>
</div>
</div>
<div class="course-exam-right">
......@@ -178,14 +171,7 @@ function genSubmitQuestion(questionList: PaperQuestionType[]) {
<CourseExamQuestionNumbers :index="questionIndex" :status="status" />
</div>
<div class="course-exam-buttons">
<el-button
size="large"
type="primary"
auto-insert-space
:disabled="disabled"
@click="handleSubmit"
style="width: 100%"
>
<el-button size="large" type="primary" auto-insert-space :disabled="disabled" @click="handleSubmit" style="width: 100%">
{{ submitButtonText }}
</el-button>
</div>
......@@ -207,17 +193,17 @@ function genSubmitQuestion(questionList: PaperQuestionType[]) {
}
.course-exam-card-hd {
border-bottom: 1px solid #ccc;
height: 80px;
height: 0.8rem;
background: #ffffff;
display: flex;
align-items: center;
padding-left: 40px;
padding-left: 0.4rem;
.title {
padding-left: 20px;
font-size: 24px;
padding-left: 0.2rem;
font-size: 0.24rem;
font-weight: bold;
color: #222222;
line-height: 80px;
line-height: 0.8rem;
}
.right {
width: 260px;
......@@ -242,10 +228,10 @@ function genSubmitQuestion(questionList: PaperQuestionType[]) {
display: flex;
flex-direction: column;
.course-exam-scroll {
padding: 0 40px;
padding: 0 0.4rem;
}
.course-exam-buttons {
padding: 20px 40px;
padding: 0.2rem 0.4rem;
border-top: 1px solid #ccc;
}
}
......@@ -256,7 +242,7 @@ function genSubmitQuestion(questionList: PaperQuestionType[]) {
position: relative;
width: 220px;
background: #fff;
padding: 0 20px;
padding: 0 0.2rem;
}
.course-exam-scroll {
flex: 1;
......@@ -264,6 +250,11 @@ function genSubmitQuestion(questionList: PaperQuestionType[]) {
overflow-y: auto;
}
.course-exam-buttons {
padding: 20px 0;
padding: 0.2rem 0;
}
.is-h5 {
.course-exam-right {
width: 80px;
}
}
</style>
......@@ -101,8 +101,7 @@ const checkboxValues = computed({
:disabled="disabled"
:maxlength="500"
:show-word-limit="true"
v-model="value"
></el-input>
v-model="value"></el-input>
</template>
</div>
<div class="question-item-ft" v-if="status === 3">
......@@ -133,53 +132,53 @@ const checkboxValues = computed({
<style lang="scss" scoped>
.question-item {
margin-bottom: 40px;
margin-bottom: 0.4rem;
}
.question-item-hd {
display: flex;
}
.question-item-hd__num {
font-size: 32px;
font-size: 0.32rem;
font-weight: bold;
color: #222;
line-height: 45px;
line-height: 0.45rem;
margin-top: 5px;
}
.question-item-hd__title {
margin-left: 5px;
padding-top: 18px;
font-size: 18px;
padding-top: 0.18rem;
font-size: 0.18rem;
font-weight: bold;
color: #222;
line-height: 25px;
line-height: 0.25rem;
}
.question-option-item {
margin-top: 20px;
margin-top: 0.2rem;
width: 100%;
}
.question-option-item__text {
display: inline-block;
font-size: 18px;
font-size: 0.18rem;
color: #222;
white-space: normal;
}
.question-item-ft {
margin-top: 20px;
margin-top: 0.2rem;
}
.question-item-ft__title {
font-size: 18px;
font-size: 0.18rem;
font-weight: bold;
color: #222;
line-height: 25px;
line-height: 0.25rem;
}
.answer-item {
margin-top: 10px;
margin-left: 28px;
margin-top: 0.1rem;
margin-left: 0.28rem;
display: flex;
font-size: 18px;
font-size: 0.18rem;
color: #222;
line-height: 25px;
line-height: 0.25rem;
}
.answer-item-label {
white-space: nowrap;
......
......@@ -56,13 +56,7 @@ function handleClick(index: number) {
<!-- <div v-for="item in dataList" :key="item.question_item_id">
<div class="tit">{{ item.title }}</div> -->
<ul>
<li
v-for="(item, index) in questionList"
class="question-num-item"
:class="genClass(item, index)"
:key="index"
@click="handleClick(index)"
>
<li v-for="(item, index) in questionList" class="question-num-item" :class="genClass(item, index)" :key="index" @click="handleClick(index)">
{{ index + 1 }}
</li>
</ul>
......@@ -169,4 +163,12 @@ function handleClick(index: number) {
background: #c01540;
border-radius: 50%;
}
.is-h5 {
.question-num {
ul {
grid-template-columns: repeat(2, 1fr);
}
}
}
</style>
......@@ -52,13 +52,7 @@ function handleClick(index: number) {
<!-- <div v-for="item in dataList" :key="item.question_item_id">
<div class="tit">{{ item.title }}</div> -->
<ul>
<li
v-for="(item, index) in questionList"
class="question-num-item"
:class="genClass(item)"
:key="index"
@click="handleClick(index)"
>
<li v-for="(item, index) in questionList" class="question-num-item" :class="genClass(item)" :key="index" @click="handleClick(index)">
{{ index + 1 }}
</li>
</ul>
......@@ -161,4 +155,12 @@ function handleClick(index: number) {
.is-info.is-success {
color: #fff;
}
.is-h5 {
.question-num {
ul {
grid-template-columns: repeat(8, 1fr);
}
}
}
</style>
......@@ -32,9 +32,9 @@ const isActive = computed(() => props.data.course_id === courseId)
const targetUrlQuery = computed(() => {
let queryString = `course_id=${props.data.course_id}&semester_id=${props.data.semester_id}`
if (props.data.section && props.data.section?.watch_video_length) {
queryString += `&chapter_id=${props.data.section?.chapter_id ?? ''}&section_id=${
props.data.section?.section_id ?? ''
}&resource_id=${props.data.section?.resource_id ?? ''}`
queryString += `&chapter_id=${props.data.section?.chapter_id ?? ''}&section_id=${props.data.section?.section_id ?? ''}&resource_id=${
props.data.section?.resource_id ?? ''
}`
}
return queryString
......@@ -62,9 +62,7 @@ function handleTop(data: CourseListItemType) {
<h2 class="course-item__name">{{ data.course_alias_name || data.name }}</h2>
</div>
</div>
<div class="course-item-progress">
总进度<el-progress :stroke-width="4" :percentage="parseFloat(data.schedule)" />
</div>
<div class="course-item-progress">总进度<el-progress :stroke-width="4" :percentage="parseFloat(data.schedule)" /></div>
</router-link>
<div class="course-item-ft">
<div class="course-item-playlist" v-if="data.section?.watch_video_length">
......@@ -205,9 +203,8 @@ function handleTop(data: CourseListItemType) {
border-bottom-left-radius: 0;
}
}
::v-deep {
.el-progress-bar__outer {
background-color: #efefef;
}
:deep(.el-progress-bar__outer) {
background-color: #efefef;
}
</style>
......@@ -173,7 +173,7 @@ const filterList = computed(() => {
padding: 8px;
}
.course-filter {
padding: 8px;
padding: 8px 0;
}
.course-filter-item + .course-filter-item {
margin-top: 20px;
......
......@@ -49,9 +49,7 @@ function formatDuration(duration: number | undefined) {
<p>{{ item.name }}</p>
</dt>
<dd v-for="section in item.sections" :key="section.id" :class="{ 'is-active': section.id === sectionId }">
<router-link
:to="`/course/player?course_id=${courseId}&chapter_id=${item.id}&section_id=${section.id}&semester_id=${semesterId}`"
>
<router-link :to="`/course/player?course_id=${courseId}&chapter_id=${item.id}&section_id=${section.id}&semester_id=${semesterId}`">
{{ section.name }}
</router-link>
</dd>
......@@ -59,12 +57,7 @@ function formatDuration(duration: number | undefined) {
</el-tab-pane>
<el-tab-pane label="讲义" name="ppt" v-if="pptList && pptList.length">
<ul class="lecture-list">
<li
v-for="(item, index) in pptList"
:class="{ 'is-active': index === pptIndex }"
:key="item.url"
@click="$emit('clickPPT', item)"
>
<li v-for="(item, index) in pptList" :class="{ 'is-active': index === pptIndex }" :key="item.url" @click="$emit('clickPPT', item)">
<img :src="`${item.url}?x-oss-process=image/resize,m_fill,h_128,w_218`" loading="lazy" />
<span>{{ formatDuration(item.point) }}</span>
</li>
......@@ -77,7 +70,7 @@ function formatDuration(duration: number | undefined) {
<style lang="scss" scoped>
.course-player-chapter {
height: 100%;
padding: 20px;
padding: 0.2rem;
background-color: #1f1e24;
box-sizing: border-box;
:deep(.el-tabs__nav) {
......@@ -88,9 +81,9 @@ function formatDuration(duration: number | undefined) {
display: none;
}
:deep(.el-tabs__item) {
height: 40px;
font-size: 16px;
line-height: 40px;
height: 0.4rem;
font-size: 0.16rem;
line-height: 0.4rem;
color: #89898b;
&.is-active {
color: #fff;
......@@ -98,7 +91,7 @@ function formatDuration(duration: number | undefined) {
}
dl {
color: #fff;
padding: 20px 0;
padding: 0.2rem 0;
}
dl + dl {
border-top: 1px dashed #b2b2b2;
......@@ -106,30 +99,30 @@ function formatDuration(duration: number | undefined) {
dt {
display: flex;
align-items: center;
margin-bottom: 10px;
margin-bottom: 0.1rem;
span {
display: inline-block;
width: 26px;
height: 26px;
width: 0.26rem;
height: 0.26rem;
color: var(--main-color);
line-height: 26px;
line-height: 0.26rem;
text-align: center;
background-color: #fff;
border-radius: 50%;
}
p {
flex: 1;
margin-left: 8px;
font-size: 16px;
margin-left: 0.08rem;
font-size: 0.16rem;
font-weight: 500;
line-height: 26px;
line-height: 0.26rem;
color: #fff;
}
}
dd {
margin-left: 34px;
margin-left: 0.34rem;
padding: 5px 0 5px 1em;
font-size: 14px;
font-size: 0.14rem;
font-weight: 400;
line-height: 24px;
color: #ffffff;
......@@ -141,7 +134,7 @@ function formatDuration(duration: number | undefined) {
.lecture-list {
li {
position: relative;
margin: 10px 0;
margin: 0.1rem 0;
height: 128px;
cursor: pointer;
&.is-active {
......@@ -154,8 +147,8 @@ function formatDuration(duration: number | undefined) {
}
span {
position: absolute;
left: 10px;
top: 10px;
left: 0.1rem;
top: 0.1rem;
padding: 0 5px;
font-size: 12px;
background: rgba(255, 255, 255, 0.5);
......
......@@ -11,6 +11,8 @@ import { Close } from '@element-plus/icons-vue'
import AppVideoPlayer from '@/components/base/AppVideoPlayer.vue'
import { getCoursePlayInfo, getVideoRecords, uploadVideoRecords } from '../api'
import { useLog } from '@/composables/useLog'
import { useDevice } from '@/composables/useDevice'
const { mobile } = useDevice()
const log = useLog({ hasKey: true })
interface Props {
......@@ -275,8 +277,8 @@ onUnmounted(() => {
<template>
<div class="course-player-wrapper">
<div ref="playerWrapperRef" :style="resource ? `height: 510px` : ''">
<div class="player-box" :class="{ 'is-pinned': !playerIsVisible && !miniPlayerClosed }">
<div class="course-player-box" ref="playerWrapperRef" :style="resource ? `height: 510px` : ''">
<div class="player-box" :class="{ 'is-pinned': !playerIsVisible && !miniPlayerClosed && !mobile }">
<AppVideoPlayer
:options="options"
:src="src"
......@@ -286,8 +288,7 @@ onUnmounted(() => {
@seeked="onSeeked"
@ended="onEnded"
style="width: 100%; height: 100%"
v-if="src"
></AppVideoPlayer>
v-if="src"></AppVideoPlayer>
<el-icon class="mini-player-close" @click="miniPlayerClosed = true">
<Close></Close>
</el-icon>
......@@ -302,12 +303,7 @@ onUnmounted(() => {
</button>
</template>
<ul class="video-definition">
<li
v-for="(item, index) in currentPlayList"
:key="index"
:class="{ 'is-active': item.PlayURL === src.src }"
@click="changeSrc(item)"
>
<li v-for="(item, index) in currentPlayList" :key="index" :class="{ 'is-active': item.PlayURL === src.src }" @click="changeSrc(item)">
{{ item.DefinitionName }}
</li>
</ul>
......@@ -330,8 +326,7 @@ onUnmounted(() => {
:key="item.id"
class="video-item"
:class="{ 'is-active': item.resource_id === resourceId }"
@click="changeResource(item)"
>
@click="changeResource(item)">
<div class="video-item-pic">
<img :src="item.info?.cover" />
</div>
......@@ -343,7 +338,7 @@ onUnmounted(() => {
<style lang="scss" scoped>
.course-player-wrapper {
margin-bottom: 40px;
margin-bottom: 0.4rem;
border-bottom: 1px solid #e2e2e2;
}
.player-box {
......@@ -387,14 +382,14 @@ onUnmounted(() => {
}
.video-item {
position: relative;
margin: 20px 0;
width: 238px;
margin: 0.2rem 0;
width: 2.38rem;
cursor: pointer;
box-sizing: border-box;
p {
padding: 0 8px;
font-size: 14px;
font-size: 0.14rem;
line-height: 30px;
color: #333;
white-space: nowrap;
......@@ -424,7 +419,7 @@ onUnmounted(() => {
}
.video-item-pic {
width: 100%;
height: 148px;
height: 1.48rem;
border-radius: 10px;
box-sizing: border-box;
overflow: hidden;
......@@ -477,8 +472,8 @@ onUnmounted(() => {
:deep(.swiper-button-prev) {
margin-top: -30px;
--swiper-navigation-size: 14px;
width: 34px;
height: 34px;
width: 0.34rem;
height: 0.34rem;
color: #fff;
background: #303133;
border-radius: 50%;
......
......@@ -4,7 +4,8 @@ import type { CourseAssessChapterType } from '../types'
import format from 'format-duration'
import { getChapterVideoTreeList } from '../api'
import { useDevice } from '@/composables/useDevice'
const { mobile } = useDevice()
const { query } = useRoute()
const courseId = $ref(query.course_id as string)
const semesterId = $ref(query.semester_id as string)
......@@ -94,10 +95,10 @@ function formatDuration(duration: number | undefined) {
<template v-else>{{ row.name }}</template>
</template>
</el-table-column>
<el-table-column prop="watch_video_length" label="学习时长" width="180" align="center">
<el-table-column prop="watch_video_length" label="学习时长" :width="mobile ? '90' : '180'" align="center">
<template #default="{ row }">{{ formatDuration(row.watch_video_length) }}</template>
</el-table-column>
<el-table-column prop="name" label="百分比" width="180" align="center">
<el-table-column prop="name" label="百分比" :width="mobile ? '100' : '180'" align="center">
<template #default="{ row }">
<el-progress :percentage="parseFloat(row.schedule)" />
</template>
......@@ -106,14 +107,14 @@ function formatDuration(duration: number | undefined) {
</div>
</template>
<style lang="scss" scoped>
<style lang="scss">
.course-assess-hd {
padding-bottom: 20px;
padding-bottom: 0.2rem;
display: flex;
align-items: center;
.t1 {
flex: 1;
font-size: 16px;
font-size: 0.16rem;
font-weight: 400;
color: var(--main-color);
}
......@@ -121,19 +122,32 @@ function formatDuration(duration: number | undefined) {
.course-assess-hd__aside {
display: flex;
.t2 {
padding: 0 20px;
font-size: 16px;
padding: 0 0.2rem;
font-size: 0.16rem;
color: #333333;
}
}
:deep(.el-table__row--level-0) {
font-size: 16px;
font-weight: 500;
color: #333;
.course-assess {
.el-table__row--level-0 {
font-size: 0.16rem;
font-weight: 500;
color: #333;
}
.el-table__row--level-1 {
font-size: 0.16rem;
font-weight: 400;
color: #333;
}
}
:deep(.el-table__row--level-1) {
font-size: 16px;
font-weight: 400;
color: #333;
.is-h5 {
.course-assess {
.course-assess-hd {
flex-direction: column;
}
.el-table__indent {
padding-left: 0 !important;
}
}
}
</style>
......@@ -23,4 +23,22 @@ const semesterId = route.query.semester_id as string
padding: 0;
}
}
.is-h5 {
.course-bbs {
.table-list-hd {
display: block;
.el-select {
width: 82px;
}
.el-form-item {
margin-right: 0;
}
.el-input__wrapper {
padding: 0;
padding-right: 5px;
box-shadow: none;
}
}
}
}
</style>
......@@ -156,8 +156,7 @@ defineExpose({
:to="`/course/exam/result?course_id=${courseId}&semester_id=${semesterId}&paper_id=${resource.resource_id}&type=2&paper_title=${resource.name}`"
target="_blank"
style="margin: 0 20px"
v-if="resource.paper_status === 2 || resource.paper_status === 3"
>
v-if="resource.paper_status === 2 || resource.paper_status === 3">
<el-button round size="small">查看报告</el-button>
</router-link>
......@@ -174,8 +173,7 @@ defineExpose({
class="icon-star"
:class="!!resource.collection_count ? 'is-active' : ''"
@click="toggleCollection(resource, section, item)"
v-if="canCollection(resource)"
></i>
v-if="canCollection(resource)"></i>
<i class="icon-download" @click="downloadFile(resource)" v-if="!!resource.can_download">
<Download />
</i>
......@@ -193,9 +191,9 @@ defineExpose({
.course-resource-item {
display: flex;
align-items: center;
padding: 0 48px 0 60px;
height: 48px;
line-height: 48px;
padding: 0 0.28rem 0 0.4rem;
height: 0.48rem;
line-height: 0.48rem;
border-bottom: 1px solid #e6e6e6;
p {
flex: 1;
......@@ -205,6 +203,9 @@ defineExpose({
color: #666;
}
a {
white-space: nowrap;
text-overflow: ellipsis;
overflow: hidden;
&:hover {
color: var(--main-color);
}
......@@ -214,7 +215,7 @@ defineExpose({
}
.actions {
min-width: 60px;
min-width: 0.6rem;
display: flex;
align-items: center;
justify-content: space-between;
......@@ -226,8 +227,8 @@ defineExpose({
}
.icon-star {
display: inline-block;
width: 16px;
height: 16px;
width: 0.16rem;
height: 0.16rem;
background: url(@/assets/images/icon_star.png) no-repeat;
background-size: contain;
cursor: pointer;
......@@ -238,21 +239,21 @@ defineExpose({
}
.icon-download {
display: inline-block;
width: 20px;
height: 20px;
width: 0.2rem;
height: 0.2rem;
cursor: pointer;
}
.icon-chapter {
margin-right: 10px;
margin-right: 0.1rem;
display: inline-block;
width: 16px;
height: 20px;
width: 0.16rem;
height: 0.2rem;
background: url(@/assets/images/icon_chapter.png) no-repeat;
background-size: contain;
}
.course-chapters {
:deep(.el-collapse-item__header) {
padding: 0 20px;
padding: 0 0.2rem;
background-color: #e8e9eb;
border-bottom: none;
}
......@@ -260,18 +261,18 @@ defineExpose({
.course-sections {
margin-top: 10px;
:deep(.el-collapse-item__header) {
padding: 0 40px;
padding: 0 0.2rem 0 0.3rem;
background-color: #f7f8fa;
border-bottom: none;
}
}
.chapter-title {
font-size: 16px;
font-size: 0.16rem;
font-weight: 500;
color: #333333;
}
.section-title {
font-size: 14px;
font-size: 0.1rrem;
font-weight: 400;
color: #333333;
}
......@@ -288,4 +289,12 @@ defineExpose({
:deep(.el-collapse-item) {
margin-bottom: 10px;
}
.is-h5 {
.video-duration {
display: none;
}
.actions {
min-width: unset;
}
}
</style>
......@@ -35,6 +35,11 @@ defineProps<Props>()
flex: 1;
line-height: 48px;
}
a {
white-space: nowrap;
text-overflow: ellipsis;
overflow: hidden;
}
&:hover {
color: var(--main-color);
}
......@@ -45,4 +50,10 @@ defineProps<Props>()
justify-content: space-between;
}
}
.is-h5 {
.actions {
display: none;
}
}
</style>
......@@ -118,12 +118,7 @@ onMounted(() => {
</div>
<div class="chart-box-bd">
<div class="score">
<el-progress
color="#ba143e"
:stroke-width="8"
:percentage="detail.score ? parseFloat(detail.score) : 0"
style="width: 100%"
>
<el-progress color="#ba143e" :stroke-width="8" :percentage="detail.score ? parseFloat(detail.score) : 0" style="width: 100%">
<img src="@/assets/images/icon_exam_result.png" width="24" />
</el-progress>
<template v-if="detail.status !== 3">
......@@ -152,11 +147,11 @@ onMounted(() => {
height: 100%;
background-color: #fff;
border-radius: 6px;
padding: 20px;
padding: 0.2rem;
box-sizing: border-box;
}
.course-exam-card + .course-exam-card {
margin-left: 20px;
margin-left: 0.2rem;
}
.chart-box-hd {
display: flex;
......@@ -168,7 +163,7 @@ onMounted(() => {
border-bottom: 1px solid #ccc;
}
.chart-box-bd {
padding: 20px 0;
padding: 0.2rem 0;
}
.chart-wrapper {
display: flex;
......@@ -176,24 +171,24 @@ onMounted(() => {
justify-content: center;
}
.chart-item {
padding: 40px;
padding: 0.4rem;
display: flex;
align-items: center;
}
.chart-item__title {
padding: 20px;
font-size: 22px;
padding: 0.2rem;
font-size: 0.22rem;
color: #333;
}
.chart-item__content {
p {
font-size: 22px;
font-size: 0.22rem;
color: #333;
}
}
.score {
width: 300px;
margin: 10px auto;
width: 3rem;
margin: 0.1rem auto;
display: flex;
flex-direction: column;
align-items: center;
......@@ -214,4 +209,18 @@ onMounted(() => {
margin: 50px 0 68px 0;
}
}
.is-h5 {
.course-exam-result {
flex-direction: column;
}
.course-exam-card {
margin-bottom: 0.2rem;
margin-left: 0;
}
.chart-item {
padding: 0;
}
}
</style>
......@@ -5,6 +5,8 @@ import type { CourseListParamsType, CourseListItemType } from '../types'
import { getCourseList } from '../api'
import { useUserStore } from '@/stores/user'
import { useLog } from '@/composables/useLog'
import { useDevice } from '@/composables/useDevice'
const { mobile } = useDevice()
const log = useLog()
const userStore = useUserStore()
......@@ -23,7 +25,7 @@ function fetchList() {
courseList = res.data.data
const [first] = courseList
// 进入第一个课程详情页
if (first && route.path === '/course') {
if (first && route.path === '/course' && !mobile.value) {
router.push({ path: '/course/view', query: { course_id: first.course_id, semester_id: first.semester_id } })
}
})
......@@ -44,7 +46,7 @@ log.upload({
</script>
<template>
<section class="course">
<section class="course" :class="route.path === '/course' ? 'is-list' : 'is-view'">
<div class="course-left">
<CourseListSearch @change="handleSearch"></CourseListSearch>
<div class="course-list">
......@@ -75,5 +77,24 @@ log.upload({
.course-right {
flex: 1;
overflow: hidden;
margin-left: 20px;
}
.is-h5 {
.course-left {
flex: 1;
}
.course-right {
margin-left: 0;
}
.is-list {
.course-right {
display: none;
}
}
.is-view {
.course-left {
display: none;
}
}
}
</style>
......@@ -5,6 +5,8 @@ import CoursePlayerResourceList from '../components/CoursePlayerResourceList.vue
import { ArrowLeftBold, ArrowRightBold } from '@element-plus/icons-vue'
import type { VideoJsPlayer } from 'video.js'
import type { PptType } from '@/types'
import { useDevice } from '@/composables/useDevice'
const { mobile } = useDevice()
const CoursePlayerVideo = defineAsyncComponent(() => import('../components/CoursePlayerVideo.vue'))
const CoursePlayerChapter = defineAsyncComponent(() => import('../components/CoursePlayerChapter.vue'))
......@@ -95,13 +97,8 @@ function toggleSidebar() {
</div>
<div class="course-player-bd">
<div class="course-player-main" v-loading="loading">
<CoursePlayerVideo
:chapterList="chapterList"
:key="sectionId"
@updateResource="onUpdateResource"
@timeupdate="onTimeUpdate"
/>
<el-tabs>
<CoursePlayerVideo :chapterList="chapterList" :key="sectionId" @updateResource="onUpdateResource" @timeupdate="onTimeUpdate" />
<el-tabs :stretch="mobile">
<el-tab-pane label="课件">
<CoursePlayerResourceList :list="detail.coursewares" />
</el-tab-pane>
......@@ -124,12 +121,7 @@ function toggleSidebar() {
</div>
<div class="course-player-aside" :class="{ 'is-hidden': !sidebarVisible }">
<div class="course-player-aside__inner">
<CoursePlayerChapter
:chapterList="chapterList"
:pptList="pptList"
:pptIndex="pptIndex"
@clickPPT="onClickPPT"
/>
<CoursePlayerChapter :chapterList="chapterList" :pptList="pptList" :pptIndex="pptIndex" @clickPPT="onClickPPT" />
</div>
<div class="toggle-button" :class="{ 'is-hidden': !sidebarVisible }" @click="toggleSidebar">
<el-icon>
......@@ -142,7 +134,7 @@ function toggleSidebar() {
</div>
</template>
<style lang="scss" scoped>
<style lang="scss">
.course-player {
display: flex;
flex-direction: column;
......@@ -222,4 +214,35 @@ function toggleSidebar() {
padding: 0 20px;
margin-left: -20px;
}
.is-h5 {
.course-player {
padding: 0;
background-color: transparent;
}
.course-player-bd {
position: relative;
flex-direction: column;
}
.course-player-aside {
margin-top: 220px;
order: -1;
flex: 1;
width: 100%;
margin-left: 0;
}
.course-player-box {
position: absolute;
top: 0;
width: 100%;
height: 220px !important;
}
.toggle-button {
display: none;
}
.course-player-main {
.course-resource-item {
padding: 0;
}
}
}
</style>
......@@ -2,6 +2,8 @@
import { useMapStore } from '@/stores/map'
import type { CourseType } from '@/types'
import * as api from '../api'
import { useDevice } from '@/composables/useDevice'
const { mobile } = useDevice()
const CourseViewChapter = defineAsyncComponent(() => import('../components/CourseViewChapter.vue'))
const CourseViewBBS = defineAsyncComponent(() => import('../components/CourseViewBBS.vue'))
......@@ -87,18 +89,18 @@ function handleStudy() {
<div class="btn" @click="handleStudy">立即学习</div>
</div>
<div class="course-view-r">
<div class="name">{{ detail.course_alias_name || detail.name }}</div>
<div class="tag-box">
<div class="tag">{{ electiveTypeText }}</div>
<div class="tag">{{ detail.credit }}学分</div>
<div class="tag" v-if="detail.semester">{{ detail.semester.name }}</div>
<div class="course-view-r__info">
<div class="name">{{ detail.course_alias_name || detail.name }}</div>
<div class="tag-box">
<div class="tag">{{ electiveTypeText }}</div>
<div class="tag">{{ detail.credit }}学分</div>
<div class="tag" v-if="detail.semester">{{ detail.semester.name }}</div>
</div>
</div>
<div class="view-content">
<div class="view-content-hd">
<div :class="infoIndex === 0 ? 'btn active' : 'btn'" @click="showInfo(detail.represent, 0)">课程简介</div>
<div :class="infoIndex === 1 ? 'btn active' : 'btn'" @click="showInfo(detail.previous_preparation, 1)">
预备知识
</div>
<div :class="infoIndex === 1 ? 'btn active' : 'btn'" @click="showInfo(detail.previous_preparation, 1)" v-if="false">预备知识</div>
<div :class="infoIndex === 2 ? 'btn active' : 'btn'" @click="showInfo(detail.target, 2)">授课目标</div>
</div>
<div class="view-content_c" v-if="infoText === ''">
......@@ -145,7 +147,7 @@ function handleStudy() {
</section> -->
<div class="course-view-content">
<div class="course-view-bd">
<el-tabs>
<el-tabs :stretch="mobile">
<el-tab-pane label="学习">
<CourseViewChapter ref="courseViewChapterRef" />
</el-tab-pane>
......@@ -173,8 +175,10 @@ function handleStudy() {
<div class="teacher-hd">课程讲师</div>
<div class="teacher-content" v-for="item in detail.lecturers" :key="item.id">
<img :src="item.avatar" class="lecturer-item__pic" />
<div class="name">{{ item.name }}</div>
<div class="dec" v-html="item.summarize"></div>
<div class="box">
<div class="name">{{ item.name }}</div>
<div class="dec" v-html="item.summarize"></div>
</div>
</div>
</div>
</div>
......@@ -186,24 +190,23 @@ function handleStudy() {
<style lang="scss" scoped>
.course-view-h {
position: relative;
background: #ab0a3d;
box-shadow: 0px 1px 12px 1px rgba(0, 0, 0, 0.1098);
border-radius: 10px 10px 10px 10px;
margin-left: 20px;
padding: 20px;
padding: 0.2rem;
box-sizing: border-box;
display: flex;
.view-h-l {
margin-right: 20px;
width: 243px;
margin-right: 0.2rem;
width: 2.4rem;
img {
height: 151px;
height: 1.5rem;
width: 100%;
display: block;
border-radius: 6px 6px 6px 6px;
}
.btn {
width: 243px;
background: #ffffff;
border-radius: 6px 6px 6px 6px;
text-align: center;
......@@ -218,7 +221,7 @@ function handleStudy() {
.course-view-r {
width: 100%;
.name {
font-size: 18px;
font-size: 0.18rem;
font-weight: bold;
color: #ffffff;
line-height: 100%;
......@@ -231,7 +234,7 @@ function handleStudy() {
line-height: 23px;
background: #e6b6c4;
border-radius: 4px 4px 4px 4px;
font-size: 12px;
font-size: 0.12rem;
color: #ab0a3d;
margin-right: 10px;
}
......@@ -325,13 +328,13 @@ function handleStudy() {
overflow: hidden;
}
.lecturer-item__pic {
width: 146px;
height: 106px;
width: 1.46rem;
height: 1.06rem;
object-fit: cover;
display: block;
border-radius: 10px;
overflow: hidden;
margin: 18px auto;
margin: 0 auto;
}
.lecturer-item__info {
flex: 1;
......@@ -359,9 +362,10 @@ function handleStudy() {
.course-view-bd {
flex: 1;
padding: 10px 20px;
padding: 0.1rem 0.2rem;
background-color: #fff;
border-radius: 10px 10px 10px 10px;
overflow: hidden;
}
.dialog-info {
:deep(img) {
......@@ -370,8 +374,7 @@ function handleStudy() {
}
.course-view-content {
display: flex;
padding-left: 20px;
margin-top: 20px;
margin-top: 0.2rem;
.course-view-teacher {
width: 217px;
margin-left: 20px;
......@@ -380,12 +383,12 @@ function handleStudy() {
padding: 0 13px 52px;
height: fit-content;
.teacher-hd {
line-height: 55px;
line-height: 0.55rem;
text-align: center;
position: relative;
border-bottom: 1px solid #eaeaea;
font-size: 16px;
font-weight: bold;
font-weight: 500;
color: #aa1941;
&::after {
content: '';
......@@ -399,9 +402,11 @@ function handleStudy() {
}
}
.teacher-content {
margin-top: 18px;
.name {
margin-top: 18px;
text-align: center;
font-size: 16px;
font-size: 0.16rem;
font-weight: bold;
line-height: 100%;
color: #333333;
......@@ -415,10 +420,54 @@ function handleStudy() {
}
}
}
::v-deep {
.el-empty__description {
margin-top: 5px;
font-size: 12px;
:deep(.el-empty__description) {
margin-top: 5px;
font-size: 12px;
}
.is-h5 {
.course-view-h {
display: block;
}
.view-h-l {
width: 120px;
.btn {
position: absolute;
left: 145px;
top: 80px;
width: 2rem;
}
}
.course-view-r__info {
position: absolute;
right: 0;
top: 20px;
left: 145px;
}
.course-view-content {
flex-direction: column;
}
.course-view-teacher {
width: auto;
margin-left: 0;
margin-bottom: 0.2rem;
order: -1;
padding: 0 13px 13px;
}
.teacher-hd {
font-size: 14px;
}
.teacher-content {
display: flex;
.box {
margin-left: 10px;
flex: 1;
.name,
.desc {
margin: 0;
text-align: left;
}
}
}
}
</style>
......@@ -49,7 +49,7 @@ const update = () => {
hide-required-asterisk
label-width="100px"
label-position="left"
style="width: 360px"
style="max-width: 360px"
>
<el-form-item label="旧密码" prop="old_password">
<el-input type="password" v-model="form.old_password" />
......
......@@ -40,7 +40,7 @@ const update = () => {
hide-required-asterisk
label-width="60px"
label-position="left"
style="width: 360px"
style="max-width: 360px"
>
<el-form-item label="昵称" prop="real_name">
<el-input v-model="form.real_name" maxlength="10" />
......
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论