提交 f27a18fc authored 作者: GOD_ZYX's avatar GOD_ZYX

修改 完毕 登录

上级 d03b3ea9
......@@ -29,7 +29,9 @@ $GLOBAL.BaseConfig = {
},
resolve: {
alias: {
'@services': path.resolve(__dirname, '../client/components/services')
'@services': path.resolve(__dirname, '../client/components/services'),
'@tools': path.resolve(__dirname, '../client/components/tools'),
'@actions': path.resolve(__dirname, '../client/project/' + projectName + '/actions')
}
},
module: {
......
......@@ -22,6 +22,7 @@ if ($GLOBAL.isDev) {
},
devServer: {
port: $GLOBAL.serverPort,
disableHostCheck: true,
overlay: {
errors: true
......@@ -39,6 +40,7 @@ if ($GLOBAL.isDev) {
'Referer': $GLOBAL.webConf.devDomain
},
pathRewrite: {
'^/api': ''
}
}
},
......
......@@ -36,6 +36,18 @@
<div class="fontclass">.el-icon-self-album</div>
</li>
<li>
<i class="icon selfAllIcon el-icon-self-cc-book"></i>
<div class="name">cc-book</div>
<div class="fontclass">.el-icon-self-cc-book</div>
</li>
<li>
<i class="icon selfAllIcon el-icon-self-13"></i>
<div class="name">image-o</div>
<div class="fontclass">.el-icon-self-13</div>
</li>
<li>
<i class="icon selfAllIcon el-icon-self-grade"></i>
<div class="name">Grade</div>
......
......@@ -59,6 +59,22 @@
<div class="fontclass">#el-icon-self-album</div>
</li>
<li>
<svg class="icon" aria-hidden="true">
<use xlink:href="#el-icon-self-cc-book"></use>
</svg>
<div class="name">cc-book</div>
<div class="fontclass">#el-icon-self-cc-book</div>
</li>
<li>
<svg class="icon" aria-hidden="true">
<use xlink:href="#el-icon-self-13"></use>
</svg>
<div class="name">image-o</div>
<div class="fontclass">#el-icon-self-13</div>
</li>
<li>
<svg class="icon" aria-hidden="true">
<use xlink:href="#el-icon-self-grade"></use>
......
......@@ -56,6 +56,18 @@
<div class="code">&amp;#xe734;</div>
</li>
<li>
<i class="icon selfAllIcon">&#xe615;</i>
<div class="name">cc-book</div>
<div class="code">&amp;#xe615;</div>
</li>
<li>
<i class="icon selfAllIcon">&#xe6ce;</i>
<div class="name">image-o</div>
<div class="code">&amp;#xe6ce;</div>
</li>
<li>
<i class="icon selfAllIcon">&#xe66c;</i>
<div class="name">Grade</div>
......
@font-face {font-family: "selfAllIcon";
src: url('iconfont.eot?t=1545290857246'); /* IE9*/
src: url('iconfont.eot?t=1545290857246#iefix') format('embedded-opentype'), /* IE6-IE8 */
url('data:application/x-font-woff;charset=utf-8;base64,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') format('woff'),
url('iconfont.ttf?t=1545290857246') format('truetype'), /* chrome, firefox, opera, Safari, Android, iOS 4.2+*/
url('iconfont.svg?t=1545290857246#selfAllIcon') format('svg'); /* iOS 4.1- */
src: url('iconfont.eot?t=1545735883467'); /* IE9*/
src: url('iconfont.eot?t=1545735883467#iefix') format('embedded-opentype'), /* IE6-IE8 */
url('data:application/x-font-woff;charset=utf-8;base64,d09GRgABAAAAAA1sAAsAAAAAFIwAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAABHU1VCAAABCAAAADMAAABCsP6z7U9TLzIAAAE8AAAARAAAAFY8d0kmY21hcAAAAYAAAAC1AAACWoN37dBnbHlmAAACOAAACNIAAAzo/l3krWhlYWQAAAsMAAAALwAAADYTr6OTaGhlYQAACzwAAAAcAAAAJAfeA45obXR4AAALWAAAAA8AAAA0NAAAAGxvY2EAAAtoAAAAHAAAABwWxBo0bWF4cAAAC4QAAAAfAAAAIAEfANNuYW1lAAALpAAAAVIAAAKR7FrMk3Bvc3QAAAz4AAAAcQAAAJBAeyMIeJxjYGRgYOBikGPQYWB0cfMJYeBgYGGAAJAMY05meiJQDMoDyrGAaQ4gZoOIAgCKIwNPAHicY2BkYWCcwMDKwMHUyXSGgYGhH0IzvmYwYuRgYGBiYGVmwAoC0lxTGByeMT43YW7438AQw9zA0AAUZgTJAQDhKgwZeJzlks0NwjAMhV9o6R89cKmEOHQC1BNbtTP0jDoFQ3BiiI7xMkZ5iREFCSbA1hfFduRYtgFsASTiJFLA3eEQ5Cavi/4EVfSnuMg+YC9PQcecJRt2HDhy4uxbf14W4C3Sf0a+ilPGVY8vBWqU2Km+CgVyvdsg08+hxuxHrn+SOp7X1aIz4j031EHwiXoJNkaYOjsjTJe9oU6Dg4GQYzTCJnAyNAdwNjQR+NYIW+TPBtIHBK8/mwAAAHicjVZdbBTXFb7n3tmZ3dmZnd2d3Zkd/6z3fxeM194fzwKpbewFJxaBAqYQgim4jcElJaIlJCWlFCLauAniAVpEaEVUwG3VVoqU1qpoCQJc9cVIlSI1gfJQqNoXWqV9IFWUZic9d8emtERNV7Nzzzn33L/vnPPdIV5CPrrCrrBPEy8JkRaSJhnSRZ4lRwiBIqTEiFG281W7bETEVE4KANerOSmVc22edD+4fdAPvdVcPieiUxxq/VAxuJiu2jV7ADvzRejth1rZNPoB3dIBkCKGiR6mUSvbtThUsLeaw75+PrpmmAGgCbA32Ph8PdwWxmdvqqtrZVdXSvL5Aj4fjKyAjJ3BB2rxlF+Mby34JdVSsnkRvvf6T/+SNjKUUol62tqEm+e3rFNiilfZNnm54WlvhUrMCrXE13QuPbQSDVlnYvKJp75vrDxU6QbhJt2xiK9qLwrwVcMngK+6sms7XzXgu9LK18zAu8XHW0OGaLXGpFhMkiJq4o+v//A179IaY15vxFec6D1/U8iLvlhMLHoal5c9U4Y141YQkm25POpDX23MQmXkpFE/Xt/01PmbhAgYi8vsGhtqxuJZ8ptmDFyg824oqjk91Q1iHnHL5xDSAcRLEhHPfA5RzlVraKvZiF8H2DW0oWwbKJtoMg0zDhoYJppQNkSUIxLaJB4onFVCG8pilrtgWGx3Ej7HglTN59wl+YoLkiS6g/nYBSliGu5SfCWJkv8A9AtBeSQSGRF1uVr0+iCiqQflkKdFo6J3AmDCK1KtxROSD6paBHzeYlXWxfv+Pu8n+3uct6PmsF/v6ND9w2ZUpwFLV8LPy95xzCkKgXGv/HxY0a0A1f9PP/ivTHQS6gSlH79TOSJ//FY/ccCDWMDm5jYE4eHtagnt4f0+7KiE0TGs/NuR4I9ijl1lv8YcW042NvMrj5UYB7cs3RpFLYCJ0ixlyebFmhKlCNokEYNZKdeaFZpFaYAnFW/sImA6YfVrIBpsFtMbqwq2jPpbNI9/eDXWH9YCvj1KRBCrGUXw+HU1DAINq0yQfKokJg6kf/V+41VJ0uVHx3whCMpHJMG0vBM75Kx3XPTCNXeGLd9d1rT3HH7spRlBmHlpaoYByIpaiCxOeLRwwCtptbgclnw0sKpTeoex0LHjAQi86beCHv93vq3R4CU1RkQOBvIeb3zEIotIH5lEPO7zWTaJ5w0hFEk8bagIOqpJRCuEahLNtSSvyAoXQ7wye9GHoQ9HqUgRVNMFy64hA1bKvPZc3JDnkObIAndRuXG3VAeol6jRbAWIG427RhywpQa2qxszWDYBuhplTD2o3/rsUubxq1YsmunYtgpXVQXmD9PFNg1FfKFivruDCR1L1XAY5qnqFs7u7HZXgVOleuMf7vRwym3f49PGDWc/XwdeKdWdK2xNxgpSQdTwPN8IBKIMAn5pq+gV/YooL2vpSEG4lScUAvjRDPscqxI/6SEDhGSTnLIqSY4ixywUEdNNU20eyDwCG50HtjdURaDjqHMvUQpVbfoT51Gfqvrgok9RTskqqHLjg3ihEIcfxfMA+bizKF6AoTIV4wW1cQLekVVVdp4oxNUYKLqCD32TjxmQA1D4FI4oxGkVR2DbGCjXm/pVWe3hPtfRx6Cfl1VCPHiOO+wP9O8kSJKkk1TJGCF6M7oPBD6UeOAQPDv0OHBSxvqoLFySHhNZtSQiTedSWA3323wpV8VCKXeAwQumfJLeSCwBWJJoFNwW9sDTpUGAwVKj0GwnobiqiA/krGwslrHgjTlRFDVxzp/wX4j1x1qwraMuivV57Vysn85BZ7JxI9EJ0JmghWQnNEyckhbmp77RMwQfpHHa7u5U2OIT981JAUkUr8vyOdNskeWVIha+VEfZ7z9nYowlxOY0u8t24/dBlpTJI2SEbCKbsVowgi6BYK5zEuF1UeF3Tc2D9lx3k0tq/H6yXVbJm/x6N/GmAJd2UEPPki427/2mT7rEdoT9wtzZ1+YYKKFj7MtrMG5Hel/+2uP7WOMr1E6Wi6Ud+f0rPvPYn4Jw8ejRq4L/vZHp0aHDhR2lYtn5cOsBSg9sfZK/nxS7Diiwd3BouyDsK8KmzPrOs28JwltnO9dn3qW54PKt7P27LwdzdC8bTAdk/3RlQ7DgOTSLcwqzL146Klw7HdxYmfbLAfql+3Pi/M4RNrRvaJyyZwZHNxC3DvA1Ta8086eM2PCc6XXJoh0imNsPG1I5buC1wg1pdqAR0mMAMZ3+DUMT/l8aXYFiIWwBWOECdjj35oV5s3Obq5bFlQXev8NWsQ5SIEtxd9kc/0qoNWNWaX6dpZt8z7/IHqQ9xgszlesDd58mM51eRrPW6iWDYzExGEjJ3tShbX2jGTvKWnW+HZ0WI7ztimrOWi2KNxq8gZcdzEDPC8W2TqDr+0I6VCKbt0GyUP9BjQ9xvukOhRd0yzmjRaPah8FIJDi/78PsDDtMchxVD8+35nbnsw7f0TTnX75DfpxonNqwkEoSHuBV+spzY+us9nNP7z7Xbq0be+5bwMKtujB74uSsAOEWvbGfTe3cNcXY1K6dU9vTh6/32Jcmdx2k9OCuyUt26frhNKfF9IlZTIkTGTUIOr24k7vjIEqnXA78hUDYCFZHL+dARDclefjHcgcglm7Fc7arRTlf9PFrAO8AcZ4e8iGTO0jIEV1IDKaH/dkZbV3e6mxUNU29BZY5HbNj02bLQdBi2iJF05w7EJ5W2pTpMJxBxzM/w5veGYML2MAFOv57Vb0pxdpNaa/z25bFyqiCz+IWKA3sxbHKsQjvc9SoPCpJo3IUomtVdW271/v27/BPXC68yn7OCngzdpAlZBkZRl53E6GXJbPRCk+QilTBWq/k+Xd7qNKL5+sDzoSYyobnQUVyeT4lIssbbLjdaty22oEeb4g2PFI6v2fDHhv/50uPgN34sT8YNDUNNuBGzWDwNDYxTfur1d5uUY9tN/6JXpfxhwNRb9wGTfkiPxO+AOV7XL7nyjDMFeeXioZH+hcYAixrAAB4nGNgZGBgAOJwuQNp8fw2Xxm4WRhA4IaH/mkE/b+BhYG5AcjlYGACiQIAD1QJkAB4nGNgZGBgbvjfwBDDwgACQJKRARXwAgBHEwJ2eJxjYWBgYCERAwAF5AA1AAAAAAAAxgH4AnwDIAOEBBIEpAT0BVAFogYKBnR4nGNgZGBg4GU4zsDBAAJMQMwFhAwM/8F8BgAd0AHzAHicdZDLSsNAFIb/9CYm4EKx63GjoJBeNkLBRSm0dluh+zSdtClJpiTTQje+gQufx6fwBfQp3PubHqFIzTCH73xzzpkhAM7xAQf775J7zw48Znuu4ARKuEp/I1wjd4Xr5AfhBvlR2MUdnoQ9XOCZE5zaKbNbvAo7aOJNuIIzvAtX6T+Fa+Qv4TqajifcIF8Ju5g698Ierp0Xd5DrwOq5mu1UHJosMpl1C51E/SQZM5/oxSYJ8gNzgFOdF7HJVMdvH9iRznT+O7PYLrrWRirKTaqGHK6TxKh1blY6tP7S2nWv1YrE+6FJ+cQBcmgEsIxz/tYZdowxQhhkiMpoWVfwPGHeZ0wwlvMJ7QIbmoBzjtcct1Pan464zBQ68NH+p3ZEm5X1f99ZYMv7u7SWXYo7Z0dKGsrLdTnJ0KzLsxVNSO9jWXat0UOLK/pT75d3p99T3XZbAAB4nG3BwRKCIBQFUC6IgmV/4qLpi55PxpgCZuBpfn6Ltp2jtPoZ1X8TNAw6WPQY4OAx4oIrJtyUW2PjcoTqWhCJeWsmh4+l97KngXleSnnp+8NuldZgMh1diok8P6kSS6j9uYczzr4JSWwSWakv6DQc0gAAAA==') format('woff'),
url('iconfont.ttf?t=1545735883467') format('truetype'), /* chrome, firefox, opera, Safari, Android, iOS 4.2+*/
url('iconfont.svg?t=1545735883467#selfAllIcon') format('svg'); /* iOS 4.1- */
}
.selfAllIcon {
......@@ -23,6 +23,10 @@
.el-icon-self-album:before { content: "\e734"; }
.el-icon-self-cc-book:before { content: "\e615"; }
.el-icon-self-13:before { content: "\e6ce"; }
.el-icon-self-grade:before { content: "\e66c"; }
.el-icon-self-nav:before { content: "\e66b"; }
......
......@@ -32,6 +32,12 @@ Created by iconfont
<glyph glyph-name="album" unicode="&#59188;" d="M256 448m-64 0a2 2 0 1 0 128 0 2 2 0 1 0-128 0ZM714.688 640 181.312 640C116.64 640 64 587.36 64 522.688l0-405.376C64 52.64 116.64 0 181.312 0l533.376 0C779.36 0 832 52.64 832 117.312L832 522.688C832 587.36 779.36 640 714.688 640zM768 117.312C768 87.904 744.096 64 714.688 64L181.312 64C151.936 64 128 87.904 128 117.312L128 522.688C128 552.064 151.936 576 181.312 576l533.376 0C744.096 576 768 552.064 768 522.688L768 117.312zM842.688 768 256 768C238.336 768 224 753.664 224 736s14.336-32 32-32l586.688 0C872.096 704 896 680.064 896 650.688L896 256c0-17.696 14.304-32 32-32s32 14.304 32 32L960 650.688C960 715.36 907.36 768 842.688 768zM672.64 447.264c-129.056 0-143.936-72.672-152.832-116.096-7.2-35.168-10.4-39.968-28.64-42.88-34.976-5.568-44-0.192-58.912 8.8-15.456 9.312-36.672 22.08-77.952 23.168C227.616 322.88 194.112 172.16 192.704 165.76c-3.712-17.28 7.264-34.304 24.544-38.016 2.272-0.512 4.544-0.704 6.752-0.704 14.752 0 28 10.24 31.264 25.248 0.224 1.056 23.232 104.032 95.488 104.032 0.64 0 1.28 0 1.92-0.032 24.352-0.608 33.632-6.208 46.496-13.984 24.032-14.464 48.352-25.76 102.08-17.184 64.192 10.272 74.432 60.192 81.184 93.216 8.32 40.512 13.312 64.928 90.144 64.928 17.696 0 32 14.336 32 32S690.304 447.264 672.64 447.264z" horiz-adv-x="1024" />
<glyph glyph-name="cc-book" unicode="&#58901;" d="M682.697 24.293l-440.536 0c-12.153 0-22.026 9.893-22.026 22.027 0 12.13 9.873 22.026 22.026 22.026l440.537 0c12.13 0 22.026-9.895 22.026-22.026 0-12.133-9.895-22.027-22.027-22.027zM841.773 725.675c-12.955 0-23.52-10.543-23.52-23.521l0-705.638c0-12.956-10.567-23.521-23.522-23.521l-517.47 0c-38.911 0-70.564 31.651-70.564 70.564 0 38.91 31.653 70.563 70.564 70.563l423.383 0c38.911 0 70.565 31.653 70.565 70.563l0 564.511c0 38.911-31.654 70.564-70.565 70.564l-470.426 0c-38.911 0-70.563-31.653-70.563-70.564l0-705.637c0-64.823 52.785-117.609 117.607-117.609l517.469 0c38.909 0 70.563 31.654 70.563 70.565l0 705.638c0 12.978-10.567 23.521-23.521 23.521zM230.219 772.719l470.426 0c12.955 0 23.522-10.543 23.522-23.522l0-564.511c0-12.955-10.567-23.521-23.522-23.521l-423.383 0c-26.439 0-50.902-8.821-70.564-23.567l0 611.598c0 12.979 10.543 23.522 23.521 23.522z" horiz-adv-x="1024" />
<glyph glyph-name="13" unicode="&#59086;" d="M147.2 715.2h728c41.6 0 76.8-35.2 76.8-76.8v-552c0-41.6-35.2-76.8-76.8-76.8h-728c-41.6 0-76.8 35.2-76.8 76.8v552c0 41.6 35.2 76.8 76.8 76.8v0zM147.2-30.4c243.2 0 486.4 0 728 0 64 0 115.2 51.2 115.2 115.2 0 184 0 368 0 552 0 64-51.2 115.2-115.2 115.2-243.2 0-486.4 0-728 0-64 0-115.2-51.2-115.2-115.2 0-184 0-368 0-552 0-62.4 51.2-115.2 115.2-115.2zM201.6 476.8c0-44.8 36.8-81.6 81.6-81.6s81.6 36.8 81.6 81.6c0 44.8-36.8 81.6-81.6 81.6-44.8 0-81.6-36.8-81.6-81.6v0zM240 476.8c0 24 19.2 43.2 43.2 43.2s43.2-19.2 43.2-43.2c0-24-19.2-43.2-43.2-43.2-22.4 0-43.2 19.2-43.2 43.2zM675.2 396.8l203.2-203.2c8-8 8-19.2 0-27.2v0c-8-8-19.2-8-27.2 0l-203.2 203.2c-14.4 14.4-40 14.4-54.4 0l-163.2-161.6c-30.4-30.4-80-30.4-110.4 0l-25.6 25.6c-14.4 14.4-40 14.4-54.4 0l-67.2-67.2c-8-8-19.2-8-27.2 0v0c-8 8-8 19.2 0 27.2l67.2 67.2c30.4 30.4 80 30.4 110.4 0l25.6-25.6c14.4-14.4 40-14.4 54.4 0l161.6 161.6c30.4 30.4 80 30.4 110.4 0z" horiz-adv-x="1024" />
<glyph glyph-name="grade" unicode="&#58988;" d="M863.721739 341.704348c24.486957 48.973913 28.93913 102.4 28.93913 160.278261C892.66087 706.782609 734.608696 873.73913 527.582609 873.73913 320.556522 873.73913 162.504348 706.782609 162.504348 501.982609c0-57.878261 4.452174-111.304348 28.93913-160.278261L51.2 103.513043c0 0 95.721739-35.617391 193.669565-55.652174 64.556522-73.46087 117.982609-151.373913 117.982609-151.373913l129.113043 247.095652c8.904348 0 20.034783 0 26.713043 0 8.904348 0 20.034783 0 26.713043 0l138.017391-233.73913c0 0 57.878261 64.556522 124.66087 138.017391 97.947826 20.034783 193.669565 55.652174 193.669565 55.652174L863.721739 341.704348 863.721739 341.704348 863.721739 341.704348zM353.947826-7.791304c0 0-46.747826 60.104348-89.043478 102.4-62.330435 17.808696-144.695652 35.617391-144.695652 35.617391L215.930435 294.956522c51.2-66.782609 135.791304-129.113043 220.382609-149.147826L353.947826-7.791304 353.947826-7.791304zM520.904348 185.878261c-80.13913 0-309.426087 48.973913-316.104348 316.104348C198.121739 671.165217 351.721739 831.443478 520.904348 831.443478c169.182609 0 329.46087-162.504348 329.46087-329.46087C852.591304 245.982609 601.043478 185.878261 520.904348 185.878261L520.904348 185.878261zM685.634783-7.791304l-82.365217 151.373913c84.591304 20.034783 182.53913 84.591304 233.73913 151.373913l95.721739-164.730435c0 0-82.365217-17.808696-144.695652-35.617391L685.634783-7.791304 685.634783-7.791304zM527.582609 720.13913c-117.982609 0-213.704348-95.721739-213.704348-213.704348s95.721739-213.704348 213.704348-213.704348c117.982609 0 213.704348 95.721739 213.704348 213.704348S645.565217 720.13913 527.582609 720.13913L527.582609 720.13913 527.582609 720.13913zM534.26087 337.252174c-53.426087 0-169.182609 20.034783-178.086957 178.086957-4.452174 84.591304 95.721739 164.730435 178.086957 164.730435 84.591304 0 162.504348-95.721739 164.730435-178.086957C701.217391 390.678261 587.686957 337.252174 534.26087 337.252174L534.26087 337.252174zM534.26087 337.252174" horiz-adv-x="1024" />
......
......@@ -32,6 +32,8 @@
</template>
<script>
import cAction from '@actions'
export default {
data () {
return {
......@@ -53,16 +55,25 @@
onSubmitSetAccount () {
this.$refs['setAccountform'].validate((valid) => {
if (valid) {
if (this.setAccount.user === 'admin@qq.com' && this.setAccount.pwd === '123456') {
/* 跳转 */
const loading = this.$loading({
lock: true,
text: '',
spinner: '',
background: 'rgba(255, 255, 255, 0.9)'
})
cAction.loginAction.userLogin({
account: this.setAccount.user,
password: this.$md5('uokoaduw' + this.setAccount.pwd.split('').reverse().join('') + 'auhgniq')
}).then(data => {
/* 记录 userInfo 信息 */
/* 查询上次跳转信息,并跳转回去 */
this.$router.push({ path: '/app/my-learn/course' })
} else {
this.$message.error('用户名或密码错误')
}
/* 重置密码 */
this.$refs['setAccountform'].resetFields()
/* 重置账号、密码 */
// this.$refs['setAccountform'].resetFields()
}).catch(e => { this.$message.error(e.message) }).finally(() => { loading.close() })
} else {
this.$message.error('请检查输入项,确认无误后,重新提交')
this.$message.error('请根据输入框提示,检查输入项。')
return false
}
})
......
差异被折叠。
差异被折叠。
差异被折叠。
/**
* 阅读类章节
* chapter
* handleReaded
*/
import React, { Component } from 'react'
class ChapterRead extends Component {
componentDidMount() {
const {chapter} = this.props;
if (chapter && chapter.reading) {
this.props.handleReaded();
}
}
componentWillReceiveProps(nextProps) {
if (this.props.chapter && nextProps.chapter &&
this.props.chapter.id !== nextProps.chapter.id) {
nextProps.handleReaded();
}
}
render () {
const {chapter} = this.props;
const reads = chapter.reading ? [chapter.reading] : [];
return (
<div className="play-paper">
<div className="play-paper-body">
<div className="play-paper-title"><div><h3>{chapter.name}</h3></div></div>
<div className="play-paper-content">
{reads.length ?
<ul className="play-read-files">
{reads.map((o,k) => {
return <li key={k}><a href={o.reading_attachment} target="_blank">{o.reading_content}</a></li>
})}
</ul>
:
<p className="no-data">暂无阅读材料</p>
}
</div>
</div>
</div>
);
}
}
module.exports = ChapterRead;
差异被折叠。
/**
* 作业类章节
*/
import React from 'react'
import Formsy from 'formsy-react';
import FormsyComponent from '../../components/formsy/Component.jsx'
import FormItem from '../../components/formsy/FormItem.jsx'
import CoursesAction from '../../actions/CoursesAction'
import OperateAction from '../../actions/OperateAction'
import { getRequestTypes } from '../../libs/utils';
class ChapterWork extends FormsyComponent {
constructor(props) {
super(props);
this.state = { error: '' };
}
componentDidMount () {
this.courseAction = new CoursesAction();
this.operateAction = new OperateAction();
this.startTime = (new Date()).getTime();
// 加载回答
this.props.dispatch(this.courseAction.loadChapterWork(this.props.semesterId, this.props.chapter.homework.id));
}
componentWillReceiveProps (nextProps) {
let submitType = getRequestTypes(CoursesAction.SUBMIT_CHAPTER_WORK);
switch (nextProps.action.type) {
case submitType.success:
this.enableSubmitButton();
// 提交成功,重新获取答案
nextProps.dispatch(this.courseAction.loadChapterWork(this.props.semesterId, nextProps.chapter.homework.id));
nextProps.handleSubmited(nextProps.chapter.id);
break;
case submitType.failure:
this.enableSubmitButton();
nextProps.dispatch(this.operateAction.showErrorMessage(nextProps.action.error.message || '提交章节作业失败'));
break;
}
}
/**
* 提交登录
*/
onSubmit = model => {
this.loadingSubmitButton();
const {courseId, chapter, semesterId} = this.props;
const questions = chapter.homework && chapter.homework.questions || [];
let data = {
course_id: courseId,
chapter_id:chapter.id,
work_id: chapter.homework.id,
semester_id: semesterId,
work_contents: '',
duration: Math.ceil(((new Date()).getTime() - this.startTime) / 1000),
}
// 组织返回答案结构
let answers = questions.map(q => {
return {
question_id: q.id,
descreption: model['desc_' + q.id],
file_url: model['file_' + q.id]
};
});
data.work_contents = JSON.stringify(answers);
this.props.dispatch(this.courseAction.submitChapterWork(data));
}
// 表单变更时,取消掉全局错误消息
onFormChange = () => {
this._setState({ error: '' });
}
handleUploadError = msg => {
this.props.dispatch(this.operateAction.showErrorMessage(msg || '上传文件失败'));
}
render () {
const {chapter, chapter_work} = this.props;
const questions = chapter.homework && chapter.homework.questions || [];
let work = null;
let answers = {}
if (chapter_work.data && chapter_work.data.work_contents) {
work = chapter_work.data;
try {
let answerObject = JSON.parse(work.work_contents);
answerObject.forEach(a => {
answers[a.question_id] = a;
})
} catch(e) {console.log('parse work_contents to json failed.')}
}
return (
<div className="play-paper">
<div className="play-paper-body">
<div className="play-paper-title"><div><h3>{chapter.name}</h3></div></div>
<div className="play-paper-content play-chapter-work">
<Formsy.Form
onValid={this.enableSubmitButton}
onInvalid={this.disableSubmitButton}
onValidSubmit={this.onSubmit}
onChange={this.onFormChange}
>
{questions.length ?
<ul>
{questions.map((q, qi) => {
let answer = answers[q.id] || {};
return (
<li key={qi}>
<div className="work-number">{qi + 1}.</div>
<div className="work-title">
<div className="edit_html" dangerouslySetInnerHTML={{__html: q.question_content}}></div>
</div>
<FormItem
name={'desc_' + q.id}
itemType={FormItem.TEXTRICH}
value={answer.descreption || ''}
required
/>
<FormItem
name={'file_' + q.id}
fileVal="file"
value={answer.file_url || ''}
btnClassName="upbtn"
label="请上传对应的文件附件:"
itemType={FormItem.FILE}
text="上传附件"
server="/api/tenant/util/upload-file"
fileSingleSizeLimit={1024*1024*10}
accept={[{extensions: 'docx'}]}
onFileError={this.handleUploadError}
/>
<p className="help help-file">只支持docx格式的文件,文件小于10M</p>
{answer.file_url && <a style={{display: 'block', marginBottom: '20px', color: 'blue'}} href={answer.file_url} >下载附件</a> }
</li>
);
})}
</ul>
:
<p className="no-data">暂无数据</p>
}
<p className="text-danger">{this.state.error}</p>
<div className="area-btns">
<button type="submit" disabled={!this.canSubmit() || (work && work.checker_id)} className="btn btn-primary" >{this.isSubmitLoading() ? '保存中...' : (work && work.checker_id) ? '已批改' : '提交'}</button>
<span className="help-info">&emsp;&emsp;在获老师批改之前,可以多次提交,将以最后一次提交为准</span>
{work ?
!work.checker_id ?
<p className="help">已于 {work.created_time} 提交,等待批改中</p>
:
<div className="play-paper-check">
<h4>已获批改 <small>批改于{work.check_date}</small></h4>
<div className="play-paper-check-item"><b>评分:</b>{work.score}</div>
<div className="play-paper-check-item">
<b>评语:</b>
<div className="edit_html" dangerouslySetInnerHTML={{__html:work.check_comments}}></div>
</div>
</div>
: null
}
</div>
</Formsy.Form>
</div>
</div>
</div>
);
}
}
module.exports = ChapterWork;
/**
* 课程资料
*
* courseId
* files
*/
import React, { Component } from 'react'
class CourseInfo extends Component {
render () {
const files = this.props.files || [];
return (
<div className="play-paper">
<div className="play-paper-body">
<div className="play-paper-title"><div><h3>课程资料</h3></div></div>
<div className="play-paper-content">
{files.length ?
<ul className="play-read-files">
{files.map((f, i) => {
return <li key={i}><a href={f.file_url} target="_blank">{f.file_name}</a></li>
})}
</ul>
:
<p className="no-data">暂无课程资料</p>
}
</div>
</div>
</div>
);
}
}
module.exports = CourseInfo;
/**
* 课程大作业
* porps:
* course
* course_work
* action
* dispatch
*/
import React, { Component } from 'react'
import { Link } from 'react-router';
import Formsy from 'formsy-react';
import FormsyComponent from '../../components/formsy/Component.jsx'
import FormItem from '../../components/formsy/FormItem.jsx'
import CoursesAction from '../../actions/CoursesAction'
import OperateAction from '../../actions/OperateAction'
import { getRequestTypes } from '../../libs/utils';
class CourseWork extends FormsyComponent {
constructor(props) {
super(props);
this.state = { error: '' };
}
componentDidMount () {
this.courseAction = new CoursesAction();
this.operateAction = new OperateAction();
this.courseId = this.props.course.course_id;
this.semesterId = this.props.semesterId;
// 加载回答
this.props.dispatch(this.courseAction.loadCourseWork(this.semesterId, this.courseId));
}
componentWillReceiveProps (nextProps) {
let submitType = getRequestTypes(CoursesAction.SUBMIT_COURSE_WORK);
switch (nextProps.action.type) {
case submitType.success:
this.enableSubmitButton();
if (nextProps.action.response.data.status == 0) {
nextProps.dispatch(this.operateAction.showErrorMessage('账号出错,请联系管理员'));
console.log(JSON.stringify(nextProps.action.response.data.error))
break;
}
// 提交成功,重新获取答案
nextProps.dispatch(this.courseAction.loadCourseWork(this.semesterId, this.courseId));
nextProps.handleSubmited('work');
break;
case submitType.failure:
this.enableSubmitButton();
nextProps.dispatch(this.operateAction.showErrorMessage(nextProps.action.error.message || '提交课程大作业失败'));
break;
}
}
/**
* 提交
*/
onSubmit = model => {
this.loadingSubmitButton();
model.course_id = this.props.course.course_id;
model.semester_id = this.props.semesterId;
this.props.dispatch(this.courseAction.submitCourseWork(model));
}
// 表单变更时,取消掉全局错误消息
onFormChange = () => {
this._setState({ error: '' });
}
handleUploadError = msg => {
this.props.dispatch(this.operateAction.showErrorMessage(msg || '上传文件失败'));
}
render () {
const {course, course_work} = this.props;
const info = course_work.data || {};
return (
<div className="play-paper">
<div className="play-paper-body">
<div className="play-paper-title"><div><h3>课程大作业</h3></div></div>
<div className="play-paper-content">
<div className="play-paper-step">&#9312; 阅读大作业要求</div>
<div className="edit_html" dangerouslySetInnerHTML={{__html: course.curriculum && course.curriculum.curriculum_essay || ''}}></div>
<p>截止日期:{course.essay_date || ''}</p>
<div className="play-paper-step">&#9313; 填写作业主题、摘要,上传附件(点击“提交”保存)</div>
<Formsy.Form
onValid={this.enableSubmitButton}
onInvalid={this.disableSubmitButton}
onValidSubmit={this.onSubmit}
onChange={this.onFormChange}
>
<input type="hidden" name="id" value={info.id || ''} />
<div>
<FormItem
name="essay_name"
value={info.essay_name || ''}
placeholder="主题"
required
/>
<FormItem
name="essay_description"
value={info.essay_description || ''}
label="摘要"
itemType={FormItem.TEXTRICH}
required
/>
<FormItem
name="url"
fileVal="file"
value ={info.file_url || ''}
btnClassName="upbtn"
label="大作业附件:"
itemType={FormItem.FILE}
text="选择附件"
server="/api/tenant/util/upload-file"
fileSingleSizeLimit={1024*1024*10}
accept={[{extensions: 'docx'}]}
onFileError={this.handleUploadError}
required
/>
<p className="help help-file">只支持docx格式的文件,文件小于10M</p>
{info.file_url && <a style={{display: 'block', marginBottom: '20px', color: 'blue'}} href={info.file_url} >下载附件</a> }
</div>
<p className="text-danger">{this.state.error}</p>
<div className="area-btns">
<div className="play-paper-step">&#9314; 截止日期前提交</div>
<button type="submit" disabled={!this.canSubmit() || info.checker_id} className="btn btn-primary" >{this.isSubmitLoading() ? '保存中...' : info.checker_id ? '已批改' : '提交'}</button>
<span className="help-info">&emsp;&emsp;在获老师批改之前,可以多次提交,将以最后一次提交为准</span>
{info.id ?
!info.checker_id ?
<p className="help">已于 {info.created_time} 提交,等待批改中</p>
:
<div className="play-paper-check">
<h4>已获批改 <small>批改于{info.check_date}</small></h4>
<div className="play-paper-check-item"><b>评分:</b>{info.score}</div>
<div className="play-paper-check-item">
<b>评语:</b>
<div className="edit_html" dangerouslySetInnerHTML={{__html:info.check_comments}}></div>
</div>
</div>
: null
}
</div>
</Formsy.Form>
</div>
</div>
</div>
);
}
}
module.exports = CourseWork
差异被折叠。
/**
* 侧边章节导航列表
* props:
* chapters []
* getProgressByChapterId func
* courseId
* chapterId string
* progress number
*/
import React, { Component } from 'react'
import { Link } from 'react-router';
import ProgressCircle from '../../components/ProgressCircle.jsx'
import {chapterType} from '../../libs/const'
const NAV_COURSE = {
name: '大作业及资料',
children: [{
id: 'work',
type: chapterType.WORKOREXAM,
name: '课程大作业',
homework: {work_type: chapterType.WORK_HOME}
}, {
id: 'info',
type: chapterType.READ,
name: '课程资料'
}]
};
class SideList extends Component {
reloadPages () {
window.location.reload()
}
render () {
const {chapters, getProgressByChapterId, semesterId, courseId, chapterId, progress} = this.props;
let list = (chapters || []).concat([NAV_COURSE]);
return (
<div className="tab-pane current">
<ul className="under-control chapter-list current">
{list.map((item, index) => {
return (
<li className="chapter-item" key={index}>
<span className="cpt">{item.name}</span>
<div className="knob-list-wrap">
<ul className="knob-list">
{(item.children || []).map((o, i) => {
let isCur = chapterId === o.id;
let prog = isCur ? progress : getProgressByChapterId(o.id);
let part = Math.max(Math.round(prog / 25), 0);
let type;
switch (o.type) {
case chapterType.VIDEO:
type = 'video'; break;
case chapterType.READ:
type = 'read'; break;
default:
type = 'exam';
if (o.homework && o.homework.work_type === chapterType.WORK_HOME) {
type = 'work';
}
}
return (
<li className={`knob-item ${isCur ? 'current' : ''} ${part ? ['one', 'two', 'three', 'four'][part - 1] + '-four' : ''}`} key={i}>
<ProgressCircle percent={prog} className="play-chapter-progress"/>
<i className="icon icon-pro" title={`学习进度 ${prog}%`}></i>
{(type == 'work') ?
<Link to={`/courses/${semesterId}/${courseId}/chapters/${o.id}`} className="knob-name" onClick={this.reloadPages}>{o.name}</Link>
:
<Link to={`/courses/${semesterId}/${courseId}/chapters/${o.id}`} className="knob-name" onClick={this.props.handleClickItem}>{o.name}</Link>
}
<i className={`icon-play-chapter icon-play-${type}`}></i>
</li>
);
})}
</ul>
</div>
</li>
);
})}
</ul>
</div>
);
}
}
module.exports = SideList;
/**
* 侧边显示讲义ppt
* props:
* ppts: []
* handleClickPpt: func
*/
import React, { Component } from 'react'
class SidePpt extends Component {
constructor (props) {
super(props)
this.state = { index: 0 }
}
// 根据播放时间同步展示ppt
// @param time 播放时间
setIndexByPoint = time => {
const ppts = this.props.ppts || []
const len = ppts.length
let i = 0;
for(; i < len; i++) {
if (time < ppts[i].ppt_point) {
break;
}
}
if (this.state.index !== i - 1) {
this.setState({ index: i - 1 });
}
}
//handleSyncVideoTime = e => { // 点击ppt跳转对应的播放时间
// 点击某个ppt
onClickPpt = e => {
let toIndex = e.currentTarget.getAttribute('data-index') - 0
if (this.state.index === toIndex) { return }
this.setState({ index: toIndex })
this.props.handleClickPpt(toIndex)
}
render () {
const {ppts} = this.props
return (
<div className="tab-pane current">
<div className="jiangyi-list">
<div className="jy-list">
{(ppts || []).length ?
ppts.map((item, index) => {
return (
<div key={index} onClick={this.onClickPpt} data-index={index} className={index === this.state.index ? 'current' : ''}>
<img src={item.ppt_url} alt=""/>
</div>
);
})
:
<div className="no-data">暂无讲义</div>
}
</div>
</div>
</div>
);
}
}
module.exports = SidePpt;
差异被折叠。
差异被折叠。
.play{overflow:hidden; position: fixed;top:0; z-index: 800; width: 100%; height: 100%; background-color:#3f3f3f;color:#a0a0a0;}
.left-content{ position: absolute; right: 350px; top: 0; left: 0; bottom: 0; min-width: 705px;height:100%;}
.sidebar-hide .left-content{right:0;}
.play-top{ line-height: 56px;}
.play-top p{font-size:1.5em;text-align:center;}
.play-content{position:absolute;top:56px;bottom:0;left:0;right:0;}
.play-content-video{height:100%;}
.play-center .text-error{ font-size:0.875em;line-height:1.5em; }
.play-video-hide{visible:hidden;overflow:hidden;width:0}
.play-video-init-center{position:absolute;top:50%;left:50%;margin:-180px 0 0 -275px;}
.play-ppt { position: relative;width: 550px; height: 363.375px;background-color:#000;}
.play-ppt-img { width: 100%; height: 100%;}
.play-controls {position: absolute;bottom:0;left:0;right:0;height: 44px; line-height: 42px; padding: 0 14px;background-color: #000;}
.play-controls .fl i{ color: #8c8c8b}
.play-page{ position: absolute; left: 50%; margin-left: -75px; color: #fff; width: 150px; text-align: center; font-size: 0.875em;}
.play-page .play-now { color: #d29f29;}
.play-amazing i{ color: #fff; margin: 0 10px;}
.play-amazing i.active,
.play-amazing i:hover{ color: #d29f29;}
.play-amazing .icon-rotate{ font-size: 1.125em;}
.play-footer{ position: absolute; bottom: 0; left: 0;right:0; z-index: 200;padding:18px 20px 15px;}
.play-footer a:hover{color:#a0a0a0;}
/* .play-state, .play-back{display:inline-block;color:#a0a0a0;padding-left: 25px;font-size:14px;line-height:18px;margin:0 20px;background:url(../img/play-icons.png) no-repeat 0 0;cursor:pointer} */
.play-back{position:absolute;top:10px;left:10px;width:40px;height:40px;overflow:hidden;text-indent:-300px;background-position:14px -329px;}
.play-state-prev{background-position:0 2px;}
.play-state-prev-disable{background-position:0 -78px;color:#666;}
.play-state-next{background-position:0 -38px;}
.play-state-next-disable{background-position:0 -118px;color:#666;}
.play-state-check{background-position:0 -160px;}
.play-state-check-active{background-position:0 -200px;color: #b19241;}
.play-state-ppt{background-position:0 -240px;}
.play-state-ppt-active{background-position:0 -280px;}
.play-state-prev-disable:hover,
.play-state-next-disable:hover {color:#666!important;}
.switch { display: block; width: 36px; height: 110px; position: absolute; right: 0px; top: 50%; text-align: center; margin: -55px 0 0; z-index: 998; cursor: pointer;}
/* .switch a{background:url(../img/play-side-icon.png) no-repeat 0 0;display:block;width:36px;height:54px;margin-bottom:20px;} */
.switch a.switch-handout{background-position:0 -71px;}
.right-content { position: absolute; right: 0px; width: 350px; z-index: 200; background: #212121; bottom: 0; top: 0px; border-left:19px solid #1b1b1b;}
.right-content .right-arrow{ position: absolute; left:-19px; top:0;bottom:0;width:19px;height:100%;cursor: pointer; color: #969696; font-size: 0.875em;}
.right-content .right-arrow>span{position:absolute;top: 50%;left:0;width:19px;margin-top:-10px;text-align:center}
.play .tab-content { width: 100%; position: absolute; top: 50px; bottom: 0px;}
.play .tab-content .tab-pane { display: none;}
.play .tab-content .tab-pane.current { display: block; height: 100%; overflow: auto;}
.control-panel { height: 100%; position: relative;}
.control-panel ul { margin: 0px; padding: 0px; line-height: 1.6; overflow: hidden;}
.control-panel .play-nav{padding:15px 0; border-bottom: 0;background-color:#232323;}
.play-nav li{ width: 50%;padding:0; font-size:16px; }
.play-nav li.current:after{display:none;}
.play-nav li a{ color: #909090; border:none;}
.play-nav li:first-child a{border: 0;}
.play-nav li.current a{ color: #b49441;}
.play-nav li.current:after{ width:75px; height:3px; margin: 0 0 0 -37px;}
.play-nav .videoJy{border-left:1px solid #3f3f3f;}
.control-panel span { padding: 8px 14px; color: #909090; background: #242424; display: block; padding: 14px 22px;}
.control-panel .knob-list li { position: relative; padding: 0 0px 0 23px;}
.control-panel .knob-list li a { color: #909090; font-size: 0.875em; padding: 16px 35px 16px 20px; text-decoration: none; display: block; cursor: pointer;}
.control-panel .knob-item.current { background: #232323;}
.control-panel .knob-item.current a {color:#b49441;}
.control-panel .knob-item:after { content: ""; position: absolute; left: 22px; top: 0; width: 1px; height: 100px; background: #616161; z-index: 5 }
.control-panel .knob-item:before {content: ""; width: 18px; height: 18px; border-radius:50%; border:2px solid #5b5b5b; background: #5b5b5b; position: absolute; left: 13px; top: 16px; content: ""; display: block; z-index: 10;}
.control-panel .knob-item .icon-pro{top:16px;left:23px;z-index:15;}
.control-panel .four-four .icon-pro{left:13px;}
.control-panel .jiangyi-list { line-height: 0;}
.control-panel .jiangyi-list div { cursor: pointer; padding: 8px 16px;}
.control-panel .jiangyi-list div.current { background: #888;}
.control-panel .jy-list img { width: 100%;}
#player p{color:#fff;text-align:center;padding:50px 0;}
#player p a{color:#b01c40;text-decoration:underline;}
.play-chapter-progress{position:absolute;top:16px;left:13px;z-index:20;display:none\0;}
.play-chapter-progress .circle-progress:after{background-color:#5b5b5b;}
.play-chapter-progress .circle-progress{background-color:#5b5b5b;}
.right-content .chapter-item:last-child{border-bottom:none;margin-top:10px;}
.right-content .chapter-item .cpt{color:#b0b0b0;padding:10px 22px;background-color:#2f2f2f;}
.right-content .chapter-item-active a{text-decoration:none;}
.right-content .chapter-item-active .cpt{color:#b49441;}
/* .icon-play-chapter{display:inline-block;vertical-align:middle;width:14px;height:14px;background:url(../img/icon-play-chapter.png) no-repeat;position:absolute;right:13px;top:19px;} */
.icon-play-video{background-position:0 0;}
.icon-play-work{background-position:0 -37px;}
.icon-play-exam{background-position:0 -73px;}
.icon-play-read{background-position:0 -110px;}
/*作业类页*/
.play-paper{position:absolute;top:0;bottom:0;left:0;right:0;overflow:auto;background-color:#e5e5e5;}
.play-paper-body{min-height:500px;margin:25px;padding:15px 45px 25px;color:#313131;box-shadow:0 0 2px rgba(0,0,0,.05);background-color:#f2f2f2;}
.play-paper-title{margin:0 10px;text-align:center;}
.play-paper-title div{padding-bottom:3px;display:inline-block;border-bottom:1px solid #707070;}
.play-paper-title h3{padding:0 0 5px;margin:0;display:inline-block;font-size:20px;border-bottom:3px solid #707070;}
.play-paper-body .help{color:#999;font-size:12px;}
.play-paper-body .help-file{margin-top:-10px;}
.play-paper-body .area-btns{margin:20px 0;}
.play-paper-body .area-btns .btn{padding:6px 25px;}
.play-paper-body .area-btns .help{margin-top:10px; font-size: 14px}
.play-paper-body .area-btns .help-info{display:inline-block;vertical-align:middle;}
.play-paper-body .webuploader-btn .upbtn{color:#b49441;text-decoration:underline;padding:3px 15px;font-size:.9em;display:inline-block;}
.play-paper-body .webuploader-btn .loading .fa-spin{font-size:1.2em!important;}
.play-paper-body label{font-weight:normal;}
.play-paper-body input{vertical-align:middle;}
.play-paper-check{margin-top:20px;padding:20px;border:1px solid #dedede;}
.play-paper-check h4{font-size:16px;margin:0 0 10px;}
.play-paper-check-item{padding-left:3em;}
.play-paper-check-item b{margin-left:-3em;margin-top:1px;display:inline-block;vertical-align:top;}
.play-paper-check-item .edit_html{display:inline-block;vertical-align:top;}
/*阅读材料*/
.play-read-files{padding:30px;}
.play-read-files li{font-size:16px;padding:20px 30px;margin-bottom:10px;background-color:#fff;}
/*章节作业*/
.play-chapter-work{padding:25px;}
.play-chapter-work .work-number{margin-left:-25px;}
.play-chapter-work .work-title{margin-top:-20px;margin-bottom:10px;}
.play-chapter-work .area-btns{margin:20px -25px 0;border-top:1px solid #eaeaea;padding-top:20px;}
.play-chapter-exam{padding:25px;}
.play-chapter-exam li{position:relative;margin-top:15px;border-bottom:1px solid #b49441;}
.play-chapter-exam .exam-title{margin: -20px 0 10px 25px;}
.play-chapter-exam .wrong{color:#d80000;}
.play-chapter-exam .correct{color:#090;}
.play-chapter-exam .answer{position:absolute;right:25px;bottom:10px;}
.play-chapter-exam .result{float:right;margin-top:-20px;margin-right:-20px;font-size:16px;font-weight:bold;}
.play-paper-step{font-weight:bold;font-size:16px;margin:30px -20px 15px;padding-bottom:10px;border-bottom:1px dashed #cecece;}
@media (max-width:768px){
.left-content {min-width:0;right:0;}
.play-back{margin:0;}
.play-chapter-work{padding:25px 0;margin-right:-20px;}
.play-read-files{padding:30px 0;margin:0 -20px;}
.switch{top:80%;}
.play-paper-body{ padding: 15px 25px 25px; }
.play-paper-step{ margin: 30px 0 15px; }
}
<template>
<div className={`play ${this.state.sidebar ? '' : 'sidebar-hide'}`}>
<div className="left-content">
<div className="play-top cl" style={this.state.sidebar ? {} : {marginRight: 0}}>
<Link className="play-back" to={`/courses/${params.semesterId}/${params.courseId}/cont`} onClick={this.onClickToDetail}>&lt;</Link>
<p>{course.course_name}</p>
<p>{chapter.chapter_name}</p>
</div>
<div className="play-content">
{params.chapterId === 'work' ?
<CourseWork
course={course}
semesterId={course.semester_id}
course_work={this.props.course_work}
dispatch={this.props.dispatch}
action={this.props.action}
handleSubmited={this.chapterSubmited}
/>
: params.chapterId === 'info' ?
<CourseInfo
courseId={params.courseId}
files={course.files}
/>
: chapter.type === chapterType.VIDEO ?
<ChapterVideo
ref="chapterVideo"
courseId={params.courseId}
semesterId={course.semester_id}
ppts={ppts}
chapter={chapter}
username={user.data && user.data.username || ''}
prevChapterId={prevChapterId}
nextChapterId={nextChapterId}
curProgress={curProgress}
handlePlayTime={this.handlePlayTime}
handleOver={this.handleOver}
lastTime={cpt}
/>
: chapter.type === chapterType.WORKOREXAM ?
(chapter.homework && chapter.homework.work_type === chapterType.WORK_HOME ?
<ChapterWork
chapter={chapter}
chapter_work={this.props.chapter_work}
courseId={params.courseId}
semesterId={course.semester_id}
action={this.props.action}
dispatch={this.props.dispatch}
handleSubmited={this.chapterSubmited}
/>
:
<ChapterExam
chapter={chapter}
chapter_work={this.props.chapter_work}
courseId={params.courseId}
semesterId={course.semester_id}
action={this.props.action}
dispatch={this.props.dispatch}
handleSubmited={this.chapterSubmited}
/>
)
:
<ChapterRead
chapter={chapter}
handleReaded={this.sendReaded}
/>
}
</div>
</div>
<div className="right-content" style={{ right: this.state.sidebar ? 0 : -388 }}>
<p className="right-arrow" onClick={this.handleHideSidebar}><span>&gt;</span></p>
<div className="control-panel">
<ul className="nav-tabs play-nav cl">
<li className={`videoChapter ${this.state.sidebar === SIDEBAR_CHAPTER ? 'current' : ''}`}><a href="#sidebar_chapter" onClick={this.handleShowSidebarChapter}>章节</a></li>
{ppts.length ?
<li className={`videoJy ${this.state.sidebar === SIDEBAR_PPT ? 'current' : ''}`}><a href="#sidebar_ppt" onClick={this.handleShowSidebarPpt}>讲义</a></li>
: null
}
</ul>
<div className="tab-content">
{this.state.sidebar === SIDEBAR_CHAPTER ?
<SideList
chapters={chapters}
getProgressByChapterId={this.getProgress}
courseId={params.courseId}
semesterId={params.semesterId}
chapterId={params.chapterId}
progress={curProgress}
handleClickItem={IS_PHONE ? this.handleHideSidebar1 : this.reloadPages}
/>
:
<SidePpt
ref="sidePpt"
ppts={ppts}
handleClickPpt={this.handleClickSidePpt}
/>
}
</div>
</div>
</div>
{this.state.sidebar ? null :
<div className="switch">
<a href="#sidebar_chapter" className="switch-chapter" onClick={this.handleShowSidebarChapter}></a>
{isVideo && ppts.length ?
<a href="#sidebar_ppt" className="switch-handout" onClick={this.handleShowSidebarPpt}></a>
: null
}
</div>
}
</div>
</template>
<style lang="scss" scoped>
@import './index.css';
</style>
import BaseAPI from '../base_api'
export default class ChapterAPI extends BaseAPI {
/**
* 获取章节列表信息
* @param {[string]} cur_course_id -> cid
* @param {[string]} cur_semester_id -> sid
* @param {[string]} cur_video_id -> vid
*/
getChapterList = (cid, sid, vid) => this.get(`/v2/education/courses/${sid}/${cid}`, {})
/**
* 获取对应某个章节的详细信息
* @param {[string]} vid
*/
getCurrentChapterDetail = (vid) => this.post('/v2/education/video-streaming', { vid })
/**
* 获取进度信息
* @param {[string]} vid
* @param {[string]} did
* @param {[string]} sid
*/
getProgress = (vid, did, sid) => this.get(`/v2/education/video/${sid}/${vid}/device`, { device_id: did })
/**
* 提交进度信息
* @param {[object]} obj
*/
updateProgress = (obj = {}) => this.post('/v2/analytics/upload-video', {
d: obj.did,
i: obj.did,
c: obj.cid,
s: obj.sid,
v: obj.vid,
_p: obj.pt, // 累计时间
_m: obj.mpt, // 当前播放最大时间
_c: obj.cpt // 当前播放位置
})
}
import BaseAPI from '../base_api'
export default class CourseAPI extends BaseAPI {
/**
* 获取学期分类信息
*/
getlearnFindList = () => this.get('/v2/education/semesters', {})
/**
* 获取所有课程列表 - 选课广场 和 我的课程 共用同一个,通过 isMy判断
* @param {[string]} isMy
* @param {[object]} param
*/
getCourseList = (isMy, param) => this.get('/v2/education/courses' + (isMy ? '/my' : ''), param)
/**
* 获取某个课程详细信息 - 课程考核 和 课程讨论单独获取
* @param {[string]} id
* @param {[string]} sid
*/
getCourseDetail = (id, sid) => this.get(`/v2/education/courses/${sid}/${id}`, {})
/**
* 获取课程考核信息
* @param {[string]} cid
* @param {[string]} sid
*/
getCourseAssess = (cid, sid) => this.get(`/v2/analytics/courses/${sid}/${cid}/evaluation`, {})
/**
* 获取试题信息
* @param {[string]} eid
* @param {[string]} sid
*/
getExamDetail = (eid, sid) => this.get(`/v2/education/homeworks/${sid}/${eid}`, {})
/**
* 提交考试信息
* @param {[object]} param
*/
submitExamDetail = (param) => this.post(`/v2/education/homeworks`, param)
/**
* 选课
* @param {[string]} cid
* @param {[string]} sid
*/
selectCourse = (cid, sid) => this.post(`/v2/education/courses/major`, { course_id: cid, semester_id: sid })
/**
* 退课
* @param {[string]} cid
* @param {[string]} sid
*/
outSelectCourse = (cid, sid) => this.post(`/v2/education/courses/drop`, { course_id: cid, semester_id: sid })
}
import BaseAPI from '../base_api'
export default class DiscussAPI extends BaseAPI {
/**
* 获取讨论题目列表,“我提出的问题”和“我参与的问题”信息
* dataJson.limit - 获取数量
* dataJson.offset - 偏移量
* @param {[string]} path
* @param {[object]} dataJson
*/
getDiscussList = (path, dataJson) => this.get('/v2/qa/questions' + path, dataJson)
/**
* 获取讨论题目列表,“课程的问题”信息
* dataJson.limit - 获取数量
* dataJson.offset - 偏移量
* dataJson.sort - 排序类型
* @param {[string]} cid
* @param {[string]} sid
* @param {[object]} dataJson
*/
getCourseDiscussList = (cid, sid, dataJson) => this.get(`/v2/qa/questions/course/${sid}/${cid}`, dataJson)
/**
* 获取问题详情
* @param {[string]} qid
*/
getDiscussDetail = (qid) => this.get(`/v2/qa/questions/${qid}`, {})
/**
* 删除提问
* @param {[string]} qid
*/
deleteDiscuss = (qid) => this.delete(`/v2/qa/questions/${qid}`, {})
/**
* 提出问题
* @param {[object]} param
*/
publishQues = (param) => this.get(`/v2/qa/questions`, param)
/**
* 回答问题
* @param {[object]} param
*/
answerQues = (param) => this.post(`/v2/qa/answers`, param)
/**
* 删除回答
* @param {[string]} aid
*/
deleteAnswer = (aid) => this.delete(`/v2/qa/answers/${aid}`, {})
/**
* 回复评论
* @param {[object]} param
*/
callbackComment = (param) => this.get(`/v2/qa/comments`, param)
/**
* 删除评论
* @param {[string]} cid
*/
deleteComment = (cid) => this.delete(`/v2/qa/comments/${cid}`, {})
/**
* 点赞
* @param {[object]} param
*/
like = (param) => this.post(`/v2/qa/tags`, param)
/**
* 取消点赞
* @param {[string]} tagid
*/
unlike = (tagid) => this.delete(`/v2/qa/tags/${tagid}`, {})
}
import BaseAPI from '../base_api'
export default class LoginAPI extends BaseAPI {
/**
* 调用登录接口
* @param {[string]} obj.account 用户名
* @param {[string]} obj.password 密码 md5加密
*/
userLogin = obj => this.post('/tenant/user/login', obj)
/**
* 获取政策文件列表
* @param {[string]} obj.page 传入页码
* @param {[string]} obj.per_page 每页多少条
*/
getDocuments = obj => this.get('/v1/cms/documents', obj)
/**
* 当前登录用户,检测是否该系统有权限
*/
getInfo = () => this.get('/tenant/user/getinfo', {})
}
import BaseAPI from '../base_api'
export default class MsgAPI extends BaseAPI {
/**
* 获取我的消息信息
*/
getMyMsg = () => this.get('/v2/education/message/my', {})
}
import BaseAPI from '../base_api'
export default class ScoreAPI extends BaseAPI {
/**
* 获取学术报告列表
*/
getReportList = () => this.get('/tenant/user/getinfo', {})
}
import BaseAPI from '../base_api'
export default class ScoreAPI extends BaseAPI {
/**
* 获取我的学分信息
*/
getMyScore = () => this.get('/v2/education/credits', {})
}
import BaseAPI from './base_api'
export default class BackendAPI extends BaseAPI {
/**
* 获取文章列表
*/
getArticleList = (obj = {}) => this.get('/v1/cms/projects', obj)
/**
* 获取政策文件列表
* @param {[string]} obj.page 传入页码
* @param {[string]} obj.per_page 每页多少条
*/
getDocuments = obj => this.get('/v1/cms/documents', obj)
/**
* 获取政策文件详情
* @param {[string]} id 传入政策文件id
*/
getDocumentsId = (id, obj = {}) => this.get('/v1/cms/documents/' + id, obj)
/**
* 查询证书接口
* @param {[string]} obj.id_card_type 证件类型;身份证:10 军官证:20 默认:10;不必填
* @param {[string]} obj.id_card_number 证件号码;必填
* @param {[string]} obj.name 姓名;必填
* @param {[string]} obj.cert_id 证件编号;必填
*/
getCertify = obj => this.post('/v1/ea/certificates/query', obj)
}
import axios from 'axios'
import _ from 'lodash'
import tools from '@tools'
export default class API {
constructor (config) {
/* 创建一个 自定义配置axios实例 */
axios.defaults.withCredentials = true // 让ajax携带cookie
this._axios = axios.create({
timeout: config.timeout || 5 * 1000,
/* 表示服务器响应的数据类型,可以是 'arraybuffer', 'blob', 'document', 'json', 'text', 'stream' */
......@@ -24,6 +26,30 @@ export default class API {
/* 具体执行请求失败后业务逻辑前,先执行该方法 */
let beforeFail = _config.beforeFail ? _config.beforeFail : this._reqFail
/* 这里可以统一处理 登录 */
/**
* 增加 Cookie 和 请求头传值,如果是 服务端渲染,就放Node端
* 所有请求 全部增加 token 和 tenant 请求头并 自带 cookie
*/
let s = decodeURIComponent(tools.cookies.getCookie('_SUP') || '')
let ticket = ''
s = s.match(/"([\d\w=]+)";\}$/)
if (s && s.length === 2) {
s = new Buffer(s[1], 'base64').toString() // eslint-disable-line
s = s.slice(12, s.search('-TGT') + 4)
ticket = s.split('').reverse().join('')
}
let headers = {
// 'User-Agent': req.get('user-agent'),
// 'X-Forwarded-For': req.get('x-forwarded-for'),
// 'X-Real-Ip': req.get('x-real-ip'),
// 'Referer': req.get('referer'),
// 'Cookie': tools.cookies.getAllCookies(),
'token': ticket,
'tenant': 'sofia'
}
_config.headers = _.assignIn(_config.headers, headers)
/* 创建并根据参数发起请求 */
return this._axios(_config)
.then(beforeSuccess.bind(this), beforeFail.bind(this))
......@@ -36,8 +62,18 @@ export default class API {
*/
_reqSuccess (res) {
let { status, data } = res
let err = null
/* 针对 MBA学习系统 做特殊 请求成功处理 */
if (status === 200) {
return data
if (data.status !== 200 && data.message) {
err = new Error(data.message)
throw err
} else {
return data
}
} else {
err = new Error(JSON.stringify(res.data))
throw err
}
}
......@@ -49,12 +85,17 @@ export default class API {
_reqFail (res) {
let err = null
if (res.response) {
err = new Error(res.response.message)
// err.code = res.response.result_code
if (res.response.data) {
err = new Error(res.response.data.message)
} else {
/* 错误处理,服务端非正常返回 */
err = new Error(JSON.stringify(res.response))
}
} else {
err = new Error(res.message)
err = new Error('msg:' + res.message + 'stack:' + res.stack)
err.code = 500
}
/* 如果出错,创建错误对象,并抛出一个错误。 */
throw err
}
......
import BackendAPI from './backend_api'
import LoginAPI from './api/login_api'
import ChapterAPI from './api/chapter_api'
import CourseAPI from './api/course_api'
import DiscussAPI from './api/discuss_api'
import MsgAPI from './api/msg_api'
import ScoreAPI from './api/score_api'
import ReportAPI from './api/report_api'
let backendApi = new BackendAPI(webConf)
let loginApi = new LoginAPI(webConf)
let chapterApi = new ChapterAPI(webConf)
let courseApi = new CourseAPI(webConf)
let discussApi = new DiscussAPI(webConf)
let msgApi = new MsgAPI(webConf)
let scoreApi = new ScoreAPI(webConf)
let reportApi = new ReportAPI(webConf)
export {
backendApi
loginApi,
chapterApi,
courseApi,
discussApi,
msgApi,
scoreApi,
reportApi
}
export default class ConvertTime {
/**
* 工具方法 - 播放时间 转化 h:m:s
* @param {[string]} duration 时间戳
*/
durationToTimeString (duration) {
let h = Math.floor(duration / 3600)
let m = Math.floor((duration - h * 3600) / 60)
let s = (duration - h * 3600 - m * 60) % 60
function tenify (a) {
return a >= 10 ? a : '0' + a
}
let to = { h: tenify(h), m: tenify(m), s: tenify(s) }
let format = 'h:m:s'
return format.replace(/h|m|s/g, k => to[k]).replace(/^00:/, '')
}
}
export default class Cookies {
/**
* 设置 Cookies,用于客户端
* @param {[string]} cName 要设置cookie的key值
* @param {[string]} cValue 要设置cookie的value值
* @param {[object]} obj 要设置cookie的其他值
* @param {[object]} obj.path 路径
* @param {[object]} obj.domain 域名
* @param {[object]} obj.expires 过期时间
*/
setCookie (cName, cValue, obj) {
let d = new Date()
if (obj.expires) {
d.setTime(d.getTime() + ((obj.expires || 0) * 24 * 60 * 60 * 1000))
obj.expires = d.toUTCString()
}
let str = ''
for (let key in obj) {
str += '; ' + key + '=' + obj[key]
}
document.cookie = cName + '=' + cValue + str
}
/**
* 获取指定cookie,用于客户端
* @param {[string]} cName 要获取cookie的key值
*/
getCookie (cName) {
let key = cName + '='
let ca = document.cookie.split(';')
for (let i = 0; i < ca.length; i++) {
let c = ca[i]
while (c.charAt(0) === ' ') c = c.substring(1)
if (c.indexOf(key) !== -1) {
return c.substring(key.length, c.length)
}
}
return ''
}
/**
* 获取全cookie,用于客户端
*/
getAllCookies () {
return document.cookie
}
/**
* 清除cookie,用于客户端
* @param {[string]} cName 要清除cookie的key值
*/
clearCookie (cName) {
document.cookie = cName + '=; expires=-1'
}
}
import Cookies from './cookies'
import ConvertTime from './convert_time'
let cookies = new Cookies()
let convertTime = new ConvertTime()
export default {
cookies,
convertTime
}
import { chapterApi } from '@services'
import tools from '@tools'
export default class ChapterActon {
/* 获取章节列表信息 */
getChapterList (cid, sid, vid, callback) {
return chapterApi.getChapterList(cid, sid, vid).then(res => {
let i = 0
let j = 0
let nextVideo = {}
let prevVideo = {}
/* 计算上一章 和 下一章 */
for (; i < res.data.chapters.length; i++) {
let _ = res.data.chapters[i]
for (j = 0; j < _.children.length; j++) {
if (_.children[j].resource_id === vid) {
// wx.setNavigationBarTitle({ title: _.children[j].name || '音视频' });
if (j - 1 >= 0) {
prevVideo = {
id: _.children[j - 1].resource_id,
time: (_.children[j - 1].video && tools.convertTime.durationToTimeString(_.children[j - 1].video.video_length)) || '',
name: _.children[j - 1].name
}
} else if (i - 1 >= 0) {
let _temp = res.data.chapters[i - 1]
prevVideo = {
id: _temp.children[_temp.children.length - 1].resource_id,
time: (_temp.children[_temp.children.length - 1].video && tools.convertTime.durationToTimeString(_temp.children[_temp.children.length - 1].video.video_length)) || '',
name: _temp.children[_temp.children.length - 1].name
}
}
if (j + 1 < _.children.length) {
nextVideo = {
id: _.children[j + 1].resource_id,
time: (_.children[j + 1].video && tools.convertTime.durationToTimeString(_.children[j + 1].video.video_length)) || '',
name: _.children[j + 1].name
}
} else if (i + 1 < res.data.chapters.length) {
let _temp = res.data.chapters[i + 1]
nextVideo = {
id: _temp.children[0].resource_id,
time: (_temp.children[0].video && tools.convertTime.durationToTimeString(_temp.children[0].video.video_length)) || '',
name: _temp.children[0].name
}
}
}
}
}
let json = {
isShow: false,
currentChapterId: vid,
course: res.data.chapters.map((_, i) => {
return {
title: _.name,
chapters: _.children.map((__, j) => {
let _homework = (__.type === 3 && __.homework && __.homework.work_type === 1 && __.homework) || ''
if (_homework) {
_homework.course_id = res.data.course_id
_homework.chapter_id = __.id
_homework.work_id = __.resource_id
_homework.semester_id = res.data.semester_id
}
return {
id: __.resource_id,
time: (__.video && tools.convertTime.durationToTimeString(__.video.video_length)) || '',
name: __.name,
homework: _homework
}
})
}
}),
nextVideo: nextVideo,
prevVideo: prevVideo
}
// callback(json) // 可以不使用callback 因为使用then
return json
})
}
/* 获取对应某个章节的详细信息 */
getCurrentChapterDetail (vid, callback) {
return chapterApi.getCurrentChapterDetail(vid).then(res => {
let json = {
video: {
src: res.data.video[0].playurl,
spareSrc: 'http://pd4t7ae3m.bkt.clouddn.com/test.mp4' // 正式环境时,需要将 contentVideo 中 spareSrc 改成 src
},
audio: {
src: res.data.audio[0].url,
poster: (res.data.ppts && res.data.ppts[0] && res.data.ppts[0].ppt_url) || ''
},
image: {
imgUrls: res.data.ppts && res.data.ppts.map(function (_, i) { return _.ppt_url }),
current: 0,
selectIndex: 0,
timeArr: res.data.ppts && res.data.ppts.map(function (_, i) { return _.ppt_point })
}
}
// callback(json) // 可以不使用callback 因为使用then
return json
})
}
/* 获取进度信息 */
getProgress (vid, did, sid, callback) {
return chapterApi.getProgress(vid, did, sid).then(res => {
// callback(res.data) // 可以不使用callback 因为使用then
return res.data
})
}
/* 提交进度信息 */
updateProgress (obj) {
return chapterApi.updateProgress(obj).then(res => res)
}
}
import { courseApi } from '@services'
import tools from '@tools'
export default class CourseAction {
/* 获取学期分类信息 */
getlearnFindList (callback) {
return courseApi.getlearnFindList().then(res => {
let json = [{ val: '-1', name: '全部' }]
for (let i = 0; i < res.data.length; i++) {
let _list = res.data
json.push({
val: _list[i].id,
name: _list[i].semester_name
})
}
// callback(json) // 可以不使用callback 因为使用then
return json
})
}
/* 获取所有课程列表 - 选课广场 和 我的课程 共用同一个,通过 isMy判断 */
getCourseList (isMy, param, callback) {
return courseApi.getCourseList(isMy, param).then(res => {
let json = []
for (let i = 0; i < res.data.length; i++) {
let cur = res.data[i]
let _cur = res.data[i].curriculum
/* 课程类型 */
let _type = _cur.curriculum_elective_type
let str1 = _type === 1 ? '必修课' : (_type === 2 ? '选修课' : (_type === 3 ? '重修课' : ''))
json.push({
id: cur.course_id,
sid: cur.semester_id,
src: (_cur && _cur.curriculum_picture) || '',
title: cur.course_name,
arrTab: [(((_cur && _cur.curriculum_credit) || 0) + '学分'), str1, cur.semester_name],
status: _cur.is_enabled ? '已发布' : '未发布',
time: cur.begin_date.split(' ')[0] + ' 至 ' + cur.end_date.split(' ')[0],
myStatus: cur.selected !== 0 ? (cur.score ? ('总成绩:' + cur.score) : '已选修') : '未选修',
progress: cur.course_progress + '%'
})
}
// callback(json) // 可以不使用callback 因为使用then
return json
})
}
/* 获取某个课程详细信息 - 课程考核 和 课程讨论单独获取 */
getCourseDetail (id, sid, callback) {
return courseApi.getCourseDetail(id, sid).then(res => {
let cur = res.data
let _cur = cur.curriculum
/* 课程类型 */
let _type = _cur.curriculum_elective_type
let str1 = _type === 1 ? '必修课' : (_type === 2 ? '选修课' : (_type === 3 ? '重修课' : ''))
let json = {
headerInfo: {
isStart: !!cur.selected, // 是否为开始学习按钮 或者 选课按钮
id: cur.course_id,
sid: cur.semester_id,
bgSrc: (_cur && _cur.curriculum_picture) || '../icons/home/default.jpg',
title: cur.course_name,
arrTab: [(((_cur && _cur.curriculum_credit) || 0) + '学分'), str1, cur.semester_name],
status: _cur.is_enabled ? '已发布' : '未发布',
time: cur.begin_date.split(' ')[0] + ' 至 ' + cur.end_date.split(' ')[0],
progress: cur.course_progress + '%'
},
tabs0Content: {},
tabs1ChapterList: {}
}
/* 课程简介 */
json.tabs0Content = {
text: _cur && _cur.curriculum_represent,
teachers: []
}
for (let i = 0; i < cur.lecturers.length; i++) {
let item = cur.lecturers[i]
json.tabs0Content.teachers.push({
src: item.lecturer_avatar,
name: item.lecturer_name,
edu: item.lecturer_education || '',
job: item.lecturer_office || '',
unit: item.lecturer_title || ''
})
}
/* 课程内容 */
json.tabs1ChapterList = {
currentChapterId: cur.latest_play || '',
course: cur.chapters.map((_, i) => {
return {
title: _.name,
isUp: true,
chapters: _.children.map((__, j) => {
let _homework = (__.type === 3 && __.homework && __.homework.work_type === 1 && __.homework) || ''
if (_homework) {
_homework.course_id = res.data.course_id
_homework.chapter_id = __.id
_homework.work_id = __.resource_id
_homework.semester_id = res.data.semester_id
}
return {
cid: cur.course_id,
sid: cur.semester_id,
vid: __.resource_id,
time: (__.video && tools.convertTime.durationToTimeString(__.video.video_length)) || '',
name: __.name,
homework: _homework
}
})
}
})
}
json.tabs1ChapterList.course.push({
title: '课程大作业',
isUp: true,
chapters: []
})
json.tabs1ChapterList.course.push({
title: '课程资料',
isUp: true,
chapters: []
})
/* 课程考核 考核标准文案读取 */
json.tabs3richTest = cur.course_evaluation
// callback(json) // 可以不使用callback 因为使用then
return json
})
}
/* 获取课程考核信息 */
getCourseAssess (cid, sid, callback) {
return courseApi.getCourseAssess(cid, sid).then(res => {
let cur = res.data
let video = []
for (let i in cur.video_evaluation) {
let _ = cur.video_evaluation[i]
let tempArr = []
for (let j in _.sections) {
let __ = _.sections[j]
tempArr.push({
name: __.title,
time: (__.duration && tools.convertTime.durationToTimeString(__.duration)) || '00:00',
progress: (__.progress && (__.progress + '%')) || '0%'
})
}
video.push({
title: _.title,
arr: tempArr
})
}
let homewrok = []
for (let i in cur.homework_evaluation) {
let _ = cur.homework_evaluation[i]
let tempArr = []
for (let j in _.sections) {
let __ = _.sections[j]
tempArr.push({
name: __.title,
score: __.score || '0'
})
}
homewrok.push({
title: _.title,
arr: tempArr
})
}
let json = {
score: cur.course_score,
duration: tools.convertTime.durationToTimeString(cur.course_duration || 0),
progress: cur.course_progress,
video: video,
homewrok: homewrok,
essay: {
status: cur.essay_evaluation.status || '暂无',
score: cur.essay_evaluation.score || '暂无'
}
}
// callback(json) // 可以不使用callback 因为使用then
return json
})
}
/* 获取试题信息 */
getExamDetail (eid, sid, callback) {
return courseApi.getExamDetail(eid, sid).then(res => {
// callback(res) // 可以不使用callback 因为使用then
return res
})
}
/* 提交考试信息 */
submitExamDetail (param, callback) {
return courseApi.submitExamDetail(param).then(res => {
// callback(res) // 可以不使用callback 因为使用then
return res
})
}
/* 选课 */
selectCourse (cid, sid, callback) {
return courseApi.selectCourse(cid, sid).then(res => {
// callback(res) // 可以不使用callback 因为使用then
return res
})
}
/* 退课 */
outSelectCourse (cid, sid, callback) {
return courseApi.outSelectCourse(cid, sid).then(res => {
// callback(res) // 可以不使用callback 因为使用then
return res
})
}
}
import { discussApi } from '@services'
export default class DiscussAction {
/* 获取讨论题目列表,“我提出的问题”和“我参与的问题”信息 */
/**
* dataJson.limit - 获取数量
* dataJson.offset - 偏移量
*/
getDiscussList (path, dataJson, callback) {
return discussApi.getDiscussList(path, dataJson).then(res => {
let _data = res.data
let json = _data.map(function (_, i) {
return {
id: _.id,
sid: _.semester_id,
user: {
url: _.questioner.avatar || '',
name: _.questioner.nickname,
time: _.created_time
},
title: _.title,
text: _.contents,
askCnt: _.answer_count,
TouCnt: _.tag_total_count,
courseName: '在线学习课程',
comments: _.comments,
mine: _.mine
}
})
// callback(json) // 可以不使用callback 因为使用then
return json
})
}
/* 获取讨论题目列表,“课程的问题”信息 */
/**
* dataJson.limit - 获取数量
* dataJson.offset - 偏移量
* dataJson.sort - 排序类型
*/
getCourseDiscussList (cid, sid, dataJson, callback) {
return discussApi.getCourseDiscussList(cid, sid, dataJson).then(res => {
let _data = res.data
let json = _data.map(function (_, i) {
return {
id: _.id,
sid: _.semester_id,
user: {
url: _.questioner.avatar || '',
name: _.questioner.nickname,
time: _.created_time
},
title: _.title,
text: _.contents,
askCnt: _.answer_count,
TouCnt: _.tag_total_count,
courseName: '在线学习课程',
comments: _.comments,
mine: _.mine
}
})
// callback(json) // 可以不使用callback 因为使用then
return json
})
}
/* 获取问题详情 */
getDiscussDetail (qid, callback) {
return discussApi.getDiscussDetail(qid).then(res => {
let _data = res.data
let json = {
ques: {
qid: _data.id,
sid: _data.semester_id,
user: {
url: _data.questioner.avatar || '',
name: _data.questioner.nickname,
time: _data.created_time
},
title: _data.title,
text: _data.contents,
askCnt: _data.answer_count || 0,
TouCnt: _data.tag_total_count || 0,
likeCnt: _data.tag_count || 0,
comCnt: _data.comments.length,
mine: _data.mine,
isShowComment: false,
has_tag: _data.has_tag,
tag_id: (_data.tag && _data.tag.id) || '',
comments: _data.comments.map(function (_, i) {
return {
cid: _.id,
user: {
url: _.observer.avatar || '',
name: _.observer.nickname,
time: _.created_time
},
text: _.comments,
mine: _.mine
}
})
},
answer: (_data.answers && _data.answers.map(function (_, i) {
return {
aid: _.id,
user: {
url: _.replier.avatar || '',
name: _.replier.nickname,
time: _.created_time
},
text: _.contents,
likeCnt: _.tag_count,
comCnt: _.comments.length,
mine: _.mine,
isShowComment: false,
has_tag: _.has_tag,
tag_id: (_.tag && _.tag.id) || '',
comments: _.comments.map(function (__, i) {
return {
cid: __.id,
user: {
url: __.observer.avatar || '',
name: __.observer.nickname,
time: __.created_time
},
text: __.comments,
mine: __.mine
}
})
}
})) || []
}
// callback(json) // 可以不使用callback 因为使用then
return json
})
}
/* 删除提问 */
deleteDiscuss (qid, callback) {
return discussApi.deleteDiscuss(qid).then(res => {
let _data = res.data
if (_data.success) {
// callback(res) // 可以不使用callback 因为使用then
return res
}
})
}
/* 提出问题 */
publishQues (param, callback) {
return discussApi.publishQues(param).then(res => {
let _data = res.data
if (_data.success) {
// callback(res) // 可以不使用callback 因为使用then
return res
}
})
}
/* 回答问题 */
answerQues (param, callback) {
return discussApi.answerQues(param).then(res => {
let _data = res.data
if (_data.success) {
// callback(res) // 可以不使用callback 因为使用then
return res
}
})
}
/* 删除回答 */
deleteAnswer (aid, callback) {
return discussApi.deleteAnswer(aid).then(res => {
let _data = res.data
if (_data.success) {
// callback(res) // 可以不使用callback 因为使用then
return res
}
})
}
/* 回复评论 */
callbackComment (param, callback) {
return discussApi.callbackComment(param).then(res => {
let _data = res.data
if (_data.success) {
// callback(res) // 可以不使用callback 因为使用then
return res
}
})
}
/* 删除评论 */
deleteComment (cid, callback) {
return discussApi.deleteComment(cid).then(res => {
let _data = res.data
if (_data.success) {
// callback(res) // 可以不使用callback 因为使用then
return res
}
})
}
/* 点赞 */
like (param, callback) {
return discussApi.like(param).then(res => {
let _data = res.data
if (_data.success) {
// callback(res) // 可以不使用callback 因为使用then
return res
}
})
}
/* 取消点赞 */
unlike (tagid, callback) {
return discussApi.unlike(tagid).then(res => {
let _data = res.data
if (_data.success) {
// callback(res) // 可以不使用callback 因为使用then
return res
}
})
}
}
import { loginApi } from '@services'
import tools from '@tools'
import hmacSHA256 from 'crypto-js/hmac-sha256'
import Base64 from 'crypto-js/enc-base64'
export default class LoginAction {
/**
* 当前登录用户,检测是否该系统有权限
*/
getInfo (callback) {
return loginApi.getInfo().then(res => {
// callback(res) // 可以不使用callback 因为使用then
return res
})
}
/**
* 调用登录接口
*/
userLogin (obj, callback) {
return loginApi.userLogin(obj).then(res => {
/* 设置cookie */
let expires = new Date(Date.now() + 30 * 24 * 60 * 60 * 1000)
// 翻转、加盐、base64
const salt = '0ZSGxuBkSJS5'
let sup = res.ticket.split('').reverse().join('')
let rad = Math.random()
let token = salt + sup + rad
sup = new Buffer(token).toString('base64') // eslint-disable-line
// yii格式加密 hmac sha256
let serialize = `a:2:{i:0;s:4:"_SUP";i:1;s:${sup.length}:"${sup}";}`
let hamc = Base64.stringify(hmacSHA256(serialize, 'VzpR5JMDNqUsOZ0IFQARNLU9_0KLr9UC'))
sup = encodeURIComponent(hamc + serialize)
// 设置到cookie
let opts = { path: '/', domain: '.ezijing.com', expires: expires }
tools.cookies.setCookie('_SUP', sup, opts)
// result.data.uid = result.data.sso_id
// callback(res) // 可以不使用callback 因为使用then
return res
})
}
}
import { msgApi } from '@services'
export default class MsgAction {
/* 获取我的消息信息 */
getMyMsg (callback) {
return msgApi.getMyMsg().then(res => {
let json = res.data.map(function (_, i) {
return {
isRead: false,
id: _.id,
text: _.message,
time: _.created_time,
isShow: false // 该字段用来做 每条信息的打开、关闭
}
})
// callback(json) // 可以不使用callback 因为使用then
return json
})
}
}
import { reportApi } from '@services'
export default class ReportAction {
/* 获取学术报告列表 */
getReportList (callback) {
return reportApi.getReportList().then(res => {
debugger
// callback(res) // 可以不使用callback 因为使用then
return res
})
}
}
import { scoreApi } from '@services'
export default class ScoreAction {
/* 获取我的学分信息 */
getMyScore (callback) {
return scoreApi.getMyScore().then(res => {
let _data = res.data
let json = {
total: _data.total_credits,
myTotal: _data.my_total_credits,
myTotalStr: (_data.total_credits && ((_data.my_total_credits * 1.0 / _data.total_credits * 100).toFixed(1) + '%')) || '0%',
must: _data.required_credits,
myMust: _data.my_required_credits,
myMustStr: (_data.required_credits && ((_data.my_required_credits * 1.0 / _data.required_credits * 100).toFixed(1) + '%')) || '0%',
unmust: _data.optional_credits,
myUnmust: _data.my_optional_credits,
myUnmustStr: (_data.optional_credits && ((_data.my_optional_credits * 1.0 / _data.optional_credits * 100).toFixed(1) + '%')) || '0%'
}
// callback(json) // 可以不使用callback 因为使用then
return json
})
}
}
import LoginAction from './LoginAction'
import ChapterAction from './ChapterAction'
import CourseAction from './CourseAction'
import DiscussAction from './DiscussAction'
import MsgAction from './MsgAction'
import ScoreAction from './ScoreAction'
import ReportAction from './ReportAction'
let loginAction = new LoginAction()
let chapterAction = new ChapterAction()
let courseAction = new CourseAction()
let discussAction = new DiscussAction()
let msgAction = new MsgAction()
let scoreAction = new ScoreAction()
let reportAction = new ReportAction()
export default {
loginAction,
chapterAction,
courseAction,
discussAction,
msgAction,
scoreAction,
reportAction
}
......@@ -59,4 +59,7 @@ export default {
background: #252625;
box-shadow: 0 1px 8px rgba(0, 0, 0, 0.1);
}
.el-main {
padding: 0;
}
</style>
......@@ -14,7 +14,7 @@ export default class GlobalVariable {
*/
setInitSiderbarVar (Vue, obj) {
let _$ = Vue.prototype.$GlobalVariable
if ((!_$['siderbar']) && /^\/app\//g.test(obj.to.path)) {
if (/^\/app\//g.test(obj.to.path)) {
_$['siderbar'] = {
defaultPath: (obj && obj.to && obj.to.path) || ''
}
......
<template>
<div class="con-tainer">
<router-view></router-view>
</div>
<router-view></router-view>
</template>
<style lang="scss" scoped>
.con-tainer {
background: #ffffff;
padding: 20px;
}
</style>
......@@ -46,4 +46,17 @@ export default {
}
}
}
@media (max-width: 767px) {
.menu {
.nav-left {
img.logo {
display: none;
}
.text-title {
margin-left: 0;
}
}
}
}
</style>
<template>
<el-aside :style="[obj.sidebarStyle]">
<el-menu :default-active="defaultActive" :collapse="obj.status">
<el-menu-item index="0" class="my-account" @click="goUpdatePic">
<div class="pic">
<el-menu :default-active="defaultActive" :collapse="obj.status" :default-openeds="['1']" @select="curSelect">
<el-menu-item index="0" class="my-account">
<div class="pic" @click="goUpdatePic">
<div class="set-pic">修改头像</div>
<template v-if="pic">
<img :src="pic" alt="人物头像">
</template>
......@@ -52,6 +53,8 @@ export default {
let defaultActive = ''
switch (_path) {
case '/app/my-learn/course': defaultActive = '1-1'; break
case '/app/my-learn/course-detail': defaultActive = '1-1'; break
case '/app/my-learn/course-all': defaultActive = '0'; break
case '/app/my-learn/discussion': defaultActive = '1-2'; break
case '/app/my-learn/report': defaultActive = '1-3'; break
case '/app/my-grade/credit': defaultActive = '2-1'; break
......@@ -81,6 +84,9 @@ export default {
]
}
},
mounted () {
this.defineEvent()
},
methods: {
goPages (str) {
switch (str) {
......@@ -90,16 +96,29 @@ export default {
case '2-1': this.$router.push({ path: '/app/my-grade/credit' }); break
}
},
/* 修改头像 - 跳转方法 */
goUpdatePic () {
this.$router.push({ path: '/app/account/update-pic' })
},
/* 修改密码 - 跳转方法 */
goSetPwd () {
this.$router.push({ path: '/app/account/set-pwd' })
},
/* 退出登录 - 跳转方法 */
goOutLogin () {
/* 清空一下记录,然后调整到登录页 */
this.$router.push({ path: '/login/index' })
},
/* 定义监听事件 */
defineEvent () {
this.VueEvent.$off('can-change-sidebar').$on('can-change-sidebar', (data) => {
this.defaultActive = data.defaultActive
})
},
/* 当前菜单选中 */
curSelect (i, p) {
this.defaultActive = i
},
/* 侧边栏 拖拽条按下并移动前 */
beforeMove (e) {
this.obj.isMouseDown = true
......@@ -123,6 +142,10 @@ export default {
.el-menu {
user-select: none;
height: 100%;
/* 直接消失 */
&.el-menu--collapse {
display: none;
}
.el-submenu {
.el-menu-item {
overflow: hidden;
......@@ -138,6 +161,7 @@ export default {
overflow: hidden;
text-align: center;
.pic {
position: relative;
margin-bottom: 15px;
img {
display: block;
......@@ -146,6 +170,23 @@ export default {
height: 80px;
border-radius: 50%;
}
&:hover {
.set-pic {
display: block;
color: #000000;
}
}
.set-pic {
display: none;
position: absolute;
left: 50%;
top: 70%;
width: 50%;
line-height: 2;
color: #000000;
background: #eeeeee4f;
transform: translate(-50%, -50%);
}
}
}
}
......@@ -158,5 +199,12 @@ export default {
height: 100%;
cursor: ew-resize;
}
@media (max-width: 767px) {
.el-aside {
// position: fixed;
// z-index: 99;
}
}
</style>
......@@ -12,7 +12,7 @@
<script>
import mTable from './mTable.vue'
import { backendApi } from '@services'
import cAction from '@actions'
export default {
name: 'mPage',
......@@ -46,6 +46,7 @@ export default {
* 这个参数很重要,他定义了 回调执行方式,传参方式,
* obj.paramsFn 在调用接口前,对接口参数进行处理, 返回要传的参数对象
* obj.nameAPI 对应的接口名
* obj.actionClass 对应的action类
* obj.nameExcel 对应的导出Excel接口名
*/
objFn: { type: Object, require: true }
......@@ -54,10 +55,13 @@ export default {
methods: {
getList () {
const loading = this.$loading({ lock: true, text: '数据加载中,请稍后。。。', background: 'rgba(0, 0, 0, 0.7)' })
let obj = this.objFn.paramsFn(this)
backendApi[this.objFn.nameAPI](obj)
while (this.tableData.length) {
this.tableData.pop()
}
cAction[this.objFn.actionClass][this.objFn.nameAPI](obj)
.then(data => {
// this.tableData = []
this.objFn.callback(this, data)
}).catch(e => { this.$message.error(e.message) }).finally(() => { loading.close() })
}
......
......@@ -48,3 +48,41 @@ body {
"Wenquanyi Micro Hei",
sans-serif;
}
/* 独立 特殊修改 */
/* 进度条 原始背景色 加深 */
.el-progress-bar__outer {
background-color: #e5e5e5 !important;
}
/* 富文本 */
.course-assess .detail .b1 { display: block; max-width: 5rem; margin: 0.2rem auto; width: 100%; height: auto; }
.course-assess .detail .h1 { font-size: 0.16rem; font-weight: 700; color: #313131; line-height: 0.38rem; }
.course-assess .detail .h2 { font-size: 0.14rem; font-weight: 700; color: #313131; line-height: 0.3rem; }
.course-assess .detail .p { font-size: 0.14rem; color: #313131; line-height: 1.5; text-align: justify; }
.course-assess .detail .em { font-size: 0.12rem; color: #b49441; line-height: 1.5; text-align: justify; }
/* Extra small devices (portrait phones, less than 576px) */
@media (max-width: 575px) {
html { font-size: 80px; }
}
/* Small devices (landscape phones, 576px and up) */
@media (min-width: 576px) and (max-width: 767px) {
html { font-size: 80px; }
.step3 { width: 80%; }
}
/* Medium devices (tablets, 768px and up) */
@media (min-width: 768px) and (max-width: 991px) {
html { font-size: 80px; }
}
/* Large devices (desktops, 992px and up) */
@media (min-width: 992px) and (max-width: 1199px) {
html { font-size: 90px; }
}
/* Extra large devices (large desktops, 1200px and up) */
@media (min-width: 1200px) {
html { font-size: 100px; }
}
......@@ -5,6 +5,9 @@ import VueRouter from 'vue-router' // 使用 vue-router
import createRouter from './router' // router定义
import Main from './main.vue' // 初始化 vue页面
/* 引入 md5 */
import md5 from 'js-md5'
/* 定义全局变量 */
import GlobalVariable from './components/beforeEnterPages/setGlobalVariable'
/* 处理低版本浏览器支持axiosfinally问题 */
......@@ -14,6 +17,7 @@ Vue.use(VueRouter)
const router = createRouter()
/* 设置全局变量 */
Vue.prototype.$GlobalVariable = {}
Vue.prototype.$md5 = md5
/* 导航守卫 */
router.beforeEach((to, from, next) => {
/* 设置 全局变量 */
......
<template>
<el-tabs v-model="activeName" @tab-click="handleClick">
<el-tab-pane label="修改密码" name="1">
<div>
<div class="con-title">修改密码</div>
<div class="con-box">
<el-row>
<!-- <el-col class="hidden-sm-and-down" :md="6" :lg="7" :xl="8" style="height: 1px;"></el-col> -->
<el-col :xs="24" :sm="24" :md="12" :lg="10" :xl="8">
<el-col :xs="24" :sm="16" :md="12" :lg="10" :xl="8">
<el-form ref="setpwdform" label-width="100px" :model="accountSetPwd" :rules="rules">
<el-form-item label="旧密码" prop="oldPwd">
<el-input v-model="accountSetPwd.oldPwd" type="password" placeholder="请输入密码"></el-input>
......@@ -20,8 +21,8 @@
</el-form>
</el-col>
</el-row>
</el-tab-pane>
</el-tabs>
</div>
</div>
</template>
<script>
......@@ -72,3 +73,15 @@
}
}
</script>
<style lang="scss" scoped>
.con-title {
padding: 0 30px;
font-size: 16px;
line-height: 45px;
border-bottom: 1px solid #c9c9c9;
}
.con-box {
padding: 0.5rem 0.3rem;
}
</style>
<template>
<div>页面开发中</div>
<div>
<div class="con-title">修改头像</div>
<div class="con-box">
<el-row justify="center">
<el-col :xs="24" :sm="9" :md="8" :lg="7" :xl="6">
<div class="pic-show">
<img src="" alt="">
</div>
</el-col>
<el-col :xs="24" :sm="15" :md="16" :lg="17" :xl="18">
<div class="info">支持jpg、gif、png或bmp格式的图片,建议文件小于5M</div>
<el-upload
class="upload-demo"
action="https://jsonplaceholder.typicode.com/posts/"
multiple
:limit="3">
<el-button type="primary">点击上传</el-button>
</el-upload>
</el-col>
</el-row>
</div>
</div>
</template>
<style lang="scss" scoped>
.con-title {
padding: 0 30px;
font-size: 16px;
line-height: 45px;
border-bottom: 1px solid #c9c9c9;
}
.con-box {
padding: 0.5rem 0.3rem;
.pic-show {
display: block;
margin: 0 auto;
width: 2rem;
height: 2rem;
background: #ffffff url('../../assets/img/person-default.jpg') center center no-repeat;
background-size: cover;
border: 1px solid #ffffff;
border-radius: 50%;
}
.info {
margin-top: 0.2rem;
}
.upload-demo {
display: block;
margin: 0.8rem 0 0 0;
}
}
@media (max-width: 767px) {
.con-box {
.info {
margin-top: 0.2rem;
text-align: center;
}
.upload-demo {
text-align: center;
}
}
}
</style>
差异被折叠。
差异被折叠。
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论