add.vue 32 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889
  1. <template>
  2. <div class="lenrn_content" style="margin: 20px 0 30px !important">
  3. <el-container>
  4. <el-container>
  5. <el-aside width="164px">
  6. <el-menu style="min-height: 1200px;padding-top:40px" class="el-menu-vertical-demo">
  7. <el-menu-item index="1">
  8. <span :style="active==1?'color:#308EFF':'color:#303133'" slot="title">基础信息</span>
  9. </el-menu-item>
  10. <el-menu-item index="2">
  11. <span :style="active==2?'color:#308EFF':'color:#303133'" slot="title">讲师介绍</span>
  12. </el-menu-item>
  13. <el-menu-item index="3">
  14. <span :style="active==3?'color:#308EFF':'color:#303133'" slot="title">添加视频</span>
  15. </el-menu-item>
  16. <el-menu-item index="4">
  17. <span :style="active==4?'color:#308EFF':'color:#303133'" slot="title">公告栏</span>
  18. </el-menu-item>
  19. </el-menu>
  20. </el-aside>
  21. <el-container>
  22. <el-header>
  23. <el-steps align-center :active="active" style="padding-top: 20px" finish-status="success">
  24. <el-step title="基础信息"></el-step>
  25. <el-step title="讲师介绍"></el-step>
  26. <el-step title="添加视频"></el-step>
  27. <el-step title="公告栏"></el-step>
  28. </el-steps>
  29. <el-divider></el-divider>
  30. </el-header>
  31. <el-main>
  32. <el-form v-if="active==1" style="margin-top: 60px" ref="form" label-width="80px">
  33. <el-form-item label="课程名称">
  34. <el-input show-word-limit maxlength="15" v-model="saleInfo.title"></el-input>
  35. </el-form-item>
  36. <el-form-item label="副标题">
  37. <el-input show-word-limit maxlength="15" placeholder="请简单概况一下课程亮点" type="textarea" v-model="saleInfo.desc"></el-input>
  38. </el-form-item>
  39. <el-form-item label="列表封面">
  40. <div class="common-upload">
  41. <el-upload
  42. class="avatar-uploader"
  43. action="/upload_image"
  44. :show-file-list="false"
  45. :on-success="(response, file, fileList)=> upload_img_success(response, file, fileList,1)">
  46. <img v-if="saleInfo.img_icon" :src="saleInfo.img_icon" class="avatar">
  47. <i v-else class="el-icon-plus avatar-uploader-icon" style="border-radius: 6px;border: 1px dashed #d9d9d9;height: 178px;line-height: 178px;width: 178px"></i>
  48. </el-upload>
  49. <div class="look-img">
  50. <div class="text-hover">
  51. <span class="text">查看示意图</span>
  52. <div class="img">
  53. <img class="active-img1" src="@/assets/img/learn/img-add@2x.png"/>
  54. </div>
  55. </div>
  56. </div>
  57. </div>
  58. </el-form-item>
  59. <el-form-item label="计费模式">
  60. <el-radio v-model="saleInfo.pricetype" label="1">免费</el-radio>
  61. <el-radio v-model="saleInfo.pricetype" label="2">付费</el-radio>
  62. </el-form-item>
  63. <el-form-item style="display:inline-block" v-if="saleInfo.pricetype==2" label="课程价格">
  64. <el-input v-model="saleInfo.price" v-onlyNumber="{precision: 2, min: 0, max: 99999}" type="number"></el-input>
  65. </el-form-item>
  66. <el-form-item style="display:inline-block" v-if="saleInfo.pricetype==2" label="划线价格">
  67. <el-input v-model="saleInfo.yprice" v-onlyNumber="{precision: 2, min: 0, max: 99999}" type="number"></el-input>
  68. </el-form-item>
  69. <el-form-item label="课程状态">
  70. <el-radio v-model="saleInfo.point" label="1">更新</el-radio>
  71. <el-radio v-model="saleInfo.point" label="2">完结</el-radio>
  72. </el-form-item>
  73. <el-form-item label="分类">
  74. <el-select v-model="saleInfo.cate_id" placeholder="请选择">
  75. <el-option
  76. v-for="item in consultCate"
  77. :key="item.value"
  78. :label="item.label"
  79. :value="item.value">
  80. </el-option>
  81. </el-select>
  82. </el-form-item>
  83. <el-form-item label="课程描述">
  84. <div class="content-field">
  85. <div class="content-editor">
  86. <editor
  87. :hideImage="false"
  88. :content="saleInfo.content"
  89. @change="(val)=> editor_change(val,1)"
  90. placeholder="课程描述"></editor>
  91. </div>
  92. </div>
  93. </el-form-item>
  94. <el-form-item>
  95. <el-button @click="active_set(2,false)" type="primary">下一步</el-button>
  96. </el-form-item>
  97. </el-form>
  98. <el-form v-if="active==2" style="margin-top: 60px" ref="form" label-width="80px">
  99. <el-form-item label="讲师名称">
  100. <el-input v-model="teacherInfo.name" show-word-limit maxlength="15"></el-input>
  101. </el-form-item>
  102. <el-form-item label="职称">
  103. <el-input v-model="teacherInfo.op" show-word-limit maxlength="15"></el-input>
  104. </el-form-item>
  105. <el-form-item label="封面">
  106. <div class="common-upload">
  107. <el-upload
  108. class="avatar-uploader"
  109. action="/upload_image"
  110. :show-file-list="false"
  111. :on-success="(response, file, fileList)=> upload_img_success(response, file, fileList,2)">
  112. <img v-if="teacherInfo.img" :src="teacherInfo.img" class="avatar">
  113. <i v-else class="el-icon-plus avatar-uploader-icon" style="border-radius: 6px;border: 1px dashed #d9d9d9;height: 178px;line-height: 178px;width: 178px"></i>
  114. </el-upload>
  115. <div class="look-img">
  116. <div class="text-hover">
  117. <span class="text">查看示意图</span>
  118. <div class="img">
  119. <img class="active-img1" src="@/assets/img/learn/img-add@2x.png"/>
  120. </div>
  121. </div>
  122. </div>
  123. </div>
  124. </el-form-item>
  125. <el-form-item label="自我介绍">
  126. <el-input :rows="10" type="textarea" v-model="teacherInfo.content"></el-input>
  127. </el-form-item>
  128. <el-form-item>
  129. <el-button @click="active_set(1,true)" type="primary">上一步</el-button>
  130. <el-button @click="active_set(3,false)" type="primary">下一步</el-button>
  131. </el-form-item>
  132. </el-form>
  133. <el-form v-if="active==3" style="margin-top: 60px" ref="form" label-width="80px">
  134. <el-form-item label="视频封面">
  135. <div class="common-upload">
  136. <el-upload
  137. class="avatar-uploader"
  138. action="/upload_image"
  139. :show-file-list="false"
  140. :on-success="(response, file, fileList)=> upload_img_success(response, file, fileList,3)">
  141. <img v-if="saleInfo.video_img" :src="saleInfo.video_img" class="avatar">
  142. <i v-else class="el-icon-plus avatar-uploader-icon" style="border-radius: 6px;border: 1px dashed #d9d9d9;height: 178px;line-height: 178px;width: 178px"></i>
  143. </el-upload>
  144. <div class="look-img">
  145. <div class="text-hover">
  146. <span class="text">查看示意图</span>
  147. <div class="img">
  148. <img class="active-img2" src="@/assets/img/learn/video-add@2x.png"/>
  149. </div>
  150. </div>
  151. </div>
  152. </div>
  153. </el-form-item>
  154. <el-form-item label="章节管理">
  155. <div v-for="(item,index) in video_list" :key="item.id">
  156. <el-input style="margin-top: 10px" placeholder="请输入内容" v-model="item.video_name">
  157. <template slot="prepend">第{{index+1}}章</template>
  158. <el-button slot="append" @click="del_zj(index,item.id)" icon="el-icon-delete"></el-button>
  159. </el-input>
  160. <div v-for="(item2,index2) in item.list" :key="item2.id" style="background: #f6f6f6;padding: 10px;margin-top: 10px">
  161. <el-input style="margin-top: 10px" placeholder="请输入课程名称" v-model="item2.video_name" class="input-with-select">
  162. <div slot="prepend" style="width: 120px;text-align: center">{{index+1}}-{{index2+1}}</div>
  163. <el-checkbox slot="append" style="margin-right: 15px" v-model="item2.checked">试看</el-checkbox>
  164. <el-button slot="append" @click="del_kc(index,index2,item2.id)" icon="el-icon-delete"></el-button>
  165. </el-input>
  166. <div style="padding-top: 10px;padding-bottom: 10px">
  167. <el-upload
  168. class="upload-demo"
  169. style="display: inline-block"
  170. action=""
  171. :show-file-list="false"
  172. :http-request="(e)=> fileChange(e,index,index2)">
  173. <el-button size="small" type="primary">点击上传</el-button>
  174. </el-upload>
  175. <div class="file-upload" style="margin-top: 10px">
  176. <el-progress :text-inside="true" :stroke-width="20" :percentage="item2.progress"></el-progress>
  177. </div>
  178. </div>
  179. </div>
  180. <div style="background: #f6f6f6;padding: 10px;margin-top: 10px;text-align:center">
  181. <el-button @click="add_new_kc(index)" :disabled="kc_disabled" type="primary">添加新的课程</el-button>
  182. <el-button @click="add_new_zj()" :disabled="zj_disabled" type="primary">添加新的章节</el-button>
  183. </div>
  184. </div>
  185. </el-form-item>
  186. <el-form-item>
  187. <el-button @click="active_set(2,true)" type="primary">上一步</el-button>
  188. <el-button @click="active_set(4,false)" type="primary">下一步</el-button>
  189. </el-form-item>
  190. </el-form>
  191. <el-form v-if="active==4" style="margin-top: 60px" ref="form" label-width="80px">
  192. <el-form-item style="display: none" label="群二维码">
  193. <el-upload
  194. class="avatar-uploader"
  195. action="/upload_image"
  196. :show-file-list="false"
  197. :on-success="(response, file, fileList)=> upload_img_success(response, file, fileList,4)">
  198. <img v-if="saleInfo.ewm" :src="saleInfo.ewm" class="avatar">
  199. <i v-else class="el-icon-plus avatar-uploader-icon" style="border-radius: 6px;border: 1px dashed #d9d9d9;height: 178px;line-height: 178px;width: 178px"></i>
  200. </el-upload>
  201. </el-form-item>
  202. <el-form-item label="公告栏">
  203. <div class="content-field">
  204. <div class="content-editor">
  205. <editor
  206. :hideImage="false"
  207. :content="saleInfo.notice_msg"
  208. @change="(val)=> editor_change(val,3)"
  209. placeholder="公告栏用于发布课程通知,常见用于课件下载等信息。"></editor>
  210. </div>
  211. </div>
  212. </el-form-item>
  213. <el-form-item>
  214. <el-button @click="active_set(3,true)" type="primary">上一步</el-button>
  215. <el-button @click="active_set(5,false)" type="primary">确认提交</el-button>
  216. </el-form-item>
  217. </el-form>
  218. </el-main>
  219. </el-container>
  220. </el-container>
  221. </el-container>
  222. <!-- vueCropper 剪裁图片实现-->
  223. <el-dialog title="图片剪裁" :visible.sync="dialogVisible" append-to-body>
  224. <div class="cropper-content">
  225. <div class="cropper" style="text-align:center">
  226. <vueCropper
  227. ref="cropper"
  228. :img="option.img"
  229. :outputSize="option.size"
  230. :outputType="option.outputType"
  231. :info="true"
  232. :full="option.full"
  233. :canMove="option.canMove"
  234. :canMoveBox="option.canMoveBox"
  235. :original="option.original"
  236. :autoCrop="option.autoCrop"
  237. :fixed="option.fixed"
  238. :fixedNumber="option.fixedNumber"
  239. :centerBox="option.centerBox"
  240. :infoTrue="option.infoTrue"
  241. :fixedBox="option.fixedBox"
  242. ></vueCropper>
  243. </div>
  244. </div>
  245. <div slot="footer" class="dialog-footer">
  246. <el-button @click="dialogVisible = false">取 消</el-button>
  247. <el-button type="primary" @click="finish">确认</el-button>
  248. </div>
  249. </el-dialog>
  250. </div>
  251. </template>
  252. <script>
  253. import { mapState } from "vuex";
  254. import editor from "@/components/editor";
  255. import multiUploader from '@/components/multi-uploader';
  256. if(process.client)
  257. {
  258. import('@/assets/js/aliyun-upload-sdk/aliyun-upload-sdk-1.5.2.min.js');
  259. }
  260. export default {
  261. head: {
  262. title: '新建咨询服务',
  263. },
  264. head() {
  265. return {
  266. script: [
  267. {src: 'https://gosspublic.alicdn.com/aliyun-oss-sdk-6.13.0.min.js'},
  268. ]
  269. }
  270. },
  271. components: {
  272. editor,
  273. multiUploader,
  274. },
  275. data () {
  276. return {
  277. sale_id: '', // 编辑时
  278. kc_disabled:false,
  279. zj_disabled:false,
  280. active:1,
  281. selectedConsultCate: [],//选中的技能分类
  282. consultCate: [], // 技能分类数据源
  283. saleInfo:{
  284. point:"1",
  285. pricetype:"1",
  286. img_icon:"",
  287. video_img:"",
  288. ewm:"",
  289. desc:"",
  290. price: '0.00',
  291. yprice: '0.00'
  292. },
  293. dialogVisible: false,
  294. // 裁剪组件的基础配置option
  295. option: {
  296. img: '', // 裁剪图片的地址
  297. type:'',//类型
  298. info: true, // 裁剪框的大小信息
  299. outputSize: 1, // 裁剪生成图片的质量
  300. outputType: 'jpeg', // 裁剪生成图片的格式
  301. canScale: false, // 图片是否允许滚轮缩放
  302. autoCrop: true, // 是否默认生成截图框
  303. // autoCropWidth: 300, // 默认生成截图框宽度
  304. // autoCropHeight: 200, // 默认生成截图框高度
  305. fixedBox: true, // 固定截图框大小 不允许改变
  306. fixed: true, // 是否开启截图框宽高固定比例
  307. fixedNumber: [16, 9], // 截图框的宽高比例
  308. full: true, // 是否输出原图比例的截图
  309. canMoveBox: false, // 截图框能否拖动
  310. original: false, // 上传图片按照原始比例渲染
  311. centerBox: false, // 截图框是否被限制在图片里面
  312. infoTrue: true // true 为展示真实输出图片宽高 false 展示看到的截图框宽高
  313. },
  314. teacherInfo:{
  315. img:""
  316. },
  317. video_list:[{"id":"","video_name":"","list":[{"id":"","kc_id":"1","progress":0,"video_name":"","checked":false,"time_type":0,"ymd":"","his":""}]}],
  318. }
  319. },
  320. mounted () {
  321. this.needLogin()
  322. var sale_id = this.$route.query.id ? this.$route.query.id : 0;
  323. this._getConsultCate()
  324. if (sale_id!=0) {
  325. this.sale_id=sale_id;
  326. this.getDetail();
  327. }
  328. if (this.saleInfo.price > 0)
  329. {
  330. this.saleInfo.pricetype="2";
  331. }
  332. else
  333. {
  334. this.saleInfo.pricetype="1";
  335. }
  336. },
  337. methods: {
  338. time_type(zj_id,kc_id,type){
  339. this.video_list[zj_id].list[kc_id].time_type=type;
  340. },
  341. // 点击裁剪,这一步是可以拿到处理后的地址
  342. finish() {
  343. this.$refs.cropper.getCropBlob((data) => {
  344. console.log("裁剪",data)
  345. let formData = new FormData();
  346. formData.append("file", data);
  347. this.$axios.$post('/upload_image', formData,{
  348. headers: {
  349. "Content-Type": "multipart/form-data"
  350. }
  351. }).then(res => {
  352. this.dialogVisible = false
  353. this.type=0;
  354. if(this.option.type==1)
  355. {
  356. this.saleInfo.img_icon=res.filename;
  357. }
  358. else if(this.option.type==2)
  359. {
  360. this.teacherInfo.img=res.filename;
  361. }
  362. else if(this.option.type==3)
  363. {
  364. this.saleInfo.video_img=res.filename;
  365. }
  366. }).catch(err => {
  367. })
  368. })
  369. },
  370. add_new_zj(){
  371. this.add_three(2);
  372. },
  373. add_new_kc(zj_id){
  374. this.add_three(3,0,zj_id);
  375. },
  376. del_kc(zj_id,kc_id,id){
  377. /*for(var i=0;i<this.video_list.length;i++)
  378. {
  379. for(var j=0;j<this.video_list[i].list.length;j++)
  380. {
  381. if(zj_id==i && kc_id==j)
  382. {
  383. this.video_list[i].list.splice(j,1);
  384. }
  385. }
  386. }*/
  387. this.$axios.$post('/api/sale/del_video', { sale_id: this.sale_id,id:id}).then(res => {
  388. if (res.status === 1) {
  389. this.video_list=res.data;
  390. }
  391. }).catch(err => {
  392. })
  393. },
  394. del_zj(zj_id,id){
  395. if(this.video_list.length==1){
  396. this.$message.error('已经是最后一个章节了不能删除了')
  397. return false
  398. }
  399. /* for(var i=0;i<this.video_list.length;i++)
  400. {
  401. if(zj_id==i)
  402. {
  403. this.video_list.splice(i,1);
  404. }
  405. }*/
  406. this.$axios.$post('/api/sale/del_video', { sale_id: this.sale_id, id}).then(res => {
  407. if (res.status === 1) {
  408. this.video_list=res.data;
  409. }
  410. }).catch(err => {
  411. })
  412. },
  413. active_set(val,return_=true){
  414. if(return_)
  415. {
  416. this.active=val;
  417. return;
  418. }
  419. if(val==2)
  420. {
  421. this.saleInfo.cate_id_one=this.saleInfo.cate_id;
  422. this.saleInfo.cate_id_two=0;
  423. this.add_one();
  424. }
  425. else if(val==3)
  426. {
  427. this.add_two();
  428. }
  429. else if(val==4)
  430. {
  431. this.add_three();//效验课程数据
  432. }
  433. else if(val==5)
  434. {
  435. this.add_fore();//提交审核
  436. }
  437. else
  438. {
  439. this.active=val;
  440. }
  441. },
  442. upload_img_success(res, file, fileList,type){
  443. if(type==1)
  444. {
  445. let filename=res.filename;
  446. // 上传成功后将图片地址赋值给裁剪框显示图片
  447. this.$nextTick(() => {
  448. this.option.img =filename;
  449. this.option.fixedNumber=[16,9]
  450. this.option.type=type;
  451. this.dialogVisible = true
  452. })
  453. }
  454. else if(type==2)
  455. {
  456. let filename=res.filename;
  457. // 上传成功后将图片地址赋值给裁剪框显示图片
  458. this.$nextTick(() => {
  459. this.option.img =filename;
  460. this.option.fixedNumber=[100,100]
  461. this.option.type=type;
  462. this.dialogVisible = true
  463. })
  464. }
  465. else if(type==3)
  466. {
  467. let filename=res.filename;
  468. // 上传成功后将图片地址赋值给裁剪框显示图片
  469. this.$nextTick(() => {
  470. this.option.img =filename;
  471. this.option.fixedNumber=[7,5]
  472. this.option.type=type;
  473. this.dialogVisible = true
  474. })
  475. }
  476. else if(type==4)
  477. {
  478. this.saleInfo.ewm=res.filename;
  479. }
  480. },
  481. editor_change(val,type)//编辑器内容发生改变的时候
  482. {
  483. if(type==1) {
  484. this.saleInfo.content = val;
  485. }
  486. else if(type==2) {
  487. this.teacherInfo.content = val;
  488. }
  489. else if(type==3) {
  490. this.saleInfo.notice_msg = val;
  491. }
  492. },
  493. fileChange (e,zj_id,kc_id) {
  494. let videoFile = e.file
  495. let filename=e.file.name;
  496. this.createUploader(videoFile,zj_id,kc_id,filename)
  497. },
  498. createUploader (videoFile,zj_id,kc_id,filename) {
  499. let self = this
  500. let uploader = new AliyunUpload.Vod({
  501. timeout: 60000,
  502. partSize: 1048576,
  503. parallel: 5,
  504. retryCount: 3,
  505. retryDuration: 2,
  506. region: 'cn-shanghai',
  507. userId: '1024',
  508. // 添加文件成功
  509. addFileSuccess: function (uploadInfo) {
  510. self.statusText = '添加文件成功, 等待上传...'
  511. console.log("addFileSuccess: " + uploadInfo.file.name)
  512. },
  513. // 开始上传
  514. onUploadstarted: function (uploadInfo) {
  515. self.$axios.$post("/api/sale/video", {filename: uploadInfo.file.name}).then(({data}) => {
  516. let uploadAuth = data.UploadAuth;
  517. let uploadAddress = data.UploadAddress;
  518. let videoId = data.VideoId;
  519. self.videoId = data.VideoId;
  520. self.video_list[zj_id].list[kc_id].temp_video_id=videoId;
  521. self.video_list[zj_id].list[kc_id].video_name=data.filename;
  522. uploader.setUploadAuthAndAddress(uploadInfo, uploadAuth, uploadAddress, videoId)
  523. })
  524. self.statusText = '文件开始上传...'
  525. console.log("onUploadStarted:" + uploadInfo.file.name + ", endpoint:" + uploadInfo.endpoint + ", bucket:" + uploadInfo.bucket + ", object:" + uploadInfo.object)
  526. },
  527. // 文件上传成功
  528. onUploadSucceed: function (uploadInfo) {
  529. self.video_list[zj_id].list[kc_id].video_id= self.video_list[zj_id].list[kc_id].temp_video_id;
  530. //self.add_three(4);//保存课程
  531. },
  532. // 文件上传进度,单位:字节, 可以在这个函数中拿到上传进度并显示在页面上
  533. onUploadProgress: function (uploadInfo, totalSize, progress) {
  534. let progressPercent = Math.ceil(progress * 100)
  535. self.video_list[zj_id].list[kc_id].progress=progressPercent;
  536. },
  537. })
  538. uploader.addFile(videoFile);
  539. uploader.startUpload();//上传文件
  540. },
  541. /** 获取咨询分类 */
  542. async _getConsultCate () {
  543. this.$axios.$post('/api/sale/cateListYes', { type: 4, point: 1 }).then(res => {
  544. if (res.status === 1) {
  545. let consultCate = res.data || []
  546. this.consultCate = consultCate.map(item => {
  547. let children = item.child_list.map(child => {
  548. return {
  549. value: child.category_id,
  550. label: child.name
  551. }
  552. })
  553. return {
  554. value: item.category_id,
  555. label: item.name,
  556. children: children
  557. }
  558. })
  559. }
  560. }).catch(err => {
  561. console.log('get consult cate error: ', err)
  562. })
  563. },
  564. /** 第一步添加 */
  565. async add_one() {
  566. if(!this.saleInfo.title)
  567. {
  568. this.$message.error('课程名称必须填写');
  569. return false;
  570. }
  571. if(!this.saleInfo.desc)
  572. {
  573. this.$message.error('课程概述必须填写');
  574. return false;
  575. }
  576. if(!this.saleInfo.img_icon)
  577. {
  578. this.$message.error('课程封面必须上传');
  579. return false;
  580. }
  581. if(this.saleInfo.pricetype==2 && !this.saleInfo.price>0)
  582. {
  583. this.$message.error('价格必须设置');
  584. return false;
  585. }
  586. if(!this.saleInfo.cate_id_one)
  587. {
  588. this.$message.error('分类必须选择');
  589. return false;
  590. }
  591. if(!this.saleInfo.content)
  592. {
  593. this.$message.error('课程描述必须填写');
  594. return false;
  595. }
  596. var data=JSON.stringify(this.saleInfo);
  597. await this.$axios.$post('/api/sale/sale_add_one', {sale_id:this.sale_id, data}).then(res => {
  598. if (res.status === 1) {
  599. this.active=2;
  600. this.sale_id=res.data.sale_id;
  601. this.saleInfo.sale_id=res.data.sale_id;
  602. }
  603. }).catch(err => {
  604. })
  605. },
  606. /** 第二步添加 */
  607. async add_two() {
  608. if(!this.teacherInfo.name)
  609. {
  610. this.$message.error('讲师名称必须填写');
  611. return false;
  612. }
  613. if(!this.teacherInfo.op)
  614. {
  615. this.$message.error('职称必须填写');
  616. return false;
  617. }
  618. if(!this.teacherInfo.img)
  619. {
  620. this.$message.error('封面必须上传');
  621. return false;
  622. }
  623. if(!this.teacherInfo.content)
  624. {
  625. this.$message.error('自我介绍必须填写');
  626. return false;
  627. }
  628. this.teacherInfo.sale_id=this.sale_id;
  629. var data=JSON.stringify(this.teacherInfo);
  630. await this.$axios.$post('/api/sale/sale_add_two', { data }).then(res => {
  631. if (res.status === 1) {
  632. this.active=3;
  633. }
  634. }).catch(err => {
  635. })
  636. },
  637. /** 第三步添加 */
  638. async add_three(type=1,kc_id=0,zj_id=0) {
  639. var video_list=JSON.stringify(this.video_list);
  640. var saleInfo=JSON.stringify(this.saleInfo);
  641. await this.$axios.$post('/api/sale/sale_add_three', {type, sale_id:this.sale_id, video_list,saleInfo }).then(res => {
  642. if (res.status === 1) {
  643. this.video_list=res.data.list;
  644. if(!res.data.result)
  645. {
  646. if(type==1)
  647. {
  648. this.active=4;
  649. }
  650. else if(type==2)
  651. {
  652. var new_object={"id":"","video_name":"","list":[{"id":"","kc_id":"","progress":0,"video_name":"","checked":false,"time_type":0,"ymd":"","his":""}]};
  653. this.video_list.push(new_object);
  654. this.add_video();
  655. }
  656. else if(type==3)
  657. {
  658. var new_object={"id":"","kc_id":"","progress":0,"video_name":"","checked":false,"time_type":0,"ymd":"","his":""};
  659. this.video_list[zj_id].list.push(new_object);
  660. this.add_video();
  661. }
  662. }
  663. else
  664. {
  665. this.$message.error(res.data.result_msg);
  666. }
  667. }
  668. }).catch(err => {
  669. })
  670. },
  671. /** 第四步添加 */
  672. async add_fore() {
  673. var video_list=JSON.stringify(this.video_list);
  674. var saleInfo=JSON.stringify(this.saleInfo);
  675. await this.$axios.$post('/api/sale/sale_add_fore', {sale_id:this.sale_id, video_list, saleInfo}).then(res => {
  676. if (res.status === 1) {
  677. this.$message.success('我们已经收到您的审核提交,请耐心等待');
  678. location.href = `/workbench/learn/index`
  679. }
  680. }).catch(err => {
  681. })
  682. },
  683. /** 课程添加 */
  684. async add_video() {
  685. this.kc_disabled=true;
  686. this.zj_disabled=true;
  687. var data=JSON.stringify(this.video_list);
  688. await this.$axios.$post('/api/sale/sale_add_video', { data,sale_id:this.sale_id}).then(res => {
  689. if (res.status === 1) {
  690. this.video_list=res.data;
  691. }
  692. this.kc_disabled=false;
  693. this.zj_disabled=false;
  694. }).catch(err => {
  695. this.kc_disabled=false;
  696. this.zj_disabled=false;
  697. })
  698. },
  699. /** 课程添加 */
  700. async getDetail() {
  701. await this.$axios.$post('/api/sale/info', {sale_id:this.sale_id}).then(res => {
  702. if (res.status === 1) {
  703. if(res.data.video.length>0)
  704. {
  705. this.video_list=res.data.video;
  706. }
  707. this.saleInfo=res.data.sale;
  708. this.teacherInfo=res.data.teacher;
  709. this.selectedConsultCate = [res.data.sale.cate_id_one, res.data.sale.cate_id_two]
  710. }
  711. }).catch(err => {
  712. })
  713. },
  714. }
  715. }
  716. </script>
  717. <style scope lang="scss">
  718. @import "@/assets/css/consult/create.scss";
  719. .common-upload {
  720. display: flex;
  721. align-items: end;
  722. .look-img {
  723. margin-left: 14px;
  724. .text {
  725. font-size: 14px;
  726. font-family: PingFangSC, PingFangSC-Medium;
  727. font-weight: 500;
  728. color: #308eff;
  729. cursor: pointer;
  730. }
  731. .text-hover:hover {
  732. position: relative;
  733. .img {
  734. display: block;
  735. }
  736. }
  737. .img {
  738. background: #fff;
  739. border: 1px solid #e0e5ed;
  740. box-shadow: 0px 2px 20px 0px rgba(22,40,63,0.15);
  741. border-radius: 10px;
  742. text-align: center;
  743. position: relative;
  744. position: absolute;
  745. top: -120px;
  746. left: 0;
  747. width: 300px;
  748. height: 120px;
  749. display: none;
  750. transition: all ease .3s;
  751. .active-img2 {
  752. width: 234px;
  753. height: 71px;
  754. background-size: cover;
  755. overflow: hidden;
  756. margin-top: 24px;
  757. }
  758. .active-img1 {
  759. width: 262px;
  760. height: 78px;
  761. background-size: cover;
  762. overflow: hidden;
  763. margin-top: 22px;
  764. }
  765. }
  766. .img:after {
  767. content: '';
  768. width: 0;
  769. height: 0;
  770. border-right: 10px solid transparent;
  771. border-bottom: 10px solid transparent;
  772. border-top: 10px solid #e0e5ed;
  773. border-left: 10px solid transparent;
  774. position: absolute;
  775. left: 24px;
  776. bottom: -20px;
  777. }
  778. .img:before {
  779. content: '';
  780. width: 0;
  781. height: 0;
  782. border-right: 9px solid transparent;
  783. border-bottom: 9px solid transparent;
  784. border-top: 9px solid #fff;
  785. border-left: 9px solid transparent;
  786. position: absolute;
  787. left: 25px;
  788. bottom: -18px;
  789. z-index: 1;
  790. }
  791. }
  792. }
  793. </style>
  794. <style>
  795. .el-select .el-input {
  796. width: 130px;
  797. }
  798. .avatar-uploader img{max-width: 200px}
  799. .input-with-select .el-input-group__prepend {
  800. background-color: #fff;
  801. }
  802. .lenrn_content{width: 1000px;margin: 0px auto;background: white}
  803. input::-webkit-outer-spin-button,
  804. input::-webkit-inner-spin-button {
  805. -webkit-appearance: none !important;
  806. }
  807. input[type="number"]{
  808. -moz-appearance: textfield !important;
  809. }
  810. .el-form-item__content .content-field span{line-height: normal}
  811. .cropper-content{
  812. width: 100%;
  813. height: 300px;
  814. }
  815. .cropper {
  816. width: 100%;
  817. height: 240px;
  818. }
  819. .btnGroup{
  820. float: right;
  821. margin-top: 10px;
  822. margin-right: 15px;
  823. }
  824. </style>
  825. <style lang="scss">
  826. // 编辑器样式
  827. .content-editor {
  828. .my-editor {
  829. .ql-snow {
  830. border: 1px solid #d7dfe8 !important;
  831. border-radius: 3px 3px 0 0 !important;
  832. }
  833. .quill-editor {
  834. border-width: 1px !important;
  835. border-top: 0 !important;
  836. border-color: #d7dfe8 !important;
  837. border-radius: 0 0 3px 3px !important;
  838. }
  839. }
  840. }
  841. // 图片上传器样式
  842. .consult-image-uploader {
  843. .el-upload-list__item {
  844. width: 300px !important;
  845. height: 168.75px !important;
  846. line-height: 168.75px !important;
  847. }
  848. .el-upload--picture-card {
  849. width: 300px !important;
  850. height: 168.75px !important;
  851. line-height: 168.75px !important;
  852. .el-upload-list__item-thumbnail {
  853. object-fit: scale-down !important;
  854. }
  855. }
  856. .el-upload-list--picture-card {
  857. .el-upload-list__item-thumbnail {
  858. object-fit: scale-down !important;
  859. }
  860. }
  861. }
  862. </style>