add.vue 13KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430
  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>
  9. <el-upload
  10. class="avatar-uploader"
  11. action='string'
  12. :http-request="toolClass.upload"
  13. :show-file-list="false"
  14. :on-success="handleAvatarSuccess">
  15. <img v-if="detail.CourseImg" :src="detail.CourseImg" class="avatar">
  16. <i v-else class="el-icon-plus avatar-uploader-icon"></i>
  17. </el-upload>
  18. </div>
  19. </div>
  20. </li>
  21. <li class="flex-h">
  22. <span>课程名称:<em>*</em></span>
  23. <div class="flex-item">
  24. <div style="width: 50%;">
  25. <el-input
  26. placeholder="请输入课程名称"
  27. v-model="detail.CourseName"
  28. clearable
  29. >
  30. </el-input>
  31. </div>
  32. </div>
  33. </li>
  34. <li class="flex-h">
  35. <span>课程类型:<em>*</em></span>
  36. <div class="flex-item">
  37. <div style="width: 50%;">
  38. <el-select v-model="detail.LocationId" placeholder="请选择">
  39. <el-option
  40. v-for="item in location"
  41. :key="item.LocationId"
  42. :label="item.LocationName"
  43. :value="item.LocationId">
  44. </el-option>
  45. </el-select>
  46. </div>
  47. </div>
  48. </li>
  49. <li class="flex-h">
  50. <span>课程价格:<em>*</em></span>
  51. <div class="flex-item">
  52. <div style="width: 200px;">
  53. <el-input
  54. placeholder="请输入课程价格"
  55. v-model="detail.Price"
  56. clearable
  57. >
  58. </el-input>
  59. </div>
  60. </div>
  61. </li>
  62. <li class="flex-h">
  63. <span>案场:<em>*</em></span>
  64. <div class="flex-item">
  65. <div style="width: 50%;">
  66. <el-select v-model="CaseId" placeholder="请选择">
  67. <el-option
  68. v-for="item in cases"
  69. :key="item.CaseId"
  70. :label="item.CaseName"
  71. :value="item.CaseId">
  72. </el-option>
  73. </el-select>
  74. </div>
  75. </div>
  76. </li>
  77. <li class="flex-h">
  78. <span>开课人数:<em>*</em></span>
  79. <div class="flex-item">
  80. <div style="width: 200px;">
  81. <el-input
  82. placeholder="请输入开课人数"
  83. v-model="detail.MaxNum"
  84. clearable
  85. >
  86. </el-input>
  87. </div>
  88. </div>
  89. </li>
  90. <li class="flex-h">
  91. <span>最小开课人数:<em>*</em></span>
  92. <div class="flex-item">
  93. <div style="width: 200px;">
  94. <el-input
  95. placeholder="请输入开课人数"
  96. v-model="detail.MinNum"
  97. clearable
  98. >
  99. </el-input>
  100. </div>
  101. </div>
  102. </li>
  103. <li class="flex-h">
  104. <span>课时数:<em>*</em></span>
  105. <div class="flex-item">
  106. <div style="width: 200px;">
  107. <el-input
  108. placeholder="请输入课时数"
  109. v-model="detail.CourseNum"
  110. clearable
  111. >
  112. </el-input>
  113. </div>
  114. </div>
  115. </li>
  116. <li class="flex-h">
  117. <span>课程时间:<em>*</em></span>
  118. <div class="flex-item">
  119. <div>
  120. <el-date-picker
  121. value-format="yyyy-MM-dd 00:00:00"
  122. v-model="detail.BeginDate"
  123. type="date"
  124. placeholder="选择起始日期">
  125. </el-date-picker>
  126. <span style="line-height:40px;"></span>
  127. <el-date-picker
  128. value-format="yyyy-MM-dd 23:59:59"
  129. v-model="detail.EndDate"
  130. type="date"
  131. placeholder="选择截止日期">
  132. </el-date-picker>
  133. <!-- <el-date-picker
  134. v-model="courseDate"
  135. type="daterange"
  136. align="right"
  137. unlink-panels
  138. range-separator="至"
  139. start-placeholder="开始日期"
  140. end-placeholder="结束日期"
  141. :default-time="['00:00:00', '23:59:59']"
  142. :picker-options="pickerOptions">
  143. </el-date-picker> -->
  144. </div>
  145. </div>
  146. </li>
  147. <li class="flex-h">
  148. <span>课程计划备注:</span>
  149. <div class="flex-item">
  150. <div style="width: 50%;">
  151. <el-input
  152. type="textarea"
  153. autosize
  154. placeholder="请输入备注"
  155. v-model="detail.Remark"
  156. clearable
  157. >
  158. </el-input>
  159. </div>
  160. </div>
  161. </li>
  162. <li class="flex-h">
  163. <span>课程标签:</span>
  164. <div class="flex-item">
  165. <div style="width: 50%;">
  166. <el-select
  167. style="width:100%"
  168. v-model="tags"
  169. multiple
  170. filterable
  171. allow-create
  172. default-first-option
  173. placeholder="请选择课程标签">
  174. <el-option
  175. v-for="item in tagList.list"
  176. :key="item.TagId"
  177. :label="item.TagName"
  178. :value="item.TagId"
  179. :value-key="item.TagId"
  180. >
  181. </el-option>
  182. </el-select>
  183. </div>
  184. </div>
  185. </li>
  186. <li class="flex-h">
  187. <span>课程简介:</span>
  188. <div class="flex-item">
  189. <div style="width: 50%;">
  190. <el-input
  191. type="textarea"
  192. autosize
  193. placeholder="请输入课程简介"
  194. v-model="detail.CourseDesc"
  195. clearable
  196. >
  197. </el-input>
  198. </div>
  199. </div>
  200. </li>
  201. <li class="flex-h">
  202. <span>是否精选课程:<em>*</em></span>
  203. <div class="flex-item">
  204. <div>
  205. <el-radio v-model="detail.IsSelect" :label="1"></el-radio>
  206. <el-radio v-model="detail.IsSelect" :label="0"></el-radio>
  207. </div>
  208. </div>
  209. </li>
  210. <li style="text-align:center">
  211. <el-button type="primary" size="mini" @click="submit">保存</el-button>
  212. <el-button type="danger" size="mini" @click="cancel">取消</el-button>
  213. </li>
  214. </ul>
  215. </form>
  216. </div>
  217. </template>
  218. <script>
  219. import { createNamespacedHelpers, mapState } from 'vuex'
  220. const { mapState: mapCourseState, mapActions: mapCourseActions } = createNamespacedHelpers('course')
  221. const { mapState: mapLocationState, mapActions: mapLocationActions } = createNamespacedHelpers('cms')
  222. const { mapState: mapTagState, mapActions: mapTagActions } = createNamespacedHelpers('coursetag')
  223. export default {
  224. name: '',
  225. data () {
  226. return {
  227. pickerOptions: {
  228. shortcuts: [{
  229. text: '最近一周',
  230. onClick (picker) {
  231. const end = new Date()
  232. const start = new Date()
  233. start.setTime(start.getTime() - 3600 * 1000 * 24 * 7)
  234. picker.$emit('pick', [start, end])
  235. }
  236. }, {
  237. text: '最近一个月',
  238. onClick (picker) {
  239. const end = new Date()
  240. const start = new Date()
  241. start.setTime(start.getTime() - 3600 * 1000 * 24 * 30)
  242. picker.$emit('pick', [start, end])
  243. }
  244. }, {
  245. text: '最近三个月',
  246. onClick (picker) {
  247. const end = new Date()
  248. const start = new Date()
  249. start.setTime(start.getTime() - 3600 * 1000 * 24 * 90)
  250. picker.$emit('pick', [start, end])
  251. }
  252. }]
  253. },
  254. }
  255. },
  256. computed: {
  257. ...mapLocationState({
  258. location: x => x.location
  259. }),
  260. ...mapCourseState({
  261. detail: x => x.courseInfo
  262. }),
  263. ...mapState({
  264. cases: x => x.app.cases.list,
  265. caseid: x => x.app.cases.default,
  266. orgid: x => x.app.user.OrgId,
  267. }),
  268. ...mapTagState({
  269. tagList: x => x.tagList
  270. }),
  271. CaseId: {
  272. get () {
  273. return this.detail.CaseId || this.caseid
  274. },
  275. set (val) {
  276. this.UpdateInfo({ ...this.detail, CaseId: val })
  277. }
  278. },
  279. courseDate: {
  280. get () {
  281. return this.detail.BeginDate && this.detail.EndDate ? [this.detail.BeginDate, this.detail.EndDate] : []
  282. },
  283. set (val) {
  284. this.UpdateInfo({ ...this.detail, BeginDate: val[0], EndDate: val[1] })
  285. },
  286. },
  287. tags: {
  288. get () {
  289. return (this.detail.CourseTags || []).map(x => x.TagId)
  290. },
  291. set (val) {
  292. let v = val.map(x => {
  293. return {
  294. TagId: x,
  295. }
  296. })
  297. this.UpdateInfo({ ...this.detail, CourseTags: v })
  298. }
  299. },
  300. },
  301. components: {},
  302. methods: {
  303. ...mapCourseActions([
  304. 'GetCourseByID',
  305. 'AddCourse',
  306. 'UpdateCourse',
  307. 'UpdateInfo',
  308. ]),
  309. ...mapLocationActions([
  310. 'updateLocationInfo',
  311. ]),
  312. ...mapTagActions([
  313. 'GetCourseTagList',
  314. ]),
  315. handleAvatarSuccess (res, file) {
  316. this.UpdateInfo({ ...this.detail, CourseImg: res.result.url })
  317. },
  318. upLoad (item) {
  319. this.toolClass.upload(item).then((res) => { this.handleAvatarSuccess(res, item.file) })
  320. },
  321. checkFn (arr) {
  322. for (var n = 0; n < arr.length; n++) {
  323. if ((arr[n].type === 'isNull' && arr[n].target === '') || (arr[n].type === 'Array' && arr[n].target.length)) {
  324. this.$message({
  325. message: arr[n].errorMsg,
  326. type: 'error'
  327. })
  328. return false
  329. }
  330. }
  331. return true
  332. },
  333. submit () { // 提交数据
  334. var checkOff = this.checkFn([{
  335. target: (this.detail.CourseImg || ''),
  336. errorMsg: '课程主图不能为空',
  337. type: 'isNull'
  338. }, {
  339. target: (this.detail.CourseName || ''),
  340. errorMsg: '课程名称不能为空',
  341. type: 'isNull'
  342. }, {
  343. target: (this.detail.LocationId || ''),
  344. errorMsg: '课程类型不能为空',
  345. type: 'isNull'
  346. }, {
  347. target: (this.detail.Price || ''),
  348. errorMsg: '课程价格不能为空',
  349. type: 'isNull'
  350. }, {
  351. target: (this.detail.MaxNum || ''),
  352. errorMsg: '开课人数不能为空',
  353. type: 'isNull'
  354. }, {
  355. target: (this.detail.MinNum || ''),
  356. errorMsg: '最小开课人数不能为空',
  357. type: 'isNull'
  358. }, {
  359. target: (this.detail.CourseNum || ''),
  360. errorMsg: '课时数不能为空',
  361. type: 'isNull'
  362. }, {
  363. target: (this.detail.BeginDate || ''),
  364. errorMsg: '起始日期不能为空',
  365. type: 'isNull'
  366. }, {
  367. target: (this.detail.EndDate || ''),
  368. errorMsg: '截止日期不能为空',
  369. type: 'isNull'
  370. }, {
  371. target: (this.detail.IsSelect || ''),
  372. errorMsg: '是否精选课程不能为空',
  373. type: 'isNull'
  374. }])
  375. if (!checkOff) {
  376. return false
  377. }
  378. const { id } = this.$route.query
  379. if (!id || id === '') {
  380. this.UpdateInfo({ ...this.detail, CourseId: '' })
  381. }
  382. const _that = this
  383. this.detail.tagids = this.tags.map(x => {
  384. let tagfilter = (_that.tagList.list || []).filter(tag => tag.TagId === x)
  385. if (tagfilter.length > 0) {
  386. return tagfilter[0].TagName + ':' + tagfilter[0].TagId
  387. } else {
  388. return x
  389. }
  390. }).join(',')
  391. if ((this.detail.CourseId || '') === '') {
  392. this.detail.OrgId = this.orgid
  393. if (!this.detail.CaseId || this.detail.CaseId === '') {
  394. this.detail.CaseId = this.caseid
  395. }
  396. this.AddCourse({ ...this.detail, callback: _that.afterSave })
  397. } else {
  398. this.UpdateCourse({ ...this.detail, callback: _that.afterSave })
  399. }
  400. },
  401. afterSave () {
  402. this.$message({
  403. type: 'success',
  404. message: '操作成功'
  405. })
  406. this.$router.push({ name: 'courseList' })
  407. },
  408. cancel () {
  409. this.$router.push({ name: 'courseList' })
  410. }
  411. },
  412. mounted () {
  413. this.updateLocationInfo(false)
  414. this.GetCourseTagList({ pagesize: 100 })
  415. const { id } = this.$route.query
  416. if (id && id !== '') {
  417. this.GetCourseByID({ id: id })
  418. } else {
  419. // this.SetNull()
  420. }
  421. }
  422. }
  423. </script>
  424. <!-- Add "scoped" attribute to limit CSS to this component only -->
  425. <style lang="scss" scoped>
  426. </style>