Commit 0f8401fc031d64c8d383bf6bca29653b9bcda315
1 parent
6c06084a
电子站牌项目
1、添加resource-gallery通用组件,整合图片和视频的上传选取等功能,定义在core/support下 2、添加自定义插件bsth-slide轮播组件,可以轮播图片和视频,现阶段完成了初步功能和自定义属性编辑器 bsth-slide__editor
Showing
11 changed files
with
694 additions
and
0 deletions
front-end/h5/package.json
| @@ -42,6 +42,7 @@ | @@ -42,6 +42,7 @@ | ||
| 42 | "vue-quill-editor": "^3.0.6", | 42 | "vue-quill-editor": "^3.0.6", |
| 43 | "vue-router": "^3.0.3", | 43 | "vue-router": "^3.0.3", |
| 44 | "vuex": "^3.0.1", | 44 | "vuex": "^3.0.1", |
| 45 | + "vue-video-player": "^5.0.2", | ||
| 45 | "x-data-spreadsheet": "^1.1.4" | 46 | "x-data-spreadsheet": "^1.1.4" |
| 46 | }, | 47 | }, |
| 47 | "devDependencies": { | 48 | "devDependencies": { |
front-end/h5/src/components/core/plugins/bsth-slide__editor.js
0 → 100644
| 1 | +/** | ||
| 2 | + * 对应bsth-slide组件的属性中设置 | ||
| 3 | + * editor: { | ||
| 4 | + * custom: true | ||
| 5 | + * } | ||
| 6 | + */ | ||
| 7 | + | ||
| 8 | +import { GalleryValue, GalleryValueType } from 'core/support/resource-gallery/components/galleryValue' | ||
| 9 | + | ||
| 10 | +export default { | ||
| 11 | + props: { | ||
| 12 | + elementProps: { | ||
| 13 | + type: Object, | ||
| 14 | + default: () => ({ | ||
| 15 | + items: [], // 对应bsth-slide组件的items属性 | ||
| 16 | + activeIndex: 0 // 对应bsth-slide组件的activeIndex属性 | ||
| 17 | + }) | ||
| 18 | + } | ||
| 19 | + }, | ||
| 20 | + computed: { | ||
| 21 | + innerItems () { | ||
| 22 | + return this.elementProps.items | ||
| 23 | + } | ||
| 24 | + }, | ||
| 25 | + data () { | ||
| 26 | + return { | ||
| 27 | + current: 1 // 下标从1开始 | ||
| 28 | + } | ||
| 29 | + }, | ||
| 30 | + methods: { | ||
| 31 | + p_change (page) { // 分页条change事件处理器 | ||
| 32 | + this.current = page | ||
| 33 | + this.elementProps.activeIndex = page - 1 | ||
| 34 | + }, | ||
| 35 | + g_change (item) { // gallery change事件处理器, item 是 GalleryValue 类型 | ||
| 36 | + const currentItem = this.innerItems[this.current - 1] | ||
| 37 | + let itemObj = item.toObject() | ||
| 38 | + currentItem.url = itemObj.url | ||
| 39 | + currentItem.flag = itemObj.flag | ||
| 40 | + }, | ||
| 41 | + itemRender (current, type, originalElement) { | ||
| 42 | + if (type === 'prev') { // 上一页 | ||
| 43 | + return <a-button style={{ marginRight: '8px' }} size="small" icon="minus" | ||
| 44 | + onClick={() => this.minus(current)} | ||
| 45 | + disabled={this.innerItems.length === 1}></a-button> | ||
| 46 | + } else if (type === 'next') { // 下一页 | ||
| 47 | + return <a-button style={{ marginLeft: '8px' }} size="small" icon="plus" | ||
| 48 | + onClick={this.add}></a-button> | ||
| 49 | + } | ||
| 50 | + return originalElement | ||
| 51 | + }, | ||
| 52 | + minus (index) { // index 下标从0开始 | ||
| 53 | + if (this.innerItems.length === 1) { // 只有一个元素,不能再移除 | ||
| 54 | + return | ||
| 55 | + } | ||
| 56 | + this.elementProps.items.splice(index, 1) | ||
| 57 | + this.elementProps.activeIndex = Math.max(index - 1, 0) | ||
| 58 | + this.current = Math.max(index - 1, 0) + 1 | ||
| 59 | + }, | ||
| 60 | + add () { | ||
| 61 | + this.elementProps.items.push(new GalleryValue({ url: '', type: GalleryValueType.IMAGE }).toObject()) | ||
| 62 | + this.current = this.elementProps.items.length | ||
| 63 | + this.elementProps.activeIndex = this.current - 1 | ||
| 64 | + } | ||
| 65 | + }, | ||
| 66 | + render () { | ||
| 67 | + const currentItem = GalleryValue.toGalleryValue(this.innerItems[this.current - 1]) | ||
| 68 | + // console.log(currentItem) | ||
| 69 | + return ( | ||
| 70 | + <div> | ||
| 71 | + <a-pagination | ||
| 72 | + current={this.current} | ||
| 73 | + onChange={this.p_change} | ||
| 74 | + size="small" | ||
| 75 | + total={this.innerItems.length} | ||
| 76 | + defaultPageSize={1} | ||
| 77 | + itemRender={this.itemRender} | ||
| 78 | + /> | ||
| 79 | + <bsth-resource-gallery | ||
| 80 | + style={{ margin: '16px 0' }} | ||
| 81 | + value={currentItem} | ||
| 82 | + onChange={this.g_change} | ||
| 83 | + /> | ||
| 84 | + </div> | ||
| 85 | + ) | ||
| 86 | + } | ||
| 87 | +} |
front-end/h5/src/components/core/plugins/bsth/bsth-slide.js
0 → 100644
| 1 | +/** | ||
| 2 | + * 自定义轮播组件(可以轮播视频)。 | ||
| 3 | + */ | ||
| 4 | + | ||
| 5 | +import PropTypes from '@luban-h5/plugin-common-props' | ||
| 6 | +import { Swipe, SwipeItem } from 'vant' | ||
| 7 | +import 'vant/lib/swipe/style' | ||
| 8 | +import 'vant/lib/swipe-item/style' | ||
| 9 | +import { VideoPlayer } from 'vue-video-player' | ||
| 10 | +import 'video.js/dist/video-js.css' | ||
| 11 | + | ||
| 12 | +import { GalleryValue, GalleryValueType } from 'core/support/resource-gallery/components/galleryValue' | ||
| 13 | + | ||
| 14 | +function getDefaultItems () { | ||
| 15 | + const defaultItems = [ // TODO:目前鲁班的后端渲染引擎处理不了组件属性的自定义类型,所以自定义转换成普通对象 | ||
| 16 | + new GalleryValue({ type: GalleryValueType.IMAGE, url: 'https://img.yzcdn.cn/vant/apple-1.jpg' }).toObject(), | ||
| 17 | + new GalleryValue({ type: GalleryValueType.IMAGE, url: 'https://img.yzcdn.cn/vant/apple-2.jpg' }).toObject() | ||
| 18 | + ] | ||
| 19 | + return defaultItems | ||
| 20 | +} | ||
| 21 | + | ||
| 22 | +export default { | ||
| 23 | + extra: { | ||
| 24 | + defaultStyle: { // 默认属性 | ||
| 25 | + top: 0, | ||
| 26 | + left: 0, | ||
| 27 | + width: 350, | ||
| 28 | + height: 300 | ||
| 29 | + } | ||
| 30 | + }, | ||
| 31 | + name: 'bsth-slide', | ||
| 32 | + data () { | ||
| 33 | + return {} | ||
| 34 | + }, | ||
| 35 | + props: { | ||
| 36 | + editorMode: PropTypes.string({ // 编辑模式会由编辑器自动注入(值:edit, preview) | ||
| 37 | + defaultValue: 'preview', | ||
| 38 | + label: '模式', | ||
| 39 | + visible: false | ||
| 40 | + }), | ||
| 41 | + // -------------- 调用定制editor的属性 -------------// | ||
| 42 | + items: { // 每个轮播项的内容 | ||
| 43 | + type: Array, | ||
| 44 | + default: () => getDefaultItems(), | ||
| 45 | + editor: { | ||
| 46 | + custom: true | ||
| 47 | + } | ||
| 48 | + }, | ||
| 49 | + activeIndex: { // 当前轮播项目的index(对应items数组下标) | ||
| 50 | + type: Number, | ||
| 51 | + default: 0, | ||
| 52 | + editor: { | ||
| 53 | + custom: true | ||
| 54 | + } | ||
| 55 | + }, | ||
| 56 | + // -------------- 数据属性 ------------- // | ||
| 57 | + interval: PropTypes.number({ label: '间隔时间', defaultValue: 4000 }) | ||
| 58 | + }, | ||
| 59 | + render () { | ||
| 60 | + const { items, activeIndex } = this | ||
| 61 | + if (this.editorMode === 'edit') { // 如果是编辑状态显示item中的activeIndex下标项 | ||
| 62 | + if (items.length > 0) { | ||
| 63 | + return (<div><p>{items[activeIndex].url}</p></div>) | ||
| 64 | + } else { | ||
| 65 | + return (<div><p>无轮播项目</p></div>) | ||
| 66 | + } | ||
| 67 | + } else { | ||
| 68 | + return ( | ||
| 69 | + <Swipe autoplay={+this.interval} indicator-color="red"> | ||
| 70 | + { | ||
| 71 | + items.map(item => ( | ||
| 72 | + <SwipeItem><p>{item.url}</p></SwipeItem> | ||
| 73 | + )) | ||
| 74 | + } | ||
| 75 | + </Swipe> | ||
| 76 | + ) | ||
| 77 | + } | ||
| 78 | + }, | ||
| 79 | + mounted () {}, | ||
| 80 | + destroyed () {}, | ||
| 81 | + watch: {}, | ||
| 82 | + methods: {} | ||
| 83 | +} |
front-end/h5/src/components/core/plugins/index.js
| @@ -21,6 +21,7 @@ import LbpNewsList from 'core/plugins/lbp-news-list' | @@ -21,6 +21,7 @@ import LbpNewsList from 'core/plugins/lbp-news-list' | ||
| 21 | 21 | ||
| 22 | import BsthLineChart from 'core/plugins/bsth/bsth-line-chart' | 22 | import BsthLineChart from 'core/plugins/bsth/bsth-line-chart' |
| 23 | import BsthLineChartList from 'core/plugins/bsth/bsth-line-chart-list' | 23 | import BsthLineChartList from 'core/plugins/bsth/bsth-line-chart-list' |
| 24 | +import BsthSlide from 'core/plugins/bsth/bsth-slide' | ||
| 24 | 25 | ||
| 25 | export const pluginsList = [ | 26 | export const pluginsList = [ |
| 26 | { | 27 | { |
| @@ -330,6 +331,19 @@ export const pluginsList = [ | @@ -330,6 +331,19 @@ export const pluginsList = [ | ||
| 330 | component: BsthLineChartList, | 331 | component: BsthLineChartList, |
| 331 | visible: true, | 332 | visible: true, |
| 332 | name: BsthLineChartList.name | 333 | name: BsthLineChartList.name |
| 334 | + }, | ||
| 335 | + | ||
| 336 | + { | ||
| 337 | + i18nTitle: { | ||
| 338 | + 'en-US': 'Carousel2', | ||
| 339 | + 'zh-CN': '轮播图2' | ||
| 340 | + }, | ||
| 341 | + title: '轮播图2', | ||
| 342 | + icon: 'photo', | ||
| 343 | + component: BsthSlide, | ||
| 344 | + visible: true, | ||
| 345 | + name: BsthSlide.name | ||
| 346 | + // disabled: true | ||
| 333 | } | 347 | } |
| 334 | ] | 348 | ] |
| 335 | 349 |
front-end/h5/src/components/core/support/index.js
| @@ -16,6 +16,7 @@ import Vue from 'vue' | @@ -16,6 +16,7 @@ import Vue from 'vue' | ||
| 16 | import PropMultiTextItemsEditor from './prop-multi-items-editor/text.js' | 16 | import PropMultiTextItemsEditor from './prop-multi-items-editor/text.js' |
| 17 | import ImageGallery from './image-gallery/gallery.js' | 17 | import ImageGallery from './image-gallery/gallery.js' |
| 18 | import VideoGallery from './video-gallery/gallery.js' | 18 | import VideoGallery from './video-gallery/gallery.js' |
| 19 | +import ResourceGallery from './resource-gallery/gallery.js' | ||
| 19 | import LbsExcelEditor from './excel' | 20 | import LbsExcelEditor from './excel' |
| 20 | import ColorsPanel from './colors-panel' | 21 | import ColorsPanel from './colors-panel' |
| 21 | import LbpTextAlign from '@luban-h5/lbs-text-align' | 22 | import LbpTextAlign from '@luban-h5/lbs-text-align' |
| @@ -31,6 +32,7 @@ Vue.component(ColorPicker.name, ColorPicker) | @@ -31,6 +32,7 @@ Vue.component(ColorPicker.name, ColorPicker) | ||
| 31 | Vue.component(PropMultiTextItemsEditor.name, PropMultiTextItemsEditor) | 32 | Vue.component(PropMultiTextItemsEditor.name, PropMultiTextItemsEditor) |
| 32 | Vue.component(ImageGallery.name, ImageGallery) | 33 | Vue.component(ImageGallery.name, ImageGallery) |
| 33 | Vue.component(VideoGallery.name, VideoGallery) | 34 | Vue.component(VideoGallery.name, VideoGallery) |
| 35 | +Vue.component(ResourceGallery.name, ResourceGallery) | ||
| 34 | Vue.component(LbpTextAlign.name, LbpTextAlign) | 36 | Vue.component(LbpTextAlign.name, LbpTextAlign) |
| 35 | Vue.component(LbsExcelEditor.name, LbsExcelEditor) | 37 | Vue.component(LbsExcelEditor.name, LbsExcelEditor) |
| 36 | Vue.component(ColorsPanel.name, ColorsPanel) | 38 | Vue.component(ColorsPanel.name, ColorsPanel) |
front-end/h5/src/components/core/support/resource-gallery/components/galleryValue.js
0 → 100644
| 1 | +/** | ||
| 2 | + * bsth-resource-gallery 的属性value 对应的类型 | ||
| 3 | + */ | ||
| 4 | + | ||
| 5 | +const IMAGE = 1 // 图片 | ||
| 6 | +const VIDEO = 2 // 视频 | ||
| 7 | + | ||
| 8 | +const GalleryValueType = Object.freeze({ | ||
| 9 | + IMAGE: Symbol(IMAGE), | ||
| 10 | + VIDEO: Symbol(VIDEO) | ||
| 11 | +}) | ||
| 12 | + | ||
| 13 | +class GalleryValue { | ||
| 14 | + constructor (value = {}) { | ||
| 15 | + /** 类型 使用 GalleryValueType */ | ||
| 16 | + this.type = value.type | ||
| 17 | + /** 资源获取路径 */ | ||
| 18 | + this.url = value.url | ||
| 19 | + | ||
| 20 | + // TODO:其他属性再议 | ||
| 21 | + } | ||
| 22 | + | ||
| 23 | + toObject () { // 转换成一般对象形式,和静态方法 toGalleryValue 参数对应 | ||
| 24 | + switch (this.type) { | ||
| 25 | + case GalleryValueType.IMAGE: | ||
| 26 | + return { url: this.url, flag: IMAGE } | ||
| 27 | + case GalleryValueType.VIDEO: | ||
| 28 | + return { url: this.url, flag: VIDEO } | ||
| 29 | + default: | ||
| 30 | + throw new Error(`未知的GalleryValue类型:${this.type}`) | ||
| 31 | + } | ||
| 32 | + } | ||
| 33 | + | ||
| 34 | + /** | ||
| 35 | + * 转换成GalleryValue对象 | ||
| 36 | + * @param url | ||
| 37 | + * @param flag | ||
| 38 | + */ | ||
| 39 | + static toGalleryValue ({ url, flag }) { | ||
| 40 | + if (GalleryValueType.IMAGE.toString() === 'Symbol(' + flag + ')') { | ||
| 41 | + return new GalleryValue({ url: url, type: GalleryValueType.IMAGE }) | ||
| 42 | + } else if (GalleryValueType.VIDEO.toString() === 'Symbol(' + flag + ')') { | ||
| 43 | + return new GalleryValue({ url: url, type: GalleryValueType.VIDEO }) | ||
| 44 | + } else { | ||
| 45 | + throw new Error(`错误的GalleryValue类型Flag:${flag}`) | ||
| 46 | + } | ||
| 47 | + } | ||
| 48 | +} | ||
| 49 | + | ||
| 50 | +export { | ||
| 51 | + GalleryValueType, | ||
| 52 | + GalleryValue | ||
| 53 | +} |
front-end/h5/src/components/core/support/resource-gallery/components/uploader.js
0 → 100644
| 1 | +/** | ||
| 2 | + * 上传文件组件。 | ||
| 3 | + */ | ||
| 4 | +export default { | ||
| 5 | + props: { | ||
| 6 | + uploadSuccess: { | ||
| 7 | + type: Function, | ||
| 8 | + default: () => {} | ||
| 9 | + }, | ||
| 10 | + beforeUpload: { | ||
| 11 | + type: Function, | ||
| 12 | + default: (file) => file | ||
| 13 | + } | ||
| 14 | + }, | ||
| 15 | + data () { | ||
| 16 | + return { | ||
| 17 | + loading: false | ||
| 18 | + } | ||
| 19 | + }, | ||
| 20 | + methods: { | ||
| 21 | + handleBeforeUpload (file) { | ||
| 22 | + return this.beforeUpload(file) | ||
| 23 | + }, | ||
| 24 | + handleChange (info) { | ||
| 25 | + this.loading = true | ||
| 26 | + const status = info.file.status | ||
| 27 | + if (status !== 'uploading') { | ||
| 28 | + this.loading = true | ||
| 29 | + const status = info.file.status | ||
| 30 | + if (status !== 'uploading') { | ||
| 31 | + console.log(info.file, info.fileList) | ||
| 32 | + } | ||
| 33 | + if (status === 'done') { | ||
| 34 | + this.loading = false | ||
| 35 | + this.uploadSuccess(info) | ||
| 36 | + this.$message.success(`${info.file.name} 文件上传成功.`) | ||
| 37 | + } else if (status === 'error') { | ||
| 38 | + this.$message.error(`${info.file.name} 文件上传失败.`) | ||
| 39 | + } | ||
| 40 | + } | ||
| 41 | + } | ||
| 42 | + }, | ||
| 43 | + render (h) { | ||
| 44 | + return ( | ||
| 45 | + <a-upload | ||
| 46 | + name="files" | ||
| 47 | + action="/upload" | ||
| 48 | + beforeUpload={this.handleBeforeUpload} | ||
| 49 | + onChange={this.handleChange}> | ||
| 50 | + <slot> | ||
| 51 | + <a-button> | ||
| 52 | + <a-icon type="upload"/>点击上传 | ||
| 53 | + </a-button> | ||
| 54 | + </slot> | ||
| 55 | + </a-upload> | ||
| 56 | + ) | ||
| 57 | + } | ||
| 58 | +} |
front-end/h5/src/components/core/support/resource-gallery/gallery.js
0 → 100644
| 1 | +/** | ||
| 2 | + * 资源库组件(整合图片和视频资源) | ||
| 3 | + * 整合lbs-image-gallery和lbs-video-gallery | ||
| 4 | + */ | ||
| 5 | + | ||
| 6 | +import { GalleryValue, GalleryValueType } from 'core/support/resource-gallery/components/galleryValue' | ||
| 7 | +import PersonalImage from './tabs/personalImage.js' | ||
| 8 | +import PersonalVideo from './tabs/personalVideo.js' | ||
| 9 | + | ||
| 10 | +export default { | ||
| 11 | + name: 'bsth-resource-gallery', | ||
| 12 | + props: { | ||
| 13 | + visible: { // 是否可见 | ||
| 14 | + type: Boolean, | ||
| 15 | + default: false | ||
| 16 | + }, | ||
| 17 | + value: { // 对应的值 | ||
| 18 | + type: GalleryValue | ||
| 19 | + } | ||
| 20 | + }, | ||
| 21 | + data () { | ||
| 22 | + return { | ||
| 23 | + tabs: [ | ||
| 24 | + { | ||
| 25 | + value: 'personalImage', | ||
| 26 | + label: '我的图片库' | ||
| 27 | + }, | ||
| 28 | + { | ||
| 29 | + value: 'personalVideo', | ||
| 30 | + label: '我的视频库' | ||
| 31 | + } | ||
| 32 | + ], | ||
| 33 | + activeTab: 'personalImage', | ||
| 34 | + innerVisible: false // 对应visible属性 | ||
| 35 | + } | ||
| 36 | + }, | ||
| 37 | + watch: { | ||
| 38 | + visible (value) { | ||
| 39 | + this.innerVisible = value | ||
| 40 | + } | ||
| 41 | + }, | ||
| 42 | + methods: { | ||
| 43 | + showGallery () { | ||
| 44 | + this.innerVisible = true | ||
| 45 | + }, | ||
| 46 | + handleClose () { | ||
| 47 | + this.innerVisible = false | ||
| 48 | + }, | ||
| 49 | + changeTab ({ key }) { | ||
| 50 | + this.activeTab = key | ||
| 51 | + }, | ||
| 52 | + handleSelect (item) { // item是GalleryValue类型 | ||
| 53 | + this.handleClose() | ||
| 54 | + this.$emit('change', item) | ||
| 55 | + }, | ||
| 56 | + renderContent () { | ||
| 57 | + switch (this.activeTab) { | ||
| 58 | + case 'personalImage' : | ||
| 59 | + return <PersonalImage onChangeItem={item => { | ||
| 60 | + this.handleSelect(item) | ||
| 61 | + }}/> | ||
| 62 | + case 'personalVideo' : | ||
| 63 | + return <PersonalVideo onChangeItem={item => { | ||
| 64 | + this.handleSelect(item) | ||
| 65 | + }}/> | ||
| 66 | + } | ||
| 67 | + }, | ||
| 68 | + renderDefaultActivator () { | ||
| 69 | + const activatorWithout = ( | ||
| 70 | + <div | ||
| 71 | + class="default-activator cursor-pointer empty-bg-activator" | ||
| 72 | + onClick={this.showGallery} | ||
| 73 | + > | ||
| 74 | + <a-icon type="plus" /> | ||
| 75 | + </div> | ||
| 76 | + ) | ||
| 77 | + | ||
| 78 | + const activatorWithImg = ( | ||
| 79 | + <div onClick={this.showGallery}> | ||
| 80 | + <div class="default-activator cursor-pointer "><img src={this.value.url} width="50%" style={{ margin: 'auto' }} /></div> | ||
| 81 | + <div class="flex-space-between" style="margin-top: 8px;"> | ||
| 82 | + <a-button size="small">更换</a-button> | ||
| 83 | + {/* <a-button size="small" onClick={e => { | ||
| 84 | + e.stopPropagation() | ||
| 85 | + }}>裁剪</a-button> */} | ||
| 86 | + <a-button size="small" onClick={(e) => { | ||
| 87 | + e.stopPropagation() | ||
| 88 | + this.handleSelect(new GalleryValue({ type: GalleryValueType.IMAGE, url: '' })) | ||
| 89 | + }}>移除</a-button> | ||
| 90 | + </div> | ||
| 91 | + </div> | ||
| 92 | + ) | ||
| 93 | + | ||
| 94 | + const activatorWithVideo = ( | ||
| 95 | + <div onClick={this.showGallery}> | ||
| 96 | + <div class="default-activator cursor-pointer "><video src={this.value.url} width="50%" style={{ margin: 'auto' }} /></div> | ||
| 97 | + <div class="flex-space-between" style="margin-top: 8px;"> | ||
| 98 | + <a-button size="small">更换</a-button> | ||
| 99 | + <a-button size="small" onClick={(e) => { | ||
| 100 | + e.stopPropagation() | ||
| 101 | + this.handleSelect(new GalleryValue({ type: GalleryValueType.VIDEO, url: '' })) | ||
| 102 | + }}>移除</a-button> | ||
| 103 | + </div> | ||
| 104 | + </div> | ||
| 105 | + ) | ||
| 106 | + if (this.value && this.value.url && this.value.type === GalleryValueType.IMAGE) { | ||
| 107 | + return (activatorWithImg) | ||
| 108 | + } else if (this.value && this.value.url && this.value.type === GalleryValueType.VIDEO) { | ||
| 109 | + return (activatorWithVideo) | ||
| 110 | + } else { | ||
| 111 | + return (activatorWithout) | ||
| 112 | + } | ||
| 113 | + } | ||
| 114 | + }, | ||
| 115 | + render (h) { | ||
| 116 | + return ( | ||
| 117 | + <div> | ||
| 118 | + <slot>{this.renderDefaultActivator()}</slot> | ||
| 119 | + <a-modal | ||
| 120 | + closable | ||
| 121 | + title="资源库" | ||
| 122 | + width="65%" | ||
| 123 | + visible={this.innerVisible} | ||
| 124 | + onOk={this.handleClose} | ||
| 125 | + onCancel={this.handleClose} | ||
| 126 | + bodyStyle={{ margin: 0, padding: 0 }} | ||
| 127 | + > | ||
| 128 | + <div slot='okText'>确认</div> | ||
| 129 | + <div slot='cancelText'>取消</div> | ||
| 130 | + <a-layout style="height: 500px; position: relative;"> | ||
| 131 | + <a-layout-sider width="200px" style="background-color: white;"> | ||
| 132 | + <a-menu mode="inline" | ||
| 133 | + defaultSelectedKeys={['personalImage']} | ||
| 134 | + onClick={this.changeTab}> | ||
| 135 | + { | ||
| 136 | + this.tabs.map((tab, index) => ( | ||
| 137 | + <a-menu-item key={tab.value} > | ||
| 138 | + <a-icon type="user" /> | ||
| 139 | + <span>{tab.label}</span> | ||
| 140 | + </a-menu-item> | ||
| 141 | + )) | ||
| 142 | + } | ||
| 143 | + </a-menu> | ||
| 144 | + </a-layout-sider> | ||
| 145 | + <a-layout-content> | ||
| 146 | + {this.renderContent()} | ||
| 147 | + </a-layout-content> | ||
| 148 | + </a-layout> | ||
| 149 | + </a-modal> | ||
| 150 | + </div> | ||
| 151 | + ) | ||
| 152 | + } | ||
| 153 | +} |
front-end/h5/src/components/core/support/resource-gallery/gallery.scss
0 → 100644
front-end/h5/src/components/core/support/resource-gallery/tabs/personalImage.js
0 → 100644
| 1 | +/** | ||
| 2 | + * 我的图片库组件。 | ||
| 3 | + */ | ||
| 4 | + | ||
| 5 | +import axios from 'axios' | ||
| 6 | +import Uploader from 'core/support/resource-gallery/components/uploader.js' | ||
| 7 | +import { GalleryValue, GalleryValueType } from 'core/support/resource-gallery/components/galleryValue' | ||
| 8 | + | ||
| 9 | +export default { | ||
| 10 | + data () { | ||
| 11 | + return { | ||
| 12 | + items: [], // 数据列表(GalleryValue类型) | ||
| 13 | + loading: false, // 是否载入中 | ||
| 14 | + total: 30, // 总记录数 | ||
| 15 | + page: 1, // 第几页(从1开始) | ||
| 16 | + pageSize: 30 // 每页大小 | ||
| 17 | + } | ||
| 18 | + }, | ||
| 19 | + methods: { | ||
| 20 | + uploadSuccess ({ file }) { | ||
| 21 | + this.searchFiles() | ||
| 22 | + }, | ||
| 23 | + beforeUpload (file) { | ||
| 24 | + this.loading = true | ||
| 25 | + }, | ||
| 26 | + searchFiles () { | ||
| 27 | + this.loading = true | ||
| 28 | + axios.get('/upload/getFiles', { | ||
| 29 | + params: { | ||
| 30 | + '_limit': this.pageSize, | ||
| 31 | + '_start': (this.page - 1) * this.pageSize, // 后台页码从0开始 | ||
| 32 | + 'mime': 'image' | ||
| 33 | + // TODO:后面再加其他参数 | ||
| 34 | + } | ||
| 35 | + }) | ||
| 36 | + .then(res => { | ||
| 37 | + this.items = [] | ||
| 38 | + if (res.data && res.data.dataList && res.data.dataList.length > 0) { | ||
| 39 | + for (let uploadFileDto of res.data.dataList) { | ||
| 40 | + this.items.push(new GalleryValue({ | ||
| 41 | + url: uploadFileDto.url, // 获取路径 | ||
| 42 | + type: GalleryValueType.IMAGE // 图片类型 | ||
| 43 | + })) | ||
| 44 | + } | ||
| 45 | + this.total = res.data.totalDataCount | ||
| 46 | + this.page = res.data.page | ||
| 47 | + this.pageSize = res.data.size | ||
| 48 | + } | ||
| 49 | + }) | ||
| 50 | + .catch(err => { | ||
| 51 | + this.$message.error('资源库数据查询失败') | ||
| 52 | + }) | ||
| 53 | + .finally(() => { | ||
| 54 | + this.loading = false | ||
| 55 | + }) | ||
| 56 | + } | ||
| 57 | + }, | ||
| 58 | + render (h) { | ||
| 59 | + return ( | ||
| 60 | + <div> | ||
| 61 | + <a-spin tip="载入中..." spinning={this.loading}> | ||
| 62 | + <a-card> | ||
| 63 | + <Uploader | ||
| 64 | + slot="extra" | ||
| 65 | + beforeUpload={file => this.beforeUpload(file)} | ||
| 66 | + uploadSuccess={info => this.uploadSuccess(info)} | ||
| 67 | + /> | ||
| 68 | + <a-list | ||
| 69 | + pagination={{ | ||
| 70 | + showSizeChanger: true, | ||
| 71 | + total: this.total, | ||
| 72 | + pageSize: this.pageSize, | ||
| 73 | + onChange: (page, pageSize) => { | ||
| 74 | + this.page = page | ||
| 75 | + this.searchFiles() | ||
| 76 | + console.log(page) | ||
| 77 | + }, | ||
| 78 | + onShowSizeChange: (currentPage, pageSize) => { | ||
| 79 | + this.pageSize = pageSize | ||
| 80 | + this.searchFiles() | ||
| 81 | + } | ||
| 82 | + }} | ||
| 83 | + style="height: 400px; overflow: auto;" | ||
| 84 | + grid={{ gutter: 12, column: 3 }} | ||
| 85 | + dataSource={this.items} | ||
| 86 | + renderItem={(item, index) => ( | ||
| 87 | + <a-list-item onClick={() => { | ||
| 88 | + this.$emit('changeItem', item) | ||
| 89 | + }}> | ||
| 90 | + <a-card hoverable> | ||
| 91 | + <div | ||
| 92 | + slot="cover" | ||
| 93 | + style={{ | ||
| 94 | + backgroundImage: `url(${item.url})`, | ||
| 95 | + backgroundSize: 'cover', | ||
| 96 | + height: '142px' | ||
| 97 | + }}> | ||
| 98 | + </div> | ||
| 99 | + </a-card> | ||
| 100 | + </a-list-item> | ||
| 101 | + )} | ||
| 102 | + > | ||
| 103 | + </a-list> | ||
| 104 | + </a-card> | ||
| 105 | + </a-spin> | ||
| 106 | + </div> | ||
| 107 | + ) | ||
| 108 | + }, | ||
| 109 | + mounted () { | ||
| 110 | + // 请求数据 | ||
| 111 | + this.searchFiles() | ||
| 112 | + } | ||
| 113 | +} |
front-end/h5/src/components/core/support/resource-gallery/tabs/personalVideo.js
0 → 100644
| 1 | +/** | ||
| 2 | + * 我的视频库组件。 | ||
| 3 | + */ | ||
| 4 | + | ||
| 5 | +import axios from 'axios' | ||
| 6 | +import Uploader from 'core/support/resource-gallery/components/uploader.js' | ||
| 7 | +import { GalleryValue, GalleryValueType } from 'core/support/resource-gallery/components/galleryValue' | ||
| 8 | + | ||
| 9 | +export default { | ||
| 10 | + data () { | ||
| 11 | + return { | ||
| 12 | + items: [], // 数据列表(GalleryValue类型) | ||
| 13 | + loading: false, // 是否载入中 | ||
| 14 | + total: 30, // 总记录数 | ||
| 15 | + page: 1, // 第几页(从1开始) | ||
| 16 | + pageSize: 30 // 每页大小 | ||
| 17 | + } | ||
| 18 | + }, | ||
| 19 | + methods: { | ||
| 20 | + uploadSuccess ({ file }) { | ||
| 21 | + this.searchFiles() | ||
| 22 | + }, | ||
| 23 | + beforeUpload (file) { | ||
| 24 | + this.loading = true | ||
| 25 | + }, | ||
| 26 | + searchFiles () { | ||
| 27 | + this.loading = true | ||
| 28 | + axios.get('/upload/getFiles', { | ||
| 29 | + params: { | ||
| 30 | + '_limit': this.pageSize, | ||
| 31 | + '_start': (this.page - 1) * this.pageSize, // 后台页码从0开始 | ||
| 32 | + 'mime': 'video' | ||
| 33 | + // TODO:后面再加其他参数 | ||
| 34 | + } | ||
| 35 | + }) | ||
| 36 | + .then(res => { | ||
| 37 | + this.items = [] | ||
| 38 | + if (res.data && res.data.dataList && res.data.dataList.length > 0) { | ||
| 39 | + for (let uploadFileDto of res.data.dataList) { | ||
| 40 | + this.items.push(new GalleryValue({ | ||
| 41 | + url: uploadFileDto.url, // 获取路径 | ||
| 42 | + type: GalleryValueType.VIDEO // 图片类型 | ||
| 43 | + })) | ||
| 44 | + } | ||
| 45 | + this.total = res.data.totalDataCount | ||
| 46 | + this.page = res.data.page | ||
| 47 | + this.pageSize = res.data.size | ||
| 48 | + } | ||
| 49 | + }) | ||
| 50 | + .catch(err => { | ||
| 51 | + this.$message.error('资源库数据查询失败') | ||
| 52 | + }) | ||
| 53 | + .finally(() => { | ||
| 54 | + this.loading = false | ||
| 55 | + }) | ||
| 56 | + } | ||
| 57 | + }, | ||
| 58 | + render (h) { | ||
| 59 | + return ( | ||
| 60 | + <div> | ||
| 61 | + <a-spin tip="载入中..." spinning={this.loading}> | ||
| 62 | + <a-card> | ||
| 63 | + <Uploader | ||
| 64 | + slot="extra" | ||
| 65 | + beforeUpload={file => this.beforeUpload(file)} | ||
| 66 | + uploadSuccess={info => this.uploadSuccess(info)} | ||
| 67 | + /> | ||
| 68 | + <a-list | ||
| 69 | + pagination={{ | ||
| 70 | + showSizeChanger: true, | ||
| 71 | + total: this.total, | ||
| 72 | + pageSize: this.pageSize, | ||
| 73 | + onChange: (page, pageSize) => { | ||
| 74 | + this.page = page | ||
| 75 | + this.searchFiles() | ||
| 76 | + console.log(page) | ||
| 77 | + }, | ||
| 78 | + onShowSizeChange: (currentPage, pageSize) => { | ||
| 79 | + this.pageSize = pageSize | ||
| 80 | + this.searchFiles() | ||
| 81 | + } | ||
| 82 | + }} | ||
| 83 | + style="height: 400px; overflow: auto;" | ||
| 84 | + grid={{ gutter: 12, column: 3 }} | ||
| 85 | + dataSource={this.items} | ||
| 86 | + renderItem={(item, index) => ( | ||
| 87 | + <a-list-item onClick={() => { | ||
| 88 | + this.$emit('changeItem', item) | ||
| 89 | + }}> | ||
| 90 | + <a-card hoverable> | ||
| 91 | + <video | ||
| 92 | + onClick={function (e) { | ||
| 93 | + e.preventDefault() /* 阻止默认点击video标签的默认行为(播放行为) */ | ||
| 94 | + }} | ||
| 95 | + controls | ||
| 96 | + slot="cover" | ||
| 97 | + src={item.url} | ||
| 98 | + style={{ | ||
| 99 | + height: '240px' | ||
| 100 | + }}> | ||
| 101 | + </video> | ||
| 102 | + </a-card> | ||
| 103 | + </a-list-item> | ||
| 104 | + )} | ||
| 105 | + > | ||
| 106 | + </a-list> | ||
| 107 | + </a-card> | ||
| 108 | + </a-spin> | ||
| 109 | + </div> | ||
| 110 | + ) | ||
| 111 | + }, | ||
| 112 | + mounted () { | ||
| 113 | + // 请求数据 | ||
| 114 | + this.searchFiles() | ||
| 115 | + } | ||
| 116 | +} |