index.vue 20 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636
  1. <template>
  2. <div class="kaifainAdd">
  3. <div class="topArea">
  4. <div class="title">
  5. 添加解决方案,成为合作伙伴
  6. <div class="backBox" @click="jumpTo()">
  7. <p class="backIcon"/>
  8. <p class="backWord">企业信息</p>
  9. </div>
  10. </div>
  11. <div class="line">
  12. </div>
  13. </div>
  14. <div class="bodyArea">
  15. <div class="statusBox" :class="{none: !(statusObj.isOk)}">
  16. <p>{{statusObj.name}}</p>
  17. </div>
  18. <div class="nameBox">
  19. <div class="stitle">方案名称</div>
  20. <el-input v-model="data.title" placeholder="20字以内 不能包含 & ¥ % / \ *"></el-input>
  21. </div>
  22. <div class="selectArea">
  23. <div class="left">
  24. <div class="stitle">行业领域</div>
  25. <el-select style="width: 280px" v-model="data.industry" placeholder="选择行业类型">
  26. <el-option
  27. v-for="item in industryList"
  28. :key="item.id"
  29. :label="item.name"
  30. :value="item.id">
  31. </el-option>
  32. </el-select>
  33. </div>
  34. <div class="right">
  35. <div class="stitle">技术分类</div>
  36. <el-select style="width: 427px" v-model="data.tech_type" placeholder="选择技术分类">
  37. <el-option
  38. v-for="item in techTypeList"
  39. :key="item.id"
  40. :label="item.name"
  41. :value="item.id">
  42. </el-option>
  43. </el-select>
  44. </div>
  45. </div>
  46. <div class="logoBox">
  47. <div class="stitle">缩略图</div>
  48. <div class="uploadInfo">
  49. <div class="left">
  50. <el-upload
  51. class="avatar-uploader"
  52. action="#"
  53. :show-file-list="false"
  54. :multiple="false"
  55. accept="image/png, image/jpeg"
  56. :before-upload="(file) => handleFileChange(file, 'images')"
  57. >
  58. <i v-if="data.images" class="el-icon-delete avatar-uploader-icon"
  59. @click.stop="(file) => handleDeleteFile('images')"></i>
  60. <img v-if="data.images" :src="data.images" class="avatar"/>
  61. <div v-else class="noneImage">
  62. <i class="el-icon-plus avatar-uploader-icon"></i>
  63. <span class="title">上传照片</span>
  64. </div>
  65. </el-upload>
  66. <p class="rightTips">支持JPG、PNG格式</p>
  67. </div>
  68. <div class="right">
  69. <p>(800*800,图片最大2M,最多1张)</p>
  70. </div>
  71. </div>
  72. </div>
  73. <div class="smallIntro">
  74. <div class="stitle">方案简介</div>
  75. <el-input v-model="data.description" placeholder="请用一句话来介绍您的方案,10-50字符"></el-input>
  76. </div>
  77. <div class="intro">
  78. <div class="stitle">方案介绍<span @click="jumpToOther">查看参考示例</span></div>
  79. <div class="editor">
  80. <editor :content="data.detail"
  81. @change="(val) => data.detail = val"
  82. :haveVideo="true"
  83. placeholder="支持图文混排,请至少添加:【文字描述】【方案视频】【方案介绍图片】【架构图片】【架构说明】等模块;可添加方案截图/PDF文档转图片,不低于500字"
  84. ></editor>
  85. </div>
  86. </div>
  87. <div class="successIntro">
  88. <div class="stitle">成功案例</div>
  89. <div class="list">
  90. <div class="titleCell">
  91. <div class="tt1"><p>品牌logo</p></div>
  92. <div class="tt2">案例描述</div>
  93. <div class="tt3">附件</div>
  94. <div class="tt4">操作</div>
  95. </div>
  96. <div class="cell"
  97. v-for="(item, index) in data.successful_case"
  98. @click="openEditCase(item)"
  99. >
  100. <div class="img">
  101. <img :src="item.logo" alt="">
  102. </div>
  103. <div class="content">
  104. <p>【{{data.title}}】帮助【{{item.title}}】提供解决方案</p>
  105. </div>
  106. <div class="pdf" @click.stop="openNewUrl(item)">
  107. <div class="icon"></div>
  108. <p>成功案例.PDF</p>
  109. </div>
  110. <div class="del" @click.stop="deleteCase(item)">
  111. <div class="icon"></div>
  112. </div>
  113. </div>
  114. <div class="addCell" @click="addSuccessInfo">
  115. <div class="icon"></div>
  116. <p>添加成功案例</p>
  117. </div>
  118. </div>
  119. </div>
  120. <div class="bottomBtn" v-if="Number(data.status) !== 2 ">
  121. <div class="preview" @click="preview">
  122. <p>预览</p>
  123. </div>
  124. <div class="submit" @click="submitAll">
  125. <p>提交审核</p>
  126. </div>
  127. <div class="keepTmp" @click="saveDraft()" v-if="!lastId || Number(data.status) === 0">
  128. <p>存草稿</p>
  129. </div>
  130. </div>
  131. </div>
  132. <el-dialog
  133. title="添加成功案例"
  134. :visible.sync="dialogVisible"
  135. width="613px"
  136. :append-to-body="true"
  137. :center="true"
  138. >
  139. <div class="diaContentWork">
  140. <div class="taskName">
  141. <div class="name">案例名称</div>
  142. <div class="value">
  143. <el-input v-model="dataItem.title" placeholder="请输入案例名称(2-10个字符)"></el-input>
  144. </div>
  145. </div>
  146. <div class="ourLogo">
  147. <div class="name">品牌logo</div>
  148. <div class="value">
  149. <div class="uploadInfo">
  150. <div class="left">
  151. <el-upload
  152. class="avatar-uploader"
  153. action="#"
  154. :show-file-list="false"
  155. :multiple="false"
  156. accept="image/png, image/jpeg"
  157. :before-upload="(file) => handleFileChange(file, 'logo')"
  158. >
  159. <i v-if="dataItem.logo" class="el-icon-delete avatar-uploader-icon"
  160. @click.stop="() => handleDeleteFile('logo') "></i>
  161. <img v-if="dataItem.logo" :src="dataItem.logo" class="avatar"/>
  162. <div v-else class="noneImage">
  163. <i class="el-icon-plus avatar-uploader-icon"></i>
  164. </div>
  165. </el-upload>
  166. </div>
  167. <div class="right">
  168. <p>(800*800,图片最大2M,最多1张)</p>
  169. </div>
  170. </div>
  171. </div>
  172. </div>
  173. <div class="taskFile">
  174. <div class="name">案例附件</div>
  175. <div class="value">
  176. <el-upload
  177. class="upload-demo"
  178. action="#"
  179. :show-file-list="true"
  180. :multiple="false"
  181. accept="application/pdf"
  182. :file-list="fileList"
  183. :before-upload="handlePDFFileChange"
  184. :before-remove="handlePDFFileRemove"
  185. >
  186. <div style="margin-top: 10px">
  187. <span class="uploadFileWord">立即上传</span>
  188. <span class="uploadFileTip">仅支持PDF格式(最大2M)</span>
  189. </div>
  190. </el-upload>
  191. </div>
  192. </div>
  193. <div class="taskDesc">
  194. <div class="name">案例描述</div>
  195. <div class="value">
  196. <editor :content="dataItem.description"
  197. @change="(val) => dataItem.description = val"
  198. :haveVideo="true"
  199. placeholder="支持图文混排,请至少添加不低于100字成功案例描述"
  200. ></editor>
  201. </div>
  202. </div>
  203. </div>
  204. <div class="dialog-footer">
  205. <div class="preview" @click="previewCase">
  206. <p>预览</p>
  207. </div>
  208. <div class="submit" @click="addCase"><p>提交</p></div>
  209. <div class="cancle" @click="dialogVisible=false"><p>取消</p></div>
  210. </div>
  211. </el-dialog>
  212. <KaifainFooter style="margin-top: 30px;" :data="footer"/>
  213. </div>
  214. </template>
  215. <script>
  216. import editor from "@/components/editor";
  217. import uploadFile from "@/mixins/uploadFile";
  218. import DealSeoFooter from "@/components/kaifain/dealSeoFooter"
  219. import KaifainFooter from "@/components/SeoFooter"
  220. export default {
  221. name: 'userSetting',
  222. components: {
  223. editor, KaifainFooter
  224. },
  225. data() {
  226. return {
  227. lastId: 0,
  228. data: {
  229. city: 1,
  230. industry: null, //所处行业的ID
  231. title: '', //服务名称
  232. description: '', //简单描述
  233. images: '', //封面图片,缩略图的地址URL
  234. detail: '',//具体的描述
  235. tech_type: null,//技术类型
  236. successful_case: [],
  237. status: 0
  238. },
  239. tempData: {},
  240. industryList: [],
  241. techTypeList: [],
  242. dialogVisible: false,
  243. dataItem: {
  244. provider_id: 0,//服务商ID
  245. title: '', //成功案例1
  246. logo: '',//http://www.baidu.com,URL
  247. description: '', //描述一下啊啥的发啊的算法
  248. file: '', //https://www.baidu.com,用户上传的PDF,格式必须为PDF,URL
  249. },
  250. fileList: [],
  251. }
  252. },
  253. async asyncData({ ...params}) {
  254. try {
  255. params.store.commit("updateNoneCommonFooter", true)
  256. } catch (e) {
  257. console.log("updateNoneCommonFooter", e)
  258. }
  259. let dealSeoFooterObj = new DealSeoFooter(params)
  260. let footer = await dealSeoFooterObj.dealData()
  261. return {
  262. ...footer,
  263. mobile: params.app.$deviceType.isMobile()
  264. };
  265. },
  266. mixins: [uploadFile],
  267. computed: {
  268. statusObj() {
  269. let status = Number(this.data.status || 0)
  270. let nameList = ['未申请', '审核中', '已入驻', '拒绝']
  271. let o = {
  272. isOk: status === 2,
  273. name: nameList[status]
  274. }
  275. return o
  276. },
  277. isDis() {
  278. let status = Number(this.data.status || 0)
  279. return status === 1
  280. }
  281. },
  282. async mounted() {
  283. this.needLogin();
  284. let query = new URLSearchParams(location.search)
  285. this.lastId = query.get('lastId') || 0
  286. //如果存在ID,则优先获取ID
  287. if (this.lastId) {
  288. this.getLastDetail()
  289. } else {
  290. this.getDraftInfo()
  291. }
  292. this.getTypeList()
  293. },
  294. methods: {
  295. jumpTo() {
  296. location.href = "/otherpage/companyComplete";
  297. },
  298. /** 图片文件上传 **/
  299. handleFileChange(file, type) {
  300. const isJPG = file.type === 'image/jpeg';
  301. const isPNG = file.type === 'image/png';
  302. const isLt2M = file.size / 1024 / 1024 < 2;
  303. if (!isJPG && !isPNG) {
  304. this.$message.error('上传头像图片只能是 JPG/PNG 格式!');
  305. return
  306. }
  307. if (!isLt2M) {
  308. this.$message.error('上传头像图片大小不能超过 2MB!');
  309. return
  310. }
  311. const formData = new FormData();
  312. formData.append("file", file);
  313. formData.append("original_filename", file.name);
  314. this.uploading = true;
  315. this.$axios
  316. .$post(`/upload_image`, formData, {
  317. headers: { "Content-Type": "multipart/form-data" }
  318. })
  319. .then(res => {
  320. if (type === 'images') {
  321. this.data.images = res.filename
  322. } else if (type === 'logo') {
  323. this.dataItem.logo = res.filename
  324. }
  325. console.log('type', type, this.data, this.dataItem)
  326. })
  327. .finally(() => {
  328. this.uploading = false;
  329. });
  330. },
  331. /** 删除问及爱你 **/
  332. handleDeleteFile(type) {
  333. if (type === 'images') {
  334. this.data.images = ''
  335. } else if (type === 'logo') {
  336. this.dataItem.logo = ''
  337. }
  338. },
  339. /** pdf上传 **/
  340. handlePDFFileChange(file, type) {
  341. console.log(file)
  342. const isPDF = file.type === 'application/pdf';
  343. const isLt2M = file.size / 1024 / 1024 < 2;
  344. if (!isPDF) {
  345. this.$message.error('上传文件只能是 JPG/PNG 格式!');
  346. return
  347. }
  348. // if (!isLt2M) {
  349. // this.$message.error('上传文件大小不能超过 2MB!');
  350. // return
  351. // }
  352. const formData = new FormData();
  353. formData.append("file", file);
  354. formData.append("original_filename", file.name);
  355. this.uploading = true;
  356. this.apiPrepareUpload(file, (res)=>{
  357. if (res.data && res.data.status === 1) {
  358. let url = res.data.data.url
  359. this.dataItem.file = url
  360. this.fileList = [{name:file.name, url: url}]
  361. } else {
  362. this.$message.error('上传失败')
  363. }
  364. })
  365. return false
  366. },
  367. /** pdf删除 **/
  368. handlePDFFileRemove() {
  369. this.fileList = []
  370. this.dataItem.file = ""
  371. },
  372. /** 弹窗逻辑 **/
  373. submitChange() {
  374. },
  375. /** 获取选择信息 **/
  376. getTypeList() {
  377. this.$axios.get('/api/kaifawu/get_options').then(res => {
  378. if (Number(res.data.status) === 1) {
  379. this.industryList = res.data.data.industries
  380. this.techTypeList = res.data.data.tech_types
  381. }
  382. })
  383. },
  384. /** 点击添加生成案例 **/
  385. async addSuccessInfo() {
  386. let res = null
  387. if (!this.data.id) {
  388. res = await this.saveDraft()
  389. }
  390. if (this.data.id || res) {
  391. this.dialogVisible = true
  392. this.dataItem = {
  393. provider_id: '',//服务商ID
  394. title: '', //成功案例1
  395. logo: '',//http://www.baidu.com,URL
  396. description: '', //描述一下啊啥的发啊的算法
  397. file: '', //https://www.baidu.com,用户上传的PDF,格式必须为PDF,URL
  398. }
  399. }
  400. },
  401. /** 删除案例 **/
  402. deleteCase(item) {
  403. this.$confirm('此操作将直接删除该成功案例, 是否继续?', '提示', {
  404. confirmButtonText: '确定',
  405. cancelButtonText: '取消',
  406. type: 'warning'
  407. }).then(() => {
  408. this.$axios.post('/api/kaifawu/delete_case', {
  409. id: item.id
  410. }).then(res => {
  411. if (Number(res.data.status) === 1) {
  412. this.$message({
  413. type: 'success',
  414. message: '删除成功!'
  415. });
  416. }
  417. })
  418. }).catch(() => {
  419. this.$message({
  420. type: 'info',
  421. message: '已取消删除'
  422. });
  423. });
  424. },
  425. /** 添加案例 **/
  426. async addCase() {
  427. let p = {}
  428. let keyList = ['id', 'provider_id', 'title', 'logo', 'description', 'file']
  429. for (let key of keyList) {
  430. if (this.dataItem[key]) {
  431. p[key] = this.dataItem[key]
  432. }
  433. }
  434. p.provider_id = this.data.id
  435. let isEdit = !!p.id
  436. if (!p.title || p.title.length < 2 || p.title.length > 20) {
  437. this.$message.warning('请填写2-20字符的案例名称!')
  438. return
  439. }
  440. if (!p.logo) {
  441. this.$message.warning('请上传品牌logo')
  442. return
  443. }
  444. if (!p.description || p.description.length < 100) {
  445. this.$message.warning('请填写100字符的案例描述')
  446. return
  447. }
  448. // if (!p.file) {
  449. // this.$message.warning('请上传案例附件')
  450. // return
  451. // }
  452. let url = isEdit ? '/api/kaifawu/update_case' : '/api/kaifawu/store_case'
  453. this.$axios.post(url, p).then(res => {
  454. if (Number(res.data.status) === 1) {
  455. this.dataItem.id = 4
  456. if (!isEdit) {
  457. this.data.successful_case.push(this.dataItem)
  458. } else {
  459. this.getDraftInfo()
  460. }
  461. this.dataItem = {
  462. provider_id: 0, title: '', logo: '', description: '', file: '',
  463. }
  464. this.dialogVisible = false
  465. this.fileList = []
  466. this.$message.success(isEdit ? '更新成功' : '添加成功')
  467. }
  468. })
  469. },
  470. openEditCase(item) {
  471. this.dataItem = {
  472. ...item
  473. }
  474. if (item.file) {
  475. this.fileList = [ {
  476. name: '成功案例.pdf',
  477. url: item.file
  478. } ]
  479. } else {
  480. this.fileList = []
  481. }
  482. this.dialogVisible = true
  483. console.log('openEditCase', this)
  484. },
  485. /** 获取草稿 **/
  486. getDraftInfo(isPreview) {
  487. this.$axios.get('/api/kaifawu/get_draft').then(res => {
  488. if (Number(res.data.status) == 1 && res.data.data) {
  489. let data = res.data.data
  490. if (!Array.isArray(data.successful_case)) {
  491. if (data.successful_case && typeof data.successful_case === "object") {
  492. data.successful_case = [ data.successful_case ]
  493. } else {
  494. data.successful_case = []
  495. }
  496. }
  497. data.city = Number(data.city)
  498. data.industry = Number(data.industry)
  499. data.tech_type = Number(data.tech_type)
  500. this.data = data
  501. }
  502. })
  503. },
  504. /** 传入id后处理 **/
  505. getLastDetail() {
  506. this.$axios.post('/api/kaifawu/get_provider', {
  507. id: this.lastId,
  508. self: 1,
  509. }).then(res=>{
  510. if (Number(res.data.status) === 1) {
  511. let data = res.data.data
  512. data.city = Number(data.city)
  513. data.industry = Number(data.industry)
  514. data.tech_type = Number(data.tech_type)
  515. if (!Array.isArray(data.successful_case)) {
  516. if (data.successful_case && typeof data.successful_case === "object") {
  517. data.successful_case = [ data.successful_case ]
  518. } else {
  519. data.successful_case = []
  520. }
  521. }
  522. this.data = data
  523. }
  524. })
  525. },
  526. /** 存储草稿 **/
  527. async saveDraft(isPublish, isPreview) {
  528. let url = '/api/kaifawu/store'
  529. if (this.data.id) {
  530. url = '/api/kaifawu/publish'
  531. }
  532. let p = {
  533. ...this.data,
  534. publish: isPublish ? 1 : 0
  535. }
  536. //服务名称
  537. if (!p.title) {
  538. this.$message.warning('请填写正确的服务名称(2-10字符)')
  539. return
  540. }
  541. //所处行业
  542. if (!p.industry) {
  543. this.$message.warning('请选择所处行业')
  544. return
  545. }
  546. //技术类型
  547. if (!p.tech_type) {
  548. this.$message.warning('请选择技术类型')
  549. return
  550. }
  551. //缩略图
  552. if (!p.images) {
  553. this.$message.warning('请上传缩略图')
  554. return
  555. }
  556. //方案简介
  557. if (!p.description || p.description.length < 10 || p.description.length > 50) {
  558. this.$message.warning('请填写正确的方案简介(10-50字符)')
  559. return
  560. }
  561. //方案简介
  562. if (!p.detail) {
  563. this.$message.warning('请填写方案介绍')
  564. return
  565. }
  566. // 更改已有的时候发布,校验状态
  567. if (p.publish === 1 && this.lastId && Number(this.data.status) === 2) {
  568. this.$message.warning('该解决方案已发布,暂不允许修改')
  569. return
  570. }
  571. let res = await this.$axios.post(url, p)
  572. if (Number(res.data.status) === 1) {
  573. if (!isPublish) {
  574. this.getDraftInfo(isPreview)
  575. this.$message.success('保存草稿成功')
  576. } else {
  577. this.$message.success('您已提交申请入驻,请耐心等待审核结果')
  578. setTimeout(()=>{
  579. location.href = "/company/" + this.$store.state.userinfo.uid
  580. }, 1000)
  581. }
  582. return true
  583. }
  584. },
  585. /** 确认提交 **/
  586. submitAll() {
  587. this.saveDraft(true)
  588. },
  589. /** 预览 **/
  590. preview() {
  591. try {
  592. localStorage.setItem('kaifainPreviewData', JSON.stringify(this.data))
  593. window.open(`/kaifain/preview`, '_black')
  594. } catch (e) {
  595. console.log('')
  596. }
  597. },
  598. /** 预览 **/
  599. previewCase() {
  600. try {
  601. localStorage.setItem('kaifainPreviewCaseData', JSON.stringify(this.dataItem))
  602. window.open(`/kaifain/previewCase`, '_black')
  603. } catch (e) {
  604. console.log('')
  605. }
  606. },
  607. openNewUrl(item) {
  608. window.open(item.file, '__black')
  609. },
  610. jumpToOther() {
  611. let url = "https://kaifain.proginn.com/s/10"
  612. window.open(url, '__black')
  613. }
  614. },
  615. }
  616. </script>
  617. <style lang="scss" scoped>
  618. @import '../../../assets/css/kaifain/kaifainAdd.scss';
  619. </style>
  620. <style lang="scss">
  621. @import '../../../assets/css/kaifain/kaifainAddNoScoped.scss';
  622. </style>