index.vue 37 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275
  1. <template>
  2. <div id="festivalAdd">
  3. <div class="boxWidth">
  4. <el-form
  5. label-position="right"
  6. label-width="120px"
  7. :model="listData"
  8. :rules="rules"
  9. ref="listData"
  10. >
  11. <el-form-item label="适用业务层级" required>
  12. <el-select
  13. v-model="eduType"
  14. placeholder="请选择教育类型"
  15. @change="changeEduType"
  16. >
  17. <el-option
  18. v-for="(item, index) in eduTypeOptions"
  19. :key="index"
  20. :label="item.educationName"
  21. :value="item.id"
  22. >
  23. </el-option>
  24. </el-select>
  25. <el-select
  26. v-model="courType"
  27. placeholder="请选择业务层次"
  28. @change="changecourseType"
  29. >
  30. <el-option
  31. v-for="(item, index) in newCourTypeOptions"
  32. :key="index"
  33. :label="item.projectName + '-' + item.businessName"
  34. :value="item.id"
  35. >
  36. </el-option>
  37. </el-select>
  38. <el-popover
  39. ref="popovers"
  40. placement="bottom"
  41. trigger="click"
  42. @show="showHandle"
  43. @hide="hideHandle"
  44. :disabled="courType ? false : true"
  45. >
  46. <el-checkbox
  47. v-model="checkAll"
  48. @change="handleCheckAllChange"
  49. :indeterminate="isIndeterminate"
  50. >全选</el-checkbox
  51. >
  52. <el-checkbox-group
  53. v-model="sujectArray"
  54. class="checkboxSty"
  55. @change="handleCheckedCitiesChange"
  56. >
  57. <el-checkbox
  58. v-for="(item, index) in newSujectOption"
  59. :label="item.newId"
  60. :key="index"
  61. >{{ item.subjectName }}</el-checkbox
  62. >
  63. </el-checkbox-group>
  64. <div style="display: block; text-align: center; margin-top: 10px">
  65. <el-button size="mini" type="primary" @click="submitSujectArray"
  66. >确定</el-button
  67. >
  68. </div>
  69. <el-button
  70. slot="reference"
  71. style="margin-left: 12px"
  72. @click="getMessage"
  73. >请选择科目</el-button
  74. >
  75. </el-popover>
  76. <span style="margin-left: 10px">注:可多选</span>
  77. </el-form-item>
  78. <el-form-item label="">
  79. <div :class="changeHeight ? 'ach' : 'clh'">
  80. <div
  81. v-for="(item, index) in newSujectApis"
  82. :key="index"
  83. class="listBoxStys"
  84. >
  85. {{
  86. item.educationName +
  87. " - " +
  88. item.projectName +
  89. " - " +
  90. item.businessName +
  91. " - " +
  92. item.subjectName
  93. }}
  94. <i class="el-icon-error closeIcons" @click="closeType(index)"></i>
  95. </div>
  96. </div>
  97. <el-popover
  98. placement="bottom-start"
  99. trigger="hover"
  100. :close-delay="50"
  101. >
  102. <ul style="margin: 0; max-width: 600px">
  103. <li
  104. class="copyDataLi"
  105. :class="changeSty(itemT)"
  106. v-for="(itemT, indexT) in localData"
  107. :key="indexT"
  108. @click="unTime(itemT)"
  109. >
  110. {{
  111. `${itemT.educationName}-${itemT.projectName}-${itemT.businessName}-${itemT.subjectName}`
  112. }}
  113. </li>
  114. </ul>
  115. <el-button
  116. v-show="localData.length"
  117. type="danger"
  118. slot="reference"
  119. size="mini"
  120. style="margin-right: 10px"
  121. >最近选择</el-button
  122. >
  123. </el-popover>
  124. <el-button
  125. size="mini"
  126. v-if="newSujectApis.length > 1"
  127. @click="changeType"
  128. >{{ changeHeight ? "展开" : "关闭" }}</el-button
  129. ><el-button
  130. size="mini"
  131. v-if="newSujectApis.length > 0"
  132. @click="sujectApis = []"
  133. >清空</el-button
  134. >
  135. <!-- <span v-if="newSujectApis.length === 0">未选项目类型</span> -->
  136. </el-form-item>
  137. <el-form-item label="标题前缀">
  138. <el-input v-model="listData.prefixName"></el-input>
  139. <div style="color: #999">注:便于检索、归类,以及区分一样的标题</div>
  140. </el-form-item>
  141. <el-form-item label="节标题" prop="name">
  142. <el-input v-model="listData.name"></el-input>
  143. <div style="color: #999">
  144. 注:请尽量规范易懂,方便在课程目录表呈现给学员
  145. </div>
  146. </el-form-item>
  147. <el-form-item label="节类型">
  148. <el-select
  149. clearable
  150. v-model="listData.sectionType"
  151. placeholder="请选择节类型"
  152. @change="changeTypeSection"
  153. >
  154. <el-option
  155. v-for="(item, index) in sectionTypeOptions"
  156. :key="index"
  157. :label="item.label"
  158. :value="item.value"
  159. >
  160. </el-option>
  161. </el-select>
  162. </el-form-item>
  163. <el-form-item
  164. label="频道号"
  165. v-if="listData.sectionType === 2"
  166. prop="liveUrl"
  167. >
  168. <el-input
  169. style="width: 300px"
  170. v-model="listData.liveUrl"
  171. placeholder="请输入频道号"
  172. ></el-input>
  173. <el-select
  174. v-model="newActiveLiveUrl"
  175. placeholder="快捷选中频道号"
  176. @change="changeLiveUrl"
  177. >
  178. <el-option
  179. v-for="(item, index) in newLiveUrl"
  180. :key="index"
  181. :label="item.streamingName"
  182. :value="item.id"
  183. >
  184. </el-option>
  185. </el-select>
  186. <div v-if="listData.liveUrl" style="margin-top: 10px">
  187. <el-button
  188. size="small"
  189. type="warning"
  190. @click="watchZbVideo(listData.liveUrl)"
  191. >直播预览</el-button
  192. >
  193. </div>
  194. </el-form-item>
  195. <el-form-item
  196. label="直播开始时间"
  197. v-if="listData.sectionType === 2"
  198. prop="liveStartTime"
  199. >
  200. <el-date-picker
  201. v-model="listData.liveStartTime"
  202. type="datetime"
  203. placeholder="请选择直播开始时间"
  204. value-format="timestamp"
  205. >
  206. </el-date-picker>
  207. </el-form-item>
  208. <el-form-item
  209. label="直播结束时间"
  210. v-if="listData.sectionType === 2"
  211. prop="liveEndTime"
  212. >
  213. <el-date-picker
  214. v-model="listData.liveEndTime"
  215. type="datetime"
  216. placeholder="请选择直播结束时间"
  217. value-format="timestamp"
  218. >
  219. </el-date-picker>
  220. </el-form-item>
  221. <el-form-item
  222. label="直播时长"
  223. v-if="
  224. listData.sectionType === 2 &&
  225. listData.liveStartTime &&
  226. listData.liveEndTime
  227. "
  228. >
  229. {{ compTimeOUT(listData.liveStartTime, listData.liveEndTime) }}
  230. </el-form-item>
  231. <el-form-item
  232. label="URL地址"
  233. v-if="listData.sectionType === 1 || listData.sectionType === 3"
  234. prop="recordingUrl"
  235. >
  236. <el-input
  237. style="width: 300px"
  238. v-model="listData.recordingUrl"
  239. placeholder="请输入URL地址"
  240. @change="getApiTime(listData.recordingUrl)"
  241. ></el-input>
  242. <label
  243. for="mobles"
  244. class="el-button el-button--primary"
  245. style="margin: 0px 6px; padding: 10px 20px"
  246. >上传</label
  247. ><input
  248. style="display: none"
  249. type="file"
  250. id="mobles"
  251. @change="importMoble"
  252. />
  253. <el-select
  254. v-if="listData.sectionType === 1"
  255. v-model="newActiveRecordingUrl1"
  256. filterable
  257. placeholder="快捷选中录播URL地址"
  258. @change="changeRecordingUrl1"
  259. >
  260. <el-option
  261. v-for="(item, index) in newSteamUrl1"
  262. :key="index"
  263. :label="item.streamingName"
  264. :value="item.id"
  265. >
  266. </el-option>
  267. </el-select>
  268. <el-select
  269. v-if="listData.sectionType === 3"
  270. v-model="newActiveRecordingUrl2"
  271. placeholder="快捷选中回放URL地址"
  272. filterable
  273. @change="changeRecordingUrl2"
  274. >
  275. <el-option
  276. v-for="(item, index) in newSteamUrl2"
  277. :key="index"
  278. :label="item.streamingName"
  279. :value="item.id"
  280. >
  281. </el-option>
  282. </el-select>
  283. <div v-if="listData.recordingUrl" style="margin-top: 10px">
  284. <el-button
  285. size="small"
  286. type="warning"
  287. @click="watchVideo(listData.recordingUrl)"
  288. >视频预览</el-button
  289. >
  290. </div>
  291. </el-form-item>
  292. <el-form-item
  293. label="节时长"
  294. v-if="listData.sectionType === 1 || listData.sectionType === 3"
  295. prop="durationTime"
  296. >
  297. <el-time-picker
  298. :disabled="disabloutime"
  299. value-format="HH:mm:ss"
  300. range-separator=":"
  301. v-model="listData.durationTime"
  302. placeholder="请填入节时长"
  303. >
  304. </el-time-picker>
  305. </el-form-item>
  306. <el-form-item
  307. label="讲师"
  308. :prop="listData.sectionType === 2 ? 'teacherId' : ''"
  309. >
  310. <el-select
  311. v-model="listData.teacherId"
  312. placeholder="请选择讲师"
  313. filterable
  314. >
  315. <el-option
  316. v-for="(item, index) in teacherList"
  317. :key="index"
  318. :label="item.teacherName"
  319. :value="item.teacherId"
  320. >
  321. </el-option>
  322. </el-select>
  323. </el-form-item>
  324. <el-form-item label="节封面" prop="coverUrl">
  325. <el-row :gutter="10" style="margin-bottom: 10px">
  326. <el-col :span="12">
  327. <div
  328. style="
  329. width: 100%;
  330. height: 150px;
  331. border: 2px dashed #999;
  332. border-radius: 28px;
  333. line-height: 150px;
  334. text-align: center;
  335. "
  336. v-if="!listData.coverUrl"
  337. >
  338. <label for="uplose">
  339. <i class="el-icon-circle-plus-outline iconStsz"></i
  340. ></label>
  341. <input
  342. ref="file"
  343. type="file"
  344. style="display: none"
  345. id="uplose"
  346. @change="getImgFile"
  347. />
  348. </div>
  349. <el-image
  350. v-else
  351. style="width: 100%"
  352. :src="$methodsTools.splitImgHost(listData.coverUrl)"
  353. :preview-src-list="[
  354. $methodsTools.splitImgHost(listData.coverUrl),
  355. ]"
  356. >
  357. </el-image>
  358. </el-col>
  359. <el-col :span="11">
  360. <span style="color: #999; font-size: 14px"
  361. >注:请上传小于300kb,尺寸为750*440的图片,支持gif、jpg、jpeg、png等类型</span
  362. >
  363. </el-col>
  364. </el-row>
  365. <el-button
  366. v-if="listData.coverUrl"
  367. type="danger"
  368. size="mini"
  369. class="margin-top: 20px;"
  370. @click="clearImgs"
  371. >删除</el-button
  372. >
  373. </el-form-item>
  374. <el-form-item label="是否发布" prop="publishStatus">
  375. <el-radio-group v-model="listData.publishStatus">
  376. <el-radio :label="1">是</el-radio>
  377. <el-radio :label="0">否</el-radio>
  378. </el-radio-group>
  379. </el-form-item>
  380. <el-form-item>
  381. <el-button @click="backPage">取消</el-button>
  382. <el-button
  383. type="primary"
  384. @click="submit('listData')"
  385. :loading="disabledBtn"
  386. >确定</el-button
  387. >
  388. </el-form-item>
  389. </el-form>
  390. </div>
  391. <el-dialog
  392. :visible.sync="diavos"
  393. width="840px"
  394. @opened="isOkBf"
  395. :show-close="false"
  396. :close-on-click-modal="false"
  397. >
  398. <div slot="title" class="hearders">
  399. <div class="leftTitle">视频预览</div>
  400. <div class="rightBoxs">
  401. <img src="@/assets/images/Close@2x.png" alt="" @click="clears" />
  402. </div>
  403. </div>
  404. <div>
  405. <div id="player"></div>
  406. </div>
  407. <span slot="footer" class="dialog-footer">
  408. <el-button @click="clears">取 消</el-button>
  409. </span>
  410. </el-dialog>
  411. <el-dialog
  412. :visible.sync="diavoszb"
  413. width="840px"
  414. @opened="isOkBfzb"
  415. :show-close="false"
  416. :close-on-click-modal="false"
  417. >
  418. <div slot="title" class="hearders">
  419. <div class="leftTitle">直播预览</div>
  420. <div class="rightBoxs">
  421. <img src="@/assets/images/Close@2x.png" alt="" @click="clearszb" />
  422. </div>
  423. </div>
  424. <div>
  425. <div id="playerzb"></div>
  426. </div>
  427. <span slot="footer" class="dialog-footer">
  428. <el-button @click="clearszb">取 消</el-button>
  429. </span>
  430. </el-dialog>
  431. </div>
  432. </template>
  433. <script>
  434. import { uploadFile } from "@/utils/uopladFile.js";
  435. export default {
  436. name: "FestivalAdd",
  437. data() {
  438. return {
  439. disabledBtn: false,
  440. isIndeterminate: false,
  441. checkAll: false,
  442. vodPlayerJs: "https://player.polyv.net/script/player.js",
  443. vid: "",
  444. playerJs:
  445. "https://player.polyv.net/resp/live-h5-player/latest/liveplayer.min.js",
  446. uidzb: "egsxlptzdq",
  447. vidzb: "",
  448. diavos: false,
  449. diavoszb: false,
  450. fileSetting: {
  451. desc: "i am desc", // 描述
  452. cataid: "1639399775001", // 分类ID 可以后端传递 也可以不写 或写死
  453. tag: "i am tag", // 标签
  454. luping: 0, // 是否开启视频课件优化处理,对于上传录屏类视频清晰度有所优化:0为不开启,1为开启
  455. keepsource: 1, // 是否源文件播放(不对视频进行编码):0为编码,1为不编码
  456. },
  457. sectionTypeOptions: [
  458. {
  459. label: "录播",
  460. value: 1,
  461. },
  462. {
  463. label: "直播",
  464. value: 2,
  465. },
  466. // {
  467. // label: "回放",
  468. // value: 3,
  469. // },
  470. ],
  471. // 弹窗数据
  472. changeHeight: true,
  473. bfImg: "oss/images/avatar/20211013/1634097664410_1397766697",
  474. listData: {
  475. durationTime: "",
  476. sectionType: 1,
  477. publishStatus: 1,
  478. recordingUrl: "",
  479. liveUrl: "",
  480. coverUrl: "oss/images/avatar/20211013/1634097664410_1397766697",
  481. },
  482. newActiveLiveUrl: "",
  483. newLiveUrl: [], //直播流地址
  484. newActiveRecordingUrl1: "",
  485. newSteamUrl1: [], //录播流地址
  486. newActiveRecordingUrl2: "",
  487. newSteamUrl2: [], //回放流地址
  488. eduTypeOptions: [], //教育类型数据
  489. projectTypeOptions: [], //项目类型数据
  490. courTypeOptions: [], //业务层次数据
  491. newCourTypeOptions: [], //当前业务层次数据
  492. sujectOption: [], //科目数据
  493. newSujectOption: [], //当前科目数据数据
  494. eduType: "", //当前选中教育类型
  495. courType: "", //当前选中业务层次
  496. sujectApis: [], //当前存在的科目
  497. newSujectApis: [],
  498. sujectArray: [], //选中的科目
  499. disabloutime: false,
  500. localData: [], //缓存数据
  501. teacherList: [], //教师列表
  502. //表单验证
  503. rules: {
  504. prefixName: [
  505. { required: true, message: "请输入标题前缀", trigger: "blur" },
  506. ],
  507. name: [{ required: true, message: "请输入节标题", trigger: "blur" }],
  508. // liveDuration: [
  509. // { required: true, message: "节时长不能为空" },
  510. // { type: "number", message: "节时长必须为数字值" },
  511. // ],
  512. recordingUrl: [
  513. {
  514. required: true,
  515. message: "请输入URL地址",
  516. trigger: ["blur", "change"],
  517. },
  518. ],
  519. durationTime: [
  520. { required: true, message: "请选择节时长", trigger: "change" },
  521. ],
  522. liveUrl: [
  523. {
  524. required: true,
  525. message: "请输入频道号",
  526. trigger: ["blur", "change"],
  527. },
  528. ],
  529. liveStartTime: [
  530. { required: true, message: "请选择直播开始时间", trigger: "change" },
  531. ],
  532. liveEndTime: [
  533. { required: true, message: "请选择直播结束时间", trigger: "change" },
  534. ],
  535. teacherId: [
  536. { required: true, message: "请选择讲师", trigger: "change" },
  537. ],
  538. publishStatus: [
  539. { required: true, message: "请选择是否发布", trigger: "change" },
  540. ],
  541. coverUrl: [
  542. { required: true, message: "请上传封面", trigger: "change" },
  543. ],
  544. },
  545. };
  546. },
  547. watch: {
  548. sujectApis: {
  549. immediate: true,
  550. handler(newName, oldName) {
  551. this.changeTypes();
  552. },
  553. },
  554. },
  555. mounted() {
  556. this.localData = this.$methodsTools.getBusinessList();
  557. this.getDict();
  558. },
  559. methods: {
  560. changeTypeSection() {
  561. this.$nextTick(() => {
  562. this.$refs.listData.clearValidate();
  563. });
  564. },
  565. unTime(val) {
  566. let a = `${val.businessId}-${val.subjectId}`;
  567. if (this.sujectApis.includes(a)) {
  568. this.sujectApis.splice(this.sujectApis.indexOf(a), 1);
  569. } else {
  570. this.sujectApis.push(a);
  571. }
  572. },
  573. changeSty(val) {
  574. var arr = "";
  575. this.sujectApis.forEach((item) => {
  576. let arr1 = item.split("-").map(Number);
  577. if (val.businessId == arr1[0] && val.subjectId == arr1[1]) {
  578. arr = "activeStyIcons";
  579. }
  580. });
  581. return arr;
  582. },
  583. handleCheckedCitiesChange() {
  584. let nid = this.newSujectOption.map((item) => {
  585. return item.newId;
  586. });
  587. this.checkAll = this.sujectArray.length === nid.length;
  588. this.isIndeterminate =
  589. this.sujectArray.length > 0 && this.sujectArray.length < nid.length;
  590. },
  591. setFunc(arr) {
  592. var arrays = [];
  593. for (let i = 0; i < arr.length; i++) {
  594. if (!arrays.includes(arr[i])) {
  595. arrays.push(arr[i]);
  596. }
  597. }
  598. return arrays;
  599. },
  600. handleCheckAllChange(val) {
  601. if (val) {
  602. let nid = this.newSujectOption.map((item) => {
  603. return item.newId;
  604. });
  605. let arrays = this.sujectArray.concat(nid);
  606. this.sujectArray = this.setFunc(arrays);
  607. this.isIndeterminate = false;
  608. } else {
  609. let nid = this.newSujectOption.map((item) => {
  610. return item.newId;
  611. });
  612. let newArr = [];
  613. this.sujectArray.forEach((item) => {
  614. if (!nid.includes(item)) {
  615. newArr.push(item);
  616. }
  617. });
  618. this.sujectArray = newArr;
  619. this.isIndeterminate = false;
  620. }
  621. },
  622. compTimeOUT(start, end) {
  623. if (start && end) {
  624. if (end < start) {
  625. return "请检查开始与结束的时间范围";
  626. }
  627. const asTimes = end / 1000 - start / 1000;
  628. return this.$methodsTools.secondToDate(asTimes, false);
  629. } else {
  630. return "未检测到直播开始时间结束时间,无法计算!";
  631. }
  632. },
  633. getApiTime(val) {
  634. var self = this;
  635. const valueUrl = val.replace(/\s/g, "");
  636. if (valueUrl && valueUrl.length > 30) {
  637. this.$api
  638. .inquirepolyvvideo(valueUrl)
  639. .then((res) => {
  640. if (res.data.duration) {
  641. self.listData.durationTime = res.data.duration;
  642. self.disabloutime = true;
  643. } else {
  644. self.disabloutime = false;
  645. }
  646. })
  647. .catch((err) => {
  648. self.disabloutime = false;
  649. });
  650. }
  651. },
  652. loadPlayerScript(callback) {
  653. if (!window.polyvPlayer) {
  654. const myScript = document.createElement("script");
  655. myScript.setAttribute("src", this.vodPlayerJs);
  656. myScript.onload = callback;
  657. document.body.appendChild(myScript);
  658. } else {
  659. callback();
  660. this.player.on("serverError", (...params) => {
  661. this.$message.error(returnTitle(params[1]));
  662. });
  663. }
  664. },
  665. loadPlayer() {
  666. var self = this;
  667. const polyvPlayer = window.polyvPlayer;
  668. self.player = polyvPlayer({
  669. wrap: "#player",
  670. width: 800,
  671. height: 533,
  672. vid: self.vid,
  673. teaser_show: 0,
  674. playsafe: function (vid, next) {
  675. self.$api.obtainpolyvvideosign(vid).then((res) => {
  676. next(res.data);
  677. });
  678. },
  679. });
  680. },
  681. /**
  682. * @param {String} 关闭视频窗口-销毁实例
  683. */
  684. clears() {
  685. this.diavos = false;
  686. if (this.player) {
  687. this.player.destroy();
  688. }
  689. },
  690. /**
  691. * @param {String} 视频查看
  692. */
  693. watchVideo(url) {
  694. if (!url) {
  695. this.$message.warning("请检查URL地址是否输入完整");
  696. return;
  697. }
  698. this.vid = url;
  699. this.diavos = true;
  700. },
  701. isOkBf() {
  702. this.loadPlayerScript(this.loadPlayer);
  703. },
  704. /**
  705. * @param {String} 直播预览
  706. */
  707. watchZbVideo(url) {
  708. if (!url) {
  709. this.$message.warning("请检查直播流地址是否输入完整");
  710. return;
  711. }
  712. this.vidzb = url;
  713. this.diavoszb = true;
  714. },
  715. loadPlayerScriptzb(callback) {
  716. if (!window.polyvLivePlayer) {
  717. const myScript = document.createElement("script");
  718. myScript.setAttribute("src", this.playerJs);
  719. myScript.onload = callback;
  720. document.body.appendChild(myScript);
  721. } else {
  722. callback();
  723. }
  724. },
  725. loadPlayerzb() {
  726. const polyvLivePlayer = window.polyvLivePlayer;
  727. this.playerzb = polyvLivePlayer({
  728. wrap: "#playerzb",
  729. width: 800,
  730. height: 533,
  731. uid: this.uidzb,
  732. vid: this.vidzb,
  733. });
  734. },
  735. clearszb() {
  736. this.diavoszb = false;
  737. if (this.playerzb) {
  738. this.playerzb.destroy();
  739. }
  740. },
  741. isOkBfzb() {
  742. this.loadPlayerScriptzb(this.loadPlayerzb);
  743. },
  744. importMoble(event) {
  745. // var self = this;
  746. var file = event.target.files[0];
  747. // let formData = new FormData();
  748. // formData.append("file", file);
  749. if (!event.target.value) {
  750. this.$message.error("请选择您要上传的文件");
  751. return false;
  752. }
  753. /**
  754. * @param: event.target.files -> 传递的文件list
  755. * @param: this.fileSetting -> 常规配置 上面有备注
  756. * @param: 回调
  757. */
  758. uploadFile(file, this.fileSetting, (event) => {
  759. this.listData.recordingUrl = event.vid;
  760. this.listData.durationTime = "";
  761. this.getApiTime(event.vid);
  762. });
  763. },
  764. getMessage() {
  765. if (!this.courType) {
  766. this.$message.warning("请先选择业务层级");
  767. }
  768. },
  769. clearImgs() {
  770. this.listData.coverUrl = "";
  771. this.$refs.listData.validateField("coverUrl");
  772. },
  773. changeTypes() {
  774. var self = this;
  775. var arrays = [];
  776. this.sujectApis.map((item, index) => {
  777. this.courTypeOptions.map((items) => {
  778. if (items.id === item.split("-").map(Number)[0]) {
  779. var obj = {
  780. educationTypeId: items.educationId,
  781. educationName: items.educationName,
  782. projectId: items.projectId,
  783. projectName: items.projectName,
  784. businessId: items.id,
  785. businessName: items.businessName,
  786. };
  787. self.sujectOption.map((i) => {
  788. if (
  789. i.id === item.split("-").map(Number)[1] &&
  790. i.courseArrays.indexOf(items.projectId) !== -1
  791. ) {
  792. obj.subjectName = i.subjectName;
  793. obj.subjectId = i.id;
  794. }
  795. });
  796. arrays.push(obj);
  797. }
  798. });
  799. });
  800. this.newSujectApis = arrays;
  801. },
  802. changeType() {
  803. this.changeHeight = !this.changeHeight;
  804. },
  805. submitSujectArray() {
  806. var self = this;
  807. this.sujectApis = this.sujectApis.filter((item, index) => {
  808. return item.split("-").map(Number)[0] !== Number(self.courType);
  809. });
  810. for (let i = 0; i < this.sujectArray.length; i++) {
  811. this.sujectApis.push(this.sujectArray[i]);
  812. }
  813. this.$refs.popovers.doClose();
  814. this.$nextTick(() => {
  815. this.changeUrl();
  816. });
  817. },
  818. changeUrl() {
  819. var arr = this.newSujectApis.map((val) => val.businessId);
  820. const unique = [...new Set(arr)];
  821. var busId = "";
  822. if (unique.length) {
  823. busId = unique.toString();
  824. } else {
  825. busId = "";
  826. }
  827. this.$api.inquireCourseStreaming({ status: 1 }).then((res) => {
  828. var arraystt = [];
  829. var newarrays1tt = [];
  830. var newarrays2tt = [];
  831. res.rows.map((item) => {
  832. if (item.streamingType === 1) {
  833. arraystt.push(item);
  834. }
  835. if (item.streamingType === 2) {
  836. newarrays1tt.push(item);
  837. }
  838. if (item.streamingType === 3) {
  839. newarrays2tt.push(item);
  840. }
  841. });
  842. this.$api
  843. .inquireCourseStreaming({ status: 1, businessId: busId })
  844. .then((result) => {
  845. var arrays = [];
  846. var newarrays1 = [];
  847. var newarrays2 = [];
  848. result.rows.map((item) => {
  849. if (item.streamingType === 1) {
  850. arrays.push(item);
  851. }
  852. if (item.streamingType === 2) {
  853. newarrays1.push(item);
  854. }
  855. if (item.streamingType === 3) {
  856. newarrays2.push(item);
  857. }
  858. });
  859. if (arrays.length) {
  860. this.newLiveUrl = arrays;
  861. } else {
  862. this.newLiveUrl = arraystt;
  863. }
  864. if (newarrays1.length) {
  865. this.newSteamUrl1 = newarrays1;
  866. } else {
  867. this.newSteamUrl1 = newarrays1tt;
  868. }
  869. if (newarrays2.length) {
  870. this.newSteamUrl2 = newarrays2;
  871. } else {
  872. this.newSteamUrl2 = newarrays2tt;
  873. }
  874. });
  875. });
  876. },
  877. showHandle() {
  878. var array = [];
  879. for (let i = 0; i < this.sujectApis.length; i++) {
  880. if (
  881. this.sujectApis[i].split("-").map(Number)[0] === Number(this.courType)
  882. ) {
  883. array.push(this.sujectApis[i]);
  884. }
  885. }
  886. this.sujectArray = array;
  887. if (!this.newSujectOption.length) {
  888. this.$message.warning("该业务层次暂无关联科目");
  889. this.$refs.popovers.doClose();
  890. return;
  891. }
  892. this.newSujectOption.map((item) => {
  893. item.newId = this.courType + "-" + item.id;
  894. });
  895. this.handleCheckedCitiesChange();
  896. },
  897. hideHandle() {},
  898. getDict() {
  899. this.$api.inquiresystemteacherlist({ status: 1 }).then((res) => {
  900. this.teacherList = res.rows;
  901. });
  902. this.$api.inquireCourseEducationType({ status: 1 }).then((res) => {
  903. this.eduTypeOptions = res.rows;
  904. });
  905. this.$api.inquireCourseProjectType({ status: 1 }).then((res) => {
  906. this.projectTypeOptions = res.rows;
  907. });
  908. this.$api.inquirebusinessList({ status: 1 }).then((res) => {
  909. this.courTypeOptions = res.rows;
  910. this.newCourTypeOptions = res.rows;
  911. });
  912. this.$api.inquireCourseSubject({ status: 1 }).then((res) => {
  913. res.rows.map((item, index) => {
  914. var array = [];
  915. item.courseProjectTypes.map((items, indexs) => {
  916. array.push(items.id);
  917. });
  918. item.courseArrays = array;
  919. });
  920. this.sujectOption = res.rows;
  921. });
  922. this.$api.inquireCourseStreaming({ status: 1 }).then((res) => {
  923. var arrays = [];
  924. var newarrays1 = [];
  925. var newarrays2 = [];
  926. res.rows.map((item) => {
  927. if (item.streamingType === 1) {
  928. arrays.push(item);
  929. }
  930. if (item.streamingType === 2) {
  931. newarrays1.push(item);
  932. }
  933. if (item.streamingType === 3) {
  934. newarrays2.push(item);
  935. }
  936. });
  937. this.newLiveUrl = arrays;
  938. this.newSteamUrl1 = newarrays1;
  939. this.newSteamUrl2 = newarrays2;
  940. });
  941. },
  942. changeEduType() {
  943. if (!(this.courType === undefined || this.courType === "")) {
  944. this.courType = "";
  945. }
  946. var arrays = [];
  947. this.courTypeOptions.map((item) => {
  948. if (item.educationId === this.eduType) {
  949. arrays.push(item);
  950. }
  951. });
  952. this.newCourTypeOptions = arrays;
  953. },
  954. changecourseType() {
  955. this.newCourTypeOptions.map((item, index) => {
  956. if (item.id === this.courType) {
  957. this.eduType = item.educationId;
  958. var array = [];
  959. this.sujectOption.map((items, indexs) => {
  960. if (items.courseArrays.indexOf(item.projectId) !== -1) {
  961. array.push(items);
  962. }
  963. });
  964. this.newSujectOption = array;
  965. }
  966. });
  967. var arrays = [];
  968. this.courTypeOptions.map((item) => {
  969. if (item.educationId === this.eduType) {
  970. arrays.push(item);
  971. }
  972. });
  973. this.newCourTypeOptions = arrays;
  974. this.$refs.popovers.doClose();
  975. },
  976. submit(formName) {
  977. this.$refs[formName].validate((valid) => {
  978. if (valid) {
  979. if (!this.newSujectApis.length) {
  980. this.$message.error("请选择适用业务层级");
  981. return;
  982. }
  983. // if (
  984. // this.listData.coverUrl === "" ||
  985. // this.listData.coverUrl === null ||
  986. // this.listData.coverUrl === undefined
  987. // ) {
  988. // this.$message.error("请上传节封面");
  989. // return false;
  990. // }
  991. this.rulesTableSumbit();
  992. } else {
  993. return false;
  994. }
  995. });
  996. },
  997. async rulesTableSumbit() {
  998. this.disabledBtn = true;
  999. var dataInfos = {
  1000. status: 1,
  1001. businessList: this.newSujectApis,
  1002. coverUrl: this.listData.coverUrl,
  1003. name: this.listData.name,
  1004. prefixName: this.listData.prefixName,
  1005. publishStatus: this.listData.publishStatus,
  1006. teacherId: this.listData.teacherId,
  1007. };
  1008. if (this.listData.sectionType === 2) {
  1009. dataInfos.sectionType = 2;
  1010. dataInfos.liveUrl = this.listData.liveUrl;
  1011. dataInfos.liveStartTime = this.$methodsTools.time10to13(
  1012. this.listData.liveStartTime,
  1013. 1
  1014. );
  1015. dataInfos.liveEndTime = this.$methodsTools.time10to13(
  1016. this.listData.liveEndTime,
  1017. 1
  1018. );
  1019. if (
  1020. dataInfos.liveStartTime &&
  1021. dataInfos.liveEndTime &&
  1022. dataInfos.liveEndTime < dataInfos.liveStartTime
  1023. ) {
  1024. this.$message.warning("请检查直播开始与结束时间范围");
  1025. this.disabledBtn = false;
  1026. return;
  1027. }
  1028. dataInfos.durationTime =
  1029. dataInfos.liveEndTime - dataInfos.liveStartTime;
  1030. }
  1031. if (this.listData.sectionType === 1) {
  1032. dataInfos.sectionType = 1;
  1033. dataInfos.recordingUrl = this.listData.recordingUrl;
  1034. dataInfos.durationTime = this.$methodsTools.secondFormDate(
  1035. this.listData.durationTime
  1036. );
  1037. }
  1038. if (this.listData.sectionType === 3) {
  1039. dataInfos.sectionType = 3;
  1040. dataInfos.recordingUrl = this.listData.recordingUrl;
  1041. dataInfos.durationTime = this.$methodsTools.secondFormDate(
  1042. this.listData.durationTime
  1043. );
  1044. }
  1045. this.$api
  1046. .appCourseSection(dataInfos)
  1047. .then((res) => {
  1048. this.$methodsTools.cacheBusinessList(this.newSujectApis);
  1049. this.$message.success("新增成功");
  1050. setTimeout(() => {
  1051. this.$store
  1052. .dispatch("tagsView/exitView", this.$route)
  1053. .then((res) => {
  1054. this.$router.push({
  1055. path: "festival",
  1056. });
  1057. });
  1058. }, 500);
  1059. })
  1060. .catch(() => {
  1061. this.disabledBtn = false;
  1062. });
  1063. },
  1064. backPage() {
  1065. this.$store.dispatch("tagsView/delView", this.$route).then((res) => {
  1066. this.$router.push({
  1067. path: "festival",
  1068. });
  1069. });
  1070. },
  1071. closeType(index) {
  1072. this.sujectApis.splice(index, 1);
  1073. this.$nextTick(() => {
  1074. this.changeUrl();
  1075. });
  1076. },
  1077. changeLiveUrl() {
  1078. this.newLiveUrl.map((item) => {
  1079. if (item.id === this.newActiveLiveUrl) {
  1080. this.listData.liveUrl = item.liveUrl;
  1081. }
  1082. });
  1083. this.newActiveLiveUrl = "";
  1084. },
  1085. changeRecordingUrl1() {
  1086. this.newSteamUrl1.map((item) => {
  1087. if (item.id === this.newActiveRecordingUrl1) {
  1088. this.listData.recordingUrl = item.recordingVideoId;
  1089. this.getApiTime(item.recordingVideoId);
  1090. }
  1091. });
  1092. this.newActiveRecordingUrl1 = "";
  1093. },
  1094. changeRecordingUrl2() {
  1095. this.newSteamUrl2.map((item) => {
  1096. if (item.id === this.newActiveRecordingUrl2) {
  1097. this.listData.recordingUrl = item.playbackUrl;
  1098. this.getApiTime(item.recordingVideoId);
  1099. }
  1100. });
  1101. this.newActiveRecordingUrl2 = "";
  1102. },
  1103. getImgFile() {
  1104. var self = this;
  1105. var file = self.$refs.file.files[0];
  1106. if (file === undefined) {
  1107. self.$set(self.listData, "coverUrl", "");
  1108. return;
  1109. }
  1110. if (file.size > 0.3 * 1024 * 1024) {
  1111. self.$message.error("图片不得大于300kb");
  1112. return;
  1113. }
  1114. var type = self.$refs.file.value.toLowerCase().split(".").splice(-1);
  1115. if (
  1116. type[0] != "jpg" &&
  1117. type[0] != "png" &&
  1118. type[0] != "jpeg" &&
  1119. type[0] != "gif"
  1120. ) {
  1121. self.$message.error("上传格式需为:.jpg/.png/.jpeg/gif");
  1122. self.$refs.file.value = "";
  1123. return;
  1124. }
  1125. this.$upload.upload(file, 0).then((res) => {
  1126. self.listData.coverUrl = res;
  1127. self.$refs.listData.validateField("coverUrl");
  1128. });
  1129. },
  1130. },
  1131. };
  1132. </script>
  1133. <style lang="less" scoped>
  1134. /deep/.el-button {
  1135. border-radius: 8px;
  1136. }
  1137. /deep/.el-dialog {
  1138. border-radius: 8px;
  1139. .el-dialog__header {
  1140. padding: 0;
  1141. .hearders {
  1142. height: 40px;
  1143. display: flex;
  1144. align-items: center;
  1145. justify-content: space-between;
  1146. padding: 0px 18px 0px 20px;
  1147. border-bottom: 1px solid #e2e2e2;
  1148. .leftTitle {
  1149. font-size: 14px;
  1150. font-weight: bold;
  1151. color: #2f4378;
  1152. }
  1153. .rightBoxs {
  1154. display: flex;
  1155. align-items: center;
  1156. img {
  1157. width: 14px;
  1158. height: 14px;
  1159. margin-left: 13px;
  1160. cursor: pointer;
  1161. }
  1162. }
  1163. }
  1164. }
  1165. .el-dialog__footer {
  1166. padding: 0;
  1167. .dialog-footer {
  1168. padding: 0px 40px;
  1169. height: 70px;
  1170. border-top: 1px solid #e2e2e2;
  1171. display: flex;
  1172. align-items: center;
  1173. justify-content: flex-end;
  1174. }
  1175. }
  1176. }
  1177. .imgBox {
  1178. width: 100%;
  1179. // height: 210px;
  1180. border: 1px solid #e2e2e2;
  1181. border-radius: 8px;
  1182. padding: 8px 8px 3px;
  1183. display: flex;
  1184. flex-direction: column;
  1185. align-items: center;
  1186. .imgLabel {
  1187. flex: 1;
  1188. width: 100%;
  1189. border: 1px dotted #e2e2e2;
  1190. color: #999;
  1191. font-size: 14px;
  1192. cursor: pointer;
  1193. border-radius: 8px;
  1194. .msPhoto {
  1195. display: flex;
  1196. justify-content: center;
  1197. align-items: center;
  1198. max-width: 100%;
  1199. max-height: 270px;
  1200. img {
  1201. max-width: 100%;
  1202. max-height: 270px;
  1203. }
  1204. }
  1205. .imgbbx {
  1206. display: flex;
  1207. flex-direction: column;
  1208. align-items: center;
  1209. justify-content: center;
  1210. width: 100%;
  1211. height: 100%;
  1212. i {
  1213. font-weight: bold;
  1214. margin: 14px 0;
  1215. font-size: 24px;
  1216. }
  1217. }
  1218. }
  1219. p {
  1220. margin: 5px 0px;
  1221. }
  1222. }
  1223. .boxWidth {
  1224. width: 770px;
  1225. }
  1226. .numInputs {
  1227. width: 150px;
  1228. }
  1229. .checkboxSty {
  1230. max-height: 210px;
  1231. overflow: auto;
  1232. display: flex;
  1233. flex-direction: column;
  1234. }
  1235. .listBoxStys {
  1236. flex-shrink: 0;
  1237. padding: 0px 10px;
  1238. border-radius: 8px;
  1239. border: 1px solid #eee;
  1240. margin-right: 10px;
  1241. margin-bottom: 6px;
  1242. }
  1243. .closeIcons {
  1244. color: red;
  1245. cursor: pointer;
  1246. margin-left: 6px;
  1247. }
  1248. .ach {
  1249. display: flex;
  1250. align-items: center;
  1251. overflow: hidden;
  1252. }
  1253. .clh {
  1254. display: flex;
  1255. align-items: center;
  1256. flex-wrap: wrap;
  1257. }
  1258. .imgBoxins {
  1259. width: 375px;
  1260. height: 220px;
  1261. text-align: center;
  1262. img {
  1263. height: 100%;
  1264. }
  1265. }
  1266. .iconStsz {
  1267. font-size: 40px;
  1268. color: #67c23a;
  1269. cursor: pointer;
  1270. }
  1271. </style>