thumbnail-panel.vue 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454
  1. <template>
  2. <div class="page-thumbnail-panel" v-loading="loading" v-if="pageData">
  3. <span class="unpublish" v-if="!pageData.isPublish && showPublishState">未发布</span>
  4. <div class="thumbnail-panel-cover">
  5. <div class="header-mask">
  6. <div class="details-btn" @click="preview(pageData._id)">预览</div>
  7. </div>
  8. <div class="image-wrapper">
  9. <img :src="pageData.coverImage || defaultCoverImage" alt=""/>
  10. </div>
  11. </div>
  12. <div class="page-item-title border-T ellipsis">
  13. <span class="item-title-i" :title="pageData.title">{{pageData.title || '未命名作品'}}</span>
  14. </div>
  15. <div class="border-T thumbnail-panel-btn" v-if="btnList.length">
  16. <div class="btn-wrapper" v-if="btnList.includes('edit')">
  17. <el-button type="text" size="mini" @click="edit">编辑</el-button>
  18. </div>
  19. <div class="btn-wrapper" v-if="btnList.includes('useTemplate')">
  20. <el-button type="text" size="mini" @click="useTemplate">使用模板</el-button>
  21. </div>
  22. <div class="btn-wrapper" v-if="btnList.includes('copyTemplate')">
  23. <el-button type="text" size="mini" @click="copyPage">复制</el-button>
  24. </div>
  25. <div class="btn-wrapper" v-if="showMoreBtn">
  26. <el-dropdown @command="command" placement="top-start">
  27. <el-button type="text" size="mini">更多 <i class="el-icon-more-outline"></i></el-button>
  28. <el-dropdown-menu>
  29. <template v-for="(item, index) in operationDataList">
  30. <el-dropdown-item
  31. :key="index"
  32. :command="item.eventType"
  33. v-if="btnList.includes(item.eventType)"
  34. >
  35. <div :class="item.extraClassName">
  36. {{item.title}}
  37. </div>
  38. </el-dropdown-item>
  39. </template>
  40. </el-dropdown-menu>
  41. </el-dropdown>
  42. </div>
  43. </div>
  44. </div>
  45. <div class="page-thumbnail-panel create" v-loading="loading" v-else>
  46. <div class="temp-create" @click="newPage">
  47. <i class="el-icon-plus"></i>
  48. <p class="paddingT10">新建页面</p>
  49. </div>
  50. </div>
  51. </template>
  52. <script>
  53. import {
  54. Dropdown,
  55. DropdownMenu,
  56. DropdownItem,
  57. } from 'element-ui'
  58. import editorProjectConfig from '@/pages/editor/DataModel'
  59. import addCooperationer from '@/components/add-cooperationer/index.js'
  60. export default {
  61. props: {
  62. showPublishState: {
  63. type: Boolean,
  64. default: true
  65. },
  66. showMoreBtn: {
  67. type: Boolean,
  68. default: true
  69. },
  70. pageType: {
  71. type: String,
  72. default: 'h5'
  73. },
  74. pageData: Object,
  75. // 操作按钮显示哪些按钮 根据type来匹配。
  76. btnList: {
  77. type: Array,
  78. default: () => {
  79. return []
  80. }
  81. },
  82. },
  83. components: {
  84. [Dropdown.name]: Dropdown,
  85. [DropdownMenu.name]: DropdownMenu,
  86. [DropdownItem.name]: DropdownItem
  87. },
  88. computed: {
  89. pageLinkMap () {
  90. return [
  91. {
  92. label: '主域名',
  93. desc: '用于PC端页面使用',
  94. domain: 'https://www.jianyu360.cn/h5-pages/' + this.pageData._id
  95. },
  96. {
  97. label: '微信域名',
  98. desc: '用于手机微信端页面',
  99. domain: 'https://wx.jianyu360.cn/h5-pages/' + this.pageData._id
  100. },
  101. {
  102. label: 'H5',
  103. desc: '用于手机H5端页面',
  104. domain: 'https://h5.jianyu360.cn/jyapp/view/' + this.pageData._id
  105. },
  106. {
  107. label: 'APP端',
  108. desc: '用于APP端页面(常用与广告位无需配置域名)',
  109. domain: '/jyapp/view/' + this.pageData._id
  110. },
  111. {
  112. label: '开发测试',
  113. desc: '用于开发测试环节预览使用的地址',
  114. domain: this.$config.baseURL + '/view/' + this.pageData._id
  115. }
  116. ]
  117. },
  118. },
  119. data() {
  120. return {
  121. loading: false,
  122. defaultCoverImage: require('@/common/images/pagecover-image.png'),
  123. operationDataList: [{
  124. title: '发布',
  125. eventType: 'publish',
  126. extraClassName: '',
  127. iconClass: ''
  128. },
  129. // {
  130. // title: '发布模板市场',
  131. // eventType: 'publishTemplate',
  132. // extraClassName: '',
  133. // iconClass: ''
  134. // },
  135. {
  136. title: '复制链接',
  137. eventType: 'copyUrl',
  138. iconClass: ''
  139. },
  140. // {
  141. // title: '设为我的模板',
  142. // eventType: 'setTemplate',
  143. // iconClass: ''
  144. // }, {
  145. // title: '页面数据',
  146. // eventType: 'viewPageData',
  147. // iconClass: ''
  148. // },
  149. {
  150. title: '协作设置',
  151. eventType: 'cooperation',
  152. iconClass: ''
  153. }, {
  154. title: '删除',
  155. eventType: 'delete',
  156. extraClassName: 'error',
  157. iconClass: ''
  158. }, {
  159. title: '退出协作',
  160. eventType: 'unCooperation',
  161. extraClassName: 'error',
  162. iconClass: ''
  163. }]
  164. }
  165. },
  166. methods: {
  167. /**
  168. * 操作命令
  169. * @param type
  170. */
  171. command(type) {
  172. switch (type) {
  173. case 'publish':
  174. this.publish();
  175. break;
  176. case 'copyUrl':
  177. this.copyUrl();
  178. break;
  179. case 'setTemplate':
  180. this.setTemplate();
  181. break;
  182. case 'viewPageData':
  183. this.viewPageData();
  184. break;
  185. case 'cooperation':
  186. this.cooperation();
  187. break;
  188. case 'delete':
  189. this.delete();
  190. break;
  191. case 'unCooperation':
  192. this.unCooperation();
  193. break;
  194. case 'publishTemplate':
  195. this.publishTemplate();
  196. break;
  197. }
  198. },
  199. // 新建页面
  200. newPage() {
  201. let newPageData = editorProjectConfig.getProjectConfig(this.pageType)
  202. this.loading = true;
  203. debugger
  204. this.$API.createPage({
  205. ...newPageData,
  206. pageMode: this.pageType
  207. }).then(res => {
  208. this.loading = false;
  209. if (res.body) {
  210. this.$router.push({name: 'Editor', query: {id: res.body._id}})
  211. }
  212. }).catch(() => {
  213. this.loading = false;
  214. })
  215. },
  216. // 编辑
  217. edit() {
  218. this.$router.push({name: 'Editor', query: {id: this.pageData._id}})
  219. },
  220. // 复制页面
  221. copyPage() {
  222. this.loading = true;
  223. this.$API.copyPage({id: this.pageData._id}).then(() => {
  224. this.loading = false;
  225. this.$router.go(0);//刷新页面不跳转
  226. }).catch(() => {
  227. this.loading = false;
  228. })
  229. },
  230. // 使用模板,与复制模板目前方法只是更改了跳转方式
  231. useTemplate(){
  232. this.loading = true;
  233. this.$API.copyPage({id: this.pageData._id}).then(res => {
  234. this.loading = false;
  235. this.$router.push({name: 'Editor', query: {id: res.body._id}}) //跳转复制页面内
  236. }).catch(() => {
  237. this.loading = false;
  238. })
  239. },
  240. // 发布
  241. publish() {
  242. this.loading = true;
  243. this.$API.publishPage({id: this.pageData._id}).then(() => {
  244. this.loading = false;
  245. this.$message.success('发布成功');
  246. this.preview(this.pageData._id);
  247. this.$emit('refresh');
  248. }).catch(() => {
  249. this.loading = false;
  250. })
  251. },
  252. // 预览
  253. preview(id) {
  254. this.$emit('showPreview', id)
  255. },
  256. // 复制链接
  257. copyUrl() {
  258. this.doCopyAll()
  259. },
  260. doCopyAll: function () {
  261. const content = this.pageLinkMap.map(item => `${item.label}: ${item.domain}`).join('\n\n')
  262. this.$copyText(content).then(() => {
  263. this.$message.success('已复制所有平台链接')
  264. })
  265. },
  266. // 设为我的模板
  267. setTemplate() {
  268. this.loading = true;
  269. this.$API.setTemplatePage({id: this.pageData._id}).then(() => {
  270. this.loading = false;
  271. this.$message.success('已添加到我的模板')
  272. }).catch(() => {
  273. this.loading = false;
  274. })
  275. },
  276. // 页面数据
  277. viewPageData() {
  278. this.$router.push({name: 'pageDataDetail', query: {id: this.pageData._id}})
  279. },
  280. // 协作设置
  281. cooperation() {
  282. addCooperationer(this.pageData._id)
  283. },
  284. // 删除
  285. delete() {
  286. this.$alert('确认删除页面?删除后,将无法访问此页面?', '操作提示', {
  287. confirmButtonText: '确定',
  288. cancelButtonText: '取消',
  289. type: 'warning',
  290. }).then(() => {
  291. this.$API.deletePage({id: this.pageData._id}).then(() => {
  292. this.$message.success('删除成功!');
  293. this.$emit('refresh')
  294. })
  295. })
  296. },
  297. // 退出协作
  298. unCooperation() {
  299. this.$alert('确认退出协作编辑?退出后,将无法编辑此页面?', '操作提示', {
  300. confirmButtonText: '确定',
  301. cancelButtonText: '取消',
  302. type: 'warning',
  303. }).then(() => {
  304. this.$API.delCooperation({pageId: this.pageData._id, userId: this.$store.state.user.userInfo._id}).then(() => {
  305. this.$message.success('已退出!');
  306. this.$emit('refresh')
  307. })
  308. })
  309. },
  310. // 发布模板到模板市场
  311. publishTemplate() {
  312. this.loading = true;
  313. this.$API.publishPage({id: this.pageData._id}).then(() => {
  314. this.loading = false;
  315. this.$message.success('发布成功');
  316. }).catch(() => {
  317. this.loading = false;
  318. })
  319. }
  320. }
  321. }
  322. </script>
  323. <style lang="scss" scoped>
  324. .page-thumbnail-panel {
  325. width: 224px;
  326. height: 296px;
  327. border-radius: 4px;
  328. overflow: hidden;
  329. display: flex;
  330. flex-direction: column;
  331. background: white;
  332. position: relative;
  333. transition: all 0.28s;
  334. &:hover {
  335. box-shadow: 0 0 16px 0 rgba(0, 0, 0, .16);
  336. transform: translate3d(0, -2px, 0);
  337. .header-mask {
  338. opacity: 1;
  339. }
  340. }
  341. .header-mask {
  342. position: absolute;
  343. top: 0;
  344. left: 0;
  345. opacity: 0;
  346. background-color: rgba(0, 0, 0, .3);
  347. width: 100%;
  348. height: 100%;
  349. border-radius: 4px 4px 0 0;
  350. padding-top: 92px;
  351. text-align: center;
  352. transition: top .28s ease, opacity .28s ease, height .28s ease;
  353. .details-btn {
  354. display: inline-block;
  355. width: 120px;
  356. height: 44px;
  357. font-size: 18px;
  358. line-height: 44px;
  359. border-radius: 22px;
  360. border: 1px solid #fff;
  361. color: #fff;
  362. cursor: pointer;
  363. }
  364. }
  365. }
  366. .thumbnail-panel-cover {
  367. flex: 1;
  368. position: relative;
  369. overflow: hidden;
  370. .image-wrapper {
  371. width: 100%;
  372. height: 100%;
  373. overflow: hidden;
  374. padding: 5px;
  375. z-index: 10;
  376. img {
  377. display: block;
  378. width: 100%;
  379. // height: 100%;
  380. }
  381. }
  382. }
  383. .page-item-title {
  384. height: 36px;
  385. line-height: 36px;
  386. padding: 0 8px;
  387. font-size: 14px;
  388. }
  389. .thumbnail-panel-btn {
  390. height: 36px;
  391. width: 100%;
  392. display: flex;
  393. flex-direction: row;
  394. .btn-wrapper {
  395. flex: 1;
  396. text-align: center;
  397. }
  398. }
  399. .unpublish {
  400. position: absolute;
  401. top: 5px;
  402. left: 5px;
  403. font-size: 12px;
  404. display: block;
  405. padding: 0 10px;
  406. height: 30px;
  407. line-height: 30px;
  408. background-color: #76838f;
  409. color: #fff;
  410. border-top-left-radius: 4px;
  411. border-bottom-right-radius: 12px;
  412. z-index: 10;
  413. }
  414. .page-thumbnail-panel.create {
  415. padding: 16px;
  416. text-align: center;
  417. .temp-create {
  418. display: inline-block;
  419. width: 100%;
  420. height: 100%;
  421. border: 1px solid #e6ebed;
  422. border-radius: 3px;
  423. padding-top: 100px;
  424. transition: all 0.28s;
  425. cursor: pointer;
  426. &:hover {
  427. color: $primary;
  428. border-color: $primary;
  429. }
  430. }
  431. .null-create {
  432. display: inline-block;
  433. width: 100%;
  434. height: 42px;
  435. line-height: 42px;
  436. border: 1px solid #4a4e52;
  437. transition: all 0.28s;
  438. cursor: pointer;
  439. &:hover {
  440. color: $primary;
  441. border-color: $primary;
  442. }
  443. }
  444. }
  445. </style>