| | |
| | | "js-cookie": "3.0.1", |
| | | "jsencrypt": "3.3.1", |
| | | "nprogress": "0.2.0", |
| | | "p-limit": "^5.0.0", |
| | | "pinia": "2.0.22", |
| | | "quill": "^2.0.0-dev.3", |
| | | "spark-md5": "^3.0.2", |
| | | "tinymce": "^5.10.2", |
| | | "video.js": "^8.12.0", |
| | | "vue": "3.2.45", |
| | | "vue-baidu-map-3x": "^1.0.35", |
| | | "vue-cropper": "1.0.3", |
对比新文件 |
| | |
| | | self.importScripts("/spark-md5.min.js"); // 导入脚本 |
| | | |
| | | // 生成文件 hash |
| | | self.onmessage = e => { |
| | | const { fileChunkList } = e.data; |
| | | const spark = new self.SparkMD5.ArrayBuffer(); |
| | | let percentage = 0; |
| | | let count = 0; |
| | | const loadNext = index => { |
| | | const reader = new FileReader(); |
| | | reader.readAsArrayBuffer(fileChunkList[index].file); |
| | | reader.onload = e => { |
| | | count++; |
| | | spark.append(e.target.result); |
| | | if (count === fileChunkList.length) { |
| | | self.postMessage({ |
| | | percentage: 100, |
| | | hash: spark.end() |
| | | }); |
| | | self.close(); |
| | | } else { |
| | | percentage += 100 / fileChunkList.length; |
| | | self.postMessage({ |
| | | percentage |
| | | }); |
| | | loadNext(count); |
| | | } |
| | | }; |
| | | }; |
| | | loadNext(0); |
| | | }; |
对比新文件 |
| | |
| | | (function(factory){if(typeof exports==="object"){module.exports=factory()}else if(typeof define==="function"&&define.amd){define(factory)}else{var glob;try{glob=window}catch(e){glob=self}glob.SparkMD5=factory()}})(function(undefined){"use strict";var add32=function(a,b){return a+b&4294967295},hex_chr=["0","1","2","3","4","5","6","7","8","9","a","b","c","d","e","f"];function cmn(q,a,b,x,s,t){a=add32(add32(a,q),add32(x,t));return add32(a<<s|a>>>32-s,b)}function md5cycle(x,k){var a=x[0],b=x[1],c=x[2],d=x[3];a+=(b&c|~b&d)+k[0]-680876936|0;a=(a<<7|a>>>25)+b|0;d+=(a&b|~a&c)+k[1]-389564586|0;d=(d<<12|d>>>20)+a|0;c+=(d&a|~d&b)+k[2]+606105819|0;c=(c<<17|c>>>15)+d|0;b+=(c&d|~c&a)+k[3]-1044525330|0;b=(b<<22|b>>>10)+c|0;a+=(b&c|~b&d)+k[4]-176418897|0;a=(a<<7|a>>>25)+b|0;d+=(a&b|~a&c)+k[5]+1200080426|0;d=(d<<12|d>>>20)+a|0;c+=(d&a|~d&b)+k[6]-1473231341|0;c=(c<<17|c>>>15)+d|0;b+=(c&d|~c&a)+k[7]-45705983|0;b=(b<<22|b>>>10)+c|0;a+=(b&c|~b&d)+k[8]+1770035416|0;a=(a<<7|a>>>25)+b|0;d+=(a&b|~a&c)+k[9]-1958414417|0;d=(d<<12|d>>>20)+a|0;c+=(d&a|~d&b)+k[10]-42063|0;c=(c<<17|c>>>15)+d|0;b+=(c&d|~c&a)+k[11]-1990404162|0;b=(b<<22|b>>>10)+c|0;a+=(b&c|~b&d)+k[12]+1804603682|0;a=(a<<7|a>>>25)+b|0;d+=(a&b|~a&c)+k[13]-40341101|0;d=(d<<12|d>>>20)+a|0;c+=(d&a|~d&b)+k[14]-1502002290|0;c=(c<<17|c>>>15)+d|0;b+=(c&d|~c&a)+k[15]+1236535329|0;b=(b<<22|b>>>10)+c|0;a+=(b&d|c&~d)+k[1]-165796510|0;a=(a<<5|a>>>27)+b|0;d+=(a&c|b&~c)+k[6]-1069501632|0;d=(d<<9|d>>>23)+a|0;c+=(d&b|a&~b)+k[11]+643717713|0;c=(c<<14|c>>>18)+d|0;b+=(c&a|d&~a)+k[0]-373897302|0;b=(b<<20|b>>>12)+c|0;a+=(b&d|c&~d)+k[5]-701558691|0;a=(a<<5|a>>>27)+b|0;d+=(a&c|b&~c)+k[10]+38016083|0;d=(d<<9|d>>>23)+a|0;c+=(d&b|a&~b)+k[15]-660478335|0;c=(c<<14|c>>>18)+d|0;b+=(c&a|d&~a)+k[4]-405537848|0;b=(b<<20|b>>>12)+c|0;a+=(b&d|c&~d)+k[9]+568446438|0;a=(a<<5|a>>>27)+b|0;d+=(a&c|b&~c)+k[14]-1019803690|0;d=(d<<9|d>>>23)+a|0;c+=(d&b|a&~b)+k[3]-187363961|0;c=(c<<14|c>>>18)+d|0;b+=(c&a|d&~a)+k[8]+1163531501|0;b=(b<<20|b>>>12)+c|0;a+=(b&d|c&~d)+k[13]-1444681467|0;a=(a<<5|a>>>27)+b|0;d+=(a&c|b&~c)+k[2]-51403784|0;d=(d<<9|d>>>23)+a|0;c+=(d&b|a&~b)+k[7]+1735328473|0;c=(c<<14|c>>>18)+d|0;b+=(c&a|d&~a)+k[12]-1926607734|0;b=(b<<20|b>>>12)+c|0;a+=(b^c^d)+k[5]-378558|0;a=(a<<4|a>>>28)+b|0;d+=(a^b^c)+k[8]-2022574463|0;d=(d<<11|d>>>21)+a|0;c+=(d^a^b)+k[11]+1839030562|0;c=(c<<16|c>>>16)+d|0;b+=(c^d^a)+k[14]-35309556|0;b=(b<<23|b>>>9)+c|0;a+=(b^c^d)+k[1]-1530992060|0;a=(a<<4|a>>>28)+b|0;d+=(a^b^c)+k[4]+1272893353|0;d=(d<<11|d>>>21)+a|0;c+=(d^a^b)+k[7]-155497632|0;c=(c<<16|c>>>16)+d|0;b+=(c^d^a)+k[10]-1094730640|0;b=(b<<23|b>>>9)+c|0;a+=(b^c^d)+k[13]+681279174|0;a=(a<<4|a>>>28)+b|0;d+=(a^b^c)+k[0]-358537222|0;d=(d<<11|d>>>21)+a|0;c+=(d^a^b)+k[3]-722521979|0;c=(c<<16|c>>>16)+d|0;b+=(c^d^a)+k[6]+76029189|0;b=(b<<23|b>>>9)+c|0;a+=(b^c^d)+k[9]-640364487|0;a=(a<<4|a>>>28)+b|0;d+=(a^b^c)+k[12]-421815835|0;d=(d<<11|d>>>21)+a|0;c+=(d^a^b)+k[15]+530742520|0;c=(c<<16|c>>>16)+d|0;b+=(c^d^a)+k[2]-995338651|0;b=(b<<23|b>>>9)+c|0;a+=(c^(b|~d))+k[0]-198630844|0;a=(a<<6|a>>>26)+b|0;d+=(b^(a|~c))+k[7]+1126891415|0;d=(d<<10|d>>>22)+a|0;c+=(a^(d|~b))+k[14]-1416354905|0;c=(c<<15|c>>>17)+d|0;b+=(d^(c|~a))+k[5]-57434055|0;b=(b<<21|b>>>11)+c|0;a+=(c^(b|~d))+k[12]+1700485571|0;a=(a<<6|a>>>26)+b|0;d+=(b^(a|~c))+k[3]-1894986606|0;d=(d<<10|d>>>22)+a|0;c+=(a^(d|~b))+k[10]-1051523|0;c=(c<<15|c>>>17)+d|0;b+=(d^(c|~a))+k[1]-2054922799|0;b=(b<<21|b>>>11)+c|0;a+=(c^(b|~d))+k[8]+1873313359|0;a=(a<<6|a>>>26)+b|0;d+=(b^(a|~c))+k[15]-30611744|0;d=(d<<10|d>>>22)+a|0;c+=(a^(d|~b))+k[6]-1560198380|0;c=(c<<15|c>>>17)+d|0;b+=(d^(c|~a))+k[13]+1309151649|0;b=(b<<21|b>>>11)+c|0;a+=(c^(b|~d))+k[4]-145523070|0;a=(a<<6|a>>>26)+b|0;d+=(b^(a|~c))+k[11]-1120210379|0;d=(d<<10|d>>>22)+a|0;c+=(a^(d|~b))+k[2]+718787259|0;c=(c<<15|c>>>17)+d|0;b+=(d^(c|~a))+k[9]-343485551|0;b=(b<<21|b>>>11)+c|0;x[0]=a+x[0]|0;x[1]=b+x[1]|0;x[2]=c+x[2]|0;x[3]=d+x[3]|0}function md5blk(s){var md5blks=[],i;for(i=0;i<64;i+=4){md5blks[i>>2]=s.charCodeAt(i)+(s.charCodeAt(i+1)<<8)+(s.charCodeAt(i+2)<<16)+(s.charCodeAt(i+3)<<24)}return md5blks}function md5blk_array(a){var md5blks=[],i;for(i=0;i<64;i+=4){md5blks[i>>2]=a[i]+(a[i+1]<<8)+(a[i+2]<<16)+(a[i+3]<<24)}return md5blks}function md51(s){var n=s.length,state=[1732584193,-271733879,-1732584194,271733878],i,length,tail,tmp,lo,hi;for(i=64;i<=n;i+=64){md5cycle(state,md5blk(s.substring(i-64,i)))}s=s.substring(i-64);length=s.length;tail=[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0];for(i=0;i<length;i+=1){tail[i>>2]|=s.charCodeAt(i)<<(i%4<<3)}tail[i>>2]|=128<<(i%4<<3);if(i>55){md5cycle(state,tail);for(i=0;i<16;i+=1){tail[i]=0}}tmp=n*8;tmp=tmp.toString(16).match(/(.*?)(.{0,8})$/);lo=parseInt(tmp[2],16);hi=parseInt(tmp[1],16)||0;tail[14]=lo;tail[15]=hi;md5cycle(state,tail);return state}function md51_array(a){var n=a.length,state=[1732584193,-271733879,-1732584194,271733878],i,length,tail,tmp,lo,hi;for(i=64;i<=n;i+=64){md5cycle(state,md5blk_array(a.subarray(i-64,i)))}a=i-64<n?a.subarray(i-64):new Uint8Array(0);length=a.length;tail=[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0];for(i=0;i<length;i+=1){tail[i>>2]|=a[i]<<(i%4<<3)}tail[i>>2]|=128<<(i%4<<3);if(i>55){md5cycle(state,tail);for(i=0;i<16;i+=1){tail[i]=0}}tmp=n*8;tmp=tmp.toString(16).match(/(.*?)(.{0,8})$/);lo=parseInt(tmp[2],16);hi=parseInt(tmp[1],16)||0;tail[14]=lo;tail[15]=hi;md5cycle(state,tail);return state}function rhex(n){var s="",j;for(j=0;j<4;j+=1){s+=hex_chr[n>>j*8+4&15]+hex_chr[n>>j*8&15]}return s}function hex(x){var i;for(i=0;i<x.length;i+=1){x[i]=rhex(x[i])}return x.join("")}if(hex(md51("hello"))!=="5d41402abc4b2a76b9719d911017c592"){add32=function(x,y){var lsw=(x&65535)+(y&65535),msw=(x>>16)+(y>>16)+(lsw>>16);return msw<<16|lsw&65535}}if(typeof ArrayBuffer!=="undefined"&&!ArrayBuffer.prototype.slice){(function(){function clamp(val,length){val=val|0||0;if(val<0){return Math.max(val+length,0)}return Math.min(val,length)}ArrayBuffer.prototype.slice=function(from,to){var length=this.byteLength,begin=clamp(from,length),end=length,num,target,targetArray,sourceArray;if(to!==undefined){end=clamp(to,length)}if(begin>end){return new ArrayBuffer(0)}num=end-begin;target=new ArrayBuffer(num);targetArray=new Uint8Array(target);sourceArray=new Uint8Array(this,begin,num);targetArray.set(sourceArray);return target}})()}function toUtf8(str){if(/[\u0080-\uFFFF]/.test(str)){str=unescape(encodeURIComponent(str))}return str}function utf8Str2ArrayBuffer(str,returnUInt8Array){var length=str.length,buff=new ArrayBuffer(length),arr=new Uint8Array(buff),i;for(i=0;i<length;i+=1){arr[i]=str.charCodeAt(i)}return returnUInt8Array?arr:buff}function arrayBuffer2Utf8Str(buff){return String.fromCharCode.apply(null,new Uint8Array(buff))}function concatenateArrayBuffers(first,second,returnUInt8Array){var result=new Uint8Array(first.byteLength+second.byteLength);result.set(new Uint8Array(first));result.set(new Uint8Array(second),first.byteLength);return returnUInt8Array?result:result.buffer}function hexToBinaryString(hex){var bytes=[],length=hex.length,x;for(x=0;x<length-1;x+=2){bytes.push(parseInt(hex.substr(x,2),16))}return String.fromCharCode.apply(String,bytes)}function SparkMD5(){this.reset()}SparkMD5.prototype.append=function(str){this.appendBinary(toUtf8(str));return this};SparkMD5.prototype.appendBinary=function(contents){this._buff+=contents;this._length+=contents.length;var length=this._buff.length,i;for(i=64;i<=length;i+=64){md5cycle(this._hash,md5blk(this._buff.substring(i-64,i)))}this._buff=this._buff.substring(i-64);return this};SparkMD5.prototype.end=function(raw){var buff=this._buff,length=buff.length,i,tail=[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],ret;for(i=0;i<length;i+=1){tail[i>>2]|=buff.charCodeAt(i)<<(i%4<<3)}this._finish(tail,length);ret=hex(this._hash);if(raw){ret=hexToBinaryString(ret)}this.reset();return ret};SparkMD5.prototype.reset=function(){this._buff="";this._length=0;this._hash=[1732584193,-271733879,-1732584194,271733878];return this};SparkMD5.prototype.getState=function(){return{buff:this._buff,length:this._length,hash:this._hash}};SparkMD5.prototype.setState=function(state){this._buff=state.buff;this._length=state.length;this._hash=state.hash;return this};SparkMD5.prototype.destroy=function(){delete this._hash;delete this._buff;delete this._length};SparkMD5.prototype._finish=function(tail,length){var i=length,tmp,lo,hi;tail[i>>2]|=128<<(i%4<<3);if(i>55){md5cycle(this._hash,tail);for(i=0;i<16;i+=1){tail[i]=0}}tmp=this._length*8;tmp=tmp.toString(16).match(/(.*?)(.{0,8})$/);lo=parseInt(tmp[2],16);hi=parseInt(tmp[1],16)||0;tail[14]=lo;tail[15]=hi;md5cycle(this._hash,tail)};SparkMD5.hash=function(str,raw){return SparkMD5.hashBinary(toUtf8(str),raw)};SparkMD5.hashBinary=function(content,raw){var hash=md51(content),ret=hex(hash);return raw?hexToBinaryString(ret):ret};SparkMD5.ArrayBuffer=function(){this.reset()};SparkMD5.ArrayBuffer.prototype.append=function(arr){var buff=concatenateArrayBuffers(this._buff.buffer,arr,true),length=buff.length,i;this._length+=arr.byteLength;for(i=64;i<=length;i+=64){md5cycle(this._hash,md5blk_array(buff.subarray(i-64,i)))}this._buff=i-64<length?new Uint8Array(buff.buffer.slice(i-64)):new Uint8Array(0);return this};SparkMD5.ArrayBuffer.prototype.end=function(raw){var buff=this._buff,length=buff.length,tail=[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],i,ret;for(i=0;i<length;i+=1){tail[i>>2]|=buff[i]<<(i%4<<3)}this._finish(tail,length);ret=hex(this._hash);if(raw){ret=hexToBinaryString(ret)}this.reset();return ret};SparkMD5.ArrayBuffer.prototype.reset=function(){this._buff=new Uint8Array(0);this._length=0;this._hash=[1732584193,-271733879,-1732584194,271733878];return this};SparkMD5.ArrayBuffer.prototype.getState=function(){var state=SparkMD5.prototype.getState.call(this);state.buff=arrayBuffer2Utf8Str(state.buff);return state};SparkMD5.ArrayBuffer.prototype.setState=function(state){state.buff=utf8Str2ArrayBuffer(state.buff,true);return SparkMD5.prototype.setState.call(this,state)};SparkMD5.ArrayBuffer.prototype.destroy=SparkMD5.prototype.destroy;SparkMD5.ArrayBuffer.prototype._finish=SparkMD5.prototype._finish;SparkMD5.ArrayBuffer.hash=function(arr,raw){var hash=md51_array(new Uint8Array(arr)),ret=hex(hash);return raw?hexToBinaryString(ret):ret};return SparkMD5}); |
对比新文件 |
| | |
| | | import request from "@/utils/request"; |
| | | |
| | | |
| | | export function checkChapterName(data) { |
| | | return request({ |
| | | url: '/course-chapter/checkNameUnique', |
| | | method: 'post', |
| | | data: data |
| | | }) |
| | | } |
| | | export function getChapters(params) { |
| | | return request({ |
| | | url: '/course-chapter/getCourseChapter', |
| | | method: 'get', |
| | | params: params |
| | | }) |
| | | } |
| | | |
| | | export function addChapter(data) { |
| | | return request({ |
| | | url: '/course-chapter', |
| | | method: 'post', |
| | | data: data |
| | | }) |
| | | } |
| | | |
| | | export function addChapterPeriod(data) { |
| | | return request({ |
| | | url: '/course-chapter-period', |
| | | method: 'post', |
| | | data: data |
| | | }) |
| | | } |
| | | |
| | | export function editChapter(params) { |
| | | return request({ |
| | | url: `/course-chapter`, |
| | | method: 'put', |
| | | data: params |
| | | }) |
| | | } |
| | | export function editChapterPeriod(params) { |
| | | return request({ |
| | | url: `/course-chapter-period`, |
| | | method: 'put', |
| | | data: params |
| | | }) |
| | | } |
| | | |
| | | export function getChapterById(params) { |
| | | return request({ |
| | | url: '/course-chapter/' +params , |
| | | method: 'get', |
| | | params: params |
| | | }) |
| | | } |
| | | |
| | | |
| | | export function delChapter(data) { |
| | | return request({ |
| | | url: `/course-chapter/` + data, |
| | | method: 'delete' |
| | | }) |
| | | } |
| | | export function delPeriod(data) { |
| | | return request({ |
| | | url: `/course-chapter-period/` + data, |
| | | method: 'delete' |
| | | }) |
| | | } |
对比新文件 |
| | |
| | | import request from "@/utils/request"; |
| | | |
| | | export function checkCourseName(data) { |
| | | return request({ |
| | | url: '/course/checkNameUnique', |
| | | method: 'post', |
| | | data: data |
| | | }) |
| | | } |
| | | |
| | | export function getCourse(params) { |
| | | return request({ |
| | | url: '/course/list', |
| | | method: 'get', |
| | | params: params |
| | | }) |
| | | } |
| | | |
| | | export function addCourse(data) { |
| | | return request({ |
| | | url: '/course', |
| | | method: 'post', |
| | | data: data |
| | | }) |
| | | } |
| | | |
| | | export function editCourse(params) { |
| | | return request({ |
| | | url: `/course`, |
| | | method: 'put', |
| | | data: params |
| | | }) |
| | | } |
| | | |
| | | export function getCourseById(params) { |
| | | return request({ |
| | | url: '/course/' +params , |
| | | method: 'get', |
| | | params: params |
| | | }) |
| | | } |
| | | |
| | | |
| | | export function delCourse(data) { |
| | | return request({ |
| | | url: `/course/` + data, |
| | | method: 'delete' |
| | | }) |
| | | } |
| | | |
| | | export function doCourse(data) { |
| | | return request({ |
| | | url: '/course/doApprove', |
| | | method: 'post', |
| | | data: data |
| | | }) |
| | | } |
| | | |
| | | export function changeCourseStatus(params) { |
| | | return request({ |
| | | url: '/course/changeStatus', |
| | | method: 'put', |
| | | data: params |
| | | }) |
| | | } |
对比新文件 |
| | |
| | | import request from "@/utils/request"; |
| | | |
| | | export function checkResourceName(data) { |
| | | return request({ |
| | | url: '/resource/checkNameUnique', |
| | | method: 'post', |
| | | data: data |
| | | }) |
| | | } |
| | | |
| | | export function getResource(params) { |
| | | return request({ |
| | | url: '/resource/list', |
| | | method: 'get', |
| | | params: params |
| | | }) |
| | | } |
| | | |
| | | export function addResource(data) { |
| | | return request({ |
| | | url: '/resource', |
| | | method: 'post', |
| | | data: data |
| | | }) |
| | | } |
| | | |
| | | export function editResource(params) { |
| | | return request({ |
| | | url: `/resource`, |
| | | method: 'put', |
| | | data: params |
| | | }) |
| | | } |
| | | |
| | | export function getResourceById(params) { |
| | | return request({ |
| | | url: '/resource/' +params , |
| | | method: 'get', |
| | | params: params |
| | | }) |
| | | } |
| | | |
| | | |
| | | export function delResource(data) { |
| | | return request({ |
| | | url: `/resource/` + data, |
| | | method: 'delete' |
| | | }) |
| | | } |
对比新文件 |
| | |
| | | import request from '@/utils/request' |
| | | |
| | | export function getStudent(param) { |
| | | return request({ |
| | | url: '/student/list', |
| | | method: 'get', |
| | | params: param |
| | | }) |
| | | } |
| | | |
| | | export function getStudentById(params) { |
| | | return request({ |
| | | url: '/system/user/' +params , |
| | | method: 'get', |
| | | params: params |
| | | }) |
| | | } |
| | | |
| | | export function addStudent(data) { |
| | | return request({ |
| | | url: '/student', |
| | | method: 'post', |
| | | data: data |
| | | }) |
| | | } |
| | | |
| | | export function checkStuIdNo(data) { |
| | | return request({ |
| | | url: '/student/checkIdNoUnique', |
| | | method: 'post', |
| | | data: data |
| | | }) |
| | | } |
| | | |
| | | export function checkStuPhone(data) { |
| | | return request({ |
| | | url: '/student/checkPhoneUnique', |
| | | method: 'post', |
| | | data: data |
| | | }) |
| | | } |
| | | |
| | | |
| | | |
| | | export function editStudent(params) { |
| | | return request({ |
| | | url: `/student`, |
| | | method: 'put', |
| | | data: params |
| | | }) |
| | | } |
| | | |
| | | export function resetPwd(params) { |
| | | return request({ |
| | | url: `/student/resetPwd`, |
| | | method: 'put', |
| | | data: params |
| | | }) |
| | | } |
| | | |
| | | export function delStudent(userId) { |
| | | return request({ |
| | | url: '/student/' + userId, |
| | | method: 'delete' |
| | | }) |
| | | } |
| | | |
对比新文件 |
| | |
| | | import request from '@/utils/request' |
| | | |
| | | |
| | | export function uploadFileRequest(data,uploadProgressHandle) { |
| | | return request({ |
| | | url: '/system/common/uploadSlice', |
| | | method: 'post', |
| | | headers:{'Content-Type':'multipart/form-data'}, |
| | | data: data, |
| | | onUploadProgress: uploadProgressHandle |
| | | }) |
| | | } |
| | | |
| | | export function mergeFileRequest(data) { |
| | | return request({ |
| | | url: '/system/common/uploadMerge', |
| | | headers:{'Content-Type':'multipart/form-data'}, |
| | | method: 'post', |
| | | data: data |
| | | }) |
| | | } |
| | |
| | | </el-dropdown> |
| | | </div> |
| | | </div> |
| | | <!-- <review-dialog ref="reviewRef" ></review-dialog>--> |
| | | |
| | | <user-dialog ref="reviewRef" ></user-dialog> |
| | | <!-- <register ref="regRef" @getList="getList" />--> |
| | | <!-- <supervise-dialog ref="superRef"></supervise-dialog>--> |
| | | </div> |
| | |
| | | import Cookies from "js-cookie"; |
| | | import {getUserById} from "@/api/sysUsers"; |
| | | import menu from "@/layout/components/Sidebar/menu"; |
| | | import userDialog from '@/views/onlineEducation/systemManage/user/components/userDialog.vue' |
| | | |
| | | const appStore = useAppStore() |
| | | const userStore = useUserStore() |
| | |
| | | |
| | | function getInfo() { |
| | | console.log("getInfo",userInfo.value) |
| | | //机构用户 |
| | | if(userInfo.value.identity === 1){ |
| | | //审核驳回(可修改) |
| | | if(userInfo.value.state === 3){ |
| | | const obj = { |
| | | id: userInfo.value.id, |
| | | username: userInfo.value.username, |
| | | agencyId: userInfo.value.agentId |
| | | } |
| | | regRef.value.openDialog('reject', obj); |
| | | }else{ |
| | | //审核通过、未审核状态(不可修改) |
| | | const obj = { |
| | | agencyId: userInfo.value.agentId |
| | | } |
| | | reviewRef.value.openDialog(obj,'view') |
| | | } |
| | | } |
| | | //监管用户 |
| | | else if (userInfo.value.identity === 0) { |
| | | const obj = { |
| | | id: userInfo.value.id |
| | | } |
| | | superRef.value.openDialog('view', obj); |
| | | } |
| | | reviewRef.value.openDialog('view',userInfo.value) |
| | | } |
| | | function editPsd() { |
| | | superRef.value.openDialog('pwd', userInfo.value); |
| | | reviewRef.value.openDialog('pwd',userInfo.value) |
| | | } |
| | | const sidebarRouters = ref([]) |
| | | |
| | |
| | | import Layout from '@/layout' |
| | | const menu = { |
| | | adminMenu: [ |
| | | // { |
| | | // path: '/course', |
| | | // name: 'Course', |
| | | // meta: { title: '课程管理',icon: 'documentation',affix: true } |
| | | // }, |
| | | { |
| | | path: '/course', |
| | | name: 'Course', |
| | | meta: { title: '课程管理',icon: 'documentation',affix: true } |
| | | path: '/onlineEducation', |
| | | redirect: '/onlineEducation/courseManage', |
| | | meta: { title: '课程管理',icon: 'form'}, |
| | | children: [ |
| | | { |
| | | path: 'course', |
| | | name: 'course', |
| | | meta: { title: '课程列表',icon: 'list'} |
| | | } , |
| | | { |
| | | path: 'courseResource', |
| | | name: 'courseResource', |
| | | meta: { title: '课程资源',icon: 'education'} |
| | | } , |
| | | ] |
| | | }, |
| | | { |
| | | path: '/question', |
| | |
| | | ], |
| | | companyMenu: [ |
| | | { |
| | | path: '/course', |
| | | name: 'Course', |
| | | meta: { title: '课程管理',icon: 'documentation',affix: true } |
| | | path: '/onlineEducation', |
| | | redirect: '/onlineEducation/courseManage', |
| | | meta: { title: '课程管理',icon: 'form'}, |
| | | children: [ |
| | | { |
| | | path: 'course', |
| | | name: 'course', |
| | | meta: { title: '课程列表',icon: 'list'} |
| | | } , |
| | | { |
| | | path: 'courseResource', |
| | | name: 'courseResource', |
| | | meta: { title: '课程资源',icon: 'education'} |
| | | } , |
| | | ] |
| | | }, |
| | | { |
| | | path: '/question', |
| | |
| | | import { Boot } from '@wangeditor/editor' |
| | | import attachmentModule from '@wangeditor/plugin-upload-attachment' |
| | | import loadMore from '@/utils/selectLoadMoreDirective' |
| | | import "video.js/dist/video-js.css" |
| | | Boot.registerModule(attachmentModule) |
| | | const app = createApp(App) |
| | | |
| | |
| | | hidden: true |
| | | }, |
| | | |
| | | { |
| | | path: '/chapters', |
| | | component: Layout, |
| | | redirect: '/chapters', |
| | | children: [ |
| | | { |
| | | path: '/chapters', |
| | | component: () => import('@/views/onlineEducation/courseManage/courseChapters/index.vue'), |
| | | name: 'Chapters', |
| | | } |
| | | ] |
| | | }, |
| | | // { |
| | | // path: '', |
| | | // component: Layout, |
| | |
| | | ] |
| | | }, |
| | | { |
| | | path: '/course', |
| | | path: '/onlineEducation', |
| | | component: Layout, |
| | | redirect: '/course', |
| | | redirect: '/onlineEducation/courseManage', |
| | | meta: { title: '课程管理'}, |
| | | children: [ |
| | | { |
| | | path: '/course', |
| | | path: 'course', |
| | | component: () => import('@/views/onlineEducation/courseManage/index.vue'), |
| | | name: 'course', |
| | | meta: { title: '课程管理',icon: 'form', affix: true } |
| | | } |
| | | meta: { title: '课程列表',icon: 'form', affix: true } |
| | | }, |
| | | { |
| | | path: 'courseResource', |
| | | component: () => import('@/views/onlineEducation/courseManage/courseResource/index.vue'), |
| | | name: 'courseResource', |
| | | meta: { title: '课程资源',icon: 'form', affix: true } |
| | | }, |
| | | ] |
| | | }, |
| | | { |
对比新文件 |
| | |
| | | |
| | | <template> |
| | | <div class="greetings"> |
| | | <el-upload accept=".mp4, .mp3, .xls, .xlsx, .doc, .docx, .ppt, .pptx, .pdf" :on-change="handleFileChange" :on-preview="view" :auto-upload="false" ref="uploadfileComponent" :limit="1" :on-exceed="handleExceed" v-model:file-list="fileList"> |
| | | <template #trigger> |
| | | <el-button type="primary">选择文件</el-button> |
| | | </template> |
| | | <el-button :disabled="uploadDisabled" style="margin-left: 10px" type="success" @click="handlerUpload">上传</el-button> |
| | | <el-button class="ml-3" type="success" @click="resetData" >重置</el-button> |
| | | <template #tip> |
| | | <br /><br /> |
| | | <span>上传进度:{{ fakeUploadPercentage }}%</span> |
| | | <el-progress :text-inside="true" :stroke-width="26" :percentage="fakeUploadPercentage" /> |
| | | <div class="el-upload__tip text-red">限制一个文件, 新文件将会覆盖原文件</div> |
| | | </template> |
| | | </el-upload> |
| | | <br> |
| | | <div v-if="container.showVideo" style="width: 300px;height: 200px"> |
| | | <video ref="videoPlayer" class="video-js" style="margin: auto auto"></video> |
| | | </div> |
| | | |
| | | </div> |
| | | </template> |
| | | |
| | | <script setup> |
| | | import { ElMessage } from "element-plus"; |
| | | import videojs from "video.js" |
| | | import { computed, nextTick, onMounted, onUnmounted,ref,reactive,watch } from "vue"; |
| | | import SparkMD5 from "spark-md5"; |
| | | import {uploadFileRequest,mergeFileRequest} from "@/api/onlineEducation/upload" |
| | | import pLimit from 'p-limit' |
| | | |
| | | const videoPlayer = ref(null) |
| | | const myPlayer = ref(null) |
| | | const uploadDisabled=ref(false) |
| | | const chunkSize = ref(10 * 1024 * 1024) // 切片大小 |
| | | const uploadedCount=ref(0) //已上传的分配个数 |
| | | const fileChunkList=ref([]) |
| | | const fileList=ref([]) |
| | | const uploadfileComponent=ref(null) |
| | | const emit = defineEmits(["getFile"]); |
| | | const props = defineProps({ |
| | | responseType: { |
| | | type: Number, |
| | | default: 0 |
| | | } |
| | | }) |
| | | const container=reactive({ |
| | | file:{ |
| | | name:'', |
| | | percentage:0, |
| | | status:1, |
| | | size:0, |
| | | url:'', |
| | | raw:null, |
| | | uid:0 |
| | | }, |
| | | fileMd5:'', |
| | | worker:null, |
| | | showVideo:false |
| | | }) |
| | | // 生成文件hash的进度 |
| | | const hashPercentage = ref(0) |
| | | // 显示在页面上的文件上传进度 |
| | | const fakeUploadPercentage = ref(0) |
| | | const type = ref(); |
| | | onMounted(() => { |
| | | type.value = props.responseType |
| | | // getVideo(props.responseType) |
| | | |
| | | }) |
| | | const resourcePath = ref(); |
| | | const getVideo = (value) => { |
| | | type.value = value; |
| | | if(value == 1){ |
| | | // container.showVideo = true |
| | | nextTick(() => { |
| | | console.log("111111",videoPlayer.value) |
| | | myPlayer.value = videojs(videoPlayer.value, { |
| | | poster: "",//视频封面 |
| | | controls: true,//视频控件 |
| | | autoplay:true,//自动播放 |
| | | sources: [ |
| | | { |
| | | src: resourcePath.value ? "http://192.168.2.16:9000/trainexam/" + resourcePath.value : '', |
| | | // src:'', |
| | | type: 'application/x-mpegURL', |
| | | } |
| | | ], |
| | | controlBar: { |
| | | remainingTimeDisplay: { |
| | | displayNegative: false |
| | | } |
| | | }, |
| | | playbackRates: [0.5, 1, 1.5, 2]//设置播放速度 |
| | | }, onPlayerReady) |
| | | }); |
| | | } |
| | | } |
| | | // watch(() => props.responseType, value => getVideo(value)) |
| | | onUnmounted(() => { |
| | | if (myPlayer.value) { |
| | | myPlayer.value.dispose() |
| | | } |
| | | }) |
| | | |
| | | const dispose = () => { |
| | | // if (myPlayer.value) { |
| | | // myPlayer.value.dispose() |
| | | // resourcePath.value = '' |
| | | // } |
| | | container.showVideo = false; |
| | | resourcePath.value = '' |
| | | hashPercentage.value=0 |
| | | uploadPercentage.value=0 |
| | | fakeUploadPercentage.value=0 |
| | | uploadedCount.value=0 |
| | | fileChunkList.value=[] |
| | | fileList.value=[] |
| | | } |
| | | |
| | | const changeType = (val) => { |
| | | type.value = val |
| | | dispose() |
| | | if(val == 1){ |
| | | container.showVideo = true |
| | | nextTick(() => { |
| | | getVideo(val) |
| | | }) |
| | | } |
| | | } |
| | | const openValue = ref(); |
| | | const open = (val) => { |
| | | console.log("val",val) |
| | | openValue.value = val |
| | | fakeUploadPercentage.value = 100 |
| | | if(val.resourceType == 1){ |
| | | container.showVideo = true |
| | | resourcePath.value = val.resourcePath; |
| | | getVideo(val.resourceType) |
| | | }else { |
| | | container.showVideo = false |
| | | // if (myPlayer.value) { |
| | | // myPlayer.value.dispose() |
| | | // } |
| | | fileList.value.push({ |
| | | path: val.resourcePath, |
| | | name: val.originName |
| | | }) |
| | | } |
| | | } |
| | | const view = (file) => { |
| | | console.log('vlco',file) |
| | | // console.log("点击文件=>", file); |
| | | const url = 'http://192.168.2.16:9000/trainexam/' + file.path; |
| | | const link = document.createElement("a"); |
| | | link.href = url; |
| | | link.download = file.name; |
| | | // link.target = "_blank"; |
| | | document.body.appendChild(link); |
| | | link.click(); |
| | | document.body.removeChild(link); |
| | | } |
| | | // video初始化完成的回调函数 |
| | | const onPlayerReady = () => { |
| | | myPlayer.value.log("play.....") |
| | | bindVideoEvents() |
| | | } |
| | | // 绑定事件 |
| | | const bindVideoEvents = () => { |
| | | if (!myPlayer.value) return |
| | | myPlayer.value.on('play', onPlay) |
| | | myPlayer.value.on('pause', onPause) |
| | | myPlayer.value.on('ended', onEnded) |
| | | myPlayer.value.on('timeupdate', onTimeupdate) |
| | | myPlayer.value.on('loadedmetadata', onLoadedmetadata) |
| | | myPlayer.value.on('fullscreenchange', onFullscreenchange) |
| | | myPlayer.value.on('error', err => { |
| | | console.log('视频加载发生错误', err) |
| | | }) |
| | | } |
| | | |
| | | const onPlay = () => { |
| | | console.log('播放视频') |
| | | } |
| | | const onPause = () => { |
| | | console.log('暂停播放') |
| | | } |
| | | const onEnded = () => {} |
| | | const onTimeupdate = () => { |
| | | console.log('播放位置已更改时,播放时间更新') |
| | | } |
| | | // 全屏切换 |
| | | const onFullscreenchange = () => { |
| | | console.log('全屏状态改变') |
| | | } |
| | | // 元数据加载完成 |
| | | const onLoadedmetadata = () => { |
| | | console.log('元数据加载完成') |
| | | |
| | | } |
| | | |
| | | |
| | | //计算文件上传的进度 |
| | | const uploadPercentage= computed({ |
| | | get(){ |
| | | if(!container.file||!fileChunkList.value.length){ |
| | | return 0 |
| | | } |
| | | const loaded=fileChunkList.value.map(item => item.size * item.percentage).reduce((acc,cur) => { |
| | | return acc+cur |
| | | }) |
| | | console.log('loaded',uploadedCount.value,loaded) |
| | | return parseInt((loaded/container.file.size).toFixed(2)) |
| | | }, |
| | | set(value){ |
| | | return value |
| | | } |
| | | }) |
| | | |
| | | // watch uploadPercentage,得到fakeUploadPercentage |
| | | watch(uploadPercentage, (newValue) => { |
| | | if (newValue >= fakeUploadPercentage.value) { |
| | | fakeUploadPercentage.value = newValue |
| | | } |
| | | }) |
| | | |
| | | const resetData = () => { |
| | | container.showVideo = false |
| | | resourcePath.value = '' |
| | | hashPercentage.value=0 |
| | | uploadPercentage.value=0 |
| | | fakeUploadPercentage.value=0 |
| | | uploadedCount.value=0 |
| | | fileChunkList.value=[] |
| | | fileList.value=[] |
| | | if(container.worker){ |
| | | container.worker.onmessage=null |
| | | } |
| | | // if (myPlayer.value) { |
| | | // myPlayer.value.dispose() |
| | | // } |
| | | const file = { |
| | | resourceSize: null, |
| | | md5: '', |
| | | resourcePath: '', |
| | | mediaType: '', |
| | | docPage: 0, |
| | | resourceLength: '', |
| | | originName:'' |
| | | } |
| | | emit("getFile",file) |
| | | } |
| | | |
| | | //选择了文件 |
| | | const handleFileChange=(uploadFile,uploadFiles) =>{ |
| | | // resetData() |
| | | if(!uploadFile){ |
| | | return |
| | | } |
| | | container.file=uploadFile |
| | | fileList.value=uploadFiles |
| | | } |
| | | |
| | | const handleExceed= (files) => { |
| | | uploadfileComponent.value.clearFiles() |
| | | nextTick(() => { |
| | | uploadfileComponent.value.handleStart(files[0]) |
| | | }) |
| | | } |
| | | |
| | | //上传 |
| | | const handlerUpload= async() => { |
| | | |
| | | if(type.value == null){ |
| | | ElMessage({ |
| | | type: 'warning', |
| | | message: '请先选择资源类型' |
| | | }); |
| | | return false |
| | | } |
| | | |
| | | if(!container.file.raw){ |
| | | return |
| | | } |
| | | if(container.file.raw.size > 1024 * 1024 * 1000){ |
| | | ElMessage({ |
| | | type: 'warning', |
| | | message: '文件大小不能超过1G' |
| | | }); |
| | | return false |
| | | } |
| | | const filetype = container.file.raw.name.split(".").pop(); |
| | | const extension = (filetype === "mp4" || filetype ==="mp3" || filetype ==="xls" || filetype === "xlsx" || filetype ==="doc" || filetype ==="docx" || filetype === "ppt" || filetype ==="pptx" || filetype ==="pdf"); |
| | | if (!extension ) { |
| | | ElMessage({ |
| | | type: 'warning', |
| | | message: '暂不支持该格式上传' |
| | | }); |
| | | return false; |
| | | } |
| | | if((type.value == 1 && filetype != 'mp4') || (type.value == 2 && filetype != 'mp3')){ |
| | | ElMessage({ |
| | | type: 'warning', |
| | | message: '请上传所选资源类型的文件' |
| | | }); |
| | | return false; |
| | | } |
| | | if(type.value == 3){ |
| | | if( filetype == 'xls' || filetype == 'xlsx' || filetype == 'doc'|| filetype == 'docx'|| filetype == 'ppt'|| filetype == 'pptx'|| filetype == 'pdf' ){ |
| | | |
| | | }else { |
| | | ElMessage({ |
| | | type: 'warning', |
| | | message: '请上传所选资源类型的文件' |
| | | }); |
| | | return false; |
| | | } |
| | | } |
| | | |
| | | //文件分片 |
| | | const chunkList=createFileChunk(container.file.raw) |
| | | console.log('文件分了多少片:',chunkList.length) |
| | | //通过webworker计算出文件hash |
| | | container.fileMd5=await calculateMd5(chunkList) |
| | | console.log('文件hash1:',container.fileMd5) |
| | | // container.fileMd5=await getFileMD5(container.file.raw) |
| | | // console.log('文件hash2:',container.hash) |
| | | |
| | | fileChunkList.value=[] |
| | | fileChunkList.value=chunkList.map(({file},index) => ({ |
| | | fileMd5:container.fileMd5, |
| | | index, |
| | | chunkName: `${container.fileMd5}-${index}`, |
| | | chunk:file, |
| | | size:file.size, |
| | | // 如果已上传切片数组uploadedList中包含这个切片,则证明这个切片之前已经上传成功了,进度设为100。 |
| | | percentage:0 |
| | | })) |
| | | |
| | | uploadChunks(fileChunkList) |
| | | } |
| | | |
| | | //文件分片 |
| | | const createFileChunk = (file,size=chunkSize.value) => { |
| | | const chunkList=[] |
| | | let cur=0 |
| | | while(cur<file.size){ |
| | | chunkList.push({ |
| | | file:file.slice(cur,cur+size), |
| | | }) |
| | | cur+=size |
| | | } |
| | | return chunkList |
| | | } |
| | | |
| | | //计算文件md5 方法1 |
| | | const calculateMd5 = (chunkList) => { |
| | | return new Promise((resolve) => { |
| | | container.worker=new Worker('/hash.js') |
| | | container.worker.postMessage({fileChunkList:chunkList}) |
| | | container.worker.onmessage= (e) => { |
| | | const {percentage,hash} = e.data |
| | | hashPercentage.value=percentage.toFixed(2) |
| | | if(hash){ |
| | | resolve(hash) |
| | | } |
| | | } |
| | | }) |
| | | } |
| | | |
| | | //计算文件md5 方法2 |
| | | const getFileMD5 = (file) => { |
| | | return new Promise((resolve, reject) => { |
| | | const spark = new SparkMD5.ArrayBuffer() |
| | | const fileReader = new FileReader() |
| | | fileReader.onload = (e) => { |
| | | spark.append(e.target?.result) |
| | | resolve(spark.end()) |
| | | } |
| | | fileReader.onerror = () => { |
| | | reject('') |
| | | } |
| | | fileReader.readAsArrayBuffer(file) |
| | | }) |
| | | } |
| | | |
| | | //计算上传进度 |
| | | const createProgressHandler = (item) => { |
| | | console.log('createProgresshandler -> item', item); |
| | | return (p) => { |
| | | if(item.percentage>=100){ |
| | | item.percentage = 100 |
| | | }else{ |
| | | item.percentage=parseInt(String((p.loaded/p.total)*100)) |
| | | } |
| | | // 确保进度百分比不会超过100% |
| | | if (item.percentage > 100) item.percentage = 100 |
| | | } |
| | | } |
| | | |
| | | |
| | | |
| | | //上传切片 |
| | | const uploadChunks= async(uploadedList) => { |
| | | const limit = pLimit(10); // 控制并发数为10 |
| | | const requestList=uploadedList.value.map(({chunk,chunkName,index,fileMd5}) => { |
| | | const formdata=new FormData() |
| | | formdata.append('file',chunk) |
| | | formdata.append('chunkName',chunkName) |
| | | formdata.append('fileName',container.file.name) |
| | | formdata.append('fileMd5',fileMd5) |
| | | formdata.append('index',index) |
| | | return {formdata,index} |
| | | }).map(async ({formdata,index}) => { |
| | | return limit(() => doUploadChunk({data:formdata,onUploadProgress:createProgressHandler(fileChunkList.value[index])})) |
| | | }) |
| | | await Promise.all(requestList) |
| | | console.log("数组:",fileChunkList) |
| | | if(uploadedCount.value>=fileChunkList.value.length){ |
| | | mergeRequest() |
| | | } |
| | | |
| | | } |
| | | |
| | | |
| | | const doUploadChunk = ({data,onUploadProgress}) => { |
| | | return new Promise((resolve) => { |
| | | uploadFileRequest(data,onUploadProgress).then((result) => { |
| | | let resData=result.data |
| | | if(result&&result.code==200){ |
| | | uploadedCount.value=uploadedCount.value+1 |
| | | fileChunkList.value[data.get('index')].percentage=100 //手动更新进度 |
| | | console.log(uploadedCount.value,'result--------------') |
| | | } |
| | | resolve('done') |
| | | }) |
| | | }) |
| | | } |
| | | |
| | | const mergeRequest = async() => { |
| | | if(container.file.name.lastIndexOf(".") === -1){ |
| | | ElMessage.warning("请输入文件后缀名") |
| | | return |
| | | } |
| | | let data=await mergeFileRequest({fileMd5:container.fileMd5,fileName:container.file.name}) |
| | | console.log(data,"mege------------222") |
| | | if(data && data.code==200){ |
| | | const filetype = data.data.originName.split(".").pop(); |
| | | if(filetype == 'mp4' || filetype == 'MP4'){ |
| | | container.showVideo = true |
| | | await nextTick(() => { |
| | | |
| | | console.log("myPlayer.value",myPlayer.value) |
| | | myPlayer.value.src( |
| | | { |
| | | src:"http://192.168.2.16:9000/trainexam/"+data.data.path, |
| | | type: 'application/x-mpegURL', |
| | | }) |
| | | // myPlayer.value.load() |
| | | myPlayer.value.play().catch((error) => { |
| | | console.error('Error playing video:', error); |
| | | }); |
| | | }) |
| | | // myPlayer.value.pause() |
| | | //myPlayer.value.reset() |
| | | } |
| | | const file = { |
| | | resourceSize: data.data.size, |
| | | md5: data.data.md5, |
| | | resourcePath: data.data.path, |
| | | mediaType: filetype, |
| | | docPage: data.data.docPage, |
| | | resourceLength: data.data.resourceLength, |
| | | originName: data.data.originName |
| | | } |
| | | emit("getFile",file) |
| | | |
| | | |
| | | |
| | | ElMessage.success("上传成功") |
| | | }else{ |
| | | ElMessage.success("合并数据失败") |
| | | } |
| | | } |
| | | |
| | | defineExpose({ |
| | | dispose, |
| | | changeType, |
| | | open |
| | | }); |
| | | </script> |
| | | |
| | | |
| | | <style scoped> |
| | | .greetings{ |
| | | :deep(.video-js) { |
| | | width: 300px; |
| | | height: 200px; |
| | | } |
| | | :deep(.el-icon--close) { |
| | | display: none; |
| | | } |
| | | } |
| | | |
| | | |
| | | |
| | | h1 { |
| | | font-weight: 500; |
| | | font-size: 2.6rem; |
| | | position: relative; |
| | | top: -10px; |
| | | } |
| | | |
| | | h3 { |
| | | font-size: 1.2rem; |
| | | } |
| | | |
| | | .greetings h1, |
| | | .greetings h3 { |
| | | text-align: center; |
| | | } |
| | | |
| | | @media (min-width: 1024px) { |
| | | .greetings h1, |
| | | .greetings h3 { |
| | | text-align: left; |
| | | } |
| | | } |
| | | </style> |
对比新文件 |
| | |
| | | <template> |
| | | <div class="notice"> |
| | | <el-dialog |
| | | v-model="dialogVisible" |
| | | :title="title" |
| | | width="500px" |
| | | :before-close="handleClose" |
| | | > |
| | | <el-form :model="state.form" size="default" ref="busRef" :rules="state.formRules" label-width="150px" > |
| | | <el-form-item label="课程名称:" prop="name"> |
| | | <el-input v-model.trim="state.form.name" placeholder="请输入课程名称"></el-input> |
| | | </el-form-item> |
| | | <el-form-item label="课程分类:" prop="categoryId" > |
| | | <!-- <el-select clearable v-model="state.form.categoryId" style="width: 100%" placeholder="请选择课程分类" @change="changeType">--> |
| | | <!-- <el-option v-for="item in state.classifyList" :key="item" :label="item.name" :value="item.id" />--> |
| | | <!-- </el-select>--> |
| | | <el-cascader |
| | | ref="classifyRef" |
| | | v-model="state.form.categoryId" |
| | | :options="state.classifyList" |
| | | :props="state.props" |
| | | clearable |
| | | :show-all-levels="false" |
| | | @change="handleChange" |
| | | /> |
| | | </el-form-item> |
| | | <el-form-item label="要求课时:" prop="period"> |
| | | <el-input v-model="state.form.period" placeholder="请输入要求课时"> |
| | | <template #append>分钟</template> |
| | | </el-input> |
| | | </el-form-item> |
| | | <el-form-item label="提交单位:" prop="companyName" > |
| | | <el-input v-model="state.form.companyName" disabled/> |
| | | </el-form-item> |
| | | <el-form-item label="封面:"> |
| | | <el-upload accept="image/*" :action="state.uploadUrl" :headers="state.header" method="post" :on-success="(res, uploadFile)=>handleAvatarSuccess(res, uploadFile)" :on-exceed="showTip" :limit='state.imgLimit' v-model:file-list="state.imgList" list-type="picture-card" :before-upload="picSize" :on-remove="(file, uploadFiles)=>handleRemove(file, uploadFiles)" > |
| | | <el-icon><Plus /></el-icon> |
| | | <template #tip> |
| | | <div class="el-upload__tip">上传jpg/png图片尺寸小于5M,最多可上传1张</div> |
| | | </template> |
| | | </el-upload> |
| | | </el-form-item> |
| | | </el-form> |
| | | <template #footer> |
| | | <span class="dialog-footer"> |
| | | <el-button @click="handleClose" size="default">取 消</el-button> |
| | | <el-button type="primary" @click="onSubmit" size="default" v-preReClick>确认</el-button> |
| | | </span> |
| | | </template> |
| | | </el-dialog> |
| | | </div> |
| | | </template> |
| | | <script setup> |
| | | import {reactive, ref, toRefs} from 'vue' |
| | | import Editor from "@/components/Editor/index.vue"; |
| | | import {ElMessage} from "element-plus"; |
| | | import {addNotice} from "@/api/backManage/notice"; |
| | | import {addDict, editDict, getDictDetail} from "@/api/backManage/evaluate"; |
| | | import {addCompany, checkName, distributeCompany, editCompany} from "@/api/onlineEducation/company"; |
| | | import {verifyPhone} from "@/utils/validate"; |
| | | import { |
| | | addClassification, |
| | | checkClassName, |
| | | editClassification, |
| | | getClassification |
| | | } from "@/api/onlineEducation/courseClass"; |
| | | import {addCourse, checkCourseName, editCourse, getCourseById} from "@/api/onlineEducation/courseManage"; |
| | | import {getToken} from "@/utils/auth"; |
| | | import {delPic, getBannerById} from "@/api/onlineEducation/banner"; |
| | | import Cookies from "js-cookie"; |
| | | |
| | | const dialogVisible = ref(false); |
| | | const title = ref(""); |
| | | const busRef = ref(); |
| | | const length = ref() |
| | | const emit = defineEmits(["getList"]); |
| | | const startUsername = ref(''); |
| | | const classifyRef = ref(null) |
| | | |
| | | const validateName = (rule, value, callback)=>{ |
| | | if(value === ''){ |
| | | callback(new Error('请输入课程名称')) |
| | | }else if(title.value === '编辑' && value === startUsername.value){ |
| | | callback() |
| | | }else{ |
| | | let param = {} |
| | | if(title.value === '新增') { |
| | | param = { |
| | | name:value |
| | | } |
| | | }else if(title.value === '编辑'){ |
| | | param = { |
| | | name:value, |
| | | id: state.form.id |
| | | } |
| | | } |
| | | checkCourseName(param).then((res)=>{ |
| | | if(res.data == false){ |
| | | callback(new Error('课程名称已被占用,请更换其他名称')) |
| | | }else{ |
| | | callback() |
| | | } |
| | | }) |
| | | } |
| | | } |
| | | const state = reactive({ |
| | | form: { |
| | | id: '', |
| | | name: '', |
| | | categoryId: null, |
| | | period: null, |
| | | logo: '', |
| | | companyId: null |
| | | }, |
| | | formRules: { |
| | | name: [{required: true, trigger: "blur", validator: validateName}], |
| | | categoryId: [{required: true, message: '请选择课程分类', trigger: 'blur'}], |
| | | period: [{required: true, message: '请输入要求课时', trigger: 'blur'}], |
| | | }, |
| | | classifyList: [], |
| | | uploadUrl: import.meta.env.VITE_APP_BASE_API + '/system/common/uploadFile', |
| | | header: { |
| | | Authorization: getToken() |
| | | }, |
| | | imgLimit: 1, |
| | | imgList: [], |
| | | isAdmin: false, |
| | | props: { |
| | | checkStrictly: true, |
| | | } |
| | | }) |
| | | |
| | | const openDialog = async (type, value) => { |
| | | await getClassifyList(); |
| | | const userInfo = JSON.parse(Cookies.get('userInfo')) |
| | | console.log("userInfo",userInfo) |
| | | if(userInfo.userType === 0){ |
| | | state.isAdmin = true; |
| | | state.form.companyName = '公开课' |
| | | state.form.companyId = null |
| | | }else { |
| | | state.isAdmin = false; |
| | | state.form.companyName = userInfo.companyName |
| | | state.form.companyId = userInfo.companyId |
| | | } |
| | | title.value = type === 'addFirst' || type === 'add' ? '新增' : type ==='edit' ? '编辑' : '' ; |
| | | if(type === 'edit') { |
| | | const res = await getCourseById(value.id); |
| | | if(res.code === 200){ |
| | | state.form = res.data |
| | | console.log("11",res.data) |
| | | if(res.data.logo) { |
| | | const obj = { |
| | | url: import.meta.env.VITE_APP_BASE_API + "/" + res.data.logo, |
| | | name: '' |
| | | } |
| | | state.imgList = [obj] |
| | | } |
| | | }else{ |
| | | ElMessage.warning(res.message) |
| | | } |
| | | startUsername.value = value.username; |
| | | }else if(type === 'add' && value ){ |
| | | state.form.parentId = value.id |
| | | } |
| | | dialogVisible.value = true; |
| | | } |
| | | const getClassifyList = async () => { |
| | | const res = await getClassification(); |
| | | if(res.code === 200){ |
| | | state.classifyList = recursion(res.data) |
| | | }else{ |
| | | ElMessage.warning(res.message) |
| | | } |
| | | } |
| | | const recursion = (data) => { |
| | | let tmp = [] |
| | | for (let i = 0; i < data.length; i++) { |
| | | let item = data[i] |
| | | // children为空 |
| | | if (item.children&& item.children.length==0) { |
| | | tmp.push({ |
| | | value: item.id, |
| | | label: item.name |
| | | }) |
| | | // 有children |
| | | } else { |
| | | tmp.push({ |
| | | value: item.id, |
| | | label: item.name, |
| | | children:recursion(item.children) |
| | | }) |
| | | } |
| | | } |
| | | return tmp; |
| | | } |
| | | const handleAvatarSuccess = (res, uploadFile) => { |
| | | if(res.code == 200){ |
| | | state.form.logo = res.data.path |
| | | }else{ |
| | | state.imgList = [] |
| | | ElMessage({ |
| | | type: 'warning', |
| | | message: '文件上传失败' |
| | | }) |
| | | } |
| | | } |
| | | const handleChange = ()=> { |
| | | console.log("label====",classifyRef.value.getCheckedNodes()[0].value) |
| | | state.form.categoryId = classifyRef.value.getCheckedNodes()[0].value |
| | | // 我这里只是打印了一下label的值哦,需要赋值的话自己去赋值哦 |
| | | } |
| | | |
| | | |
| | | const showTip =()=>{ |
| | | ElMessage({ |
| | | type: 'warning', |
| | | message: '超出文件上传数量' |
| | | }); |
| | | } |
| | | const picSize = async (rawFile) => { |
| | | if(rawFile.size / 1024 / 1024 > 5){ |
| | | ElMessage({ |
| | | type: 'warning', |
| | | message: '文件大小不能超过5M' |
| | | }); |
| | | return false |
| | | } |
| | | }; |
| | | const handleRemove = async (file, uploadFiles) => { |
| | | let path = state.form.logo; |
| | | await delPic({path: path}).then(res => { |
| | | if(res.code == 200){ |
| | | // ElMessage({ |
| | | // type: 'success', |
| | | // message: '文件已删除' |
| | | // }) |
| | | state.form.logo = '' |
| | | }else{ |
| | | ElMessage({ |
| | | type: 'warning', |
| | | message: res.message |
| | | }) |
| | | } |
| | | }).catch(() => { |
| | | state.form.imgUrl = '' |
| | | }); |
| | | } |
| | | const onSubmit = async () => { |
| | | const valid = await busRef.value.validate(); |
| | | if(valid){ |
| | | if(title.value === '新增'){ |
| | | const {id, ...data} = JSON.parse(JSON.stringify(state.form)) |
| | | const res = await addCourse(data) |
| | | if(res.code === 200){ |
| | | ElMessage({ |
| | | type: 'success', |
| | | message: '新增成功' |
| | | }); |
| | | }else{ |
| | | ElMessage.warning(res.message) |
| | | } |
| | | emit("getList") |
| | | busRef.value.clearValidate(); |
| | | reset(); |
| | | dialogVisible.value = false; |
| | | }else if(title.value === '编辑'){ |
| | | const {...data} = JSON.parse(JSON.stringify(state.form)) |
| | | const res = await editCourse(data) |
| | | if(res.code === 200){ |
| | | ElMessage({ |
| | | type: 'success', |
| | | message: '编辑成功' |
| | | }); |
| | | }else{ |
| | | ElMessage.warning(res.message) |
| | | } |
| | | emit("getList") |
| | | busRef.value.clearValidate(); |
| | | reset(); |
| | | dialogVisible.value = false; |
| | | } |
| | | } |
| | | } |
| | | |
| | | const handleClose = () => { |
| | | busRef.value.clearValidate(); |
| | | reset(); |
| | | dialogVisible.value = false; |
| | | emit("getList") |
| | | |
| | | } |
| | | const reset = () => { |
| | | state.form = { |
| | | id: '', |
| | | name: '', |
| | | categoryId: null, |
| | | period: null, |
| | | logo: '', |
| | | companyId: null |
| | | } |
| | | } |
| | | defineExpose({ |
| | | openDialog |
| | | }); |
| | | |
| | | </script> |
| | | |
| | | <style scoped lang="scss"> |
| | | .notice{ |
| | | :deep(.el-form .el-form-item__label) { |
| | | font-size: 15px; |
| | | } |
| | | .file { |
| | | display: flex; |
| | | flex-direction: column; |
| | | align-items: flex-start; |
| | | } |
| | | } |
| | | </style> |
对比新文件 |
| | |
| | | <template> |
| | | <div class="notice"> |
| | | <el-dialog |
| | | v-model="dialogVisible" |
| | | :title="title" |
| | | width="550px" |
| | | :before-close="handleClose" |
| | | > |
| | | <el-form :model="state.form" size="default" ref="busRef" :rules="state.formRules" label-width="100px" > |
| | | <el-form-item label="章名称:" prop="name"> |
| | | <el-input v-model.trim="state.form.name" maxlength="100" show-word-limit :disabled="!state.isFirst"></el-input> |
| | | </el-form-item> |
| | | <el-form-item label="节名称:" prop="chapter.name" v-if="!state.isFirst"> |
| | | <el-input v-model.trim="state.chapter.name"></el-input> |
| | | </el-form-item> |
| | | <el-form-item label="资源:" v-if="!state.isFirst"> |
| | | <div style="display: flex;align-items: center; width: 100%;justify-content: space-between;"> |
| | | <el-input v-model.trim="state.chapter.resourceName" disabled style="width: 80%"></el-input> |
| | | <el-button type="primary" style="margin-left: 20px" plain size="default" @click="openResource">选择资源</el-button> |
| | | </div> |
| | | |
| | | </el-form-item> |
| | | |
| | | <el-form-item label="排序:" prop="sort" > |
| | | <el-input-number v-model="state.form.sort" /> |
| | | </el-form-item> |
| | | </el-form> |
| | | <template #footer> |
| | | <span class="dialog-footer"> |
| | | <el-button @click="handleClose" size="default">取 消</el-button> |
| | | <el-button type="primary" @click="onSubmit" size="default" v-preReClick>确认</el-button> |
| | | </span> |
| | | </template> |
| | | </el-dialog> |
| | | <courseDialog ref="courseRef" @choose-res="choosedResource" ></courseDialog> |
| | | </div> |
| | | </template> |
| | | <script setup> |
| | | import {reactive, ref, toRefs} from 'vue' |
| | | import Editor from "@/components/Editor/index.vue"; |
| | | import {ElMessage} from "element-plus"; |
| | | import {addNotice} from "@/api/backManage/notice"; |
| | | import {addDict, editDict, getDictDetail} from "@/api/backManage/evaluate"; |
| | | import {addCompany, checkName, distributeCompany, editCompany} from "@/api/onlineEducation/company"; |
| | | import {verifyPhone} from "@/utils/validate"; |
| | | import {addClassification, checkClassName, editClassification} from "@/api/onlineEducation/courseClass"; |
| | | import courseDialog from './chooseResource.vue' |
| | | import { |
| | | addChapter, |
| | | addChapterPeriod, |
| | | checkChapterName, |
| | | editChapter, |
| | | editChapterPeriod |
| | | } from "@/api/onlineEducation/chapters"; |
| | | |
| | | const dialogVisible = ref(false); |
| | | const title = ref(""); |
| | | const busRef = ref(); |
| | | const courseRef = ref() |
| | | const length = ref() |
| | | const emit = defineEmits(["getList"]); |
| | | const startUsername = ref(''); |
| | | const startUsernamePeriod = ref(''); |
| | | |
| | | |
| | | const validateName = (rule, value, callback)=>{ |
| | | if(value === ''){ |
| | | callback(new Error('请输入章名称')) |
| | | }else if(title.value === '编辑' && value === startUsername.value || title.value === '新增' && value === startUsername.value){ |
| | | callback() |
| | | }else{ |
| | | let param = {} |
| | | if(title.value === '新增') { |
| | | param = { |
| | | name:value, |
| | | courseId: state.form.courseId |
| | | } |
| | | }else if(title.value === '编辑'){ |
| | | param = { |
| | | name:value, |
| | | id: state.form.id, |
| | | courseId: state.form.courseId |
| | | } |
| | | } |
| | | checkChapterName(param).then((res)=>{ |
| | | if(res.data == false){ |
| | | callback(new Error('名称已被占用,请更换其他名称')) |
| | | }else{ |
| | | callback() |
| | | } |
| | | }) |
| | | } |
| | | } |
| | | const state = reactive({ |
| | | form: { |
| | | id: '', |
| | | name: '', |
| | | sort: 0, |
| | | courseId: null, |
| | | chapterPeriods: [] |
| | | }, |
| | | formRules:{ |
| | | name: [{ required: true, trigger: "blur", validator: validateName }], |
| | | }, |
| | | isFirst: true, |
| | | chapter: {} |
| | | }) |
| | | |
| | | const openDialog = async (type, value) => { |
| | | length.value = value.listLength |
| | | state.form.courseId = value.courseId |
| | | title.value = type === 'addFirst' || type === 'add' ? '新增' : type ==='edit' ? '编辑' : '' ; |
| | | if(type === 'edit') { |
| | | if(!value.chapterId){ |
| | | state.isFirst = true; |
| | | startUsername.value = value.name; |
| | | state.form = value; |
| | | state.form.sort = value.sort; |
| | | }else { |
| | | state.isFirst = false; |
| | | startUsernamePeriod.value = value.name; |
| | | state.chapter = value; |
| | | state.form.name = value.capterName; |
| | | startUsername.value = value.capterName; |
| | | state.chapter.resourceName = value.resource.name |
| | | } |
| | | |
| | | }else if(type === 'add' && value ){ |
| | | startUsername.value = value.name; |
| | | state.chapter.chapterId = value.id; |
| | | state.chapter.courseId = value.courseId; |
| | | state.form.name = value.name |
| | | state.isFirst = false; |
| | | }else { |
| | | state.isFirst = true; |
| | | } |
| | | dialogVisible.value = true; |
| | | } |
| | | const choosedResource = (val) => { |
| | | state.chapter.resourceName = val.name |
| | | state.chapter.resourceId = val.id |
| | | } |
| | | |
| | | const onSubmit = async () => { |
| | | const valid = await busRef.value.validate(); |
| | | if(valid){ |
| | | if(title.value === '新增'){ |
| | | if(state.chapter.chapterId){ |
| | | const {id, ...data} = JSON.parse(JSON.stringify(state.chapter)) |
| | | const res = await addChapterPeriod(data) |
| | | if(res.code === 200){ |
| | | ElMessage({ |
| | | type: 'success', |
| | | message: '新增成功' |
| | | }); |
| | | }else{ |
| | | ElMessage.warning(res.message) |
| | | } |
| | | }else{ |
| | | const {id, ...data} = JSON.parse(JSON.stringify(state.form)) |
| | | const res = await addChapter(data) |
| | | if(res.code === 200){ |
| | | ElMessage({ |
| | | type: 'success', |
| | | message: '新增成功' |
| | | }); |
| | | }else{ |
| | | ElMessage.warning(res.message) |
| | | } |
| | | } |
| | | |
| | | emit("getList") |
| | | busRef.value.clearValidate(); |
| | | reset(); |
| | | dialogVisible.value = false; |
| | | }else if(title.value === '编辑'){ |
| | | if(state.chapter.chapterId){ |
| | | const {...data} = JSON.parse(JSON.stringify(state.chapter)) |
| | | const res = await editChapterPeriod(data) |
| | | if(res.code === 200){ |
| | | ElMessage({ |
| | | type: 'success', |
| | | message: '编辑成功' |
| | | }); |
| | | }else{ |
| | | ElMessage.warning(res.message) |
| | | } |
| | | emit("getList") |
| | | busRef.value.clearValidate(); |
| | | reset(); |
| | | dialogVisible.value = false; |
| | | }else { |
| | | const {...data} = JSON.parse(JSON.stringify(state.form)) |
| | | const res = await editChapter(data) |
| | | if(res.code === 200){ |
| | | ElMessage({ |
| | | type: 'success', |
| | | message: '编辑成功' |
| | | }); |
| | | }else{ |
| | | ElMessage.warning(res.message) |
| | | } |
| | | emit("getList") |
| | | busRef.value.clearValidate(); |
| | | reset(); |
| | | dialogVisible.value = false; |
| | | } |
| | | |
| | | } |
| | | } |
| | | } |
| | | |
| | | const handleClose = () => { |
| | | busRef.value.clearValidate(); |
| | | reset(); |
| | | dialogVisible.value = false; |
| | | emit("getList") |
| | | } |
| | | const openResource = () => { |
| | | courseRef.value.openDialog() |
| | | } |
| | | const reset = () => { |
| | | state.form = { |
| | | id: '', |
| | | name: '', |
| | | sort: 0, |
| | | courseId: null, |
| | | chapterPeriods: [] |
| | | } |
| | | state.chapter={} |
| | | } |
| | | defineExpose({ |
| | | openDialog |
| | | }); |
| | | |
| | | </script> |
| | | |
| | | <style scoped lang="scss"> |
| | | .notice{ |
| | | :deep(.el-form .el-form-item__label) { |
| | | font-size: 15px; |
| | | } |
| | | .file { |
| | | display: flex; |
| | | flex-direction: column; |
| | | align-items: flex-start; |
| | | } |
| | | } |
| | | </style> |
对比新文件 |
| | |
| | | <template> |
| | | <div class="app-container"> |
| | | <el-dialog |
| | | v-model="dialogVisible" |
| | | title="选择资源" |
| | | width="600px" |
| | | :before-close="handleClose" |
| | | > |
| | | <div style="margin-bottom: 10px"> |
| | | <el-form> |
| | | <el-form-item label="资源名称"> |
| | | <el-input style="width: 20%" v-model="data.queryParams.name "></el-input> |
| | | <el-button type="primary" style="margin-left: 30px" @click="getList">查询</el-button> |
| | | <el-button plain @click="reset">重置</el-button> |
| | | </el-form-item> |
| | | |
| | | </el-form> |
| | | </div> |
| | | <!-- 表格数据 --> |
| | | <el-table v-loading="loading" :data="dataList" :border="true"> |
| | | <el-table-column label="序号" type="index" align="center" width="80" /> |
| | | <el-table-column label="资源名称" prop="name" align="center" /> |
| | | <el-table-column label="资源类型" prop="resourceType" align="center" > |
| | | <template #default="scope"> |
| | | <span>{{scope.row.resourceType == 1 ? '视频':scope.row.resourceType == 2 ? '音频':'文档'}}</span> |
| | | </template> |
| | | </el-table-column> |
| | | <el-table-column label="操作" align="center" class-name="small-padding fixed-width" > |
| | | <template #default="scope"> |
| | | <el-button link type="primary" @click="choose(scope.row)">选择</el-button> |
| | | </template> |
| | | </el-table-column> |
| | | </el-table> |
| | | |
| | | <pagination |
| | | v-show="total > 0" |
| | | :total="total" |
| | | v-model:page="queryParams.pageNum" |
| | | v-model:limit="queryParams.pageSize" |
| | | @pagination="getList" |
| | | /> |
| | | </el-dialog> |
| | | </div> |
| | | </template> |
| | | |
| | | <script setup> |
| | | import {getCurrentInstance, onMounted, onUnmounted, reactive, ref, toRefs} from "vue"; |
| | | import {ElMessage, ElMessageBox} from "element-plus"; |
| | | import {checkResourceName, delResource, getResource} from "@/api/onlineEducation/courseResource"; |
| | | import {checkName} from "@/api/onlineEducation/company"; |
| | | const { proxy } = getCurrentInstance(); |
| | | const loading = ref(false); |
| | | const emit = defineEmits(["chooseRes"]); |
| | | const dialogRef = ref(); |
| | | const data = reactive({ |
| | | queryParams: { |
| | | pageNum: 1, |
| | | pageSize: 10, |
| | | name: '' |
| | | }, |
| | | total: 0, |
| | | dataList: [] |
| | | }); |
| | | |
| | | const dialogVisible = ref(false); |
| | | const { queryParams, total, dataList } = toRefs(data); |
| | | |
| | | onMounted(()=>{ |
| | | |
| | | }) |
| | | |
| | | onUnmounted(()=>{ |
| | | |
| | | }) |
| | | |
| | | const openDialog = async () => { |
| | | await getList() |
| | | dialogVisible.value = true; |
| | | } |
| | | |
| | | const handleClose = () => { |
| | | dialogVisible.value = false; |
| | | } |
| | | const getList = async () => { |
| | | loading.value = true |
| | | const res = await getResource(data.queryParams) |
| | | if(res.code == 200){ |
| | | data.dataList = res.data.list.map(item => { |
| | | return{ |
| | | ...item, |
| | | sizeMB: Number((item.resourceSize /1024 /1024).toFixed(2))+'MB' |
| | | } |
| | | }) |
| | | console.log("ddd",data.dataList) |
| | | data.total = res.data.total |
| | | }else{ |
| | | ElMessage.warning(res.message) |
| | | } |
| | | loading.value = false |
| | | } |
| | | |
| | | const choose = (value) => { |
| | | console.log("co",value) |
| | | emit('chooseRes',value) |
| | | dialogVisible.value = false |
| | | // dialogRef.value.openDialog(type, value); |
| | | } |
| | | defineExpose({ |
| | | openDialog |
| | | }); |
| | | |
| | | |
| | | /** 重置新增的表单以及其他数据 */ |
| | | function reset() { |
| | | data.queryParams = { |
| | | pageNum: 1, |
| | | pageSize: 10, |
| | | name: '' |
| | | } |
| | | getList() |
| | | } |
| | | |
| | | </script> |
对比新文件 |
| | |
| | | <template> |
| | | <div class="app-container"> |
| | | <div style="margin-bottom: 10px"> |
| | | <el-button type="success" plain @click="openDialog('addFirst',{courseId: data.courseId})">章添加</el-button> |
| | | |
| | | </div> |
| | | <!-- 表格数据 --> |
| | | <el-table v-loading="loading" :data="dataList" :border="true" row-key="id" :tree-props="{ children: 'chapterPeriods' }"> |
| | | <el-table-column label="序号" type="index" align="center" width="80" /> |
| | | <el-table-column label="章节名称" > |
| | | <template #default="scope"> |
| | | <span>{{scope.row.name}}</span> |
| | | </template> |
| | | </el-table-column> |
| | | <el-table-column label="排序" prop="sort" align="center" width="80" /> |
| | | <el-table-column label="操作" align="center" class-name="small-padding fixed-width" width="250" > |
| | | <template #default="scope"> |
| | | <el-button type="success" plain @click="openDialog('add',scope.row)" v-if="!scope.row.chapterId">节添加</el-button> |
| | | <el-button type="primary" plain @click="openDialog('edit',scope.row)">编辑</el-button> |
| | | <el-button type="danger" plain @click="handleDelete(scope.row)">删除</el-button> |
| | | </template> |
| | | </el-table-column> |
| | | </el-table> |
| | | <chapters-dialog ref="areaRef" @getList="getList"></chapters-dialog> |
| | | </div> |
| | | </template> |
| | | |
| | | <script setup> |
| | | import {getCurrentInstance, onMounted, reactive, ref, toRefs} from "vue"; |
| | | import {ElMessage, ElMessageBox} from "element-plus"; |
| | | import chaptersDialog from "./components/chapterDialog.vue" |
| | | import {delArea, getArea} from "@/api/backManage/area"; |
| | | import {getDictList} from "@/api/backManage/evaluate"; |
| | | import {delMonitor} from "@/api/sysUsers"; |
| | | import {useRoute} from 'vue-router' |
| | | import {delClassification, getClassification} from "@/api/onlineEducation/courseClass"; |
| | | import {delChapter, delPeriod, getChapters} from "@/api/onlineEducation/chapters"; |
| | | const { proxy } = getCurrentInstance(); |
| | | const route = useRoute() |
| | | const loading = ref(false); |
| | | const areaRef = ref(); |
| | | const cityList = ref([]) |
| | | const data = reactive({ |
| | | queryParams: { |
| | | name: '', |
| | | }, |
| | | total: 0, |
| | | dataList: [ |
| | | ], |
| | | courseId: '' |
| | | }); |
| | | |
| | | const { queryParams, total, dataList } = toRefs(data); |
| | | |
| | | //页面加载 |
| | | onMounted(() => { |
| | | |
| | | data.courseId = route.query.courseId |
| | | console.log("rou",data.courseId) |
| | | getList(); |
| | | }); |
| | | const getList = async () => { |
| | | loading.value = true; |
| | | const param = { |
| | | courseId: data.courseId |
| | | } |
| | | const res = await getChapters(param); |
| | | if(res.code === 200){ |
| | | dataList.value = res.data |
| | | }else{ |
| | | ElMessage.warning(res.message) |
| | | } |
| | | loading.value = false; |
| | | console.log('dataList.value',dataList.value) |
| | | } |
| | | |
| | | const openDialog = (type, value) => { |
| | | dataList.value.forEach(item => { |
| | | if(item.id == value.chapterId){ |
| | | value.capterName = item.name |
| | | } |
| | | }) |
| | | areaRef.value.openDialog(type, value); |
| | | } |
| | | |
| | | /** 重置新增的表单以及其他数据 */ |
| | | function reset() { |
| | | data.queryParams.name = ''; |
| | | data.queryParams.pageNum = 1; |
| | | getList(); |
| | | } |
| | | const handleDelete = (val) => { |
| | | ElMessageBox.confirm( |
| | | '确定删除此条数据?', |
| | | '提示', |
| | | { |
| | | confirmButtonText: '确定', |
| | | cancelButtonText: '取消', |
| | | type: 'warning', |
| | | }) |
| | | .then( async() => { |
| | | if(!val.chapterId){ |
| | | const res = await delChapter(val.id) |
| | | if(res.code == 200){ |
| | | ElMessage.success('数据删除成功') |
| | | await getList() |
| | | }else{ |
| | | ElMessage.warning(res.message) |
| | | } |
| | | }else { |
| | | const res = await delPeriod(val.id) |
| | | if(res.code == 200){ |
| | | ElMessage.success('数据删除成功') |
| | | await getList() |
| | | }else{ |
| | | ElMessage.warning(res.message) |
| | | } |
| | | } |
| | | |
| | | }) |
| | | } |
| | | |
| | | |
| | | </script> |
对比新文件 |
| | |
| | | <template> |
| | | <div class="notice"> |
| | | <el-dialog |
| | | v-model="dialogVisible" |
| | | :title="title" |
| | | width="550px" |
| | | :before-close="handleClose" |
| | | > |
| | | <el-form :model="state.form" size="default" ref="busRef" :rules="state.formRules" label-width="130px" > |
| | | <el-form-item label="资源名称:" prop="name" > |
| | | <el-input v-model.trim="state.form.name" placeholder="请输入资源名称"></el-input> |
| | | </el-form-item> |
| | | <el-form-item label="资源类型:" prop="resourceType" > |
| | | <el-select |
| | | @change="changeType" |
| | | v-model="state.form.resourceType" |
| | | placeholder="请选择资源类型" |
| | | size="default" |
| | | style="width: 100%" |
| | | |
| | | > |
| | | <el-option |
| | | v-for="item in state.typeList" |
| | | :key="item.id" |
| | | :label="item.name" |
| | | :value="item.id" |
| | | /> |
| | | </el-select> |
| | | </el-form-item> |
| | | <el-form-item label="资源时长(秒):" prop="resourceLength" v-if="(state.form.resourceType == 1 || state.form.resourceType == 2)&& state.form.resourceLength"> |
| | | <el-input |
| | | :disabled="state.form.resourceLength!=0" |
| | | v-model="state.form.resourceLength" |
| | | style="width: 100%" |
| | | placeholder="请输入资源时长(秒)" |
| | | > |
| | | <template #append>秒</template> |
| | | </el-input> |
| | | </el-form-item> |
| | | <el-form-item label="文档页数:" prop="docPage" v-if="state.form.resourceType == 3 && state.form.docPage "> |
| | | <el-input |
| | | :disabled="state.form.docPage!=0" |
| | | v-model="state.form.docPage" |
| | | style="width: 100%" |
| | | placeholder="请输入文档页数:" |
| | | > |
| | | <template #append>页</template> |
| | | </el-input> |
| | | </el-form-item> |
| | | |
| | | <el-form-item label="资源上传:"> |
| | | <file-upload ref="fileRef" :responseType="state.form.resourceType" @getFile="getFile"></file-upload> |
| | | </el-form-item> |
| | | |
| | | </el-form> |
| | | <template #footer> |
| | | <span class="dialog-footer"> |
| | | <el-button @click="handleClose" size="default">取 消</el-button> |
| | | <el-button type="primary" @click="onSubmit" size="default" v-preReClick>确认</el-button> |
| | | </span> |
| | | </template> |
| | | </el-dialog> |
| | | </div> |
| | | </template> |
| | | <script setup> |
| | | import {nextTick, reactive, ref, toRefs} from 'vue' |
| | | import Editor from "@/components/Editor/index.vue"; |
| | | import {ElMessage} from "element-plus"; |
| | | import {addNotice} from "@/api/backManage/notice"; |
| | | import {addDict, editDict, getDictDetail} from "@/api/backManage/evaluate"; |
| | | import {addCompany, checkName, distributeCompany, editCompany} from "@/api/onlineEducation/company"; |
| | | import {verifyPhone} from "@/utils/validate"; |
| | | import {addBanner, delPic, editBanner, getBannerById} from "@/api/onlineEducation/banner"; |
| | | import {getToken} from "@/utils/auth"; |
| | | import {getUserById} from "@/api/onlineEducation/user"; |
| | | import {addResource, checkResourceName, editResource, getResourceById} from "@/api/onlineEducation/courseResource"; |
| | | import fileUpload from '@/views/components/upload.vue' |
| | | import Cookies from "js-cookie"; |
| | | |
| | | const dialogVisible = ref(false); |
| | | const title = ref(""); |
| | | const fileRef = ref(); |
| | | const busRef = ref(); |
| | | const length = ref() |
| | | const emit = defineEmits(["getList"]); |
| | | const startUsername = ref(''); |
| | | const startPhone = ref(''); |
| | | |
| | | const validateName = (rule, value, callback)=>{ |
| | | if(value === ''){ |
| | | callback(new Error('请输入资源名称')) |
| | | }else if(title.value === '编辑' && value === startUsername.value){ |
| | | callback() |
| | | }else{ |
| | | let param = {} |
| | | if(title.value === '新增') { |
| | | param = { |
| | | name:value, |
| | | } |
| | | }else if(title.value === '编辑'){ |
| | | param = { |
| | | name:value, |
| | | id: state.form.id |
| | | } |
| | | } |
| | | checkResourceName(param).then((res)=>{ |
| | | if(res.data == false){ |
| | | callback(new Error('资源名称已被占用,请更换其他名称')) |
| | | }else{ |
| | | callback() |
| | | } |
| | | }) |
| | | } |
| | | } |
| | | |
| | | const state = reactive({ |
| | | form: { |
| | | id: '', |
| | | name: '', |
| | | mediaType: '', |
| | | resourceType: null, |
| | | companyId: null, |
| | | resourcePath:'', |
| | | md5: '', |
| | | resourceSize: null, |
| | | resourceLength: '', |
| | | docPage: null, |
| | | originName: '' |
| | | }, |
| | | formRules:{ |
| | | name: [{ required: true, trigger: "blur", validator: validateName }], |
| | | resourceType:[{ required: true, message: '请选择资源类型', trigger: 'blur' }], |
| | | resourceLength: [{ required: true, trigger: "blur", message: '请输入资源时长(秒)' }], |
| | | }, |
| | | uploadUrl: import.meta.env.VITE_APP_BASE_API + '/system/common/uploadFile', |
| | | header: { |
| | | Authorization:getToken() |
| | | }, |
| | | imgLimit: 1, |
| | | imgList: [], |
| | | typeList: [ |
| | | { |
| | | id: 1, |
| | | name: '视频' |
| | | }, |
| | | { |
| | | id: 2, |
| | | name: '音频' |
| | | }, |
| | | { |
| | | id: 3, |
| | | name: '文档' |
| | | }, |
| | | ] |
| | | }) |
| | | const handleChange = (file, fileLists) => { |
| | | state.form.file = file.raw; |
| | | console.log(file); |
| | | // 这里把数组置空是为了每次只能上传一个文件,以防报错 |
| | | state.imgList = []; |
| | | state.form.mediaType = file.raw.type |
| | | } |
| | | const handleAvatarSuccess = (response, file, fileList) => { |
| | | if(response.code == 200){ |
| | | if(file && file.raw){ |
| | | state.form.mediaType = file.raw.type |
| | | } |
| | | state.form.file = file |
| | | }else{ |
| | | state.imgList = [] |
| | | ElMessage({ |
| | | type: 'warning', |
| | | message: '文件上传失败' |
| | | }) |
| | | } |
| | | } |
| | | const showTip =()=>{ |
| | | ElMessage({ |
| | | type: 'warning', |
| | | message: '超出文件上传数量' |
| | | }); |
| | | } |
| | | const picSize = async (rawFile) => { |
| | | if(rawFile.size / 1024 / 1024 > 5){ |
| | | ElMessage({ |
| | | type: 'warning', |
| | | message: '文件大小不能超过5M' |
| | | }); |
| | | return false |
| | | } |
| | | }; |
| | | const handleRemove = async (file, uploadFiles) => { |
| | | let path = state.form.imgUrl; |
| | | await delPic({path: path}).then(res => { |
| | | if(res.code == 200){ |
| | | // ElMessage({ |
| | | // type: 'success', |
| | | // message: '文件已删除' |
| | | // }) |
| | | state.form.imgUrl = '' |
| | | }else{ |
| | | ElMessage({ |
| | | type: 'warning', |
| | | message: res.message |
| | | }) |
| | | } |
| | | }).catch(() => { |
| | | state.form.imgUrl = '' |
| | | }); |
| | | } |
| | | |
| | | const openDialog = async (type, value) => { |
| | | length.value = value.listLength |
| | | title.value = type === 'add' ? '新增' : type ==='edit' ? '编辑' : '' ; |
| | | if(type === 'edit') { |
| | | const res = await getResourceById(value.id); |
| | | if(res.code === 200){ |
| | | state.form = res.data |
| | | }else{ |
| | | ElMessage.warning(res.message) |
| | | } |
| | | } |
| | | dialogVisible.value = true; |
| | | if(type === 'edit') { |
| | | await nextTick(() => { |
| | | fileRef.value.open(state.form); |
| | | }) |
| | | } |
| | | } |
| | | const getFile = (val) => { |
| | | |
| | | if(val.md5 != ''){ |
| | | state.form.md5 = val.md5 |
| | | state.form.resourcePath = val.resourcePath |
| | | state.form.mediaType = val.mediaType |
| | | state.form.resourceSize = val.resourceSize |
| | | state.form.docPage = val.docPage |
| | | state.form.resourceLength = val.resourceLength |
| | | state.form.originName = val.originName |
| | | } else if( val.md5 == ''){ |
| | | state.form.resourceType = '' |
| | | |
| | | } else { |
| | | ElMessage({ |
| | | type: 'warning', |
| | | message: '请上传题库资源' |
| | | }); |
| | | } |
| | | } |
| | | |
| | | const changeType = (val) => { |
| | | state.form.md5 = '' |
| | | state.form.resourcePath = '' |
| | | state.form.mediaType ='' |
| | | state.form.resourceSize = null |
| | | state.form.docPage = null |
| | | state.form.resourceLength = null |
| | | state.form.originName = '' |
| | | fileRef.value.changeType(val); |
| | | } |
| | | const onSubmit = async () => { |
| | | const valid = await busRef.value.validate(); |
| | | if(valid){ |
| | | if(title.value === '新增'){ |
| | | const {id,...data} = JSON.parse(JSON.stringify(state.form)) |
| | | const res = await addResource(data) |
| | | if(res.code === 200){ |
| | | ElMessage({ |
| | | type: 'success', |
| | | message: '新增成功' |
| | | }); |
| | | }else{ |
| | | ElMessage.warning(res.message) |
| | | } |
| | | dialogVisible.value = false; |
| | | emit("getList") |
| | | busRef.value.clearValidate(); |
| | | fileRef.value.dispose(); |
| | | reset(); |
| | | |
| | | |
| | | }else if(title.value === '编辑'){ |
| | | const {...data} = JSON.parse(JSON.stringify(state.form)) |
| | | const res = await editResource(data) |
| | | if(res.code === 200){ |
| | | ElMessage({ |
| | | type: 'success', |
| | | message: '编辑成功' |
| | | }); |
| | | }else{ |
| | | ElMessage.warning(res.message) |
| | | } |
| | | dialogVisible.value = false; |
| | | emit("getList") |
| | | busRef.value.clearValidate(); |
| | | fileRef.value.dispose(); |
| | | reset(); |
| | | |
| | | |
| | | } |
| | | } |
| | | } |
| | | |
| | | const handleClose = () => { |
| | | dialogVisible.value = false; |
| | | fileRef.value.dispose(); |
| | | busRef.value.clearValidate(); |
| | | reset(); |
| | | |
| | | emit("getList") |
| | | |
| | | } |
| | | const reset = () => { |
| | | state.form = { |
| | | id: '', |
| | | name: '', |
| | | mediaType: '', |
| | | resourceType: null, |
| | | companyId: null, |
| | | resourcePath:'', |
| | | md5: '', |
| | | resourceSize: null, |
| | | resourceLength: '', |
| | | docPage: null, |
| | | originName: '' |
| | | } |
| | | } |
| | | defineExpose({ |
| | | openDialog |
| | | }); |
| | | |
| | | </script> |
| | | |
| | | <style scoped lang="scss"> |
| | | .notice{ |
| | | :deep(.el-form .el-form-item__label) { |
| | | font-size: 15px; |
| | | } |
| | | .file { |
| | | display: flex; |
| | | flex-direction: column; |
| | | align-items: flex-start; |
| | | } |
| | | } |
| | | </style> |
对比新文件 |
| | |
| | | <template> |
| | | <div class="app-container"> |
| | | <div style="margin-bottom: 10px"> |
| | | <el-button |
| | | type="primary" |
| | | plain |
| | | icon="Plus" |
| | | @click="openDialog('add',{})" |
| | | >新增</el-button> |
| | | </div> |
| | | <!-- 表格数据 --> |
| | | <el-table v-loading="loading" :data="dataList" :border="true"> |
| | | <el-table-column label="序号" type="index" align="center" width="80" /> |
| | | <el-table-column label="资源名称" prop="name" align="center" /> |
| | | <el-table-column label="资源大小" prop="sizeMB" align="center" > |
| | | </el-table-column> |
| | | <el-table-column label="资源类型" prop="resourceType" align="center" > |
| | | <template #default="scope"> |
| | | <span>{{scope.row.resourceType == 1 ? '视频':scope.row.resourceType == 2 ? '音频':'文档'}}</span> |
| | | </template> |
| | | </el-table-column> |
| | | <el-table-column label="操作" align="center" class-name="small-padding fixed-width" > |
| | | <template #default="scope"> |
| | | <el-button link type="primary" @click="openDialog('edit',scope.row)">编辑</el-button> |
| | | <el-button link type="danger" @click="handleDelete(scope.row)">删除</el-button> |
| | | </template> |
| | | </el-table-column> |
| | | </el-table> |
| | | |
| | | <pagination |
| | | v-show="total > 0" |
| | | :total="total" |
| | | v-model:page="queryParams.pageNum" |
| | | v-model:limit="queryParams.pageSize" |
| | | @pagination="getList" |
| | | /> |
| | | <resource-dialog ref="dialogRef" @getList="getList"></resource-dialog> |
| | | </div> |
| | | </template> |
| | | |
| | | <script setup> |
| | | import {getCurrentInstance, onMounted, onUnmounted, reactive, ref, toRefs} from "vue"; |
| | | import {ElMessage, ElMessageBox} from "element-plus"; |
| | | import resourceDialog from './componets/resourceDialog.vue' |
| | | import {checkResourceName, delResource, getResource} from "@/api/onlineEducation/courseResource"; |
| | | import {checkName} from "@/api/onlineEducation/company"; |
| | | const { proxy } = getCurrentInstance(); |
| | | const loading = ref(false); |
| | | const dialogRef = ref(); |
| | | const data = reactive({ |
| | | queryParams: { |
| | | pageNum: 1, |
| | | pageSize: 10, |
| | | }, |
| | | total: 0, |
| | | dataList: [] |
| | | }); |
| | | |
| | | const { queryParams, total, dataList } = toRefs(data); |
| | | |
| | | onMounted(()=>{ |
| | | getList() |
| | | }) |
| | | |
| | | onUnmounted(()=>{ |
| | | |
| | | }) |
| | | |
| | | const getList = async () => { |
| | | loading.value = true |
| | | const res = await getResource(data.queryParams) |
| | | if(res.code == 200){ |
| | | data.dataList = res.data.list.map(item => { |
| | | return{ |
| | | ...item, |
| | | sizeMB: Number((item.resourceSize /1024 /1024).toFixed(2))+'MB' |
| | | } |
| | | }) |
| | | console.log("ddd",data.dataList) |
| | | data.total = res.data.total |
| | | }else{ |
| | | ElMessage.warning(res.message) |
| | | } |
| | | loading.value = false |
| | | } |
| | | |
| | | const openDialog = (type, value) => { |
| | | dialogRef.value.openDialog(type, value); |
| | | } |
| | | |
| | | /** 重置新增的表单以及其他数据 */ |
| | | function reset() { |
| | | proxy.resetForm("roleRef"); |
| | | } |
| | | const handleDelete = (val) => { |
| | | ElMessageBox.confirm( |
| | | '确定删除此条数据?', |
| | | '提示', |
| | | { |
| | | confirmButtonText: '确定', |
| | | cancelButtonText: '取消', |
| | | type: 'warning', |
| | | }) |
| | | .then( async() => { |
| | | const res = await delResource(val.id) |
| | | if(res.code == 200){ |
| | | ElMessage.success('数据删除成功') |
| | | await getList() |
| | | }else{ |
| | | ElMessage.warning(res.message) |
| | | } |
| | | }) |
| | | } |
| | | |
| | | </script> |
| | |
| | | <template> |
| | | <div>课程管理</div> |
| | | <div class="app-container"> |
| | | <div style="margin-bottom: 10px"> |
| | | <el-button |
| | | type="primary" |
| | | plain |
| | | icon="Plus" |
| | | @click="openDialog('add',{})" |
| | | >新增</el-button> |
| | | </div> |
| | | <!-- 表格数据 --> |
| | | <el-table v-loading="loading" :data="dataList" :border="true"> |
| | | <el-table-column label="序号" type="index" align="center" width="80" /> |
| | | <el-table-column label="封面" prop="logo" align="center" > |
| | | <template #default="scope"> |
| | | <div class="demo-image__preview" v-if="scope.row.logo && scope.row.logo.length>0"> |
| | | <el-image |
| | | style="width: 100px; height: 100px" |
| | | :src= "scope.row.logo[0]" |
| | | :zoom-rate="1.2" |
| | | :max-scale="7" |
| | | :min-scale="0.2" |
| | | :preview-src-list="scope.row.logo" |
| | | :initial-index="0" |
| | | fit="cover" |
| | | :preview-teleported=true |
| | | /> |
| | | </div> |
| | | </template> |
| | | </el-table-column> |
| | | <el-table-column label="课程名称" prop="name" align="center" /> |
| | | <el-table-column label="课程分类" prop="categoryName" align="center" /> |
| | | <el-table-column label="要求课时" prop="period" align="center" /> |
| | | <el-table-column label="提交单位" prop="companyName" align="center" /> |
| | | <el-table-column label="审核状态" prop="state" align="center" > |
| | | <template #default="scope"> |
| | | <span>{{scope.row.state == 1?'待审核':scope.row.state == 2?'审批通过':'审批不通过'}}</span> |
| | | </template> |
| | | </el-table-column> |
| | | <el-table-column label="创建时间" prop="createTime" align="center" width="180" /> |
| | | <el-table-column label="状态" prop="status" align="center" > |
| | | |
| | | <template #default="scope" v-if="data.isAdmin"> |
| | | <el-switch |
| | | v-if="scope.row.state == 2" |
| | | v-model="scope.row.status" |
| | | :active-value="0" |
| | | :inactive-value="1" |
| | | inline-prompt |
| | | active-text="正常" |
| | | inactive-text="停用" |
| | | @change="switchStatus($event,scope.row)" |
| | | /> |
| | | <span v-else>--</span> |
| | | </template> |
| | | <template #default="scope" v-else> |
| | | <span v-if="scope.row.state == 2">{{scope.row.status == 1? '停用' : '正常'}}</span> |
| | | <span v-else>--</span> |
| | | </template> |
| | | </el-table-column> |
| | | <el-table-column label="操作" align="center" class-name="small-padding fixed-width" width="180"> |
| | | <template #default="scope"> |
| | | <div v-if="scope.row.state == 2"> |
| | | <div v-if="data.isAdmin"> |
| | | <el-button link type="primary" @click="openDialog('edit',scope.row)">编辑</el-button> |
| | | <el-button link type="primary" @click="toChapters(scope.row)">章节</el-button> |
| | | <el-button link type="danger" @click="handleDelete(scope.row)">删除</el-button> |
| | | </div> |
| | | <div v-else>--</div> |
| | | </div> |
| | | <div v-else-if="scope.row.state == 1" > |
| | | <el-button link type="primary" @click="openDialog('edit',scope.row)">编辑</el-button> |
| | | <el-button link type="primary" v-if="data.isAdmin" @click="openApprove(scope.row)">审核</el-button> |
| | | <el-button link type="primary" @click="toChapters(scope.row)">章节</el-button> |
| | | <el-button link type="danger" @click="handleDelete(scope.row)">删除</el-button> |
| | | </div> |
| | | <div v-else-if="scope.row.state == 3" > |
| | | <div v-if="data.isAdmin">--</div> |
| | | <div v-else> |
| | | <el-button link type="primary" @click="openDialog('edit',scope.row)">编辑</el-button> |
| | | <el-button link type="primary" @click="submitApprove(scope.row)">提交审核</el-button> |
| | | <el-button link type="primary" @click="toChapters(scope.row)">章节</el-button> |
| | | <el-button link type="danger" @click="handleDelete(scope.row)">删除</el-button> |
| | | </div> |
| | | </div> |
| | | </template> |
| | | </el-table-column> |
| | | </el-table> |
| | | |
| | | <pagination |
| | | v-show="total > 0" |
| | | :total="total" |
| | | v-model:page="queryParams.pageNum" |
| | | v-model:limit="queryParams.pageSize" |
| | | @pagination="getList" |
| | | /> |
| | | <course-manage-dialog ref="dialogRef" @getList=getList></course-manage-dialog> |
| | | <el-dialog v-model="data.appDialog" title="审批课程" width="30%" center align-center> |
| | | <el-radio-group v-model="data.appoveForm.state" style="width: 100%"> |
| | | <el-radio :label="2" size="large" border>通过</el-radio> |
| | | <el-radio :label="3" size="large" border>驳回</el-radio> |
| | | </el-radio-group> |
| | | <template #footer> |
| | | <span class="dialog-footer"> |
| | | <el-button @click="data.appDialog = false">取消</el-button> |
| | | <el-button type="primary" @click="confirmApproval">确认</el-button> |
| | | </span> |
| | | </template> |
| | | </el-dialog> |
| | | </div> |
| | | </template> |
| | | |
| | | <script setup> |
| | | import {getCurrentInstance, onMounted, onUnmounted, reactive, ref, toRefs} from "vue"; |
| | | import {ElMessage, ElMessageBox} from "element-plus"; |
| | | import {delCompany, getCompany} from "@/api/onlineEducation/company"; |
| | | import courseManageDialog from './components/courseManageDialog.vue' |
| | | import {delBanner, getBanner} from "@/api/onlineEducation/banner"; |
| | | import {useRouter} from 'vue-router' |
| | | import Cookies from "js-cookie"; |
| | | import {changeCourseStatus, delCourse, doCourse, getCourse} from "@/api/onlineEducation/courseManage"; |
| | | const { proxy } = getCurrentInstance(); |
| | | const router = useRouter() |
| | | const loading = ref(false); |
| | | const dialogRef = ref(); |
| | | const data = reactive({ |
| | | queryParams: { |
| | | pageNum: 1, |
| | | pageSize: 10, |
| | | }, |
| | | total: 0, |
| | | dataList: [], |
| | | isAdmin: false, |
| | | appDialog: false, |
| | | appoveForm: { |
| | | id: null, |
| | | state: null |
| | | }, |
| | | }); |
| | | |
| | | const { queryParams, total, dataList } = toRefs(data); |
| | | |
| | | onMounted(async ()=>{ |
| | | const userInfo = JSON.parse(Cookies.get('userInfo')) |
| | | console.log("userInfo",userInfo) |
| | | if(userInfo.userType === 0){ |
| | | data.isAdmin = true; |
| | | }else { |
| | | data.isAdmin = false; |
| | | } |
| | | await getList() |
| | | }) |
| | | |
| | | onUnmounted(()=>{ |
| | | |
| | | }) |
| | | |
| | | const getList = async () => { |
| | | loading.value = true |
| | | const res = await getCourse(data.queryParams) |
| | | if(res.code == 200){ |
| | | data.dataList = res.data.list.map(item => { |
| | | return { |
| | | ...item, |
| | | logo: item.logo ?[import.meta.env.VITE_APP_BASE_API + "/" + item.logo] : [], |
| | | } |
| | | }) |
| | | console.log("ddd",data.dataList) |
| | | data.total = res.data.total |
| | | }else{ |
| | | ElMessage.warning(res.message) |
| | | } |
| | | loading.value = false |
| | | } |
| | | |
| | | const openDialog = (type, value) => { |
| | | dialogRef.value.openDialog(type, value); |
| | | } |
| | | |
| | | /** 重置新增的表单以及其他数据 */ |
| | | function reset() { |
| | | proxy.resetForm("roleRef"); |
| | | } |
| | | const handleDelete = (val) => { |
| | | ElMessageBox.confirm( |
| | | '确定删除此条数据?', |
| | | '提示', |
| | | { |
| | | confirmButtonText: '确定', |
| | | cancelButtonText: '取消', |
| | | type: 'warning', |
| | | }) |
| | | .then( async() => { |
| | | const res = await delCourse(val.id) |
| | | if(res.code == 200){ |
| | | ElMessage.success('数据删除成功') |
| | | await getList() |
| | | }else{ |
| | | ElMessage.warning(res.message) |
| | | } |
| | | }) |
| | | } |
| | | const switchStatus = (e,val) => { |
| | | ElMessageBox.confirm( |
| | | '确定修改该课程当前状态?', |
| | | '提示', |
| | | { |
| | | confirmButtonText: '确定', |
| | | cancelButtonText: '取消', |
| | | type: 'warning', |
| | | }) |
| | | .then( async() => { |
| | | const res = await changeCourseStatus({id: val.id,status: e}) |
| | | if(res.code == 200){ |
| | | ElMessage.success('状态修改成功') |
| | | await getList() |
| | | }else{ |
| | | ElMessage.warning(res.message) |
| | | } |
| | | }) |
| | | .catch(() => { |
| | | getList() |
| | | }) |
| | | |
| | | } |
| | | const openApprove = (val) => { |
| | | data.appoveForm = { |
| | | id: null, |
| | | state: null |
| | | } |
| | | data.appoveForm.id = val.id |
| | | data.appDialog = true |
| | | } |
| | | const confirmApproval = async () =>{ |
| | | if(data.appoveForm.state !== null){ |
| | | const res = await doCourse(data.appoveForm) |
| | | if(res.code == 200){ |
| | | ElMessage.success('审批成功') |
| | | await getList() |
| | | data.appDialog = false |
| | | }else{ |
| | | ElMessage.warning(res.message) |
| | | } |
| | | } |
| | | } |
| | | const submitApprove = async (val) => { |
| | | const param = { |
| | | id: val.id, |
| | | state: 1 |
| | | } |
| | | const res = await doCourse(param) |
| | | if(res.code == 200){ |
| | | ElMessage.success('提交成功') |
| | | await getList() |
| | | }else{ |
| | | ElMessage.warning(res.message) |
| | | } |
| | | } |
| | | const toChapters = (val) => { |
| | | router.push({ path: "/chapters", query: { courseId: val.id } }); |
| | | } |
| | | |
| | | </script> |
| | | |
| | | |
| | | |
| | | <style scoped lang="scss"> |
| | | |
| | | </style> |
对比新文件 |
| | |
| | | <template> |
| | | <div class="notice"> |
| | | <el-dialog |
| | | v-model="dialogVisible" |
| | | :title="state.title" |
| | | width="550px" |
| | | :before-close="handleClose" |
| | | > |
| | | <el-form :model="state.form" size="default" ref="superRef" :rules="state.formRules" label-width="180px" > |
| | | <el-form-item label="企业:" prop="companyName" v-if="state.title !== '修改密码'"> |
| | | <el-input v-model.trim="state.form.companyName" disabled></el-input> |
| | | </el-form-item> |
| | | <el-form-item label="姓名:" prop="name" v-if="state.title !== '修改密码'"> |
| | | <el-input v-model.trim="state.form.name" :disabled="disabled" placeholder="请输入姓名" ></el-input> |
| | | </el-form-item> |
| | | <el-form-item label="性别:" prop="sex" v-if="state.title !== '修改密码'"> |
| | | <el-radio-group v-model="state.form.sex" :disabled="disabled"> |
| | | <el-radio :label="0">男</el-radio> |
| | | <el-radio :label="1">女</el-radio> |
| | | </el-radio-group> |
| | | </el-form-item> |
| | | <el-form-item label="身份证号:" prop="idNo" v-if="state.title !== '修改密码'"> |
| | | <el-input v-model.trim="state.form.idNo" :disabled="disabled" placeholder="请输入身份证号" ></el-input> |
| | | </el-form-item> |
| | | <el-form-item label="手机号(登录用户名):" prop="phone" v-if="state.title !== '修改密码'" > |
| | | <el-input v-model.trim="state.form.phone" :maxlength="11" :disabled="disabled" placeholder="请输入手机号"></el-input> |
| | | </el-form-item> |
| | | <el-form-item label="密码:" prop="password" v-if="state.title == '新增' || state.title == '修改密码'"> |
| | | <el-input v-model.trim="state.form.password" type="password" show-password placeholder="请输入密码"></el-input> |
| | | </el-form-item> |
| | | <el-form-item label="重复密码:" prop="confirmPassword" v-if="state.title == '新增' || state.title == '修改密码'"> |
| | | <el-input v-model.trim="state.form.confirmPassword" type="password" show-password placeholder="请输入确认密码"></el-input> |
| | | </el-form-item> |
| | | <el-form-item label="工号:" prop="empno" v-if="state.title !== '修改密码'"> |
| | | <el-input v-model.trim="state.form.empno" :disabled="disabled" placeholder="请输入工号" ></el-input> |
| | | </el-form-item> |
| | | <el-form-item label="岗位:" prop="post" v-if="state.title !== '修改密码'"> |
| | | <el-input v-model.trim="state.form.post" :disabled="disabled" placeholder="请输入岗位" ></el-input> |
| | | </el-form-item> |
| | | <el-form-item label="职务:" prop="duty" v-if="state.title !== '修改密码'"> |
| | | <el-input v-model.trim="state.form.duty" :disabled="disabled" placeholder="请输入职务" ></el-input> |
| | | </el-form-item> |
| | | </el-form> |
| | | <template #footer v-if="state.title !='查看'"> |
| | | <span class="dialog-footer"> |
| | | <el-button @click="handleClose" size="default">取 消</el-button> |
| | | <el-button type="primary" @click="onSubmit" size="default" v-preReClick>确认</el-button> |
| | | </span> |
| | | </template> |
| | | </el-dialog> |
| | | </div> |
| | | </template> |
| | | <script setup> |
| | | import {reactive, ref, toRefs, defineEmits, nextTick, onMounted} from 'vue' |
| | | import { View } from "@element-plus/icons-vue"; |
| | | import scorllSelect from '@/components/scrollSelect/index.vue' |
| | | import {ElMessage, ElMessageBox} from "element-plus"; |
| | | import {verifyPhone, verifyPwd, verifyUsername} from "@/utils/validate"; |
| | | import { checkUserName, checkPhone } from "@/api/login" |
| | | import {resetPwd} from "@/api/onlineEducation/student" |
| | | import {Base64} from "js-base64" |
| | | import Cookies from "js-cookie"; |
| | | import {addStudent, checkStuIdNo, checkStuPhone, editStudent} from "@/api/onlineEducation/student"; |
| | | |
| | | const emit = defineEmits(["getList"]); |
| | | const dialogVisible = ref(false) |
| | | const superRef = ref(null) |
| | | const scrollRef = ref(null) |
| | | |
| | | |
| | | const equalToPassword = (rule, value, callback) => { |
| | | if (state.form.password !== value) { |
| | | callback(new Error("两次输入的密码不一致")); |
| | | } else { |
| | | callback(); |
| | | } |
| | | }; |
| | | |
| | | const validateUserPhone = (rule, value, callback)=>{ |
| | | if(value === ''){ |
| | | callback(new Error('请输入手机号')) |
| | | }else if(state.title === '编辑' && value === startPhone.value){ |
| | | callback() |
| | | } else if(!verifyPhone(value)){ |
| | | callback(new Error('手机号格式有误')) |
| | | }else{ |
| | | let param = {} |
| | | if(state.title === '新增') { |
| | | param = { |
| | | phone:value |
| | | } |
| | | }else if(state.title === '编辑'){ |
| | | param = { |
| | | phone:value, |
| | | id: state.form.id |
| | | } |
| | | } |
| | | checkStuPhone(param).then((res)=>{ |
| | | if(res.data == false){ |
| | | callback(new Error('手机号已被占用,请更换其他手机号')) |
| | | }else{ |
| | | callback() |
| | | } |
| | | }) |
| | | } |
| | | } |
| | | |
| | | let validatePwd = (rule, value, callback)=>{ |
| | | if(value === ''){ |
| | | callback(new Error('请输入密码')) |
| | | }else{ |
| | | if(!verifyPwd(value)){ |
| | | callback(new Error('密码须包含字母、数字、特殊字符,长度在6-16之间')) |
| | | }else{ |
| | | callback() |
| | | } |
| | | } |
| | | } |
| | | let validateIdNo = (rule, value, callback)=>{ |
| | | if(value === ''){ |
| | | callback(new Error('请输入身份证号')) |
| | | }else if(state.title === '编辑' && value === startIdNo.value){ |
| | | callback() |
| | | }else{ |
| | | let param = {} |
| | | if(state.title === '新增') { |
| | | param = { |
| | | idNo:value |
| | | } |
| | | }else if(state.title === '编辑'){ |
| | | param = { |
| | | idNo:value, |
| | | id: state.form.id |
| | | } |
| | | } |
| | | checkStuIdNo(param).then((res)=>{ |
| | | if(res.data == false){ |
| | | callback(new Error('身份证号已被占用,请更换其他身份证号')) |
| | | // ElMessageBox.confirm( |
| | | // `该人员${state.form.name}(身份证号:${state.form.idNo})与${state.form.idNo}已经绑定,确定将该人员的责任归属变更到贵公企业?`, |
| | | // '提示', |
| | | // { |
| | | // confirmButtonText: '确认', |
| | | // cancelButtonText: '取消', |
| | | // type: 'warning', |
| | | // icon: '' |
| | | // } |
| | | // ) |
| | | // .then(() => { |
| | | // ElMessage({ |
| | | // type: 'success', |
| | | // message: 'Delete completed', |
| | | // }) |
| | | // }) |
| | | // .catch(() => { |
| | | // callback(new Error('身份证号已被占用,请更换其他身份证号')) |
| | | // }) |
| | | }else{ |
| | | callback() |
| | | } |
| | | }) |
| | | } |
| | | } |
| | | |
| | | |
| | | const state = reactive({ |
| | | title: '', |
| | | form: { |
| | | id: null, |
| | | name: '', |
| | | phone: '', |
| | | password: '', |
| | | confirmPassword: '', |
| | | sex: 0, |
| | | companyId: null, |
| | | empno: '', |
| | | post: '', |
| | | duty: '', |
| | | idNo: '' |
| | | |
| | | }, |
| | | formRules:{ |
| | | name: [{ required: true, message: '请输入公司、部门或者车间岗位名称', trigger: 'blur' }], |
| | | password: [{ required: true, validator: validatePwd, trigger: 'blur' }], |
| | | confirmPassword: [{ required: true, validator: equalToPassword, trigger: 'blur' }], |
| | | phone: [{ required: true, validator: validateUserPhone, trigger: 'blur' }], |
| | | idNo: [{ required: true, validator: validateIdNo, trigger: 'blur' }], |
| | | }, |
| | | isAdmin: false |
| | | |
| | | }) |
| | | const startPhone = ref(''); |
| | | const startIdNo = ref(''); |
| | | const UisMounted = ref(false); |
| | | onMounted(() => { |
| | | UisMounted.value = true; |
| | | |
| | | }); |
| | | |
| | | const disabled = ref(false); |
| | | const openDialog = async (type, value) => { |
| | | const userInfo = JSON.parse(Cookies.get('userInfo')) |
| | | console.log("userInfo",userInfo) |
| | | if(userInfo.userType === 0){ |
| | | state.isAdmin = true; |
| | | state.form.userType = 0; |
| | | }else { |
| | | state.isAdmin = false; |
| | | state.form.companyId = userInfo.companyId; |
| | | state.form.companyName = userInfo.companyName; |
| | | state.form.userType = 1; |
| | | } |
| | | state.title = type === 'add' ? '新增' : type ==='edit' ? '编辑' : type ==='pwd' ? '修改密码' : '查看' ; |
| | | if(type === 'edit' || type === 'view') { |
| | | if( type === 'view'){ |
| | | disabled.value = true; |
| | | } |
| | | startPhone.value = value.phone |
| | | startIdNo.value = value.idNo |
| | | state.form = value |
| | | state.form.companyName = value.company.name; |
| | | console.log("ba",state.form) |
| | | } |
| | | if(type == 'pwd'){ |
| | | state.form.id = value.id |
| | | } |
| | | dialogVisible.value = true |
| | | } |
| | | const onSubmit = async () => { |
| | | const valid = await superRef.value.validate(); |
| | | if(valid){ |
| | | if(state.title == '新增'){ |
| | | const {confirmPassword,id,...data} = state.form |
| | | data.password = Base64.encode(data.password) |
| | | const res = await addStudent(data) |
| | | if(res.code == 200){ |
| | | ElMessage.success(res.message) |
| | | emit('getList') |
| | | handleClose() |
| | | dialogVisible.value = false; |
| | | }else{ |
| | | ElMessage.warning(res.message) |
| | | } |
| | | }else if(state.title == '编辑'){ |
| | | const {id, name, phone, sex, companyId, empno, post, duty, idNo} = state.form |
| | | const data = {id, name, phone, sex, companyId, empno, post, duty, idNo} |
| | | const res = await editStudent(data) |
| | | if(res.code == 200){ |
| | | ElMessage.success(res.message) |
| | | emit('getList') |
| | | handleClose() |
| | | }else{ |
| | | ElMessage.warning(res.message) |
| | | } |
| | | }else{ |
| | | const {id,password} = state.form |
| | | const data = {id,password} |
| | | data.password = Base64.encode(data.password) |
| | | const res = await resetPwd(data) |
| | | if(res.code == 200){ |
| | | ElMessage.success(res.message) |
| | | emit('getList') |
| | | handleClose() |
| | | }else{ |
| | | ElMessage.warning(res.message) |
| | | } |
| | | } |
| | | } |
| | | } |
| | | const handleClose = () => { |
| | | state.form = { |
| | | id: null, |
| | | name: '', |
| | | phone: '', |
| | | password: '', |
| | | confirmPassword: '', |
| | | sex: 0, |
| | | companyId: null, |
| | | empno: '', |
| | | post: '', |
| | | duty: '', |
| | | idNo: '' |
| | | } |
| | | superRef.value.clearValidate(); |
| | | superRef.value.resetFields() |
| | | dialogVisible.value = false; |
| | | } |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | defineExpose({ |
| | | openDialog |
| | | }); |
| | | |
| | | </script> |
| | | |
| | | <style scoped lang="scss"> |
| | | .notice{ |
| | | :deep(.el-form .el-form-item__label) { |
| | | font-size: 15px; |
| | | } |
| | | .file { |
| | | display: flex; |
| | | flex-direction: column; |
| | | align-items: flex-start; |
| | | } |
| | | } |
| | | </style> |
| | |
| | | <template> |
| | | <div>人员管理</div> |
| | | <div class="app-container"> |
| | | <div style="margin-bottom: 10px"> |
| | | <el-button |
| | | type="primary" |
| | | plain |
| | | icon="Plus" |
| | | @click="openDialog('add',{})" |
| | | >新增</el-button> |
| | | </div> |
| | | <!-- 表格数据 --> |
| | | <el-table v-loading="loading" :data="dataList" :border="true"> |
| | | <el-table-column label="序号" type="index" align="center" width="80" /> |
| | | <el-table-column label="工号" prop="empno" align="center" /> |
| | | <el-table-column label="姓名" prop="name" align="center" /> |
| | | <el-table-column label="性别" prop="sex" align="center" > |
| | | <template #default="scope"> |
| | | <span>{{scope.row.sex == 0 ? '男':'女'}}</span> |
| | | </template> |
| | | </el-table-column> |
| | | <el-table-column label="手机号" prop="phone" align="center" width="130"/> |
| | | <el-table-column label="身份证" prop="idNo" align="center" width="200" :show-overflow-tooltip="true"/> |
| | | <el-table-column label="创建人" prop="createBy" align="center"/> |
| | | <el-table-column label="工作岗位" prop="post" align="center"/> |
| | | <el-table-column label="职务" prop="duty" align="center"/> |
| | | <el-table-column label="一人一档" prop="duty" align="center" width="120"> |
| | | <template #default="scope"> |
| | | <el-button link type="primary">培训考试记录</el-button> |
| | | </template> |
| | | </el-table-column> |
| | | <el-table-column label="操作" align="center" class-name="small-padding fixed-width" width="180"> |
| | | <template #default="scope"> |
| | | <el-button link type="primary" @click="openDialog('edit',scope.row)">编辑</el-button> |
| | | <el-button link type="danger" @click="handleDelete(scope.row)">删除</el-button> |
| | | <el-button link type="primary" @click="openDialog('pwd',scope.row)">修改密码</el-button> |
| | | </template> |
| | | </el-table-column> |
| | | </el-table> |
| | | |
| | | <pagination |
| | | v-show="total > 0" |
| | | :total="total" |
| | | v-model:page="queryParams.pageNum" |
| | | v-model:limit="queryParams.pageSize" |
| | | @pagination="getList" |
| | | /> |
| | | |
| | | <stu-dialog ref="dialogRef" @getList=getList></stu-dialog> |
| | | </div> |
| | | </template> |
| | | |
| | | <script setup> |
| | | import {getCurrentInstance, onMounted, onUnmounted, reactive, ref, toRefs} from "vue"; |
| | | import {ElMessage, ElMessageBox} from "element-plus"; |
| | | import {delCompany, getCompany} from "@/api/onlineEducation/company"; |
| | | import stuDialog from "./components/stuDialog.vue" |
| | | import {delUser, getUser} from "@/api/onlineEducation/user"; |
| | | import Cookies from "js-cookie"; |
| | | import {delStudent, getStudent} from "@/api/onlineEducation/student"; |
| | | |
| | | |
| | | const { proxy } = getCurrentInstance(); |
| | | const loading = ref(false); |
| | | const dialogRef = ref(); |
| | | const data = reactive({ |
| | | queryParams: { |
| | | pageNum: 1, |
| | | pageSize: 10, |
| | | }, |
| | | total: 0, |
| | | dataList: [], |
| | | isAdmin: false |
| | | |
| | | }); |
| | | |
| | | const { queryParams, total, dataList } = toRefs(data); |
| | | |
| | | onMounted(async ()=>{ |
| | | const userInfo = JSON.parse(Cookies.get('userInfo')) |
| | | console.log("userInfo",userInfo) |
| | | if(userInfo.userType === 0){ |
| | | data.isAdmin = true; |
| | | }else { |
| | | data.isAdmin = false; |
| | | } |
| | | await getList() |
| | | }) |
| | | onUnmounted(()=>{ |
| | | |
| | | }) |
| | | |
| | | const getList = async () => { |
| | | loading.value = true |
| | | const res = await getStudent(data.queryParams) |
| | | if(res.code == 200){ |
| | | data.dataList = res.data.list |
| | | data.total = res.data.total |
| | | }else{ |
| | | ElMessage.warning(res.message) |
| | | } |
| | | loading.value = false |
| | | } |
| | | |
| | | const openDialog = (type, value) => { |
| | | if(type == 'add' && data.isAdmin){ |
| | | ElMessage.warning('监管部门请联系企业创建企业学员') |
| | | }else{ |
| | | dialogRef.value.openDialog(type, value); |
| | | } |
| | | |
| | | |
| | | } |
| | | |
| | | /** 重置新增的表单以及其他数据 */ |
| | | function reset() { |
| | | proxy.resetForm("roleRef"); |
| | | } |
| | | const handleDelete = (val) => { |
| | | ElMessageBox.confirm( |
| | | '确定删除此条数据?', |
| | | '提示', |
| | | { |
| | | confirmButtonText: '确定', |
| | | cancelButtonText: '取消', |
| | | type: 'warning', |
| | | }) |
| | | .then( async() => { |
| | | const res = await delStudent(val.id) |
| | | if(res.code == 200){ |
| | | ElMessage.success('数据删除成功') |
| | | await getList() |
| | | }else{ |
| | | ElMessage.warning(res.message) |
| | | } |
| | | }) |
| | | } |
| | | |
| | | </script> |
| | | |
| | | |
| | | |
| | | <style scoped lang="scss"> |
| | | |
| | | </style> |
| | |
| | | <el-input v-model.trim="state.form.title"></el-input> |
| | | </el-form-item> |
| | | <el-form-item prop="imgUrl" label="图片:"> |
| | | <el-upload accept="image/*" :action="state.uploadUrl" :headers="state.header" method="post" :on-success="(res, uploadFile)=>handleAvatarSuccess(res, uploadFile)" :on-exceed="showTip" :limit='state.imgLimit' v-model:file-list="state.imgList" list-type="picture-card" :before-upload="picSize" :on-remove="(file, uploadFiles)=>handleRemove(file, uploadFiles,'证书')" > |
| | | <el-upload accept="image/*" :action="state.uploadUrl" :headers="state.header" method="post" :on-success="(res, uploadFile)=>handleAvatarSuccess(res, uploadFile)" :on-exceed="showTip" :limit='state.imgLimit' v-model:file-list="state.imgList" list-type="picture-card" :before-upload="picSize" :on-remove="(file, uploadFiles)=>handleRemove(file, uploadFiles)" > |
| | | <el-icon><Plus /></el-icon> |
| | | <template #tip> |
| | | <div class="el-upload__tip">上传jpg/png图片尺寸小于5M,最多可上传1张</div> |
| | |
| | | :before-close="handleClose" |
| | | > |
| | | <el-form :model="state.form" size="default" ref="busRef" :rules="state.formRules" label-width="150px" > |
| | | <el-form-item label="上级分类:" prop="name" v-if="!state.isFirst"> |
| | | <el-input v-model.trim="state.form.parentName" disabled></el-input> |
| | | </el-form-item> |
| | | <el-form-item label="名称:" prop="name"> |
| | | <el-input v-model.trim="state.form.name"></el-input> |
| | | </el-form-item> |
| | |
| | | form: { |
| | | id: '', |
| | | name: '', |
| | | parentName: '', |
| | | sort: 0, |
| | | parentId: null, |
| | | status: true |
| | |
| | | formRules:{ |
| | | name: [{ required: true, trigger: "blur", validator: validateName }], |
| | | }, |
| | | isFirst: true |
| | | }) |
| | | |
| | | |
| | | const openDialog = async (type, value) => { |
| | | length.value = value.listLength |
| | |
| | | state.form.sort = value.sort; |
| | | startUsername.value = value.username; |
| | | }else if(type === 'add' && value ){ |
| | | state.form.parentId = value.id |
| | | state.isFirst = false; |
| | | state.form.parentId = value.id; |
| | | state.form.parentName = value.name; |
| | | }else { |
| | | state.isFirst = true; |
| | | } |
| | | dialogVisible.value = true; |
| | | } |
| | |
| | | state.form = { |
| | | id: '', |
| | | name: '', |
| | | parentName: '', |
| | | sort: 0, |
| | | parentId: null, |
| | | status: true |
| | |
| | | const data = reactive({ |
| | | queryParams: { |
| | | name: '', |
| | | pageNum: 1, |
| | | pageSize: 10, |
| | | }, |
| | | total: 0, |
| | | dataList: [ |
| | |
| | | </el-select> |
| | | <el-input v-else disabled style="width: 45%" v-model="state.form.companyName"></el-input> |
| | | <scorllSelect |
| | | :disabled="disabled" |
| | | ref="scrollRef" |
| | | v-if="UisMounted && (state.form.userType === 2 || state.form.userType === 3)" |
| | | v-model="state.form.parentName" |
| | |
| | | state.form.userType = 1; |
| | | } |
| | | |
| | | await getCompanyList('open') |
| | | if(type !== 'view' && type !== 'pwd'){ |
| | | await getCompanyList('open') |
| | | } |
| | | state.title = type === 'add' ? '新增' : type ==='edit' ? '编辑' : type ==='pwd' ? '修改密码' : '查看' ; |
| | | if(type === 'edit' || type === 'view') { |
| | | if( type === 'view'){ |