oss上传秘钥加密

dev_review
yujialong 4 months ago
parent 812f1c916a
commit 58f007cfc9
  1. 10
      package-lock.json
  2. 2
      package.json
  3. 4
      src/App.vue
  4. 46
      src/components/upload/config.js
  5. 42
      src/components/upload/index.vue
  6. 49
      src/components/upload/upload.js
  7. 3
      src/setting.js
  8. 1
      src/utils/api.js
  9. 654
      src/views/course/AddCurriculum.vue

10
package-lock.json generated

@ -3871,6 +3871,11 @@
"randomfill": "^1.0.3" "randomfill": "^1.0.3"
} }
}, },
"crypto-js": {
"version": "4.2.0",
"resolved": "https://registry.npmjs.org/crypto-js/-/crypto-js-4.2.0.tgz",
"integrity": "sha512-KALDyEYgpY+Rlob/iriUtjV6d5Eq+Y191A5g4UqLAi8CyGP9N1+FdVbkc1SxKc2r4YAYqG8JzO2KGL+AizD70Q=="
},
"css": { "css": {
"version": "2.2.4", "version": "2.2.4",
"resolved": "https://registry.npmjs.org/css/-/css-2.2.4.tgz", "resolved": "https://registry.npmjs.org/css/-/css-2.2.4.tgz",
@ -9509,6 +9514,11 @@
"resolved": "https://registry.npmjs.org/jsbn/-/jsbn-0.1.1.tgz", "resolved": "https://registry.npmjs.org/jsbn/-/jsbn-0.1.1.tgz",
"integrity": "sha1-peZUwuWi3rXyAdls77yoDA7y9RM=" "integrity": "sha1-peZUwuWi3rXyAdls77yoDA7y9RM="
}, },
"jsencrypt": {
"version": "3.3.2",
"resolved": "https://registry.npmjs.org/jsencrypt/-/jsencrypt-3.3.2.tgz",
"integrity": "sha512-arQR1R1ESGdAxY7ZheWr12wCaF2yF47v5qpB76TtV64H1pyGudk9Hvw8Y9tb/FiTIaaTRUyaSnm5T/Y53Ghm/A=="
},
"jsesc": { "jsesc": {
"version": "2.5.2", "version": "2.5.2",
"resolved": "https://registry.npmjs.org/jsesc/-/jsesc-2.5.2.tgz", "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-2.5.2.tgz",

@ -14,6 +14,7 @@
"babel-polyfill": "^6.26.0", "babel-polyfill": "^6.26.0",
"blueimp-md5": "^2.19.0", "blueimp-md5": "^2.19.0",
"clipboard": "^2.0.11", "clipboard": "^2.0.11",
"crypto-js": "^4.2.0",
"decimal.js": "^10.4.3", "decimal.js": "^10.4.3",
"echarts": "^5.4.1", "echarts": "^5.4.1",
"element-theme": "^2.0.1", "element-theme": "^2.0.1",
@ -22,6 +23,7 @@
"image-conversion": "^2.1.1", "image-conversion": "^2.1.1",
"image-webpack-loader": "^8.1.0", "image-webpack-loader": "^8.1.0",
"js-cookie": "^3.0.1", "js-cookie": "^3.0.1",
"jsencrypt": "^3.3.2",
"jszip": "^3.10.1", "jszip": "^3.10.1",
"lodash": "^4.17.21", "lodash": "^4.17.21",
"mavon-editor": "^2.10.4", "mavon-editor": "^2.10.4",

@ -16,7 +16,7 @@ export default {
data () { data () {
return { return {
Setting, Setting,
ip: localStorage.getItem('nakadaiIp') ? +localStorage.getItem('nakadaiIp') : 0, ip: localStorage.getItem('ip') ? +localStorage.getItem('ip') : 0,
}; };
}, },
created () { created () {
@ -32,7 +32,7 @@ export default {
}, },
methods: { methods: {
ipChange (val) { ipChange (val) {
localStorage.setItem('nakadaiIp', val) localStorage.setItem('ip', val)
location.reload() location.reload()
}, },
} }

@ -1,15 +1,41 @@
/** /**
* 阿里云oss配置 * 阿里云oss配置
* */ * */
import { get } from '@/utils/http'
import api from '@/utils/api'
import CryptoJS from 'crypto-js'
import JSEncrypt from 'jsencrypt'
export default { const A = (key, encryptedData) => {
// oss账号信息 const keyHex = CryptoJS.enc.Base64.parse(key)
config: { const decrypted = CryptoJS.AES.decrypt(encryptedData, keyHex, {
region: 'oss-cn-shenzhen', mode: CryptoJS.mode.ECB,
accessKeyId: 'LTAI4FzqQHnk4rozqLZ8jCNj', padding: CryptoJS.pad.Pkcs7
accessKeySecret: 'mveW7B1OyFoKUkHm8WsxmrjHmkJWHq', })
bucket: 'huoran' return decrypted.toString(CryptoJS.enc.Utf8)
}, }
// 上传成功url前置部分(成功回调没有返回url)
preUrl: 'https://huoran.oss-cn-shenzhen.aliyuncs.com/' const R = (encryptedKey, privateKey) => {
const decrypt = new JSEncrypt()
decrypt.setPrivateKey(privateKey)
const decryptedKey = decrypt.decrypt(encryptedKey)
return decryptedKey
}
export default async function () {
try {
const res = await get(api.encrypt)
const RE = A(R(res.encryptedKey, res.privateKey), res.encryptedData).split('/')
return {
// oss账号信息
config: {
region: 'oss-cn-shenzhen',
accessKeyId: RE[0],
accessKeySecret: RE[1],
bucket: 'huoran'
},
// 上传成功url前置部分(成功回调没有返回url)
preUrl: 'https://huoran.oss-cn-shenzhen.aliyuncs.com/'
}
} catch (e) { }
} }

@ -1,25 +1,13 @@
<template> <template>
<el-upload :disabled="uploading" <el-upload :disabled="uploading" :before-upload="beforeUpload" :on-remove="onRemove" :on-error="uploadError"
:before-upload="beforeUpload" :limit="limit" action="" :on-exceed="handleExceed" :show-file-list="showFiles" :file-list="fileList"
:on-remove="onRemove" :http-request="handleRequest" name="file">
:on-error="uploadError"
:limit="limit"
action=""
:on-exceed="handleExceed"
:show-file-list="showFiles"
:file-list="fileList"
:http-request="handleRequest"
name="file">
<slot name="trigger"> <slot name="trigger">
<el-button size="small" <el-button size="small" :loading="uploading">{{ uploading ? '正在上传' : '上传文件' }}</el-button>
:loading="uploading">{{ uploading ? '正在上传' : '上传文件' }}</el-button>
</slot> </slot>
<div slot="tip" <div slot="tip" class="el-upload__tip">
class="el-upload__tip"> <el-progress v-if="uploading" class="upload-progress" :stroke-width="3"
<el-progress v-if="uploading" :percentage="uploadProgress"></el-progress>
class="upload-progress"
:stroke-width="3"
:percentage="uploadProgress"></el-progress>
<slot name="tip"> <slot name="tip">
<p>支持扩展名.rar .zip .doc .docx .pdf .jpg...</p> <p>支持扩展名.rar .zip .doc .docx .pdf .jpg...</p>
</slot> </slot>
@ -69,7 +57,8 @@ export default {
client: null, client: null,
uploading: false, uploading: false,
uploadProgress: 0, uploadProgress: 0,
showFiles: this.showFileList showFiles: this.showFileList,
Oss: {},
}; };
}, },
mounted () { mounted () {
@ -77,8 +66,9 @@ export default {
}, },
methods: { methods: {
// oss // oss
initOss () { async initOss () {
this.client = new OSS(OssConfig.config) this.Oss = await OssConfig()
this.client = new OSS(this.Oss.config)
}, },
// //
beforeUpload (file) { beforeUpload (file) {
@ -107,7 +97,7 @@ export default {
}); });
this.uploading = false this.uploading = false
const url = OssConfig.preUrl + name const url = this.Oss.preUrl + name
this.changeFileList && this.$emit('update:fileList', [ this.changeFileList && this.$emit('update:fileList', [
...this.fileList, ...this.fileList,
{ {
@ -143,8 +133,8 @@ export default {
</script> </script>
<style lang="scss" scoped> <style lang="scss" scoped>
/deep/.upload-progress { /deep/.upload-progress {
max-width: 300px; max-width: 300px;
margin: 10px 0; margin: 10px 0;
white-space: nowrap; white-space: nowrap;
} }
</style> </style>

@ -5,33 +5,36 @@ import OssConfig from './config'
import Util from '@/libs/util' import Util from '@/libs/util'
let client = null let client = null
let Oss
// 初始化oss // 初始化oss
const initOss = () => { const initOss = async () => {
if (!client) client = new OSS(OssConfig.config) Oss = await OssConfig()
if (!client) client = new OSS(Oss.config)
} }
initOss()
export default { export default {
// 上传文件 // 上传文件
upload(file) { upload (file) {
initOss() initOss()
return new Promise(async (resolve, reject) => { return new Promise(async (resolve, reject) => {
try { try {
// 上传到阿里云oss // 上传到阿里云oss
const res = await client.multipartUpload(Date.now() + '.' + Util.getFileExt(file.name), file); const res = await client.multipartUpload(Date.now() + '.' + Util.getFileExt(file.name), file);
resolve({ resolve({
format: Util.getFileExt(file.name), format: Util.getFileExt(file.name),
name: file.name, name: file.name,
url: OssConfig.preUrl + res.name, url: Oss.preUrl + res.name,
size: file.size, size: file.size,
}) })
} catch (error) { } catch (error) {
reject() reject()
} }
}) })
}, },
// 删除文件(传完整url,不是没有https的name,因为很多接口没有存name,只存url,所以统一使用url) // 删除文件(传完整url,不是没有https的name,因为很多接口没有存name,只存url,所以统一使用url)
async del(url) { async del (url) {
initOss() initOss()
await client.delete(url.replace(OssConfig.preUrl, '')); await client.delete(url.replace(Oss.preUrl, ''));
} }
} }

@ -9,14 +9,13 @@ let jumpPath = `${location.origin}/judgmentPoint/`
let sandPath = `http://121.37.12.51/sandbox` // 沙盘地址 let sandPath = `http://121.37.12.51/sandbox` // 沙盘地址
let host = `${location.origin}/` let host = `${location.origin}/`
if (isDev) { if (isDev) {
console.log("🚀 ~ localStorage.getItem('nakadaiIp'):", localStorage.getItem('nakadaiIp'))
jumpPath = 'http://192.168.31.125:8087/' // 本地调试-需要启动本地判分点系统 jumpPath = 'http://192.168.31.125:8087/' // 本地调试-需要启动本地判分点系统
// jumpPath = 'https://judgment.huorantech.cn/' // jumpPath = 'https://judgment.huorantech.cn/'
sandPath = `http://${location.hostname}:9520` sandPath = `http://${location.hostname}:9520`
host = 'http://121.37.12.51/' host = 'http://121.37.12.51/'
// host = 'https://huorantech.cn/' // host = 'https://huorantech.cn/'
const ips = ['http://192.168.31.217:9000/', 'http://192.168.31.51:9000/', 'http://121.37.12.51/'] const ips = ['http://192.168.31.217:9000/', 'http://192.168.31.51:9000/', 'http://121.37.12.51/']
host = ips[+localStorage.getItem('nakadaiIp')] host = ips[+localStorage.getItem('ip')]
} else if (isPro) { } else if (isPro) {
sandPath = `https://izhixinyun.com/sandbox` sandPath = `https://izhixinyun.com/sandbox`
jumpPath = 'https://judgment.huorantech.cn/' jumpPath = 'https://judgment.huorantech.cn/'

@ -16,6 +16,7 @@ export default {
// 阿里云文件/视频管理 // 阿里云文件/视频管理
getPlayAuth: `${uploadURL}oss/manage/getPlayAuth`, // 获取播放凭证 getPlayAuth: `${uploadURL}oss/manage/getPlayAuth`, // 获取播放凭证
encrypt: `nakadai/data/encrypt`,
staffTemplate: `https://occupationlab.com/template/%E6%89%B9%E9%87%8F%E5%AF%BC%E5%85%A5%E5%91%98%E5%B7%A5%E6%A8%A1%E6%9D%BF.xlsx`, // 后台账号模板 staffTemplate: `https://occupationlab.com/template/%E6%89%B9%E9%87%8F%E5%AF%BC%E5%85%A5%E5%91%98%E5%B7%A5%E6%A8%A1%E6%9D%BF.xlsx`, // 后台账号模板
competionPersonTemplate: `https://huoran.oss-cn-shenzhen.aliyuncs.com/%E4%B8%AD%E5%8F%B0%E4%B8%AA%E4%BA%BA%E8%B5%9B%E6%8A%A5%E5%90%8D%E4%BA%BA%E5%91%98%E5%AF%BC%E5%85%A5%E6%A8%A1%E6%9D%BF.xlsx`, // 中台个人报名人员模板 competionPersonTemplate: `https://huoran.oss-cn-shenzhen.aliyuncs.com/%E4%B8%AD%E5%8F%B0%E4%B8%AA%E4%BA%BA%E8%B5%9B%E6%8A%A5%E5%90%8D%E4%BA%BA%E5%91%98%E5%AF%BC%E5%85%A5%E6%A8%A1%E6%9D%BF.xlsx`, // 中台个人报名人员模板

@ -2,28 +2,19 @@
<div> <div>
<el-row :gutter="20"> <el-row :gutter="20">
<el-col :span="24"> <el-col :span="24">
<el-card shadow="hover" <el-card shadow="hover" class="mgb20">
class="mgb20">
<div class="flex-between"> <div class="flex-between">
<div class="per_title" <div class="per_title" v-preventReClick @click="back">
v-preventReClick
@click="back">
<i class="el-icon-arrow-left"></i> <i class="el-icon-arrow-left"></i>
<span class="per_back">返回</span> <span class="per_back">返回</span>
<span class="per_school" <span class="per_school" v-text="form.cid ? '编辑课程' : '新建课程'"></span>
v-text="form.cid ? '编辑课程' : '新建课程'"></span>
</div> </div>
<el-button type="primary" <el-button type="primary" round class="mag" v-preventReClick @click="saveAdd">确定
round
class="mag"
v-preventReClick
@click="saveAdd">确定
</el-button> </el-button>
</div> </div>
</el-card> </el-card>
<el-card shadow="hover" <el-card shadow="hover" class="mgb20 ">
class="mgb20 ">
<div class="flex-center mgb20"> <div class="flex-center mgb20">
<p class="addhr_tag"></p> <p class="addhr_tag"></p>
<span>课程信息</span> <span>课程信息</span>
@ -31,113 +22,66 @@
<div class="border-b-dashed"></div> <div class="border-b-dashed"></div>
<div> <div>
<el-form :model="form" <el-form :model="form" :rules="rules" ref="form" label-width="100px">
:rules="rules" <el-col :span="6" :offset="5">
ref="form" <el-form-item label="课程名称" prop="curriculumName">
label-width="100px"> <el-input placeholder="请输入课程名称" v-model.trim="form.curriculumName"></el-input>
<el-col :span="6"
:offset="5">
<el-form-item label="课程名称"
prop="curriculumName">
<el-input placeholder="请输入课程名称"
v-model.trim="form.curriculumName"></el-input>
</el-form-item> </el-form-item>
<el-form-item label="学科类别" <el-form-item label="学科类别" prop="categoryId">
prop="categoryId"> <el-select v-model="form.categoryId" clearable placeholder="请选择学科类别" @change="getProfessionalClass()"
<el-select v-model="form.categoryId" @clear="clearsubjectType()">
clearable <el-option v-for="(item, index) in subjectList" :key="index" :label="item.disciplineName"
placeholder="请选择学科类别" :value="item.disciplineId"></el-option>
@change="getProfessionalClass()"
@clear="clearsubjectType()">
<el-option v-for="(item,index) in subjectList"
:key="index"
:label="item.disciplineName"
:value="item.disciplineId"></el-option>
</el-select> </el-select>
</el-form-item> </el-form-item>
<el-form-item label="专业" <el-form-item label="专业" prop="professionalId">
prop="professionalId"> <el-select v-model="form.professionalId" clearable placeholder="请选择专业"
<el-select v-model="form.professionalId" :disabled="form.professionalCategoryId ? false : true">
clearable <el-option v-for="(item, index) in ProfessionalList" :key="index" :label="item.professionalName"
placeholder="请选择专业" :value="item.professionalId"></el-option>
:disabled="form.professionalCategoryId ? false : true">
<el-option v-for="(item,index) in ProfessionalList"
:key="index"
:label="item.professionalName"
:value="item.professionalId"></el-option>
</el-select> </el-select>
</el-form-item> </el-form-item>
<el-form-item label="供应厂商" <el-form-item label="供应厂商" prop="supplier">
prop="supplier"> <el-select v-model="form.supplier" clearable placeholder="请选择供应厂商" multiple>
<el-select v-model="form.supplier" <el-option v-for="(item, i) in suppliers" :key="i" :label="item.supplierName"
clearable :value="item.supplierId"></el-option>
placeholder="请选择供应厂商"
multiple>
<el-option v-for="(item, i) in suppliers"
:key="i"
:label="item.supplierName"
:value="item.supplierId"></el-option>
</el-select> </el-select>
</el-form-item> </el-form-item>
</el-col> </el-col>
<el-col :span="6" <el-col :span="6" :offset="2">
:offset="2"> <el-form-item label="课程类别" prop="curriculumType">
<el-form-item label="课程类别" <el-select v-model="form.curriculumType" clearable placeholder="请选择课程类型">
prop="curriculumType"> <el-option label="理论课程" :value="0"></el-option>
<el-select v-model="form.curriculumType" <el-option label="实训课程" :value="1"></el-option>
clearable
placeholder="请选择课程类型">
<el-option label="理论课程"
:value="0"></el-option>
<el-option label="实训课程"
:value="1"></el-option>
</el-select> </el-select>
</el-form-item> </el-form-item>
<el-form-item label="专业类" <el-form-item label="专业类" prop="professionalCategoryId">
prop="professionalCategoryId"> <el-select v-model="form.professionalCategoryId" clearable placeholder="请选择专业类"
<el-select v-model="form.professionalCategoryId" :disabled="form.categoryId ? false : true" @change="getProfessional()"
clearable @clear="clearProfessionalClass()">
placeholder="请选择专业类" <el-option v-for="(item, index) in ProfessionalClassList" :key="index"
:disabled="form.categoryId ? false : true" :label="item.professionalClassName" :value="item.professionalClassId"></el-option>
@change="getProfessional()"
@clear="clearProfessionalClass()">
<el-option v-for="(item,index) in ProfessionalClassList"
:key="index"
:label="item.professionalClassName"
:value="item.professionalClassId"></el-option>
</el-select> </el-select>
</el-form-item> </el-form-item>
<el-form-item label="预计课时" <el-form-item label="预计课时" prop="expectedCourse">
prop="expectedCourse"> <el-select v-model="form.expectedCourse" clearable placeholder="请选择预计课时">
<el-select v-model="form.expectedCourse" <el-option label="32课时" value="32课时"></el-option>
clearable <el-option label="64课时" value="64课时"></el-option>
placeholder="请选择预计课时">
<el-option label="32课时"
value="32课时"></el-option>
<el-option label="64课时"
value="64课时"></el-option>
</el-select> </el-select>
</el-form-item> </el-form-item>
</el-col> </el-col>
<el-col :span="14" <el-col :span="14" :offset="5">
:offset="5"> <el-form-item label="课程简介" prop="briefIntroduction">
<el-form-item label="课程简介" <el-input type="textarea" :autosize="{ minRows: 4 }" placeholder="请输入课程简介"
prop="briefIntroduction"> v-model.trim="form.briefIntroduction"></el-input>
<el-input type="textarea"
:autosize="{ minRows: 4 }"
placeholder="请输入课程简介"
v-model.trim="form.briefIntroduction"></el-input>
</el-form-item> </el-form-item>
<el-form-item label="教学目标" <el-form-item label="教学目标" prop="teachingObjectives">
prop="teachingObjectives"> <el-input type="textarea" :autosize="{ minRows: 4 }" placeholder="请输入教学目标"
<el-input type="textarea" v-model.trim="form.teachingObjectives"></el-input>
:autosize="{ minRows: 4 }"
placeholder="请输入教学目标"
v-model.trim="form.teachingObjectives"></el-input>
</el-form-item> </el-form-item>
</el-col> </el-col>
</el-form> </el-form>
@ -145,8 +89,7 @@
</el-card> </el-card>
<!-- 练习项目配置 --> <!-- 练习项目配置 -->
<el-card shadow="hover" <el-card shadow="hover" class="mgb20">
class="mgb20">
<div class="mgb20 flex-between"> <div class="mgb20 flex-between">
<div class="flex-center "> <div class="flex-center ">
<p class="addhr_tag"></p> <p class="addhr_tag"></p>
@ -154,64 +97,39 @@
</div> </div>
<div> <div>
<el-button @click="handleBatchDelete(0)">批量移除</el-button> <el-button @click="handleBatchDelete(0)">批量移除</el-button>
<el-button @click="handleConfig(0)" <el-button @click="handleConfig(0)" icon="el-icon-plus" circle></el-button>
icon="el-icon-plus"
circle></el-button>
</div> </div>
</div> </div>
<div class="border-b-dashed"></div> <div class="border-b-dashed"></div>
<div> <div>
<el-table :data="practiceData" <el-table :data="practiceData" class="table" stripe header-align="center" max-height="400"
class="table" @selection-change="handleSelectionPractice">
stripe <el-table-column type="selection" width="55" align="center"></el-table-column>
header-align="center" <el-table-column type="index" width="100" label="序号" align="center"></el-table-column>
max-height="400" <el-table-column prop="projectName" label="项目名称" align="center"></el-table-column>
@selection-change="handleSelectionPractice"> <el-table-column prop="remark" label="备注名称" align="center"></el-table-column>
<el-table-column type="selection" <el-table-column prop="applicationName" label="系统名称" align="center">
width="55"
align="center"></el-table-column>
<el-table-column type="index"
width="100"
label="序号"
align="center"></el-table-column>
<el-table-column prop="projectName"
label="项目名称"
align="center"></el-table-column>
<el-table-column prop="remark"
label="备注名称"
align="center"></el-table-column>
<el-table-column prop="applicationName"
label="系统名称"
align="center">
<template slot-scope="scope"> <template slot-scope="scope">
{{ scope.row.applicationName || systemAll.find(e => e.systemId == scope.row.systemId).systemName }} {{ scope.row.applicationName || systemAll.find(e => e.systemId == scope.row.systemId).systemName }}
</template> </template>
</el-table-column> </el-table-column>
<el-table-column label="排序" <el-table-column label="排序" align="center" width="100">
align="center"
width="100">
<template slot-scope="scope"> <template slot-scope="scope">
<el-input v-model.trim="scope.row.sort" <el-input v-model.trim="scope.row.sort"
@input="practiceSortChange(scope.row, scope.$index)"></el-input> @input="practiceSortChange(scope.row, scope.$index)"></el-input>
</template> </template>
</el-table-column> </el-table-column>
<el-table-column label="展示控制" <el-table-column label="展示控制" align="center" width="100">
align="center"
width="100">
<template slot-scope="scope"> <template slot-scope="scope">
<el-switch v-model="scope.row.isShow" <el-switch v-model="scope.row.isShow" :active-value="0" :inactive-value="1"
:active-value="0" :disabled="scope.row.disabled">
:inactive-value="1"
:disabled="scope.row.disabled">
</el-switch> </el-switch>
</template> </template>
</el-table-column> </el-table-column>
<el-table-column label="操作" <el-table-column label="操作" align="center" width="100">
align="center"
width="100">
<template slot-scope="scope"> <template slot-scope="scope">
<el-button :disabled="scope.row.disabled" <el-button :disabled="scope.row.disabled"
@click.native.prevent="handleDelete(scope.$index, practiceData)">移除 @click.native.prevent="handleDelete(scope.$index, practiceData)">移除
</el-button> </el-button>
</template> </template>
</el-table-column> </el-table-column>
@ -220,8 +138,7 @@
</el-card> </el-card>
<!-- 考核项目配置 --> <!-- 考核项目配置 -->
<el-card shadow="hover" <el-card shadow="hover" class="mgb20">
class="mgb20">
<div class="mgb20 flex-between"> <div class="mgb20 flex-between">
<div class="flex-center "> <div class="flex-center ">
<p class="addhr_tag"></p> <p class="addhr_tag"></p>
@ -229,65 +146,40 @@
</div> </div>
<div> <div>
<el-button @click="handleBatchDelete(1)">批量移除</el-button> <el-button @click="handleBatchDelete(1)">批量移除</el-button>
<el-button @click="handleConfig(1)" <el-button @click="handleConfig(1)" icon="el-icon-plus" circle></el-button>
icon="el-icon-plus"
circle></el-button>
</div> </div>
</div> </div>
<div class="border-b-dashed"></div> <div class="border-b-dashed"></div>
<!-- 实训配置 --> <!-- 实训配置 -->
<div> <div>
<el-table :data="assessmentData" <el-table :data="assessmentData" class="table" stripe header-align="center" max-height="400"
class="table" @selection-change="handleSelectionAssessment">
stripe <el-table-column type="selection" width="55" align="center"></el-table-column>
header-align="center" <el-table-column type="index" width="100" label="序号" align="center"></el-table-column>
max-height="400" <el-table-column prop="projectName" label="项目名称" align="center"></el-table-column>
@selection-change="handleSelectionAssessment"> <el-table-column prop="remark" label="备注名称" align="center"></el-table-column>
<el-table-column type="selection" <el-table-column prop="applicationName" label="系统名称" align="center">
width="55"
align="center"></el-table-column>
<el-table-column type="index"
width="100"
label="序号"
align="center"></el-table-column>
<el-table-column prop="projectName"
label="项目名称"
align="center"></el-table-column>
<el-table-column prop="remark"
label="备注名称"
align="center"></el-table-column>
<el-table-column prop="applicationName"
label="系统名称"
align="center">
<template slot-scope="scope"> <template slot-scope="scope">
{{ scope.row.applicationName || systemAll.find(e => e.systemId == scope.row.systemId).systemName }} {{ scope.row.applicationName || systemAll.find(e => e.systemId == scope.row.systemId).systemName }}
</template> </template>
</el-table-column> </el-table-column>
<el-table-column label="排序" <el-table-column label="排序" align="center" width="100">
align="center"
width="100">
<template slot-scope="scope"> <template slot-scope="scope">
<el-input v-model.trim="scope.row.sort" <el-input v-model.trim="scope.row.sort"
@input="assessmentSortChange(scope.row, scope.$index)"></el-input> @input="assessmentSortChange(scope.row, scope.$index)"></el-input>
</template> </template>
</el-table-column> </el-table-column>
<el-table-column label="展示控制" <el-table-column label="展示控制" align="center" width="100">
align="center"
width="100">
<template slot-scope="scope"> <template slot-scope="scope">
<el-switch v-model="scope.row.isShow" <el-switch v-model="scope.row.isShow" :active-value="0" :inactive-value="1"
:active-value="0" :disabled="scope.row.disabled">
:inactive-value="1"
:disabled="scope.row.disabled">
</el-switch> </el-switch>
</template> </template>
</el-table-column> </el-table-column>
<el-table-column label="操作" <el-table-column label="操作" align="center" width="100">
align="center"
width="100">
<template slot-scope="scope"> <template slot-scope="scope">
<el-button :disabled="scope.row.disabled" <el-button :disabled="scope.row.disabled"
@click.native.prevent="handleDelete(scope.$index, assessmentData)">移除</el-button> @click.native.prevent="handleDelete(scope.$index, assessmentData)">移除</el-button>
</template> </template>
</el-table-column> </el-table-column>
</el-table> </el-table>
@ -295,8 +187,7 @@
</el-card> </el-card>
<!-- 大赛项目配置 --> <!-- 大赛项目配置 -->
<el-card shadow="hover" <el-card shadow="hover" class="mgb20">
class="mgb20">
<div class="mgb20 flex-between"> <div class="mgb20 flex-between">
<div class="flex-center "> <div class="flex-center ">
<p class="addhr_tag"></p> <p class="addhr_tag"></p>
@ -304,62 +195,39 @@
</div> </div>
<div> <div>
<el-button @click="handleBatchDelete(2)">批量移除</el-button> <el-button @click="handleBatchDelete(2)">批量移除</el-button>
<el-button @click="handleConfig(2)" <el-button @click="handleConfig(2)" icon="el-icon-plus" circle></el-button>
icon="el-icon-plus"
circle></el-button>
</div> </div>
</div> </div>
<div class="border-b-dashed"></div> <div class="border-b-dashed"></div>
<!-- 实训配置 --> <!-- 实训配置 -->
<div> <div>
<el-table :data="matches" <el-table :data="matches" class="table" stripe header-align="center" max-height="400"
class="table" @selection-change="handleSelectionMatch">
stripe <el-table-column type="selection" width="55" align="center"></el-table-column>
header-align="center" <el-table-column type="index" width="100" label="序号" align="center"></el-table-column>
max-height="400" <el-table-column prop="projectName" label="项目名称" align="center"></el-table-column>
@selection-change="handleSelectionMatch"> <el-table-column prop="applicationName" label="系统名称" align="center">
<el-table-column type="selection"
width="55"
align="center"></el-table-column>
<el-table-column type="index"
width="100"
label="序号"
align="center"></el-table-column>
<el-table-column prop="projectName"
label="项目名称"
align="center"></el-table-column>
<el-table-column prop="applicationName"
label="系统名称"
align="center">
<template slot-scope="scope"> <template slot-scope="scope">
{{ scope.row.applicationName || systemAll.find(e => e.systemId == scope.row.systemId).systemName }} {{ scope.row.applicationName || systemAll.find(e => e.systemId == scope.row.systemId).systemName }}
</template> </template>
</el-table-column> </el-table-column>
<el-table-column label="排序" <el-table-column label="排序" align="center" width="100">
align="center"
width="100">
<template slot-scope="scope"> <template slot-scope="scope">
<el-input v-model.trim="scope.row.sort" <el-input v-model.trim="scope.row.sort"
@input="assessmentSortChange(scope.row, scope.$index)"></el-input> @input="assessmentSortChange(scope.row, scope.$index)"></el-input>
</template> </template>
</el-table-column> </el-table-column>
<el-table-column label="展示控制" <el-table-column label="展示控制" align="center" width="100">
align="center"
width="100">
<template slot-scope="scope"> <template slot-scope="scope">
<el-switch v-model="scope.row.isShow" <el-switch v-model="scope.row.isShow" :active-value="0" :inactive-value="1"
:active-value="0" :disabled="scope.row.disabled">
:inactive-value="1"
:disabled="scope.row.disabled">
</el-switch> </el-switch>
</template> </template>
</el-table-column> </el-table-column>
<el-table-column label="操作" <el-table-column label="操作" align="center" width="100">
align="center"
width="100">
<template slot-scope="scope"> <template slot-scope="scope">
<el-button :disabled="scope.row.disabled" <el-button :disabled="scope.row.disabled"
@click.native.prevent="handleDelete(scope.$index, matches)">移除</el-button> @click.native.prevent="handleDelete(scope.$index, matches)">移除</el-button>
</template> </template>
</el-table-column> </el-table-column>
</el-table> </el-table>
@ -370,29 +238,20 @@
</el-row> </el-row>
<!-- 配置弹窗 --> <!-- 配置弹窗 -->
<el-dialog :visible.sync="configVisible" <el-dialog :visible.sync="configVisible" width="1200px" center custom-class="config-dia">
width="1200px"
center
custom-class="config-dia">
<div class="config-wrap"> <div class="config-wrap">
<div class="item system"> <div class="item system">
<div class="title-wrap flex-center"> <div class="title-wrap flex-center">
<p class="addhr_tag"></p> <p class="addhr_tag"></p>
<span>系统列表</span> <span>系统列表</span>
</div> </div>
<el-input placeholder="请输入系统名称" <el-input placeholder="请输入系统名称" prefix-icon="el-icon-search" v-model.trim="systemKeyword"
prefix-icon="el-icon-search" clearable></el-input>
v-model.trim="systemKeyword"
clearable></el-input>
<ul class="systems"> <ul class="systems">
<li v-for="(item, i) in systems" <li v-for="(item, i) in systems" :key="i" :title="item.systemName">
:key="i" <el-checkbox v-model="item.check" @change="val => systemChange(val, item)"></el-checkbox>
:title="item.systemName"> <div :class="['name', { active: curSystem == item.systemId }]" @click="getProject(item)">
<el-checkbox v-model="item.check"
@change="val => systemChange(val, item)"></el-checkbox>
<div :class="['name', {active: curSystem == item.systemId}]"
@click="getProject(item)">
<span>{{ item.systemName }}</span> <span>{{ item.systemName }}</span>
<i class="el-icon-arrow-right"></i> <i class="el-icon-arrow-right"></i>
</div> </div>
@ -405,22 +264,16 @@
<p class="addhr_tag"></p> <p class="addhr_tag"></p>
<span>项目列表</span> <span>项目列表</span>
</div> </div>
<el-input placeholder="请输入项目名称" <el-input placeholder="请输入项目名称" prefix-icon="el-icon-search" v-model.trim="projectKeyword"
prefix-icon="el-icon-search" clearable></el-input>
v-model.trim="projectKeyword"
clearable></el-input>
<ul class="systems"> <ul class="systems">
<el-checkbox v-if="projects.length" <el-checkbox v-if="projects.length" v-model="checkAll" label="全选"
v-model="checkAll" @change="val => checkAllChange(val, projects[0].systemId)"></el-checkbox>
label="全选" <li v-for="(item, i) in projects" :key="i" :title="item.projectName">
@change="val => checkAllChange(val, projects[0].systemId)"></el-checkbox>
<li v-for="(item, i) in projects"
:key="i"
:title="item.projectName">
<el-checkbox v-model="item.check" <el-checkbox v-model="item.check"
:label="item.remark ? item.remark + '(' + item.projectName + ')' : item.projectName" :label="item.remark ? item.remark + '(' + item.projectName + ')' : item.projectName"
@change="val => projectChange(val, item)"></el-checkbox> @change="val => projectChange(val, item)"></el-checkbox>
</li> </li>
</ul> </ul>
</div> </div>
@ -430,58 +283,35 @@
<p class="addhr_tag"></p> <p class="addhr_tag"></p>
<span>已选择项目{{ checkeds.length }}</span> <span>已选择项目{{ checkeds.length }}</span>
</div> </div>
<el-input style="width: 200px;margin-bottom: 20px;" <el-input style="width: 200px;margin-bottom: 20px;" placeholder="请输入项目名称" prefix-icon="el-icon-search"
placeholder="请输入项目名称" v-model.trim="checkedKeyword" clearable></el-input>
prefix-icon="el-icon-search" <el-table :data="checkeds" class="table" stripe header-align="center" max-height="470">
v-model.trim="checkedKeyword" <el-table-column type="index" width="55" label="序号" align="center"></el-table-column>
clearable></el-input> <el-table-column prop="applicationName" label="系统名称" align="center">
<el-table :data="checkeds"
class="table"
stripe
header-align="center"
max-height="470">
<el-table-column type="index"
width="55"
label="序号"
align="center"></el-table-column>
<el-table-column prop="applicationName"
label="系统名称"
align="center">
<template slot-scope="scope"> <template slot-scope="scope">
{{ scope.row.applicationName || systemAll.find(e => e.systemId == scope.row.systemId).systemName }} {{ scope.row.applicationName || systemAll.find(e => e.systemId == scope.row.systemId).systemName }}
</template> </template>
</el-table-column> </el-table-column>
<el-table-column prop="projectName" <el-table-column prop="projectName" width="80" label="系统类型" align="center">
width="80"
label="系统类型"
align="center">
<template slot-scope="scope"> <template slot-scope="scope">
{{ scope.row.type ? '流程类' : '编程类' }} {{ scope.row.type ? '流程类' : '编程类' }}
</template> </template>
</el-table-column> </el-table-column>
<el-table-column prop="remark" <el-table-column prop="remark" label="备注名称" align="center"></el-table-column>
label="备注名称" <el-table-column prop="projectName" label="项目名称" align="center"></el-table-column>
align="center"></el-table-column> <el-table-column label="操作" align="center" width="55">
<el-table-column prop="projectName"
label="项目名称"
align="center"></el-table-column>
<el-table-column label="操作"
align="center"
width="55">
<template slot-scope="scope"> <template slot-scope="scope">
<i :class="['el-icon-delete rm', {disabled: scope.row.disabled}]" <i :class="['el-icon-delete rm', { disabled: scope.row.disabled }]"
@click="delProject(scope.$index, scope.row)"></i> @click="delProject(scope.$index, scope.row)"></i>
</template> </template>
</el-table-column> </el-table-column>
</el-table> </el-table>
</div> </div>
</div> </div>
<span slot="footer" <span slot="footer" class="dialog-footer">
class="dialog-footer">
<el-button @click="configVisible = false"> </el-button> <el-button @click="configVisible = false"> </el-button>
<el-button type="primary" <el-button type="primary" @click="handleConfirm"> </el-button>
@click="handleConfirm"> </el-button>
</span> </span>
</el-dialog> </el-dialog>
</div> </div>
@ -1093,141 +923,159 @@ export default {
<style lang="scss" scoped> <style lang="scss" scoped>
$avatar-width: 104px; $avatar-width: 104px;
/deep/ .avatar-uploader { /deep/ .avatar-uploader {
.el-upload { .el-upload {
position: relative; position: relative;
width: $avatar-width; width: $avatar-width;
height: $avatar-width; height: $avatar-width;
border: 1px dashed #d9d9d9; border: 1px dashed #d9d9d9;
border-radius: 2px; border-radius: 2px;
cursor: pointer; cursor: pointer;
overflow: hidden; overflow: hidden;
&:hover { &:hover {
border-color: #409eff; border-color: #409eff;
} }
.uploader-default { .uploader-default {
display: flex; display: flex;
flex-direction: column; flex-direction: column;
justify-content: center; justify-content: center;
width: $avatar-width !important; width: $avatar-width !important;
height: $avatar-width; height: $avatar-width;
text-align: center; text-align: center;
background: rgba(0, 0, 0, 0.04); background: rgba(0, 0, 0, 0.04);
i { i {
font-size: 20px; font-size: 20px;
font-weight: bold; font-weight: bold;
color: #8c939d; color: #8c939d;
} }
p { p {
margin-top: 10px; margin-top: 10px;
font-size: 14px; font-size: 14px;
color: rgba(0, 0, 0, 0.65); color: rgba(0, 0, 0, 0.65);
line-height: 1; line-height: 1;
} }
} }
.avatar { .avatar {
width: $avatar-width; width: $avatar-width;
height: $avatar-width; height: $avatar-width;
display: block; display: block;
}
} }
}
.el-upload__tip { .el-upload__tip {
margin-top: 0; margin-top: 0;
p { p {
font-size: 14px; font-size: 14px;
color: rgba(0, 0, 0, 0.45); color: rgba(0, 0, 0, 0.45);
line-height: 1; line-height: 1;
&:first-child { &:first-child {
margin-bottom: 5px; margin-bottom: 5px;
} }
}
} }
}
} }
.settlement { .settlement {
display: flex; display: flex;
align-items: center; align-items: center;
margin-bottom: 10px; margin-bottom: 10px;
.label {
margin-right: 10px; .label {
white-space: nowrap; margin-right: 10px;
color: #606266; white-space: nowrap;
font-size: 14px; color: #606266;
} font-size: 14px;
.el-input { }
width: 150px;
margin-right: 30px; .el-input {
} width: 150px;
margin-right: 30px;
}
} }
/deep/.config-dia { /deep/.config-dia {
.config-wrap { .config-wrap {
display: flex; display: flex;
} }
.title-wrap {
margin-bottom: 15px; .title-wrap {
margin-bottom: 15px;
}
.item {
width: 250px;
max-height: 600px;
padding: 10px;
margin-right: 20px;
overflow: hidden;
}
.system {
background-color: #f9f9f9;
}
.systems {
margin-top: 10px;
max-height: 520px;
overflow: auto;
li {
display: flex;
align-items: center;
margin: 10px 0;
} }
.item {
width: 250px; .name {
max-height: 600px; display: inline-flex;
padding: 10px; flex: 1;
margin-right: 20px; justify-content: space-between;
align-items: center;
margin-left: 5px;
cursor: pointer;
&.active,
&:hover {
color: #9076ff;
}
span {
max-width: 200px;
text-overflow: ellipsis;
white-space: nowrap;
overflow: hidden; overflow: hidden;
}
} }
.system { }
background-color: #f9f9f9;
} .checked {
.systems { flex: 1;
margin-top: 10px; width: auto;
max-height: 520px;
overflow: auto; .el-table .cell {
li { font-size: 12px;
display: flex;
align-items: center;
margin: 10px 0;
}
.name {
display: inline-flex;
flex: 1;
justify-content: space-between;
align-items: center;
margin-left: 5px;
cursor: pointer;
&.active,
&:hover {
color: #9076ff;
}
span {
max-width: 200px;
text-overflow: ellipsis;
white-space: nowrap;
overflow: hidden;
}
}
} }
.checked { }
flex: 1;
width: auto; .rm {
.el-table .cell { font-size: 14px;
font-size: 12px; cursor: pointer;
}
&.disabled {
color: #ccc;
cursor: not-allowed;
} }
.rm {
font-size: 14px; &:hover {
cursor: pointer; color: #17161f;
&.disabled {
color: #ccc;
cursor: not-allowed;
}
&:hover {
color: #17161f;
}
} }
}
} }
</style> </style>
Loading…
Cancel
Save