edit.vue 12KB

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