ArticleDetail.vue 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511
  1. <template>
  2. <div class="createPost-container">
  3. <el-form
  4. ref="postForm"
  5. :label-position="labelPosition"
  6. :model="postForm"
  7. :rules="rules"
  8. class="form-container"
  9. >
  10. <div class="createPost-main-container">
  11. <el-form-item prop="title" style="" label="剧场标题">
  12. <el-input
  13. v-model="postForm.title"
  14. type="textarea"
  15. style="width: 500px"
  16. autosize
  17. />
  18. </el-form-item>
  19. <el-form-item prop="desc" style="" label="描述">
  20. <el-input
  21. v-model="postForm.desc"
  22. :rows="3"
  23. type="textarea"
  24. style="width: 500px"
  25. autosize
  26. />
  27. </el-form-item>
  28. <el-form-item prop="imgUrl" style="" label="封面">
  29. <Upload v-model="postForm.imgUrl" />
  30. <span style="color: #ff4949">请上传封面边长179*98的专辑封面</span>
  31. </el-form-item>
  32. <el-form-item v-if="!isEdit" label="用户id" prop="userId">
  33. <el-input v-model="postForm.user_id" style="width: 300px" />
  34. </el-form-item>
  35. <el-form-item v-if="isEdit" prop="videoList" style="" label="视频列表">
  36. <el-button
  37. class="filter-item"
  38. type="primary"
  39. size="mini"
  40. icon="el-icon-edit"
  41. style="margin-bottom: 10px"
  42. @click="handleAdd"
  43. >
  44. 新建视频
  45. </el-button>
  46. <el-table
  47. :data="postForm.videoList"
  48. border
  49. fit
  50. highlight-current-row
  51. style="width: 100%"
  52. >
  53. <el-table-column align="center" label="视频id" width="80">
  54. <template slot-scope="scope">
  55. <span>{{ scope.row.id }}</span>
  56. </template>
  57. </el-table-column>
  58. <el-table-column align="center" label="创建日期">
  59. <template slot-scope="scope">
  60. <span>{{ scope.row.createTime }}</span>
  61. </template>
  62. </el-table-column>
  63. <el-table-column label="视频标题">
  64. <template slot-scope="{ row }">
  65. <span>{{ row.title }}</span>
  66. </template>
  67. </el-table-column>
  68. <el-table-column
  69. align="center"
  70. label="Actions"
  71. width="190"
  72. class-name="small-padding fixed-width"
  73. >
  74. <template slot-scope="scope">
  75. <el-button
  76. type="primary"
  77. size="mini"
  78. @click="handleEdit(scope)"
  79. >
  80. 修改/查看
  81. </el-button>
  82. <el-button
  83. type="danger"
  84. size="mini"
  85. style="margin-left: 10px"
  86. @click="handleDelete(scope)"
  87. >
  88. 删除
  89. </el-button>
  90. </template>
  91. </el-table-column>
  92. </el-table>
  93. </el-form-item>
  94. <el-form-item prop="status" style="" label="视频权限">
  95. <template>
  96. <el-radio-group v-model="postForm.level">
  97. <el-radio :label="1">所有用户可见</el-radio>
  98. <el-radio :label="2">仅医师可见</el-radio>
  99. </el-radio-group>
  100. </template>
  101. </el-form-item>
  102. <el-form-item prop="status" style="" label="状态">
  103. <template>
  104. <el-radio-group v-model="postForm.status">
  105. <el-radio :label="0">屏蔽</el-radio>
  106. <el-radio :label="1">显示</el-radio>
  107. </el-radio-group>
  108. </template>
  109. </el-form-item>
  110. <el-row>
  111. <el-button
  112. v-if="!isEdit"
  113. v-loading="loading"
  114. type="success"
  115. @click="submitForm"
  116. >
  117. 提交
  118. </el-button>
  119. <el-button
  120. v-if="isEdit"
  121. v-loading="loading"
  122. type="success"
  123. @click="updateArticle"
  124. >
  125. 修改
  126. </el-button>
  127. </el-row>
  128. </div>
  129. </el-form>
  130. <el-dialog
  131. :visible.sync="dialogVisible"
  132. :title="dialogType === 'edit' ? '修改' : '新增'"
  133. style="height: 800px; margin-top: -8vh"
  134. >
  135. <el-form
  136. ref="editForm"
  137. :model="temp"
  138. label-width="80px"
  139. label-position="left"
  140. style="height: 500px; overflow: auto"
  141. :rules="editPageRules"
  142. >
  143. <el-form-item label="视频地址" prop="videoUrl">
  144. <VideoUpload v-model="temp.videoUrl" />
  145. <span
  146. style="color: #ff4949"
  147. >最大视频上传不超过50M</span>
  148. </el-form-item>
  149. <el-form-item label="视频封面" prop="videoImg">
  150. <Upload v-model="temp.videoImg" />
  151. </el-form-item>
  152. <el-form-item label="视频标题" prop="title">
  153. <template>
  154. <el-input v-model="temp.title" />
  155. </template>
  156. </el-form-item>
  157. <el-form-item label="视频简介" prop="desc">
  158. <template>
  159. <el-input v-model="temp.desc" type="textarea" :rows="2" />
  160. </template>
  161. </el-form-item>
  162. </el-form>
  163. <div style="text-align: right">
  164. <el-button type="danger" @click="dialogVisible = false">取消</el-button>
  165. <el-button type="primary" @click="confirmtemp">提交</el-button>
  166. </div>
  167. </el-dialog>
  168. </div>
  169. </template>
  170. <script>
  171. import Upload from '@/components/Upload/SingleImage3'
  172. // import { validURL } from '@/utils/validate'
  173. import VideoUpload from '@/components/Upload/SingleVideo'
  174. import {
  175. fetchVideo,
  176. updateVideo,
  177. deleteVideo,
  178. updateTheatre
  179. } from '@/api/video'
  180. import { deepClone } from '@/utils'
  181. // import { CommentDropdown, PlatformDropdown, SourceUrlDropdown } from './Dropdown'
  182. const defaultForm = {
  183. status: 1,
  184. img_url: '', // 文章题目
  185. type: 1, // 文章内容
  186. sort: 1, // 文章摘要
  187. id: undefined,
  188. level: 1
  189. }
  190. const validateRequire = (rule, value, callback) => {
  191. console.log(rule)
  192. console.log(value)
  193. if (!value) {
  194. // this.$message({
  195. // message: rule.field + "不为空",
  196. // type: "error",
  197. // }); //直播标题必须为3-17个字(一个字等于两个英文字符或特殊字符)
  198. callback(new Error(rule.field + '不为空'))
  199. } else if (value.length == 0) {
  200. callback(new Error(rule.field + '不为空'))
  201. } else {
  202. callback()
  203. }
  204. }
  205. export default {
  206. name: 'ArticleDetail',
  207. components: { Upload, VideoUpload },
  208. props: {
  209. isEdit: {
  210. type: Boolean,
  211. default: false
  212. }
  213. },
  214. data() {
  215. return {
  216. postForm: Object.assign({}, defaultForm),
  217. loading: false,
  218. userListOptions: [],
  219. rules: {
  220. imgUrl: [
  221. {
  222. message: '封面不能为空',
  223. required: true,
  224. validator: validateRequire,
  225. trigger: 'change'
  226. }
  227. ],
  228. title: [
  229. {
  230. message: '剧场标题不能为空',
  231. required: true,
  232. validator: validateRequire,
  233. trigger: 'blur'
  234. }
  235. ],
  236. desc: [
  237. {
  238. message: '描述不能为空',
  239. required: true,
  240. validator: validateRequire,
  241. trigger: 'blur'
  242. }
  243. ],
  244. user_id: [
  245. {
  246. message: '用户id不能为空',
  247. required: true,
  248. validator: validateRequire,
  249. trigger: 'change'
  250. }
  251. ]
  252. },
  253. editPageRules: {},
  254. tempRoute: {},
  255. labelPosition: 'top',
  256. dialogVisible: false,
  257. dialogType: 'new',
  258. temp: {}
  259. }
  260. },
  261. computed: {
  262. contentShortLength() {
  263. return this.postForm.content_short.length
  264. },
  265. displayTime: {
  266. // set and get is useful when the data
  267. // returned by the back end api is different from the front end
  268. // back end return => "2013-06-25 06:59:25"
  269. // front end need timestamp => 1372114765000
  270. get() {
  271. return +new Date(this.postForm.display_time)
  272. },
  273. set(val) {
  274. this.postForm.display_time = new Date(val)
  275. }
  276. }
  277. },
  278. created() {
  279. if (this.isEdit) {
  280. const id = this.$route.params && this.$route.params.id
  281. this.fetchData(id)
  282. }
  283. // Why need to make a copy of this.$route here?
  284. // Because if you enter this page and quickly switch tag, may be in the execution of the setTagsViewTitle function, this.$route is no longer pointing to the current page
  285. // https://github.com/PanJiaChen/vue-element-admin/issues/1221
  286. this.tempRoute = Object.assign({}, this.$route)
  287. },
  288. methods: {
  289. fetchData(id) {
  290. fetchVideo(id)
  291. .then((response) => {
  292. this.postForm = response.data
  293. // set tags view title
  294. // this.setTagsViewTitle()
  295. // set page title
  296. // this.setPageTitle()
  297. })
  298. .catch((err) => {
  299. console.log(err)
  300. })
  301. },
  302. setPageTitle() {
  303. const title = 'Edit Article'
  304. document.title = `${title} - ${this.postForm.id}`
  305. },
  306. submitForm() {
  307. this.$refs.postForm.validate((valid) => {
  308. if (valid) {
  309. updateTheatre(this.postForm).then((response) => {
  310. this.$notify({
  311. title: '添加',
  312. message: '添加成功',
  313. type: 'success',
  314. duration: 2000
  315. })
  316. // this.postForm.status = 'published'
  317. this.loading = false
  318. this.listLoading = false
  319. this.$router.push(`/video/list`)
  320. })
  321. } else {
  322. console.log('error submit!!')
  323. return false
  324. }
  325. })
  326. },
  327. updateArticle() {
  328. updateTheatre(this.postForm).then((response) => {
  329. this.$notify({
  330. title: '修改',
  331. message: '修改成功',
  332. type: 'success',
  333. duration: 2000
  334. })
  335. // this.postForm.status = 'published'
  336. this.loading = false
  337. this.listLoading = false
  338. this.$router.push(`/video/list`)
  339. })
  340. // this.$router.push(`/advice/list`)
  341. },
  342. draftForm() {
  343. if (
  344. this.postForm.content.length === 0 ||
  345. this.postForm.title.length === 0
  346. ) {
  347. this.$message({
  348. message: '请填写必要的标题和内容',
  349. type: 'warning'
  350. })
  351. return
  352. }
  353. this.$message({
  354. message: '保存成功',
  355. type: 'success',
  356. showClose: true,
  357. duration: 1000
  358. })
  359. this.postForm.status = 'draft'
  360. },
  361. handleEdit(scope) {
  362. this.dialogType = 'edit'
  363. this.dialogVisible = true
  364. this.checkStrictly = true
  365. this.temp = deepClone(scope.row)
  366. this.editPageRules = {
  367. videoUrl: [
  368. {
  369. message: '视频地址不能为空',
  370. required: true,
  371. validator: validateRequire,
  372. trigger: 'change'
  373. }
  374. ],
  375. videoImg: [
  376. {
  377. message: '视频封面不能为空',
  378. required: true,
  379. validator: validateRequire,
  380. trigger: 'change'
  381. }
  382. ],
  383. title: [
  384. {
  385. message: '视频标题不能为空',
  386. required: true,
  387. validator: validateRequire,
  388. trigger: 'blur'
  389. }
  390. ],
  391. desc: [
  392. {
  393. message: '视频描述不能为空',
  394. required: true,
  395. validator: validateRequire,
  396. trigger: 'blur'
  397. }
  398. ]
  399. }
  400. // console.log(this.rules);
  401. },
  402. handleAdd() {
  403. this.temp = {}
  404. this.dialogType = 'new'
  405. this.dialogVisible = true
  406. },
  407. async confirmtemp() {
  408. const isEdit = this.dialogType === 'edit'
  409. if (isEdit) {
  410. await updateVideo(this.temp)
  411. for (let index = 0; index < this.postForm.videoList.length; index++) {
  412. if (this.postForm.videoList[index].id === this.temp.id) {
  413. this.postForm.videoList.splice(
  414. index,
  415. 1,
  416. Object.assign({}, this.temp)
  417. )
  418. break
  419. }
  420. }
  421. console.log(this.temp)
  422. } else {
  423. this.temp['userId'] = this.postForm.userId
  424. this.temp['theatreId'] = this.postForm.id
  425. const { data } = await updateVideo(this.temp)
  426. this.temp.id = data.id
  427. this.temp.createTime = data.createTime
  428. this.postForm.videoList.push(this.temp)
  429. }
  430. this.dialogVisible = false
  431. this.$notify({
  432. title: '成功',
  433. dangerouslyUseHTMLString: true,
  434. message: '添加成功',
  435. type: 'success'
  436. })
  437. },
  438. async handleDelete(scope) {
  439. deleteVideo(scope.row.id)
  440. this.postForm.videoList.splice(scope.$index, 1)
  441. }
  442. }
  443. /* watch: {
  444. dialogVisible(newVal) {
  445. if (!newVal) {
  446. this.editPageRules = {};
  447. this.$refs.editForm.resetFields();
  448. }
  449. },
  450. }, */
  451. }
  452. </script>
  453. <style lang="scss" scoped>
  454. @import "~@/styles/mixin.scss";
  455. .createPost-container {
  456. position: relative;
  457. .createPost-main-container {
  458. padding: 40px 45px 20px 50px;
  459. .postInfo-container {
  460. position: relative;
  461. @include clearfix;
  462. margin-bottom: 10px;
  463. .postInfo-container-item {
  464. float: left;
  465. }
  466. }
  467. }
  468. .video-border {
  469. display: inline-flex;
  470. width: 350px;
  471. height: 100%;
  472. .video-info {
  473. //display: flex;
  474. width: 300px;
  475. //height: 300px;
  476. }
  477. }
  478. .word-counter {
  479. width: 40px;
  480. position: absolute;
  481. right: 10px;
  482. top: 0px;
  483. }
  484. }
  485. .article-textarea ::v-deep {
  486. textarea {
  487. padding-right: 40px;
  488. resize: none;
  489. border: none;
  490. border-radius: 0px;
  491. border-bottom: 1px solid #bfcbd9;
  492. }
  493. }
  494. </style>