add.vue 31 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873
  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" 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"></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"></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 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:3,
  281. selectedConsultCate: [],//选中的技能分类
  282. consultCate: [], // 技能分类数据源
  283. saleInfo:{
  284. point:"1",
  285. pricetype:"1",
  286. img_icon:"",
  287. video_img:"",
  288. ewm:"",
  289. },
  290. dialogVisible: false,
  291. // 裁剪组件的基础配置option
  292. option: {
  293. img: '', // 裁剪图片的地址
  294. type:'',//类型
  295. info: true, // 裁剪框的大小信息
  296. outputSize: 1, // 裁剪生成图片的质量
  297. outputType: 'jpeg', // 裁剪生成图片的格式
  298. canScale: false, // 图片是否允许滚轮缩放
  299. autoCrop: true, // 是否默认生成截图框
  300. // autoCropWidth: 300, // 默认生成截图框宽度
  301. // autoCropHeight: 200, // 默认生成截图框高度
  302. fixedBox: true, // 固定截图框大小 不允许改变
  303. fixed: true, // 是否开启截图框宽高固定比例
  304. fixedNumber: [310, 175], // 截图框的宽高比例
  305. full: true, // 是否输出原图比例的截图
  306. canMoveBox: false, // 截图框能否拖动
  307. original: false, // 上传图片按照原始比例渲染
  308. centerBox: false, // 截图框是否被限制在图片里面
  309. infoTrue: true // true 为展示真实输出图片宽高 false 展示看到的截图框宽高
  310. },
  311. teacherInfo:{
  312. img:""
  313. },
  314. video_list:[{"id":"","video_name":"","list":[{"id":"","kc_id":"1","progress":0,"video_name":"","checked":false,"time_type":0,"ymd":"","his":""}]}],
  315. }
  316. },
  317. mounted () {
  318. this.needLogin()
  319. var sale_id = this.$route.query.id ? this.$route.query.id : 0;
  320. this._getConsultCate()
  321. if (sale_id!=0) {
  322. this.sale_id=sale_id;
  323. this.getDetail();
  324. }
  325. if (this.saleInfo.price > 0)
  326. {
  327. this.saleInfo.pricetype="2";
  328. }
  329. else
  330. {
  331. this.saleInfo.pricetype="1";
  332. }
  333. },
  334. methods: {
  335. time_type(zj_id,kc_id,type){
  336. this.video_list[zj_id].list[kc_id].time_type=type;
  337. },
  338. // 点击裁剪,这一步是可以拿到处理后的地址
  339. finish() {
  340. this.$refs.cropper.getCropBlob((data) => {
  341. console.log("裁剪",data)
  342. let formData = new FormData();
  343. formData.append("file", data);
  344. this.$axios.$post('/upload_image', formData,{
  345. headers: {
  346. "Content-Type": "multipart/form-data"
  347. }
  348. }).then(res => {
  349. this.dialogVisible = false
  350. this.type=0;
  351. if(this.option.type==1)
  352. {
  353. this.saleInfo.img_icon=res.filename;
  354. }
  355. else if(this.option.type==2)
  356. {
  357. this.teacherInfo.img=res.filename;
  358. }
  359. else if(this.option.type==3)
  360. {
  361. this.saleInfo.video_img=res.filename;
  362. }
  363. }).catch(err => {
  364. })
  365. })
  366. },
  367. add_new_zj(){
  368. this.zj_disabled=true;
  369. var new_object={"id":"","video_name":"","list":[{"id":"","kc_id":"","progress":0,"video_name":"","checked":false,"time_type":0,"ymd":"","his":""}]};
  370. this.video_list.push(new_object);
  371. this.add_video();
  372. },
  373. add_new_kc(zj_id){
  374. this.kc_disabled=true;
  375. var new_object={"id":"","kc_id":"","progress":0,"video_name":"","checked":false,"time_type":0,"ymd":"","his":""};
  376. this.video_list[zj_id].list.push(new_object);
  377. this.add_video();
  378. },
  379. del_kc(zj_id,kc_id,id){
  380. /*for(var i=0;i<this.video_list.length;i++)
  381. {
  382. for(var j=0;j<this.video_list[i].list.length;j++)
  383. {
  384. if(zj_id==i && kc_id==j)
  385. {
  386. this.video_list[i].list.splice(j,1);
  387. }
  388. }
  389. }*/
  390. this.$axios.$post('/api/sale/del_video', { sale_id: this.sale_id,id:id}).then(res => {
  391. if (res.status === 1) {
  392. this.video_list=res.data;
  393. }
  394. }).catch(err => {
  395. })
  396. },
  397. del_zj(zj_id,id){
  398. if(this.video_list.length==1){
  399. this.$message.error('已经是最后一个章节了不能删除了')
  400. return false
  401. }
  402. /* for(var i=0;i<this.video_list.length;i++)
  403. {
  404. if(zj_id==i)
  405. {
  406. this.video_list.splice(i,1);
  407. }
  408. }*/
  409. this.$axios.$post('/api/sale/del_video', { sale_id: this.sale_id,id:id}).then(res => {
  410. if (res.status === 1) {
  411. this.video_list=res.data;
  412. }
  413. }).catch(err => {
  414. })
  415. },
  416. active_set(val,return_=true){
  417. if(return_)
  418. {
  419. this.active=val;
  420. return;
  421. }
  422. if(val==2)
  423. {
  424. this.saleInfo.cate_id_one=this.saleInfo.cate_id;
  425. this.saleInfo.cate_id_two=0;
  426. this.add_one();
  427. }
  428. else if(val==3)
  429. {
  430. this.add_two();
  431. }
  432. else if(val==4)
  433. {
  434. this.add_three();//效验课程数据
  435. }
  436. else if(val==5)
  437. {
  438. this.add_fore();//提交审核
  439. }
  440. else
  441. {
  442. this.active=val;
  443. }
  444. },
  445. upload_img_success(res, file, fileList,type){
  446. if(type==1)
  447. {
  448. let filename=res.filename;
  449. // 上传成功后将图片地址赋值给裁剪框显示图片
  450. this.$nextTick(() => {
  451. this.option.img =filename;
  452. this.option.fixedNumber=[310,175]
  453. this.option.type=type;
  454. this.dialogVisible = true
  455. })
  456. }
  457. else if(type==2)
  458. {
  459. let filename=res.filename;
  460. // 上传成功后将图片地址赋值给裁剪框显示图片
  461. this.$nextTick(() => {
  462. this.option.img =filename;
  463. this.option.fixedNumber=[100,100]
  464. this.option.type=type;
  465. this.dialogVisible = true
  466. })
  467. }
  468. else if(type==3)
  469. {
  470. let filename=res.filename;
  471. // 上传成功后将图片地址赋值给裁剪框显示图片
  472. this.$nextTick(() => {
  473. this.option.img =filename;
  474. this.option.fixedNumber=[739,416]
  475. this.option.type=type;
  476. this.dialogVisible = true
  477. })
  478. }
  479. else if(type==4)
  480. {
  481. this.saleInfo.ewm=res.filename;
  482. }
  483. },
  484. editor_change(val,type)//编辑器内容发生改变的时候
  485. {
  486. if(type==1) {
  487. this.saleInfo.content = val;
  488. }
  489. else if(type==2) {
  490. this.teacherInfo.content = val;
  491. }
  492. else if(type==3) {
  493. this.saleInfo.notice_msg = val;
  494. }
  495. },
  496. fileChange (e,zj_id,kc_id) {
  497. let videoFile = e.file
  498. let filename=e.file.name;
  499. this.createUploader(videoFile,zj_id,kc_id,filename)
  500. },
  501. createUploader (videoFile,zj_id,kc_id,filename) {
  502. let self = this
  503. let uploader = new AliyunUpload.Vod({
  504. timeout: 60000,
  505. partSize: 1048576,
  506. parallel: 5,
  507. retryCount: 3,
  508. retryDuration: 2,
  509. region: 'cn-shanghai',
  510. userId: '1024',
  511. // 添加文件成功
  512. addFileSuccess: function (uploadInfo) {
  513. self.statusText = '添加文件成功, 等待上传...'
  514. console.log("addFileSuccess: " + uploadInfo.file.name)
  515. },
  516. // 开始上传
  517. onUploadstarted: function (uploadInfo) {
  518. self.$axios.$post("/api/sale/video", {filename: uploadInfo.file.name}).then(({data}) => {
  519. let uploadAuth = data.UploadAuth;
  520. let uploadAddress = data.UploadAddress;
  521. let videoId = data.VideoId;
  522. self.videoId = data.VideoId;
  523. self.video_list[zj_id].list[kc_id].temp_video_id=videoId;
  524. self.video_list[zj_id].list[kc_id].video_name=data.filename;
  525. uploader.setUploadAuthAndAddress(uploadInfo, uploadAuth, uploadAddress, videoId)
  526. })
  527. self.statusText = '文件开始上传...'
  528. console.log("onUploadStarted:" + uploadInfo.file.name + ", endpoint:" + uploadInfo.endpoint + ", bucket:" + uploadInfo.bucket + ", object:" + uploadInfo.object)
  529. },
  530. // 文件上传成功
  531. onUploadSucceed: function (uploadInfo) {
  532. console.log("filename"+filename);
  533. console.log("onUploadSucceed: " + uploadInfo.file.name + ", endpoint:" + uploadInfo.endpoint + ", bucket:" + uploadInfo.bucket + ", object:" + uploadInfo.object)
  534. self.video_list[zj_id].list[kc_id].video_id= self.video_list[zj_id].list[kc_id].temp_video_id;
  535. //执行保存
  536. self.add_video();
  537. },
  538. // 文件上传进度,单位:字节, 可以在这个函数中拿到上传进度并显示在页面上
  539. onUploadProgress: function (uploadInfo, totalSize, progress) {
  540. let progressPercent = Math.ceil(progress * 100)
  541. self.video_list[zj_id].list[kc_id].progress=progressPercent;
  542. },
  543. })
  544. uploader.addFile(videoFile);
  545. uploader.startUpload();//上传文件
  546. },
  547. /** 获取咨询分类 */
  548. async _getConsultCate () {
  549. this.$axios.$post('/api/sale/cateListYes', { type: 4, point: 1 }).then(res => {
  550. if (res.status === 1) {
  551. let consultCate = res.data || []
  552. this.consultCate = consultCate.map(item => {
  553. let children = item.child_list.map(child => {
  554. return {
  555. value: child.category_id,
  556. label: child.name
  557. }
  558. })
  559. return {
  560. value: item.category_id,
  561. label: item.name,
  562. children: children
  563. }
  564. })
  565. }
  566. }).catch(err => {
  567. console.log('get consult cate error: ', err)
  568. })
  569. },
  570. /** 第一步添加 */
  571. async add_one() {
  572. if(!this.saleInfo.title)
  573. {
  574. this.$message.error('课程名称必须填写');
  575. return false;
  576. }
  577. if(!this.saleInfo.desc)
  578. {
  579. this.$message.error('课程概述必须填写');
  580. return false;
  581. }
  582. if(!this.saleInfo.img_icon)
  583. {
  584. this.$message.error('课程封面必须上传');
  585. return false;
  586. }
  587. if(this.saleInfo.pricetype==2 && !this.saleInfo.price>0)
  588. {
  589. this.$message.error('价格必须设置');
  590. return false;
  591. }
  592. if(!this.saleInfo.cate_id_one)
  593. {
  594. this.$message.error('分类必须选择');
  595. return false;
  596. }
  597. if(!this.saleInfo.content)
  598. {
  599. this.$message.error('课程描述必须填写');
  600. return false;
  601. }
  602. var data=JSON.stringify(this.saleInfo);
  603. await this.$axios.$post('/api/sale/sale_add_one', {sale_id:this.sale_id,data: data}).then(res => {
  604. if (res.status === 1) {
  605. this.active=2;
  606. this.sale_id=res.data.sale_id;
  607. this.saleInfo.sale_id=res.data.sale_id;
  608. }
  609. }).catch(err => {
  610. })
  611. },
  612. /** 第二步添加 */
  613. async add_two() {
  614. if(!this.teacherInfo.name)
  615. {
  616. this.$message.error('讲师名称必须填写');
  617. return false;
  618. }
  619. if(!this.teacherInfo.op)
  620. {
  621. this.$message.error('职称必须填写');
  622. return false;
  623. }
  624. if(!this.teacherInfo.img)
  625. {
  626. this.$message.error('封面必须上传');
  627. return false;
  628. }
  629. if(!this.teacherInfo.content)
  630. {
  631. this.$message.error('自我介绍必须填写');
  632. return false;
  633. }
  634. this.teacherInfo.sale_id=this.sale_id;
  635. var data=JSON.stringify(this.teacherInfo);
  636. await this.$axios.$post('/api/sale/sale_add_two', { data: data}).then(res => {
  637. if (res.status === 1) {
  638. this.active=3;
  639. }
  640. }).catch(err => {
  641. })
  642. },
  643. /** 第三步添加 */
  644. async add_three() {
  645. var video_list=JSON.stringify(this.video_list);
  646. var saleInfo=JSON.stringify(this.saleInfo);
  647. await this.$axios.$post('/api/sale/sale_add_three', {sale_id:this.sale_id,video_list:video_list,saleInfo: saleInfo}).then(res => {
  648. if (res.status === 1) {
  649. this.active=4;
  650. }
  651. }).catch(err => {
  652. })
  653. },
  654. /** 第四步添加 */
  655. async add_fore() {
  656. var video_list=JSON.stringify(this.video_list);
  657. var saleInfo=JSON.stringify(this.saleInfo);
  658. await this.$axios.$post('/api/sale/sale_add_fore', {sale_id:this.sale_id,video_list:video_list,saleInfo: saleInfo}).then(res => {
  659. if (res.status === 1) {
  660. this.$message.success('我们已经收到您的审核提交,请耐心等待');
  661. }
  662. }).catch(err => {
  663. })
  664. },
  665. /** 课程添加 */
  666. async add_video() {
  667. this.kc_disabled=true;
  668. this.zj_disabled=true;
  669. var data=JSON.stringify(this.video_list);
  670. await this.$axios.$post('/api/sale/sale_add_video', { data: data,sale_id:this.sale_id}).then(res => {
  671. if (res.status === 1) {
  672. this.video_list=res.data;
  673. }
  674. this.kc_disabled=false;
  675. this.zj_disabled=false;
  676. }).catch(err => {
  677. this.kc_disabled=false;
  678. this.zj_disabled=false;
  679. })
  680. },
  681. /** 课程添加 */
  682. async getDetail() {
  683. await this.$axios.$post('/api/sale/info', {sale_id:this.sale_id}).then(res => {
  684. if (res.status === 1) {
  685. if(res.data.video.length>0)
  686. {
  687. this.video_list=res.data.video;
  688. }
  689. this.saleInfo=res.data.sale;
  690. this.teacherInfo=res.data.teacher;
  691. this.selectedConsultCate = [res.data.sale.cate_id_one, res.data.sale.cate_id_two]
  692. }
  693. }).catch(err => {
  694. })
  695. },
  696. }
  697. }
  698. </script>
  699. <style scope lang="scss">
  700. @import "@/assets/css/consult/create.scss";
  701. .common-upload {
  702. display: flex;
  703. align-items: end;
  704. .look-img {
  705. margin-left: 130px;
  706. .text {
  707. font-size: 14px;
  708. font-family: PingFangSC, PingFangSC-Medium;
  709. font-weight: 500;
  710. color: #308eff;
  711. cursor: pointer;
  712. }
  713. .text-hover:hover {
  714. position: relative;
  715. .img {
  716. display: block;
  717. }
  718. }
  719. .img {
  720. background: #fff;
  721. border: 1px solid #e0e5ed;
  722. box-shadow: 0px 2px 20px 0px rgba(22,40,63,0.15);
  723. border-radius: 10px;
  724. text-align: center;
  725. position: relative;
  726. position: absolute;
  727. top: -120px;
  728. left: -114px;
  729. width: 300px;
  730. height: 120px;
  731. display: none;
  732. transition: all ease .3s;
  733. .active-img2 {
  734. width: 234px;
  735. height: 71px;
  736. background-size: cover;
  737. overflow: hidden;
  738. margin-top: 24px;
  739. }
  740. .active-img1 {
  741. width: 262px;
  742. height: 78px;
  743. background-size: cover;
  744. overflow: hidden;
  745. margin-top: 22px;
  746. }
  747. }
  748. .img:after {
  749. content: '';
  750. width: 0;
  751. height: 0;
  752. border-right: 10px solid transparent;
  753. border-bottom: 10px solid transparent;
  754. border-top: 10px solid #e0e5ed;
  755. border-left: 10px solid transparent;
  756. position: absolute;
  757. left: 50%;
  758. bottom: -20px;
  759. transform: translate(-50%, 0);
  760. }
  761. .img:before {
  762. content: '';
  763. width: 0;
  764. height: 0;
  765. border-right: 9px solid transparent;
  766. border-bottom: 9px solid transparent;
  767. border-top: 9px solid #fff;
  768. border-left: 9px solid transparent;
  769. position: absolute;
  770. left: 50%;
  771. bottom: -18px;
  772. transform: translate(-50%, 0);
  773. z-index: 1;
  774. }
  775. }
  776. }
  777. </style>
  778. <style>
  779. .el-select .el-input {
  780. width: 130px;
  781. }
  782. .avatar-uploader img{max-width: 200px}
  783. .input-with-select .el-input-group__prepend {
  784. background-color: #fff;
  785. }
  786. .lenrn_content{width: 1000px;margin: 0px auto;background: white}
  787. input::-webkit-outer-spin-button,
  788. input::-webkit-inner-spin-button {
  789. -webkit-appearance: none !important;
  790. }
  791. input[type="number"]{
  792. -moz-appearance: textfield !important;
  793. }
  794. .el-form-item__content .content-field span{line-height: normal}
  795. .cropper-content{
  796. width: 100%;
  797. height: 300px;
  798. }
  799. .cropper {
  800. width: 100%;
  801. height: 240px;
  802. }
  803. .btnGroup{
  804. float: right;
  805. margin-top: 10px;
  806. margin-right: 15px;
  807. }
  808. </style>
  809. <style lang="scss">
  810. // 编辑器样式
  811. .content-editor {
  812. .my-editor {
  813. .ql-snow {
  814. border: 1px solid #d7dfe8 !important;
  815. border-radius: 3px 3px 0 0 !important;
  816. }
  817. .quill-editor {
  818. border-width: 1px !important;
  819. border-top: 0 !important;
  820. border-color: #d7dfe8 !important;
  821. border-radius: 0 0 3px 3px !important;
  822. }
  823. }
  824. }
  825. // 图片上传器样式
  826. .consult-image-uploader {
  827. .el-upload-list__item {
  828. width: 300px !important;
  829. height: 168.75px !important;
  830. line-height: 168.75px !important;
  831. }
  832. .el-upload--picture-card {
  833. width: 300px !important;
  834. height: 168.75px !important;
  835. line-height: 168.75px !important;
  836. .el-upload-list__item-thumbnail {
  837. object-fit: scale-down !important;
  838. }
  839. }
  840. .el-upload-list--picture-card {
  841. .el-upload-list__item-thumbnail {
  842. object-fit: scale-down !important;
  843. }
  844. }
  845. }
  846. </style>