thumbnail-panel.vue 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420
  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. pageLink(){ //页面链接
  90. return this.$config.baseURL + '/view/' + this.pageData._id
  91. }
  92. },
  93. data() {
  94. return {
  95. loading: false,
  96. defaultCoverImage: require('@/common/images/pagecover-image.png'),
  97. operationDataList: [{
  98. title: '发布',
  99. eventType: 'publish',
  100. extraClassName: '',
  101. iconClass: ''
  102. }, {
  103. title: '发布模板市场',
  104. eventType: 'publishTemplate',
  105. extraClassName: '',
  106. iconClass: ''
  107. }, {
  108. title: '复制链接',
  109. eventType: 'copyUrl',
  110. iconClass: ''
  111. }, {
  112. title: '设为我的模板',
  113. eventType: 'setTemplate',
  114. iconClass: ''
  115. }, {
  116. title: '页面数据',
  117. eventType: 'viewPageData',
  118. iconClass: ''
  119. }, {
  120. title: '协作设置',
  121. eventType: 'cooperation',
  122. iconClass: ''
  123. }, {
  124. title: '删除',
  125. eventType: 'delete',
  126. extraClassName: 'error',
  127. iconClass: ''
  128. }, {
  129. title: '退出协作',
  130. eventType: 'unCooperation',
  131. extraClassName: 'error',
  132. iconClass: ''
  133. }]
  134. }
  135. },
  136. methods: {
  137. /**
  138. * 操作命令
  139. * @param type
  140. */
  141. command(type) {
  142. switch (type) {
  143. case 'publish':
  144. this.publish();
  145. break;
  146. case 'copyUrl':
  147. this.copyUrl();
  148. break;
  149. case 'setTemplate':
  150. this.setTemplate();
  151. break;
  152. case 'viewPageData':
  153. this.viewPageData();
  154. break;
  155. case 'cooperation':
  156. this.cooperation();
  157. break;
  158. case 'delete':
  159. this.delete();
  160. break;
  161. case 'unCooperation':
  162. this.unCooperation();
  163. break;
  164. case 'publishTemplate':
  165. this.publishTemplate();
  166. break;
  167. }
  168. },
  169. // 新建页面
  170. newPage() {
  171. let newPageData = editorProjectConfig.getProjectConfig(this.pageType)
  172. this.loading = true;
  173. debugger
  174. this.$API.createPage({
  175. ...newPageData,
  176. pageMode: this.pageType
  177. }).then(res => {
  178. this.loading = false;
  179. if (res.body) {
  180. this.$router.push({name: 'Editor', query: {id: res.body._id}})
  181. }
  182. }).catch(() => {
  183. this.loading = false;
  184. })
  185. },
  186. // 编辑
  187. edit() {
  188. this.$router.push({name: 'Editor', query: {id: this.pageData._id}})
  189. },
  190. // 复制页面
  191. copyPage() {
  192. this.loading = true;
  193. this.$API.copyPage({id: this.pageData._id}).then(() => {
  194. this.loading = false;
  195. this.$router.go(0);//刷新页面不跳转
  196. }).catch(() => {
  197. this.loading = false;
  198. })
  199. },
  200. // 使用模板,与复制模板目前方法只是更改了跳转方式
  201. useTemplate(){
  202. this.loading = true;
  203. this.$API.copyPage({id: this.pageData._id}).then(res => {
  204. this.loading = false;
  205. this.$router.push({name: 'Editor', query: {id: res.body._id}}) //跳转复制页面内
  206. }).catch(() => {
  207. this.loading = false;
  208. })
  209. },
  210. // 发布
  211. publish() {
  212. this.loading = true;
  213. this.$API.publishPage({id: this.pageData._id}).then(() => {
  214. this.loading = false;
  215. this.$message.success('发布成功');
  216. this.preview(this.pageData._id);
  217. this.$emit('refresh');
  218. }).catch(() => {
  219. this.loading = false;
  220. })
  221. },
  222. // 预览
  223. preview(id) {
  224. this.$emit('showPreview', id)
  225. },
  226. // 复制链接
  227. copyUrl() {
  228. this.$copyText(this.pageLink).then(() => {
  229. this.$message.success('已复制')
  230. })
  231. },
  232. // 设为我的模板
  233. setTemplate() {
  234. this.loading = true;
  235. this.$API.setTemplatePage({id: this.pageData._id}).then(() => {
  236. this.loading = false;
  237. this.$message.success('已添加到我的模板')
  238. }).catch(() => {
  239. this.loading = false;
  240. })
  241. },
  242. // 页面数据
  243. viewPageData() {
  244. this.$router.push({name: 'pageDataDetail', query: {id: this.pageData._id}})
  245. },
  246. // 协作设置
  247. cooperation() {
  248. addCooperationer(this.pageData._id)
  249. },
  250. // 删除
  251. delete() {
  252. this.$alert('确认删除页面?删除后,将无法访问此页面?', '操作提示', {
  253. confirmButtonText: '确定',
  254. cancelButtonText: '取消',
  255. type: 'warning',
  256. }).then(() => {
  257. this.$API.deletePage({id: this.pageData._id}).then(() => {
  258. this.$message.success('删除成功!');
  259. this.$emit('refresh')
  260. })
  261. })
  262. },
  263. // 退出协作
  264. unCooperation() {
  265. this.$alert('确认退出协作编辑?退出后,将无法编辑此页面?', '操作提示', {
  266. confirmButtonText: '确定',
  267. cancelButtonText: '取消',
  268. type: 'warning',
  269. }).then(() => {
  270. this.$API.delCooperation({pageId: this.pageData._id, userId: this.$store.state.user.userInfo._id}).then(() => {
  271. this.$message.success('已退出!');
  272. this.$emit('refresh')
  273. })
  274. })
  275. },
  276. // 发布模板到模板市场
  277. publishTemplate() {
  278. this.loading = true;
  279. this.$API.publishPage({id: this.pageData._id}).then(() => {
  280. this.loading = false;
  281. this.$message.success('发布成功');
  282. }).catch(() => {
  283. this.loading = false;
  284. })
  285. }
  286. }
  287. }
  288. </script>
  289. <style lang="scss" scoped>
  290. .page-thumbnail-panel {
  291. width: 224px;
  292. height: 296px;
  293. border-radius: 4px;
  294. overflow: hidden;
  295. display: flex;
  296. flex-direction: column;
  297. background: white;
  298. position: relative;
  299. transition: all 0.28s;
  300. &:hover {
  301. box-shadow: 0 0 16px 0 rgba(0, 0, 0, .16);
  302. transform: translate3d(0, -2px, 0);
  303. .header-mask {
  304. opacity: 1;
  305. }
  306. }
  307. .header-mask {
  308. position: absolute;
  309. top: 0;
  310. left: 0;
  311. opacity: 0;
  312. background-color: rgba(0, 0, 0, .3);
  313. width: 100%;
  314. height: 100%;
  315. border-radius: 4px 4px 0 0;
  316. padding-top: 92px;
  317. text-align: center;
  318. transition: top .28s ease, opacity .28s ease, height .28s ease;
  319. .details-btn {
  320. display: inline-block;
  321. width: 120px;
  322. height: 44px;
  323. font-size: 18px;
  324. line-height: 44px;
  325. border-radius: 22px;
  326. border: 1px solid #fff;
  327. color: #fff;
  328. cursor: pointer;
  329. }
  330. }
  331. }
  332. .thumbnail-panel-cover {
  333. flex: 1;
  334. position: relative;
  335. overflow: hidden;
  336. .image-wrapper {
  337. width: 100%;
  338. height: 100%;
  339. overflow: hidden;
  340. padding: 5px;
  341. z-index: 10;
  342. img {
  343. display: block;
  344. width: 100%;
  345. // height: 100%;
  346. }
  347. }
  348. }
  349. .page-item-title {
  350. height: 36px;
  351. line-height: 36px;
  352. padding: 0 8px;
  353. font-size: 14px;
  354. }
  355. .thumbnail-panel-btn {
  356. height: 36px;
  357. width: 100%;
  358. display: flex;
  359. flex-direction: row;
  360. .btn-wrapper {
  361. flex: 1;
  362. text-align: center;
  363. }
  364. }
  365. .unpublish {
  366. position: absolute;
  367. top: 5px;
  368. left: 5px;
  369. font-size: 12px;
  370. display: block;
  371. padding: 0 10px;
  372. height: 30px;
  373. line-height: 30px;
  374. background-color: #76838f;
  375. color: #fff;
  376. border-top-left-radius: 4px;
  377. border-bottom-right-radius: 12px;
  378. z-index: 10;
  379. }
  380. .page-thumbnail-panel.create {
  381. padding: 16px;
  382. text-align: center;
  383. .temp-create {
  384. display: inline-block;
  385. width: 100%;
  386. height: 100%;
  387. border: 1px solid #e6ebed;
  388. border-radius: 3px;
  389. padding-top: 100px;
  390. transition: all 0.28s;
  391. cursor: pointer;
  392. &:hover {
  393. color: $primary;
  394. border-color: $primary;
  395. }
  396. }
  397. .null-create {
  398. display: inline-block;
  399. width: 100%;
  400. height: 42px;
  401. line-height: 42px;
  402. border: 1px solid #4a4e52;
  403. transition: all 0.28s;
  404. cursor: pointer;
  405. &:hover {
  406. color: $primary;
  407. border-color: $primary;
  408. }
  409. }
  410. }
  411. </style>