index.vue 34 KB

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