edit.vue 13KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401
  1. <template>
  2. <div class="subPage">
  3. <form class="mainForm">
  4. <ul>
  5. <li class="flex-h">
  6. <span>对应案场:<em>*</em></span>
  7. <div class="flex-item">
  8. <div style="width:50%">
  9. <el-select :disabled="id && id !== ''" v-model="CaseId" placeholder="请选择" @change="caseChange">
  10. <el-option
  11. key="all"
  12. label="全部案场"
  13. value="all">
  14. </el-option>
  15. <el-option
  16. v-for="item in caseList"
  17. :key="item.CaseId"
  18. :label="item.CaseName"
  19. :value="item.CaseId">
  20. </el-option>
  21. </el-select>
  22. </div>
  23. </div>
  24. </li>
  25. <li class="flex-h">
  26. <span>名称:<em>*</em></span>
  27. <div class="flex-item">
  28. <div style="width:50%">
  29. <el-input
  30. placeholder="请输入名称"
  31. v-model="detail.Name"
  32. clearable>
  33. </el-input>
  34. </div>
  35. </div>
  36. </li>
  37. <li class="flex-h">
  38. <span>标题:</span>
  39. <div class="flex-item">
  40. <div style="width:50%">
  41. <el-input
  42. placeholder="请输入标题"
  43. v-model="detail.Title"
  44. clearable>
  45. </el-input>
  46. </div>
  47. </div>
  48. </li>
  49. <li class="flex-h">
  50. <span>图片:<em>*</em></span>
  51. <div class="flex-item">
  52. <el-upload
  53. class="avatar-uploader"
  54. action='string'
  55. :http-request="toolClass.upload"
  56. :show-file-list="false"
  57. :on-success="handleImgSuccess">
  58. <img v-if="imgShow" :src="imgShow" class="avatar">
  59. <i v-else class="el-icon-plus avatar-uploader-icon"></i>
  60. </el-upload>
  61. </div>
  62. </li>
  63. <li class="flex-h">
  64. <span>详细图片:<em>*</em></span>
  65. <div class="flex-item">
  66. <el-upload
  67. class="avatar-uploader"
  68. action='string'
  69. :http-request="toolClass.upload"
  70. :show-file-list="false"
  71. :on-success="handleDetailImgSuccess">
  72. <img v-if="detailImgShow" :src="detailImgShow" class="avatar">
  73. <i v-else class="el-icon-plus avatar-uploader-icon"></i>
  74. </el-upload>
  75. </div>
  76. </li>
  77. <li class="flex-h">
  78. <span>专题简介:<em>*</em></span>
  79. <div class="flex-item">
  80. <div style="width:50%">
  81. <el-input
  82. placeholder="请输入专题简介"
  83. v-model="detail.DetailContent"
  84. type='textarea'
  85. :autosize="{ minRows: 3, maxRows: 5}"
  86. clearable>
  87. </el-input>
  88. </div>
  89. </div>
  90. </li>
  91. <li class="flex-h">
  92. <span>展示课程:<em>*</em></span>
  93. <div class="flex-item">
  94. <div style="width:50%" class="radio">
  95. <el-radio v-model="detail.IsAllCourse" :label='1' >全部课程</el-radio>
  96. <el-radio v-model="detail.IsAllCourse" :label='0' >指定课程</el-radio>
  97. </div>
  98. </div>
  99. </li>
  100. <li class="flex-h" v-if="detail.IsAllCourse === 0">
  101. <el-table
  102. :data="detail.Courses"
  103. stripe
  104. style="width: 100%">
  105. <el-table-column
  106. prop="CourseName"
  107. label="课程名称">
  108. </el-table-column>
  109. <el-table-column
  110. prop="BeginDate"
  111. label="课程开始时间">
  112. <template slot-scope="scope">
  113. <label>{{toolClass.dateFormat(scope.row.BeginDate,'yyyy-MM-dd')}}</label>
  114. </template>
  115. </el-table-column>
  116. <el-table-column
  117. prop="EndDate"
  118. label="课程结束时间">
  119. <template slot-scope="scope">
  120. <label>{{toolClass.dateFormat(scope.row.EndDate,'yyyy-MM-dd')}}</label>
  121. </template>
  122. </el-table-column>
  123. <el-table-column label="操作" width="450">
  124. <template slot-scope="scope">
  125. <el-button
  126. size="mini"
  127. type="danger"
  128. @click="deleteItem(scope.row)">删除</el-button>
  129. </template>
  130. </el-table-column>
  131. </el-table>
  132. <el-button type="primary" size="mini" @click="coursesShow">新增</el-button>
  133. </li>
  134. <li class="flex-h">
  135. <span>是否前台展示:<em>*</em></span>
  136. <div class="flex-item">
  137. <div style="width:50%" class="radio">
  138. <el-radio v-model="detail.Status" :label='1' ></el-radio>
  139. <el-radio v-model="detail.Status" :label='0' ></el-radio>
  140. </div>
  141. </div>
  142. </li>
  143. <li style="text-align:center">
  144. <el-button type="primary" size="mini" @click="submit">保存</el-button>
  145. <el-button type="danger" size="mini" @click="cancel">取消</el-button>
  146. </li>
  147. </ul>
  148. </form>
  149. <el-dialog
  150. title="选择课程"
  151. :visible.sync="selCourseVisible"
  152. width="500px"
  153. center>
  154. <div>
  155. <el-table
  156. ref="courseTable"
  157. :data="coursesList"
  158. tooltip-effect="dark"
  159. stripe
  160. @selection-change="handleSelectionChange"
  161. style="width: 100%">
  162. <el-table-column
  163. type="selection"
  164. width="55">
  165. </el-table-column>
  166. <el-table-column
  167. prop="CourseName"
  168. label="课程名称">
  169. </el-table-column>
  170. <el-table-column
  171. prop="BeginDate"
  172. label="课程开始时间">
  173. <template slot-scope="scope">
  174. <label>{{toolClass.dateFormat(scope.row.BeginDate,'yyyy-MM-dd')}}</label>
  175. </template>
  176. </el-table-column>
  177. <el-table-column
  178. prop="EndDate"
  179. label="课程结束时间">
  180. <template slot-scope="scope">
  181. <label>{{toolClass.dateFormat(scope.row.EndDate,'yyyy-MM-dd')}}</label>
  182. </template>
  183. </el-table-column>
  184. </el-table>
  185. </div>
  186. <span slot="footer" class="dialog-footer">
  187. <el-button @click="selCourseVisible = false">取 消</el-button>
  188. <el-button type="primary" @click="addCourseOk">确 定</el-button>
  189. </span>
  190. </el-dialog>
  191. </div>
  192. </template>
  193. <script>
  194. import { createNamespacedHelpers, mapState } from 'vuex'
  195. const { mapState: mapCaseState, mapActions: mapCaseActions } = createNamespacedHelpers('cmscase')
  196. const { mapState: mapCourseState, mapActions: mapCourseActions } = createNamespacedHelpers('course')
  197. export default {
  198. name: '',
  199. data () {
  200. return {
  201. id: '',
  202. limit: 1,
  203. // imgs: null,
  204. // detailimgs: null,
  205. img: '',
  206. detailimg: '',
  207. selCourseVisible: false,
  208. selCourseList: [],
  209. }
  210. },
  211. components: {},
  212. computed: {
  213. ...mapState({
  214. caseList: x => x.app.cases.list,
  215. defaultCaseId: x => x.app.cases.default,
  216. OrgId: x => x.app.user.OrgId
  217. }),
  218. ...mapCaseState({
  219. detail: x => x.caseInfo,
  220. }),
  221. ...mapCourseState({
  222. courses: x => x.courseList,
  223. }),
  224. CaseId: {
  225. get () {
  226. return this.detail.CaseId || this.caseid
  227. },
  228. set (val) {
  229. this.UpdateInfo({ ...this.detail, CaseId: val })
  230. this.getCourse()
  231. }
  232. },
  233. imgShow () {
  234. return this.img || ((this.detail.CmsCaseImgs || []).filter(x => x.ImageType === 'cover')[0] || {}).CaseImageUrl
  235. },
  236. detailImgShow () {
  237. return this.detailimg || ((this.detail.CmsCaseImgs || []).filter(x => x.ImageType === 'detail')[0] || {}).CaseImageUrl
  238. },
  239. coursesList () {
  240. return (this.courses.list || []).map(x => {
  241. return {
  242. CourseId: x.CourseId,
  243. CourseName: x.CourseName,
  244. BeginDate: x.BeginDate,
  245. EndDate: x.BeginDate
  246. }
  247. })
  248. },
  249. },
  250. methods: {
  251. ...mapCaseActions([
  252. 'GetCaseInfo',
  253. 'AddCaseInfo',
  254. 'SetNull',
  255. 'UpdateInfo',
  256. ]),
  257. ...mapCourseActions([
  258. 'GetCourseList',
  259. ]),
  260. caseChange () {
  261. this.selCourseList = []
  262. this.detail.Courses = []
  263. },
  264. checkFn (arr) {
  265. for (var n = 0; n < arr.length; n++) {
  266. if (arr[n].type === 'isNull' && !arr[n].target) {
  267. this.$message({
  268. message: arr[n].errorMsg,
  269. type: 'error'
  270. })
  271. return false
  272. }
  273. }
  274. return true
  275. },
  276. submit () {
  277. var checkOff = this.checkFn([{
  278. target: Boolean(this.CaseId || ''),
  279. errorMsg: '对应案场不能为空',
  280. type: 'isNull'
  281. }, {
  282. target: Boolean(this.detail.Name || ''),
  283. errorMsg: '名称不能为空',
  284. type: 'isNull'
  285. }, {
  286. target: Boolean(this.imgShow || ''),
  287. errorMsg: '图片不能为空',
  288. type: 'isNull'
  289. }, {
  290. target: Boolean(this.detailImgShow || ''),
  291. errorMsg: '详细图片不能为空',
  292. type: 'isNull'
  293. }, {
  294. target: Boolean(this.detail.DetailContent || ''),
  295. errorMsg: '专题简介不能为空',
  296. type: 'isNull'
  297. }, {
  298. target: Boolean(String(this.detail.IsAllCourse) || ''),
  299. errorMsg: '展示课程不能为空',
  300. type: 'isNull'
  301. }, {
  302. target: Boolean(String(this.detail.Status) || ''),
  303. errorMsg: '是否前台展示不能为空',
  304. type: 'isNull'
  305. }])
  306. if (!checkOff) {
  307. return false
  308. }
  309. if (this.detail.IsAllCourse === '0' && !this.detail.Courses.length) {
  310. this.$message({
  311. message: '选择指定课程不能为空',
  312. type: 'error'
  313. })
  314. return false
  315. }
  316. const courseids = (this.detail.Courses || []).map(x => x.CourseId).join(',')
  317. if (this.id === '') {
  318. this.detail.OrgId = this.OrgId
  319. // console.log(JSON.stringify({ ...this.detail, OrgId: this.OrgId, imgs: this.imgShow, detailimgs: this.detailImgShow, courseids }))
  320. this.AddCaseInfo({ ...this.detail, OrgId: this.OrgId, imgs: this.imgShow, detailimgs: this.detailImgShow, courseids }).then((res) => {
  321. this.afterSave()
  322. })
  323. } else {
  324. // console.log(JSON.stringify({ ...this.detail, OrgId: this.OrgId, imgs: this.imgShow, detailimgs: this.detailImgShow, courseids }))
  325. this.AddCaseInfo({ ...this.detail, imgs: this.imgShow, detailimgs: this.detailImgShow, courseids }).then((res) => {
  326. this.afterSave()
  327. })
  328. }
  329. },
  330. afterSave () {
  331. this.$message({
  332. message: '保存成功',
  333. type: 'success',
  334. duration: 1000
  335. })
  336. this.$router.push({ name: 'indexCase' })
  337. },
  338. cancel () {
  339. this.$router.go(-1)
  340. },
  341. getDetail () {
  342. this.GetCaseInfo({ id: this.id })
  343. },
  344. getCourse () {
  345. this.GetCourseList({ caseid: this.CaseId === 'all' ? '' : this.CaseId, page: 1, pagesize: 100, status: 1 })
  346. },
  347. toggleSelection (rows) {
  348. if (rows) {
  349. rows.forEach(row => {
  350. this.$refs.courseTable.toggleRowSelection(row)
  351. })
  352. } else {
  353. this.$refs.courseTable.clearSelection()
  354. }
  355. },
  356. addCourse () {
  357. this.GetCourseList({ caseid: this.CaseId === 'all' ? '' : this.CaseId, page: 1, pagesize: 100, callback: this.coursesShow })
  358. },
  359. coursesShow () {
  360. this.selCourseList = this.detail.Courses || []
  361. this.selCourseVisible = true
  362. setTimeout(() => {
  363. this.toggleSelection(this.coursesList.filter(x => (this.selCourseList || []).filter(y => y.CourseId === x.CourseId).length > 0))
  364. }, 30)
  365. },
  366. handleSelectionChange (val) {
  367. this.selCourseList = val
  368. },
  369. addCourseOk () {
  370. this.UpdateInfo({ ...this.detail, Courses: this.selCourseList })
  371. this.selCourseVisible = false
  372. },
  373. deleteItem (row) {
  374. this.UpdateInfo({ ...this.detail, Courses: this.detail.Courses.filter(x => x.CourseId !== row.CourseId) })
  375. },
  376. handleImgSuccess (res, file) {
  377. this.img = res.result.url
  378. },
  379. handleDetailImgSuccess (res, file) {
  380. this.detailimg = res.result.url
  381. }
  382. },
  383. mounted () {
  384. this.getCourse()
  385. const { id } = this.$route.query
  386. this.id = id
  387. if (id && id !== '') {
  388. this.getDetail()
  389. } else {
  390. this.SetNull()
  391. }
  392. }
  393. }
  394. </script>
  395. <!-- Add "scoped" attribute to limit CSS to this component only -->
  396. <style lang="scss" scoped>
  397. </style>