index.vue 39 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351
  1. <template>
  2. <div id="moduleManagementAdd">
  3. <el-form
  4. label-position="right"
  5. label-width="120px"
  6. :model="listData"
  7. :rules="rules"
  8. ref="listData"
  9. >
  10. <div class="boxWidth">
  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. ><el-checkbox
  46. v-model="checkAll"
  47. @change="handleCheckAllChange"
  48. :indeterminate="isIndeterminate"
  49. >全选</el-checkbox
  50. >
  51. <el-checkbox-group
  52. v-model="sujectArray"
  53. class="checkboxSty"
  54. @change="handleCheckedCitiesChange"
  55. >
  56. <el-checkbox
  57. v-for="(item, index) in newSujectOption"
  58. :label="item.newId"
  59. :key="index"
  60. >{{ item.subjectName }}</el-checkbox
  61. >
  62. </el-checkbox-group>
  63. <div style="display: block; text-align: center; margin-top: 10px">
  64. <el-button size="mini" type="primary" @click="submitSujectArray"
  65. >确定</el-button
  66. >
  67. </div>
  68. <el-button
  69. slot="reference"
  70. style="margin-left: 12px"
  71. @click="getMessage"
  72. >请选择科目</el-button
  73. >
  74. </el-popover>
  75. <span style="margin-left: 10px">注:可多选</span>
  76. </el-form-item>
  77. <el-form-item label="">
  78. <div :class="changeHeight ? 'ach' : 'clh'">
  79. <div
  80. v-for="(item, index) in newSujectApis"
  81. :key="index"
  82. class="listBoxStys"
  83. >
  84. {{
  85. item.educationName +
  86. " - " +
  87. item.projectName +
  88. " - " +
  89. item.businessName +
  90. " - " +
  91. item.subjectName
  92. }}
  93. <i class="el-icon-error closeIcons" @click="closeType(index)"></i>
  94. </div>
  95. </div>
  96. <el-popover
  97. placement="bottom-start"
  98. trigger="hover"
  99. :close-delay="50"
  100. >
  101. <ul style="margin: 0; max-width: 600px">
  102. <li
  103. class="copyDataLi"
  104. :class="changeSty(itemT)"
  105. v-for="(itemT, indexT) in localData"
  106. :key="indexT"
  107. @click="unTime(itemT)"
  108. >
  109. {{
  110. `${itemT.educationName}-${itemT.projectName}-${itemT.businessName}-${itemT.subjectName}`
  111. }}
  112. </li>
  113. </ul>
  114. <el-button
  115. v-show="localData.length"
  116. type="danger"
  117. slot="reference"
  118. size="mini"
  119. style="margin-right: 10px"
  120. >最近选择</el-button
  121. >
  122. </el-popover>
  123. <el-button
  124. size="mini"
  125. v-if="newSujectApis.length > 1"
  126. @click="changeType"
  127. >{{ changeHeight ? "展开" : "关闭" }}</el-button
  128. ><el-button
  129. size="mini"
  130. v-if="newSujectApis.length > 0"
  131. @click="sujectApis = []"
  132. >清空</el-button
  133. >
  134. </el-form-item>
  135. <el-form-item label="标题前缀" prop="prefixName">
  136. <el-input v-model="listData.prefixName"></el-input>
  137. <div style="color: #999">注:便于检索、归类,以及区分一样的标题</div>
  138. </el-form-item>
  139. <el-form-item label="模块标题" prop="moduleName">
  140. <el-input v-model="listData.moduleName"></el-input>
  141. <div style="color: #999">
  142. 注:请尽量规范易懂,方便在课程目录表呈现给学员
  143. </div>
  144. </el-form-item>
  145. <div class="dis_play_sty">
  146. <el-form-item label="证书专业" prop="certificateTypeId">
  147. <el-select
  148. v-model="listData.certificateTypeId"
  149. placeholder="请选择证书类型"
  150. @change="editStatus = true"
  151. clearable
  152. >
  153. <el-option
  154. v-for="(item, index) in certificate"
  155. :key="index"
  156. :label="item.certificateName"
  157. :value="item.id"
  158. >
  159. </el-option>
  160. </el-select>
  161. </el-form-item>
  162. <el-form-item
  163. v-if="certificateList.length"
  164. label=" "
  165. label-width="10px"
  166. prop="certificateId"
  167. >
  168. <el-select
  169. v-model="listData.certificateId"
  170. placeholder="请选择证书名称"
  171. @change="editStatus = true"
  172. clearable
  173. >
  174. <el-option
  175. v-for="(item, index) in certificateList"
  176. :key="index"
  177. :label="item.certificateName"
  178. :value="item.id"
  179. >
  180. </el-option>
  181. </el-select>
  182. </el-form-item>
  183. <el-form-item
  184. v-if="certificateTpList.length"
  185. label=" "
  186. label-width="10px"
  187. prop="certificateTpId"
  188. >
  189. <el-select
  190. v-model="listData.certificateTpId"
  191. placeholder="请选择证书模板"
  192. clearable
  193. >
  194. <el-option
  195. v-for="(item, index) in certificateTpList"
  196. :key="index"
  197. :label="item.title"
  198. :value="item.tpId"
  199. >
  200. </el-option>
  201. </el-select>
  202. </el-form-item>
  203. </div>
  204. <div
  205. style="
  206. color: #999;
  207. margin-left: 120px;
  208. font-size: 14px;
  209. margin-bottom: 20px;
  210. "
  211. >
  212. 注:为商品生成多证书,证书专业名称取值使用
  213. </div>
  214. <el-form-item label="模块封面">
  215. <el-row :gutter="10" style="margin-bottom: 10px">
  216. <el-col :span="12">
  217. <div
  218. style="
  219. width: 100%;
  220. height: 150px;
  221. border: 2px dashed #999;
  222. border-radius: 28px;
  223. line-height: 150px;
  224. text-align: center;
  225. "
  226. v-if="!listData.coverUrl"
  227. >
  228. <label for="uplose">
  229. <i class="el-icon-circle-plus-outline iconStsz"></i
  230. ></label>
  231. <input
  232. ref="file"
  233. type="file"
  234. style="display: none"
  235. id="uplose"
  236. @change="getImgFile"
  237. />
  238. </div>
  239. <el-image
  240. v-else
  241. style="width: 100%"
  242. :src="$methodsTools.splitImgHost(listData.coverUrl)"
  243. :preview-src-list="[
  244. $methodsTools.splitImgHost(listData.coverUrl),
  245. ]"
  246. >
  247. </el-image>
  248. </el-col>
  249. <el-col :span="11">
  250. <span style="color: #999; font-size: 14px"
  251. >注:请上传小于300kb,尺寸为750*440的图片,支持gif、jpg、jpeg、png等类型</span
  252. >
  253. </el-col>
  254. </el-row>
  255. <el-button
  256. v-if="listData.coverUrl"
  257. type="danger"
  258. size="mini"
  259. class="margin-top: 20px;"
  260. @click="clearImgs"
  261. >删除</el-button
  262. >
  263. </el-form-item>
  264. <el-form-item label="公共标识" prop="commonSign">
  265. <el-radio-group v-model="listData.commonSign">
  266. <el-radio :label="1">公共模块</el-radio>
  267. <el-radio :label="0">非公共模块</el-radio>
  268. </el-radio-group>
  269. </el-form-item>
  270. <el-form-item label="视频类型" prop="viewSign">
  271. <el-radio-group v-model="listData.viewSign">
  272. <el-radio :label="1">保利威</el-radio>
  273. <el-radio :label="2">腾讯</el-radio>
  274. </el-radio-group>
  275. </el-form-item>
  276. <el-form-item label="是否发布" prop="publishStatus">
  277. <el-radio-group v-model="listData.publishStatus">
  278. <el-radio :label="1">是</el-radio>
  279. <el-radio :label="0">否</el-radio>
  280. </el-radio-group>
  281. </el-form-item>
  282. </div>
  283. <el-form-item label="管理章">
  284. <div class="dis_plays">
  285. <div>
  286. <el-button size="small" @click="openBoxs">调用已有数据</el-button>
  287. <el-button size="small" type="success" @click="dialogDRFunc"
  288. >Excel批量新增章</el-button
  289. >
  290. <el-button size="small" @click="addChapter">自定义添加章</el-button>
  291. </div>
  292. <div style="color: #f56c6c">
  293. <span style="margin-right: 10px"
  294. >章总数:{{ tableData.length }}</span
  295. >
  296. <!-- <span>总时长:{{ minTimeAll }}分钟</span> -->
  297. </div>
  298. </div>
  299. <el-table
  300. :data="tableData"
  301. border
  302. :header-cell-style="{
  303. 'background-color': '#eee',
  304. padding: '8px',
  305. color: '#333',
  306. }"
  307. :default-sort="{ prop: 'sort', order: 'ascending' }"
  308. >
  309. <el-table-column
  310. v-for="(item, index) in tableSet"
  311. :width="item.width"
  312. :key="index"
  313. :label="item.label"
  314. align="center"
  315. :show-overflow-tooltip="true"
  316. header-align="center"
  317. :sortable="item.prop === 'sort'"
  318. sort-by="sort"
  319. :prop="item.prop"
  320. >
  321. <template slot-scope="scope">
  322. <span v-if="item.scope === 'types'">{{
  323. scope.row[item.prop] === 1
  324. ? "录播"
  325. : scope.row[item.prop] === 2
  326. ? "直播"
  327. : scope.row[item.prop] === 3
  328. ? "回放"
  329. : "未知"
  330. }}</span>
  331. <span v-else-if="item.scope === 'isOptions'">
  332. <span v-for="(items, indexs) in item.options" :key="indexs">
  333. <span v-if="scope.row[item.prop] == items.value">{{
  334. items.label
  335. }}</span>
  336. </span>
  337. </span>
  338. <span v-else-if="item.scope === 'Status'">
  339. {{
  340. scope.row[item.prop] === 1
  341. ? "发布"
  342. : scope.row[item.prop] === 0
  343. ? "未发布"
  344. : "未知"
  345. }}
  346. </span>
  347. <div v-else-if="item.scope === 'inputs'">
  348. <el-input-number
  349. style="width: 50px"
  350. size="small"
  351. :controls="false"
  352. v-model="scope.row[item.prop]"
  353. controls-position="right"
  354. :min="0"
  355. ></el-input-number>
  356. </div>
  357. <span v-else>{{ scope.row[item.prop] }}</span></template
  358. >
  359. </el-table-column>
  360. <el-table-column
  361. label="操作"
  362. align="center"
  363. fixed="right"
  364. width="180px"
  365. >
  366. <template slot-scope="scope">
  367. <el-button type="text" @click="jumpChapter(scope.row)"
  368. >章节内容</el-button
  369. >
  370. <el-button type="text" @click="delList(scope.row)"
  371. >删除</el-button
  372. >
  373. </template>
  374. </el-table-column>
  375. </el-table>
  376. </el-form-item>
  377. <el-form-item>
  378. <el-button @click="backPage">取消</el-button>
  379. <el-button
  380. type="primary"
  381. @click="submit('listData')"
  382. :loading="disabledBtn"
  383. >确定</el-button
  384. >
  385. </el-form-item>
  386. </el-form>
  387. <el-dialog
  388. @closed="closedFunc"
  389. :visible.sync="dialogVisible"
  390. width="800px"
  391. :show-close="false"
  392. :close-on-click-modal="false"
  393. >
  394. <div slot="title" class="hearders">
  395. <div class="leftTitle">添加章</div>
  396. <div class="rightBoxs">
  397. <img
  398. src="@/assets/images/Close@2x.png"
  399. alt=""
  400. @click="dialogVisible = false"
  401. />
  402. </div>
  403. </div>
  404. <search-box-new
  405. ref="searchBox"
  406. :formData="formData"
  407. :formList="formList"
  408. @search="getInfos"
  409. @init="init"
  410. />
  411. <el-table
  412. ref="multipleTable"
  413. :data="boxtableData"
  414. border
  415. @select-all="selectAll"
  416. @select="select"
  417. :row-key="getRowKeys"
  418. :header-cell-style="{
  419. 'background-color': '#eee',
  420. padding: '8px',
  421. color: '#333',
  422. }"
  423. >
  424. <el-table-column
  425. align="center"
  426. type="selection"
  427. width="55"
  428. header-align="center"
  429. :selectable="checkboxT"
  430. :reserve-selection="true"
  431. >
  432. </el-table-column>
  433. <template v-for="(item, index) in tableSet">
  434. <el-table-column
  435. v-if="item.scope !== 'inputs'"
  436. :width="item.width"
  437. :key="index"
  438. :label="item.label"
  439. align="center"
  440. :show-overflow-tooltip="true"
  441. header-align="center"
  442. >
  443. <template slot-scope="scope">
  444. <span v-if="item.scope === 'types'">{{
  445. scope.row[item.prop] === 1
  446. ? "录播"
  447. : scope.row[item.prop] === 2
  448. ? "直播"
  449. : scope.row[item.prop] === 3
  450. ? "回放"
  451. : "未知"
  452. }}</span>
  453. <span v-else-if="item.scope === 'isOptions'">
  454. <span v-for="(items, indexs) in item.options" :key="indexs">
  455. <span v-if="scope.row[item.prop] == items.value">{{
  456. items.label
  457. }}</span>
  458. </span>
  459. </span>
  460. <span v-else-if="item.scope === 'Status'">
  461. {{
  462. scope.row[item.prop] === 1
  463. ? "发布"
  464. : scope.row[item.prop] === 0
  465. ? "未发布"
  466. : "未知"
  467. }}
  468. </span>
  469. <span v-else>{{ scope.row[item.prop] }}</span></template
  470. >
  471. </el-table-column></template
  472. >
  473. </el-table>
  474. <pagination
  475. :total="total"
  476. :pageSize="formData.pageSize"
  477. :currentPage="formData.pageNum"
  478. @handleSizeChange="handleSizeChange"
  479. @handleCurrentChange="handleCurrentChange"
  480. />
  481. <span slot="footer" class="dialog-footer">
  482. <el-button @click="dialogVisible = false">取 消</el-button>
  483. <el-button
  484. type="primary"
  485. :disabled="activeLists.length === 0"
  486. @click="submitForm"
  487. >确 定</el-button
  488. >
  489. </span>
  490. </el-dialog>
  491. <batch-import-dialoga
  492. :dialogVisible.sync="dialogDR"
  493. temUrl="/oss/images/file/20220617/1655453121157.xlsx"
  494. apiKey="CoursemoduleimportData"
  495. checkKey="inquireCourseListchapter"
  496. :param="{ businessJson: JSON.stringify(newSujectApis) }"
  497. @success="success"
  498. ></batch-import-dialoga>
  499. <addChapter ref="addChapter" @backData="backData" />
  500. </div>
  501. </template>
  502. <script>
  503. import { mapGetters } from "vuex";
  504. import * as baseUrls from "@/utils/request.js";
  505. import addChapter from "../addChapter.vue";
  506. import batchImportDialoga from "@/components/Comon/batchImportDialog.vue";
  507. import searchBoxNew from "@/components/searchBoxNew";
  508. import pagination from "@/components/pagination";
  509. export default {
  510. components: { searchBoxNew, pagination, addChapter, batchImportDialoga },
  511. name: "ModuleManagementAdd",
  512. data() {
  513. return {
  514. certificateList: [],
  515. certificateTpList: [],
  516. disabledBtn: false,
  517. isIndeterminate: false,
  518. checkAll: false,
  519. // 弹窗数据
  520. changeHeight: true,
  521. bfImg: "oss/images/avatar/20211013/1634097664410_1397766697",
  522. listData: {
  523. commonSign: 0,
  524. publishStatus: 1,
  525. recordingUrl: "",
  526. liveUrl: "",
  527. viewSign:1,
  528. coverUrl: "oss/images/avatar/20211013/1634097664410_1397766697",
  529. },
  530. eduTypeOptions: [], //教育类型数据
  531. projectTypeOptions: [], //项目类型数据
  532. courTypeOptions: [], //业务层次数据
  533. newCourTypeOptions: [], //当前业务层次数据
  534. sujectOption: [], //科目数据
  535. newSujectOption: [], //当前科目数据数据
  536. eduType: "", //当前选中教育类型
  537. courType: "", //当前选中业务层次
  538. sujectApis: [], //当前存在的科目
  539. newSujectApis: [],
  540. sujectArray: [], //选中的科目
  541. //表单验证
  542. rules: {
  543. prefixName: [
  544. { required: false, message: "请输入标题前缀", trigger: "blur" },
  545. ],
  546. moduleName: [
  547. { required: true, message: "请输入节标题", trigger: "blur" },
  548. ],
  549. // liveDuration: [
  550. // { required: true, message: "节时长不能为空" },
  551. // { type: "number", message: "节时长必须为数字值" },
  552. // ],
  553. commonSign: [
  554. { required: true, message: "请选择公共标识", trigger: "change" },
  555. ],
  556. viewSign: [
  557. { required: true, message: "请选择视频类型", trigger: "change" },
  558. ],
  559. publishStatus: [
  560. { required: true, message: "请选择是否发布", trigger: "change" },
  561. ],
  562. },
  563. numberAll: 0, //节总数
  564. minTimeAll: 0, //总时长
  565. tableSet: [
  566. { label: "排序", prop: "sort", scope: "inputs", width: "100" },
  567. { label: "章编码", prop: "code", width: "120" },
  568. { label: "标题前缀", prop: "prefixName", width: "180" },
  569. { label: "章标题", prop: "name" },
  570. {
  571. label: "视频类型",
  572. prop: "viewSign",
  573. scope: "isOptions",
  574. options: [
  575. { label: "保利威", value: 1 },
  576. { label: "腾讯", value: 2 },
  577. ],
  578. width: "120",
  579. },
  580. { label: "节数量", prop: "sectionNum", width: "120" },
  581. {
  582. label: "发布状态",
  583. prop: "publishStatus",
  584. scope: "Status",
  585. width: "120",
  586. },
  587. ],
  588. tableData: [],
  589. dialogVisible: false,
  590. boxtableData: [],
  591. formList: [
  592. {
  593. prop: "educationTypeId",
  594. placeholder: "教育类型",
  595. scope: "educationType",
  596. },
  597. {
  598. prop: "businessId",
  599. placeholder: "业务层次",
  600. scope: "businessLevel",
  601. edu: "educationTypeId",
  602. },
  603. {
  604. prop: "subjectId",
  605. placeholder: "科目",
  606. scope: "sujectType",
  607. edu: "educationTypeId",
  608. },
  609. // {
  610. // prop: "publishStatus",
  611. // placeholder: "发布状态",
  612. // scope: "select",
  613. // options: [
  614. // {
  615. // label: "已发布",
  616. // value: 1,
  617. // },
  618. // {
  619. // label: "未发布",
  620. // value: 0,
  621. // },
  622. // ],
  623. // },
  624. {
  625. prop: "key",
  626. placeholder: "请输入章标题/章编码/标题前缀",
  627. },
  628. ],
  629. total: 0, //一共多少条
  630. formData: {
  631. status: 1,
  632. pageSize: 10,
  633. pageNum: 1,
  634. },
  635. disCheckList: [], //已选转禁用复选列表
  636. activeLists: [],
  637. localData: [],
  638. dialogDR: false,
  639. loading: false,
  640. };
  641. },
  642. computed: { ...mapGetters(["certificate"]) },
  643. watch: {
  644. sujectApis: {
  645. immediate: true,
  646. handler(newName, oldName) {
  647. this.changeTypes();
  648. },
  649. },
  650. "listData.certificateTypeId"(val) {
  651. this.$set(this.listData, "certificateId", "");
  652. if (val) {
  653. this.$api
  654. .inquireBaseCertificatecommon({ status: 1, certificateTypeId: val })
  655. .then((res) => {
  656. this.certificateList = res.rows;
  657. });
  658. } else {
  659. this.certificateList = [];
  660. }
  661. },
  662. "listData.certificateId"(val) {
  663. this.$set(this.listData, "certificateTpId", "");
  664. if (val) {
  665. this.$api
  666. .inquireBaseCertificatetp({ status: 1, certificateId: val })
  667. .then((res) => {
  668. this.certificateTpList = res.rows;
  669. });
  670. } else {
  671. this.certificateTpList = [];
  672. }
  673. },
  674. },
  675. mounted() {
  676. this.localData = this.$methodsTools.getBusinessList();
  677. this.getDict();
  678. // this.search();
  679. },
  680. activated() {
  681. if (this.$store.getters.modulePage) {
  682. this.$api
  683. .obtainCoursechapter(this.$store.getters.modulePage.id)
  684. .then((res) => {
  685. const FIND = this.tableData.findIndex((item) => {
  686. return item.chapterId == this.$store.getters.modulePage.id;
  687. });
  688. if (FIND !== -1) {
  689. res.data.sort = this.tableData[FIND].sort;
  690. this.tableData.splice(FIND, 1, res.data);
  691. }
  692. this.$store.dispatch("changemodulePage", null);
  693. });
  694. }
  695. },
  696. methods: {
  697. dialogDRFunc() {
  698. if (!this.newSujectApis.length) {
  699. this.$message.error("请添加科目");
  700. return;
  701. }
  702. this.dialogDR = true;
  703. },
  704. success(data) {
  705. this.activeLists = data;
  706. this.submitForm();
  707. },
  708. jumpChapter(v) {
  709. const jump = () => {
  710. this.$store.dispatch("changemodulePage", {
  711. name: "moduleManagementAdd",
  712. id: v.chapterId,
  713. });
  714. this.$router.push({
  715. path: "chapterEdit",
  716. query: {
  717. id: v.chapterId,
  718. },
  719. });
  720. };
  721. const statusPage = this.$store.state.tagsView.visitedViews.some(
  722. (item) => {
  723. return item.name == "ChapterEdit";
  724. }
  725. );
  726. if (statusPage) {
  727. this.$store
  728. .dispatch("tagsView/delCachedView", {
  729. name: "ChapterEdit",
  730. })
  731. .then((res) => {
  732. jump();
  733. });
  734. } else {
  735. jump();
  736. }
  737. },
  738. /**
  739. * 打开添加章组件
  740. */
  741. addChapter() {
  742. if (!this.newSujectApis.length) {
  743. this.$message.warning("请选择科目");
  744. return;
  745. }
  746. this.$refs.addChapter.openBoxs(this.newSujectApis);
  747. },
  748. /**
  749. * 添加章-返回数据
  750. */
  751. backData(v) {
  752. this.$api.inquireCourseListchapter({ chapterIds: v }).then((res) => {
  753. this.activeLists = res.rows;
  754. this.submitForm();
  755. });
  756. },
  757. unTime(val) {
  758. let a = `${val.businessId}-${val.subjectId}`;
  759. if (this.sujectApis.includes(a)) {
  760. this.sujectApis.splice(this.sujectApis.indexOf(a), 1);
  761. } else {
  762. this.sujectApis.push(a);
  763. }
  764. },
  765. changeSty(val) {
  766. var arr = "";
  767. this.sujectApis.forEach((item) => {
  768. let arr1 = item.split("-").map(Number);
  769. if (val.businessId == arr1[0] && val.subjectId == arr1[1]) {
  770. arr = "activeStyIcons";
  771. }
  772. });
  773. return arr;
  774. },
  775. handleCheckedCitiesChange() {
  776. let nid = this.newSujectOption.map((item) => {
  777. return item.newId;
  778. });
  779. this.checkAll = this.sujectArray.length === nid.length;
  780. this.isIndeterminate =
  781. this.sujectArray.length > 0 && this.sujectArray.length < nid.length;
  782. },
  783. setFunc(arr) {
  784. var arrays = [];
  785. for (let i = 0; i < arr.length; i++) {
  786. if (!arrays.includes(arr[i])) {
  787. arrays.push(arr[i]);
  788. }
  789. }
  790. return arrays;
  791. },
  792. handleCheckAllChange(val) {
  793. if (val) {
  794. let nid = this.newSujectOption.map((item) => {
  795. return item.newId;
  796. });
  797. let arrays = this.sujectArray.concat(nid);
  798. this.sujectArray = this.setFunc(arrays);
  799. this.isIndeterminate = false;
  800. } else {
  801. let nid = this.newSujectOption.map((item) => {
  802. return item.newId;
  803. });
  804. let newArr = [];
  805. this.sujectArray.forEach((item) => {
  806. if (!nid.includes(item)) {
  807. newArr.push(item);
  808. }
  809. });
  810. this.sujectArray = newArr;
  811. this.isIndeterminate = false;
  812. }
  813. },
  814. getMessage() {
  815. if (!this.courType) {
  816. this.$message.warning("请先选择业务层级");
  817. }
  818. },
  819. openBoxs() {
  820. var self = this;
  821. this.$api
  822. .inquireCourseListchapter({
  823. status: 1,
  824. pageNum: 1,
  825. pageSize: 10,
  826. publishStatus: 1,
  827. })
  828. .then((res) => {
  829. var aList = [];
  830. this.tableData.map((item) => {
  831. aList.push(item.chapterId);
  832. });
  833. this.disCheckList = aList;
  834. this.boxtableData = res.rows;
  835. this.total = res.total;
  836. this.dialogVisible = true;
  837. this.$nextTick(function () {
  838. self.$refs.multipleTable.clearSelection();
  839. });
  840. });
  841. },
  842. getInfosList() {
  843. this.$api
  844. .inquireCourseListmodulechapter({ chapterId: this.$route.query.id })
  845. .then((result) => {
  846. // this.numberAll = result.total;
  847. // this.minTimeAll = result.timeTotal;
  848. this.tableData = result.data;
  849. });
  850. },
  851. init() {
  852. this.getInfos(2);
  853. },
  854. getInfos(int) {
  855. if (int === 1) {
  856. this.formData.pageNum = 1;
  857. }
  858. if (int === 2) {
  859. this.formData = {
  860. status: 1,
  861. pageSize: 10,
  862. pageNum: 1,
  863. publishStatus: 1,
  864. };
  865. }
  866. this.$api.inquireCourseListchapter(this.formData).then((res) => {
  867. this.boxtableData = res.rows;
  868. this.total = res.total;
  869. });
  870. },
  871. search() {
  872. this.$api.obtainCoursemodule(this.$route.query.id).then((res) => {
  873. this.bfImg = res.data.coverUrl;
  874. this.listData = res.data;
  875. this.$api
  876. .obtainCoursechapterbusiness(this.$route.query.id)
  877. .then((result) => {
  878. var arrays = [];
  879. result.data.map((item) => {
  880. arrays.push(item.businessId + "-" + item.subjectId);
  881. });
  882. this.sujectApis = arrays;
  883. this.getInfosList();
  884. });
  885. });
  886. },
  887. clearImgs() {
  888. this.listData.coverUrl = "";
  889. },
  890. changeTypes() {
  891. var self = this;
  892. var arrays = [];
  893. this.sujectApis.map((item, index) => {
  894. this.courTypeOptions.map((items) => {
  895. if (items.id === item.split("-").map(Number)[0]) {
  896. var obj = {
  897. educationTypeId: items.educationId,
  898. educationName: items.educationName,
  899. projectId: items.projectId,
  900. projectName: items.projectName,
  901. businessId: items.id,
  902. businessName: items.businessName,
  903. };
  904. self.sujectOption.map((i) => {
  905. if (
  906. i.id === item.split("-").map(Number)[1] &&
  907. i.courseArrays.indexOf(items.projectId) !== -1
  908. ) {
  909. obj.subjectName = i.subjectName;
  910. obj.subjectId = i.id;
  911. }
  912. });
  913. arrays.push(obj);
  914. }
  915. });
  916. });
  917. this.newSujectApis = arrays;
  918. },
  919. changeType() {
  920. this.changeHeight = !this.changeHeight;
  921. },
  922. submitSujectArray() {
  923. var self = this;
  924. this.sujectApis = this.sujectApis.filter((item, index) => {
  925. return item.split("-").map(Number)[0] !== Number(self.courType);
  926. });
  927. for (let i = 0; i < this.sujectArray.length; i++) {
  928. this.sujectApis.push(this.sujectArray[i]);
  929. }
  930. this.$refs.popovers.doClose();
  931. },
  932. showHandle() {
  933. var array = [];
  934. for (let i = 0; i < this.sujectApis.length; i++) {
  935. if (
  936. this.sujectApis[i].split("-").map(Number)[0] === Number(this.courType)
  937. ) {
  938. array.push(this.sujectApis[i]);
  939. }
  940. }
  941. this.sujectArray = array;
  942. if (!this.newSujectOption.length) {
  943. this.$message.warning("该业务层次暂无关联科目");
  944. this.$refs.popovers.doClose();
  945. return;
  946. }
  947. this.newSujectOption.map((item) => {
  948. item.newId = this.courType + "-" + item.id;
  949. });
  950. this.handleCheckedCitiesChange();
  951. },
  952. hideHandle() {},
  953. getDict() {
  954. this.$api.inquireCourseEducationType({ status: 1 }).then((res) => {
  955. this.eduTypeOptions = res.rows;
  956. });
  957. this.$api.inquireCourseProjectType({ status: 1 }).then((res) => {
  958. this.projectTypeOptions = res.rows;
  959. });
  960. this.$api.inquirebusinessList({ status: 1 }).then((res) => {
  961. this.courTypeOptions = res.rows;
  962. this.newCourTypeOptions = res.rows;
  963. });
  964. this.$api.inquireCourseSubject({ status: 1 }).then((res) => {
  965. res.rows.map((item, index) => {
  966. var array = [];
  967. item.courseProjectTypes.map((items, indexs) => {
  968. array.push(items.id);
  969. });
  970. item.courseArrays = array;
  971. });
  972. this.sujectOption = res.rows;
  973. });
  974. },
  975. changeEduType() {
  976. if (!(this.courType === undefined || this.courType === "")) {
  977. this.courType = "";
  978. }
  979. var arrays = [];
  980. this.courTypeOptions.map((item) => {
  981. if (item.educationId === this.eduType) {
  982. arrays.push(item);
  983. }
  984. });
  985. this.newCourTypeOptions = arrays;
  986. },
  987. changecourseType() {
  988. this.newCourTypeOptions.map((item, index) => {
  989. if (item.id === this.courType) {
  990. this.eduType = item.educationId;
  991. var array = [];
  992. this.sujectOption.map((items, indexs) => {
  993. if (items.courseArrays.indexOf(item.projectId) !== -1) {
  994. array.push(items);
  995. }
  996. });
  997. this.newSujectOption = array;
  998. }
  999. });
  1000. var arrays = [];
  1001. this.courTypeOptions.map((item) => {
  1002. if (item.educationId === this.eduType) {
  1003. arrays.push(item);
  1004. }
  1005. });
  1006. this.newCourTypeOptions = arrays;
  1007. this.$refs.popovers.doClose();
  1008. },
  1009. submit(formName) {
  1010. this.$refs[formName].validate((valid) => {
  1011. if (valid) {
  1012. if (!this.newSujectApis.length) {
  1013. this.$message.error("请选择适用业务层级");
  1014. return;
  1015. }
  1016. // if (
  1017. // this.listData.coverUrl === "" ||
  1018. // this.listData.coverUrl === null ||
  1019. // this.listData.coverUrl === undefined
  1020. // ) {
  1021. // this.$message.error("请上传节封面");
  1022. // return false;
  1023. // }
  1024. for (let i = 0; i < this.tableData.length; i++) {
  1025. if (!this.tableData[i].sort && this.tableData[i].sort !== 0) {
  1026. this.$message.warning(`管理章第${i + 1}条请输入排序`);
  1027. return;
  1028. }
  1029. if(this.tableData[i].viewSign != this.listData.viewSign){
  1030. this.$message.warning("请保持模块视频类型与章视频类型保持一致")
  1031. return
  1032. }
  1033. }
  1034. let arr = this.tableData.map((items) => {
  1035. return items.sort;
  1036. });
  1037. if (new Set(arr).size != arr.length) {
  1038. this.$message.warning("排序不允许有重复值");
  1039. return;
  1040. }
  1041. this.rulesTableSumbit();
  1042. } else {
  1043. return false;
  1044. }
  1045. });
  1046. },
  1047. async rulesTableSumbit() {
  1048. this.disabledBtn = true;
  1049. var chapterIdList = [];
  1050. this.tableData.map((item) => {
  1051. chapterIdList.push({
  1052. chapterId: item.chapterId,
  1053. sort: Number(item.sort),
  1054. });
  1055. });
  1056. var dataInfos = {
  1057. status: 1,
  1058. viewSign:this.listData.viewSign,
  1059. businessList: this.newSujectApis,
  1060. chapterIdList: chapterIdList,
  1061. coverUrl: this.listData.coverUrl,
  1062. moduleName: this.listData.moduleName,
  1063. prefixName: this.listData.prefixName,
  1064. publishStatus: this.listData.publishStatus,
  1065. commonSign: this.listData.commonSign,
  1066. certificateTypeId: this.listData.certificateTypeId,
  1067. certificateId: this.listData.certificateId,
  1068. certificateTpId: this.listData.certificateTpId,
  1069. };
  1070. this.$api
  1071. .addCoursemodule(dataInfos)
  1072. .then((res) => {
  1073. this.$methodsTools.cacheBusinessList(this.newSujectApis);
  1074. this.$message.success("新增成功");
  1075. setTimeout(() => {
  1076. this.$store
  1077. .dispatch("tagsView/exitView", this.$route)
  1078. .then((res) => {
  1079. this.$router.push({
  1080. path: "moduleManagement",
  1081. });
  1082. });
  1083. }, 500);
  1084. })
  1085. .catch(() => {
  1086. this.disabledBtn = false;
  1087. });
  1088. },
  1089. backPage() {
  1090. this.$store.dispatch("tagsView/delView", this.$route).then((res) => {
  1091. this.$router.push({
  1092. path: "moduleManagement",
  1093. });
  1094. });
  1095. },
  1096. closeType(index) {
  1097. this.sujectApis.splice(index, 1);
  1098. },
  1099. getImgFile() {
  1100. var self = this;
  1101. var file = self.$refs.file.files[0];
  1102. if (file === undefined) {
  1103. self.$set(self.listData, "coverUrl", "");
  1104. return;
  1105. }
  1106. if (file.size > 0.3 * 1024 * 1024) {
  1107. self.$message.error("图片不得大于300kb");
  1108. return;
  1109. }
  1110. var type = self.$refs.file.value.toLowerCase().split(".").splice(-1);
  1111. if (
  1112. type[0] != "jpg" &&
  1113. type[0] != "png" &&
  1114. type[0] != "jpeg" &&
  1115. type[0] != "gif"
  1116. ) {
  1117. self.$message.error("上传格式需为:.jpg/.png/.jpeg/gif");
  1118. self.$refs.file.value = "";
  1119. return;
  1120. }
  1121. this.$upload.upload(file, 0).then((res) => {
  1122. self.listData.coverUrl = res;
  1123. });
  1124. },
  1125. handleSizeChange(v) {
  1126. this.formData.pageSize = v;
  1127. this.formData.pageNum = 1;
  1128. this.getInfos();
  1129. },
  1130. handleCurrentChange(v) {
  1131. this.formData.pageNum = v;
  1132. this.getInfos();
  1133. },
  1134. selectAll(value) {
  1135. this.activeLists = value;
  1136. },
  1137. select(value) {
  1138. this.activeLists = value;
  1139. },
  1140. checkboxT(row, index) {
  1141. if (this.disCheckList.indexOf(row.chapterId) !== -1) {
  1142. return false;
  1143. } else {
  1144. return true;
  1145. }
  1146. },
  1147. getRowKeys(row) {
  1148. return row.chapterId;
  1149. },
  1150. /**
  1151. *
  1152. * @remards 合并且排列节列表数据
  1153. */
  1154. submitForm() {
  1155. if (this.activeLists.length === 0) {
  1156. this.dialogVisible = false;
  1157. return;
  1158. }
  1159. if (this.tableData.length) {
  1160. let maxIndex = 0;
  1161. this.tableData.forEach((item) => {
  1162. if (item.sort > maxIndex) {
  1163. maxIndex = item.sort;
  1164. }
  1165. });
  1166. this.activeLists.forEach((item, index) => {
  1167. item.sort = maxIndex + index + 1;
  1168. });
  1169. } else {
  1170. this.activeLists.forEach((item, index) => {
  1171. item.sort = index + 1;
  1172. });
  1173. }
  1174. this.tableData = this.tableData.concat(this.activeLists);
  1175. this.dialogVisible = false;
  1176. this.activeLists = [];
  1177. },
  1178. delList(item) {
  1179. this.tableData.map((items, indexs) => {
  1180. if (items.chapterId === item.chapterId) {
  1181. this.tableData.splice(indexs, 1);
  1182. this.$message.success("删除成功");
  1183. }
  1184. });
  1185. },
  1186. closedFunc() {
  1187. this.activeLists = [];
  1188. },
  1189. },
  1190. };
  1191. </script>
  1192. <style lang="less" scoped>
  1193. .boxWidth {
  1194. width: 800px;
  1195. }
  1196. .numInputs {
  1197. width: 150px;
  1198. }
  1199. .checkboxSty {
  1200. max-height: 210px;
  1201. overflow: auto;
  1202. display: flex;
  1203. flex-direction: column;
  1204. }
  1205. .listBoxStys {
  1206. flex-shrink: 0;
  1207. padding: 0px 10px;
  1208. border-radius: 8px;
  1209. border: 1px solid #eee;
  1210. margin-right: 10px;
  1211. margin-bottom: 6px;
  1212. }
  1213. .closeIcons {
  1214. color: red;
  1215. cursor: pointer;
  1216. margin-left: 6px;
  1217. }
  1218. .ach {
  1219. display: flex;
  1220. align-items: center;
  1221. overflow: hidden;
  1222. }
  1223. .clh {
  1224. display: flex;
  1225. align-items: center;
  1226. flex-wrap: wrap;
  1227. }
  1228. .imgBoxins {
  1229. width: 375px;
  1230. height: 220px;
  1231. text-align: center;
  1232. img {
  1233. height: 100%;
  1234. }
  1235. }
  1236. .iconStsz {
  1237. font-size: 40px;
  1238. color: #67c23a;
  1239. cursor: pointer;
  1240. }
  1241. .dis_plays {
  1242. display: flex;
  1243. align-items: center;
  1244. justify-content: space-between;
  1245. margin-bottom: 10px;
  1246. }
  1247. .comInputsty {
  1248. width: 50px;
  1249. height: 24px;
  1250. text-align: center;
  1251. border: none;
  1252. }
  1253. /deep/.el-button {
  1254. border-radius: 8px;
  1255. }
  1256. /deep/.el-dialog {
  1257. border-radius: 8px;
  1258. .el-dialog__header {
  1259. padding: 0;
  1260. .hearders {
  1261. height: 40px;
  1262. display: flex;
  1263. align-items: center;
  1264. justify-content: space-between;
  1265. padding: 0px 18px 0px 20px;
  1266. border-bottom: 1px solid #e2e2e2;
  1267. .leftTitle {
  1268. font-size: 14px;
  1269. font-weight: bold;
  1270. color: #2f4378;
  1271. }
  1272. .rightBoxs {
  1273. display: flex;
  1274. align-items: center;
  1275. img {
  1276. width: 14px;
  1277. height: 14px;
  1278. margin-left: 13px;
  1279. cursor: pointer;
  1280. }
  1281. }
  1282. }
  1283. }
  1284. .el-dialog__footer {
  1285. padding: 0;
  1286. .dialog-footer {
  1287. padding: 0px 40px;
  1288. height: 70px;
  1289. border-top: 1px solid #e2e2e2;
  1290. display: flex;
  1291. align-items: center;
  1292. justify-content: flex-end;
  1293. }
  1294. }
  1295. }
  1296. .imgBox {
  1297. width: 100%;
  1298. // height: 210px;
  1299. border: 1px solid #e2e2e2;
  1300. border-radius: 8px;
  1301. padding: 8px 8px 3px;
  1302. display: flex;
  1303. flex-direction: column;
  1304. align-items: center;
  1305. .imgLabel {
  1306. flex: 1;
  1307. width: 100%;
  1308. border: 1px dotted #e2e2e2;
  1309. color: #999;
  1310. font-size: 14px;
  1311. cursor: pointer;
  1312. border-radius: 8px;
  1313. .msPhoto {
  1314. display: flex;
  1315. justify-content: center;
  1316. align-items: center;
  1317. max-width: 100%;
  1318. max-height: 270px;
  1319. img {
  1320. max-width: 100%;
  1321. max-height: 270px;
  1322. }
  1323. }
  1324. .imgbbx {
  1325. display: flex;
  1326. flex-direction: column;
  1327. align-items: center;
  1328. justify-content: center;
  1329. width: 100%;
  1330. height: 100%;
  1331. i {
  1332. font-weight: bold;
  1333. margin: 14px 0;
  1334. font-size: 24px;
  1335. }
  1336. }
  1337. }
  1338. p {
  1339. margin: 5px 0px;
  1340. }
  1341. }
  1342. .dis_play_sty {
  1343. display: flex;
  1344. align-items: center;
  1345. }
  1346. </style>