| 对比新文件 |
| | |
| | | <template> |
| | | <el-bus-crud ref="crud" v-bind="tableConfig"/> |
| | | </template> |
| | | |
| | | <script> |
| | | import dayjs from 'dayjs' |
| | | import 'dayjs/locale/zh-cn' |
| | | |
| | | dayjs.locale('zh-cn') |
| | | export default { |
| | | data() { |
| | | return { |
| | | tableConfig: { |
| | | url: 'flower/api/filmLocation/list', |
| | | newUrl: 'flower/api/filmLocation/new', |
| | | editUrl: 'flower/api/filmLocation/edit', |
| | | deleteUrl: 'flower/api/filmLocation/delete', |
| | | dialogNeedRequest: true, |
| | | persistSelection: true, |
| | | columns: [ |
| | | {type: 'selection'}, |
| | | {label: '拍摄地点名称', prop: 'locationName', minWidth: 120}, |
| | | {label: '拍摄地点图片', prop: 'locationUrl', minWidth: 120}, |
| | | {label: '省', prop: 'province', minWidth: 120}, |
| | | {label: '市', prop: 'city', minWidth: 150}, |
| | | {label: '区', prop: 'region'}, |
| | | {label: '详细地址', prop: 'address', minWidth: 150}, |
| | | {label: '纬度坐标', prop: 'gpsLat', minWidth: 150}, |
| | | {label: '经度坐标', prop: 'gpsLng', minWidth: 300}, |
| | | {label: '场景类型', prop: 'sceneType'}, |
| | | {label: '经典画面描述', prop: 'classicScene', minWidth: 400}, |
| | | {label: '开放参观', prop: 'isOpenVisitStr', minWidth: 200}, |
| | | {label: '参观提示', prop: 'visitInfo', minWidth: 120}, |
| | | {label: '地标性建筑描述', prop: 'landmarkDesc'}, |
| | | {label: '停车场信息', prop: 'parkingInfo', minWidth: 80}, |
| | | {label: '周边设施描述', prop: 'surroundingFacilities', minWidth: 80}, |
| | | {label: 'ARURL', prop: 'arEntry', minWidth: 80}, |
| | | {label: '打卡记录量', prop: 'checkinCount', minWidth: 80}, |
| | | // { label: '游客实拍图', prop: 'visitorPhotos', minWidth: 80 }, |
| | | {label: '景点热度', prop: 'locationWeight', minWidth: 80}, |
| | | {label: '运营权重', prop: 'operationWeight', minWidth: 80}, |
| | | { |
| | | label: '启用/禁用', |
| | | formatter: (row) => ( |
| | | <el-switch |
| | | value={row.isEnabled} |
| | | onChange={this.onEnabledChange.bind(this, row)} |
| | | ></el-switch> |
| | | ), |
| | | minWidth: 120, |
| | | fixed: 'right', |
| | | }, |
| | | ], |
| | | searchForm: [ |
| | | { |
| | | type: 'row', |
| | | items: [ |
| | | {label: '拍摄地点名称', id: 'locationName', type: 'input'}, |
| | | { |
| | | label: '启用/禁用', |
| | | id: 'isEnabled', |
| | | type: 'bus-select-dict', |
| | | default: '1', |
| | | el: { |
| | | code: 'USER_ENABLED_OR_DISABLED', |
| | | clearable: true, |
| | | style: 'width:100%', |
| | | }, |
| | | }, |
| | | ], |
| | | }, |
| | | ], |
| | | form: [ |
| | | { |
| | | label: '拍摄地点名称:', |
| | | id: 'locationName', |
| | | type: 'input', |
| | | rules: { |
| | | required: true, |
| | | message: '请输入拍摄地点名称', |
| | | trigger: 'blur', |
| | | }, |
| | | }, |
| | | { |
| | | label: '封面图片:', |
| | | id: 'locationUrl', |
| | | type: 'bus-upload', |
| | | el: { |
| | | listType: 'picture-card', |
| | | limitSize: 2, |
| | | limit: 1, |
| | | tipText: '大小不超过2M', |
| | | }, |
| | | }, |
| | | { |
| | | label: '省:', |
| | | id: 'province', |
| | | type: 'input', |
| | | rules: { |
| | | required: true, |
| | | message: '请输入省', |
| | | trigger: 'blur', |
| | | }, |
| | | }, |
| | | { |
| | | label: '市:', |
| | | id: 'city', |
| | | type: 'input', |
| | | rules: { |
| | | required: true, |
| | | message: '请输入市', |
| | | trigger: 'blur', |
| | | }, |
| | | }, |
| | | { |
| | | label: '区:', |
| | | id: 'region', |
| | | type: 'input', |
| | | rules: { |
| | | required: true, |
| | | message: '请输入区', |
| | | trigger: 'blur', |
| | | }, |
| | | }, |
| | | { |
| | | label: '详细地址:', |
| | | id: 'address', |
| | | type: 'input', |
| | | rules: { |
| | | required: true, |
| | | message: '请输详细地址', |
| | | trigger: 'blur', |
| | | }, |
| | | }, |
| | | { |
| | | label: '纬度坐标:', |
| | | id: 'gpsLat', |
| | | type: 'input', |
| | | rules: { |
| | | required: true, |
| | | message: '请输入纬度坐标', |
| | | trigger: 'blur', |
| | | }, |
| | | }, |
| | | { |
| | | label: '经度坐标:', |
| | | id: 'gpsLng', |
| | | type: 'input', |
| | | rules: { |
| | | required: true, |
| | | message: '请输入经度坐标', |
| | | trigger: 'blur', |
| | | }, |
| | | }, |
| | | { |
| | | label: '场景类型:', |
| | | id: 'sceneType', |
| | | type: 'input', |
| | | rules: { |
| | | required: true, |
| | | message: '请输入场景类型', |
| | | trigger: 'blur', |
| | | }, |
| | | }, |
| | | { |
| | | label: '经典画面描述:', |
| | | id: 'classicScene', |
| | | type: 'input', |
| | | rules: { |
| | | required: true, |
| | | message: '请输入经典画面描述', |
| | | trigger: 'blur', |
| | | }, |
| | | }, |
| | | { |
| | | label: '开放参观:', |
| | | id: 'isOpenVisit', |
| | | type: 'bus-select-dict', |
| | | el: { |
| | | code: 'IS_VISITOR', |
| | | style: 'width:100%', |
| | | clearable: true, |
| | | }, |
| | | rules: { |
| | | required: true, |
| | | message: '请选择参观类型', |
| | | }, |
| | | }, |
| | | { |
| | | label: '参观提示:', |
| | | id: 'visitInfo', |
| | | type: 'input', |
| | | rules: { |
| | | required: true, |
| | | message: '请输入参观提示', |
| | | trigger: 'blur', |
| | | }, |
| | | }, |
| | | { |
| | | label: '地标性建筑描述:', |
| | | id: 'landmarkDesc', |
| | | type: 'input', |
| | | rules: { |
| | | required: true, |
| | | message: '请输入地标性建筑描述', |
| | | trigger: 'blur', |
| | | }, |
| | | }, |
| | | { |
| | | label: '停车场信息:', |
| | | id: 'parkingInfo', |
| | | type: 'input', |
| | | rules: { |
| | | required: true, |
| | | message: '请输入停车场信息', |
| | | trigger: 'blur', |
| | | }, |
| | | }, |
| | | { |
| | | label: '周边设施描述:', |
| | | id: 'surroundingFacilities', |
| | | type: 'input', |
| | | rules: { |
| | | required: true, |
| | | message: '请输入周边设施描述', |
| | | trigger: 'blur', |
| | | }, |
| | | }, |
| | | { |
| | | label: 'ARURL:', |
| | | id: 'arEntry', |
| | | type: 'input', |
| | | rules: { |
| | | required: false, |
| | | message: '请输入ARURL', |
| | | trigger: 'blur', |
| | | }, |
| | | }, |
| | | // { |
| | | // label: '取景地内容:', |
| | | // id: 'filmContent', |
| | | // component: 'base-editor', |
| | | // richText: true, |
| | | // rules: { required: true, message: '请输入取景地内容', trigger: 'blur' }, |
| | | // }, |
| | | { |
| | | label: '打卡记录量:', |
| | | id: 'checkinCount', |
| | | type: 'input', |
| | | rules: { |
| | | required: false, |
| | | message: '请输入打卡记录量', |
| | | trigger: 'blur', |
| | | }, |
| | | }, |
| | | { |
| | | label: '景点热度:', |
| | | id: 'locationWeight', |
| | | type: 'input', |
| | | rules: { |
| | | required: false, |
| | | message: '请输入景点热度', |
| | | trigger: 'blur', |
| | | }, |
| | | }, |
| | | { |
| | | label: '运营权重:', |
| | | id: 'operationWeight', |
| | | type: 'input', |
| | | rules: { |
| | | required: false, |
| | | message: '请输入运营权重', |
| | | trigger: 'blur', |
| | | }, |
| | | }, |
| | | ], |
| | | extraButtons: [ |
| | | { |
| | | text: '清除热度', |
| | | atClick: async (row) => { |
| | | try { |
| | | await this.$elBusUtil.confirm(`确定要清除热度吗?`) |
| | | const {code} = await this.$elBusHttp.request( |
| | | 'flower/api/filmLocation/setDown', |
| | | {params: {id: row.id}} |
| | | ) |
| | | if (code === 0) { |
| | | this.$message.success(`清除热度成功`) |
| | | } |
| | | } catch (e) { |
| | | return false |
| | | } |
| | | }, |
| | | }, |
| | | ], |
| | | headerButtons: [ |
| | | { |
| | | text: '合并', |
| | | type: 'primary', |
| | | disabled: (selected) => |
| | | selected.filter((item) => item.isEnabled) |
| | | .length === 0, |
| | | atClick: async (selected) => { |
| | | const selectedNotice = selected.filter( |
| | | (item) => item.isEnabled |
| | | ) |
| | | try { |
| | | await this.$elBusUtil.confirm( |
| | | `确定要合并这${selectedNotice.length -1}个景点到第一个吗?` |
| | | ) |
| | | const {code} = await this.$elBusHttp.request( |
| | | 'flower/api/filmLocation/merge/batch', |
| | | { |
| | | method: 'post', |
| | | data: { |
| | | ids: selected.map((item) => item.id), |
| | | }, |
| | | } |
| | | ) |
| | | if (code === 0) { |
| | | this.$message.success('操作成功') |
| | | this.$refs.crud.clearSelection() |
| | | } |
| | | } catch (e) { |
| | | return false |
| | | } |
| | | }, |
| | | }, |
| | | { |
| | | text: '批量删除', |
| | | type: 'danger', |
| | | disabled: (selected) => selected.length === 0, |
| | | atClick: async (selected) => { |
| | | try { |
| | | await this.$elBusUtil.confirm( |
| | | `确定要批量删除这${selected.length}个片场内容吗?` |
| | | ) |
| | | const {code} = await this.$elBusHttp.request( |
| | | 'flower/api/filmLocation/delete/batch', |
| | | { |
| | | method: 'post', |
| | | data: { |
| | | ids: selected.map((item) => item.id), |
| | | }, |
| | | } |
| | | ) |
| | | if (code === 0) { |
| | | this.$message.success('操作成功') |
| | | this.$refs.crud.clearSelection() |
| | | } |
| | | } catch (e) { |
| | | return false |
| | | } |
| | | }, |
| | | }, |
| | | ], |
| | | }, |
| | | } |
| | | }, |
| | | head() { |
| | | return { |
| | | title: '影视景点管理', |
| | | } |
| | | }, |
| | | methods: { |
| | | onEnabledChange(row, e) { |
| | | const url = 'flower/api/filmLocation/isEnable' |
| | | const text = e ? '启用' : '禁用' |
| | | this.$elBusUtil |
| | | .confirm(`确定要${text}这个影视景点吗?`) |
| | | .then(async () => { |
| | | const { code } = await this.$elBusHttp.request(url, { |
| | | params: { |
| | | id: row.id, |
| | | }, |
| | | }) |
| | | if (code === 0) { |
| | | this.$message.success(`${text}成功`) |
| | | this.$refs.crud.getList() |
| | | } |
| | | }) |
| | | .catch(() => { }) |
| | | }, |
| | | |
| | | }, |
| | | } |
| | | </script> |
| | | |
| | | <style lang="scss" scoped> |
| | | ::v-deep { |
| | | .el-upload { |
| | | &-list__item { |
| | | width: 345px; |
| | | height: 128px; |
| | | } |
| | | |
| | | &.el-upload--picture-card { |
| | | width: 345px; |
| | | height: 128px; |
| | | } |
| | | } |
| | | } |
| | | </style> |
| 文件名从 pages/content/filmset.vue 修改 |
| | |
| | | limitSize: 2, |
| | | limit: 1, |
| | | tipText: '大小不超过2M', |
| | | valueType: 'string', |
| | | // valueType: 'string', |
| | | }, |
| | | forceDisabled: true, |
| | | inputFormat: (row) => { |
| | | if ('coverUrl' in row) { |
| | | if (typeof row.coverUrl === 'string' && row.coverUrl) { |
| | | let url = row.coverUrl |
| | | if (url.includes('doubanio')) { |
| | | url = `https://images.weserv.nl/?url=${encodeURIComponent(url)}` |
| | | } |
| | | return [{ url }] |
| | | } |
| | | if (Array.isArray(row.coverUrl)) { |
| | | return row.coverUrl |
| | | } |
| | | return [] |
| | | } |
| | | }, |
| | | outputFormat: (fileList) => { |
| | | if (Array.isArray(fileList) && fileList.length > 0) { |
| | | let url = fileList[0].url |
| | | const proxyPrefix = 'https://images.weserv.nl/?url=' |
| | | if (url.startsWith(proxyPrefix)) { |
| | | url = decodeURIComponent(url.replace(proxyPrefix, '')) |
| | | } |
| | | return url |
| | | } |
| | | return '' |
| | | } |
| | | // outputFormat: (fileList) => { |
| | | // if (Array.isArray(fileList) && fileList.length > 0) { |
| | | // return fileList[0].url |
| | | // } |
| | | // return '' |
| | | // } |
| | | // inputFormat: (row) => { |
| | | // if ('coverUrl' in row) { |
| | | // // 封面图片是字符串 |
| | | // if (typeof row.coverUrl === 'string' && row.coverUrl) { |
| | | // let url = row.coverUrl |
| | | // console.log("我进来了",url) |
| | | // // 代理 doubanio 图片 |
| | | // if (url.includes('doubanio')) { |
| | | // url = `https://images.weserv.nl/?url=${encodeURIComponent(url)}` |
| | | // console.log("我处理了",url) |
| | | // } |
| | | // return [{ url }] |
| | | // } |
| | | // // 已经是数组 |
| | | // if (Array.isArray(row.coverUrl)) { |
| | | // // 这里也可以做一遍代理处理,防止后端返回的数组里有 doubanio |
| | | // return row.coverUrl.map(item => { |
| | | // let url = item.url || item |
| | | // if (url.includes('doubanio')) { |
| | | // url = `https://images.weserv.nl/?url=${encodeURIComponent(url)}` |
| | | // } |
| | | // return { ...item, url } |
| | | // }) |
| | | // } |
| | | // return [] |
| | | // } |
| | | // }, |
| | | // formatter: (url) => this.formatImageUrl(url) |
| | | |
| | | }, |
| | | { |
| | | label: '封面图片描述:', |
| | |
| | | await this.$elBusUtil.confirm(`确定要${action}吗?`) |
| | | const { code } = await this.$elBusHttp.request( |
| | | 'flower/api/filmWorks/changeStatus', |
| | | { params: { id: row.id } } |
| | | ) |
| | | if (code === 0) { |
| | | this.$message.success(`${action}成功`) |
| | | } |
| | | } catch (e) { |
| | | return false |
| | | } |
| | | }, |
| | | }, |
| | | { |
| | | text: (row) => ( row.status === 'pending_create' ? '取消生成' : '重新生成'), |
| | | atClick: async (row) => { |
| | | const action = row.status === 'pending_create' ? '取消生成' : '重新生成' |
| | | try { |
| | | await this.$elBusUtil.confirm(`确定要${action}吗?`) |
| | | const { code } = await this.$elBusHttp.request( |
| | | 'flower/api/filmWorks/changeCreateStatus', |
| | | { params: { id: row.id } } |
| | | ) |
| | | if (code === 0) { |
| | |
| | | } |
| | | }, |
| | | methods: { |
| | | formatterImage(row) { |
| | | if (row.coverUrl) { |
| | | // 使用第三方镜像服务(示例) |
| | | const proxyUrl = `https://images.weserv.nl/?url=${encodeURIComponent(row.coverUrl)}`; |
| | | return <el-bus-image src={proxyUrl} preview-src-list={[proxyUrl]} style="width:150px" /> |
| | | // formatterImage(row) { |
| | | // if (row.coverUrl) { |
| | | // if (row.coverUrl.includes('doubanio')) { |
| | | // const proxyUrl = `https://images.weserv.nl/?url=${encodeURIComponent(row.coverUrl)}`; |
| | | // return <el-bus-image src={proxyUrl} preview-src-list={[proxyUrl]} style="width:150px" /> |
| | | // } else { |
| | | // return <el-bus-image src={row.coverUrl} preview-src-list={[row.coverUrl]} style="width:150px" /> |
| | | // } |
| | | // } |
| | | // return '无封面'; |
| | | // } |
| | | formatImageUrl(url) { |
| | | if (!url) return ''; |
| | | if (url.includes('doubanio')) { |
| | | return `https://images.weserv.nl/?url=${encodeURIComponent(url)}`; |
| | | } |
| | | return '无封面'; |
| | | return url; |
| | | }, |
| | | // formatterImage(row) { |
| | | // if (!row.coverUrl) return '无封面'; |
| | | // const displayUrl = this.formatImageUrl(row.coverUrl); |
| | | // return <el-bus-image src={displayUrl} preview-src-list={[displayUrl]} style="width:150px" />; |
| | | // } |
| | | formatterImage(row) { |
| | | if (!row.coverUrl) return '无封面'; |
| | | |
| | | // 统一处理路径:doubanio路径使用代理,其他直接使用 |
| | | const displayUrl = row.coverUrl.includes('doubanio') |
| | | ? `https://images.weserv.nl/?url=${encodeURIComponent(row.coverUrl)}` |
| | | : row.coverUrl; |
| | | |
| | | return ( |
| | | <el-bus-image |
| | | src={displayUrl} |
| | | preview-src-list={[displayUrl]} |
| | | style="width:150px" |
| | | /> |
| | | ); |
| | | } |
| | | }, |
| | | } |
| 对比新文件 |
| | |
| | | <template> |
| | | <el-bus-crud ref="crud" v-bind="tableConfig" /> |
| | | </template> |
| | | |
| | | <script> |
| | | import cloneDeep from 'lodash.clonedeep' |
| | | import { getSortConfig } from '@/utils/form-item-config' |
| | | export default { |
| | | data() { |
| | | return { |
| | | originalList: [], |
| | | expandIds: [], |
| | | tableConfig: { |
| | | url: 'flower/api/film/category/tree', |
| | | hasPagination: false, |
| | | saveQuery: false, |
| | | isTree: true, |
| | | hasView: false, |
| | | canNewChild: (row) => !row.parentId, |
| | | dialogAttrs: { |
| | | width: '70%', |
| | | }, |
| | | afterRequest: (list) => { |
| | | this.originalList = cloneDeep(list) |
| | | this.expandIds = this.expandIds.filter((i) => |
| | | list.find((item) => item.id === i) |
| | | ) |
| | | return list.map((i) => ({ |
| | | ...i, |
| | | childrenCount: Array.isArray(i.children) ? i.children.length : 0, |
| | | children: this.expandIds.includes(i.id) |
| | | ? i.children |
| | | : i.children.slice(0, 1), |
| | | })) |
| | | }, |
| | | tableEventHandlers: { |
| | | expandChange: (row, expand) => { |
| | | if (expand) { |
| | | if (!this.expandIds.includes(row.id)) { |
| | | this.expandIds.push(row.id) |
| | | } |
| | | row.children = |
| | | this.originalList.find((i) => i.id === row.id)?.children || [] |
| | | } else { |
| | | const index = this.expandIds.indexOf(row.id) |
| | | if (index !== -1) { |
| | | this.expandIds.splice(index, 1) |
| | | } |
| | | } |
| | | }, |
| | | }, |
| | | beforeOpen(row, isNew) { |
| | | if (isNew && row.name) { |
| | | row.parentName = row.name |
| | | } |
| | | if (!isNew && !row.parentId && row.parentName) { |
| | | row.parentName = '' |
| | | } |
| | | }, |
| | | extraParentKeys: ['parentName', 'levelLimit'], |
| | | tableAttrs: { |
| | | rowKey: 'id', |
| | | }, |
| | | columns: [ |
| | | { label: '板块名称', prop: 'name' }, |
| | | { |
| | | label: '板块图片', |
| | | formatter: (row) => ( |
| | | <el-bus-image |
| | | style="width:50px;height:50px" |
| | | lazy={true} |
| | | src={row.imageUrl} |
| | | /> |
| | | ), |
| | | }, |
| | | { label: '排序', prop: 'sortBy' }, |
| | | { label: '子板块数量', formatter: (row) => row.childrenCount }, |
| | | { |
| | | label: '是否显示', |
| | | formatter: (row) => ( |
| | | <el-switch |
| | | value={row.shown} |
| | | onChange={this.onShownChange.bind(this, row)} |
| | | ></el-switch> |
| | | ), |
| | | }, |
| | | ], |
| | | searchForm: [ |
| | | { |
| | | type: 'row', |
| | | items: [{ label: '板块名称', id: 'name', type: 'input' }], |
| | | }, |
| | | ], |
| | | form: [ |
| | | { |
| | | label: '上级板块:', |
| | | id: 'parentName', |
| | | type: 'input', |
| | | readonly: true, |
| | | hidden: (row) => !row.parentName, |
| | | }, |
| | | { |
| | | label: '板块名称:', |
| | | id: 'name', |
| | | type: 'input', |
| | | rules: { |
| | | required: true, |
| | | message: '请输入板块名称', |
| | | trigger: 'blur', |
| | | }, |
| | | }, |
| | | { |
| | | label: '板块图片:', |
| | | id: 'imageUrl', |
| | | type: 'bus-upload', |
| | | el: { |
| | | listType: 'picture-card', |
| | | limit: 1, |
| | | limitSize: 2, |
| | | tipText: '建议上传164*164的图片,大小不超过2M', |
| | | valueType: 'string', |
| | | }, |
| | | rules: { required: false, message: '请上传板块图片' }, |
| | | }, |
| | | { |
| | | ...getSortConfig(), |
| | | }, |
| | | ], |
| | | }, |
| | | } |
| | | }, |
| | | head() { |
| | | return { |
| | | title: '片场板块管理', |
| | | } |
| | | }, |
| | | methods: { |
| | | onShownChange(row, e) { |
| | | const url = e |
| | | ? 'flower/api/film/category/tree/shown' |
| | | : 'film/api/film/category/tree/hidden' |
| | | const text = e ? '显示' : '隐藏' |
| | | this.$elBusUtil |
| | | .confirm(`确定要${text}这个板块吗?`) |
| | | .then(async () => { |
| | | const { code } = await this.$elBusHttp.request(url, { |
| | | params: { |
| | | id: row.id, |
| | | }, |
| | | }) |
| | | if (code === 0) { |
| | | this.$message.success(`${text}成功`) |
| | | this.$refs.crud.getList() |
| | | } |
| | | }) |
| | | .catch(() => {}) |
| | | }, |
| | | }, |
| | | } |
| | | </script> |
| | | |
| | | <style lang="scss" scoped> |
| | | .category-list { |
| | | } |
| | | </style> |