|
|
@@ -1,19 +1,987 @@
|
|
|
<script>
|
|
|
- export default {
|
|
|
- name: "showing",
|
|
|
- data() {
|
|
|
- return {
|
|
|
+import axios from "axios";
|
|
|
+import {defineComponent} from "vue";
|
|
|
+import fieldIsAllow from "../../../until/fieldIsAllow"
|
|
|
+import RoundedTitle from "../../../components/public/roundedTitle.vue";
|
|
|
+import {rCode} from "../../../map/rcodeMap_esm";
|
|
|
+import {handle} from "../../../until/handle";
|
|
|
+import ImageViewer from "../../../components/public/imageViewer.vue";
|
|
|
+import ImageTable from "../../../components/public/imageTable.vue";
|
|
|
+import Pop from "../../../components/public/pop.vue";
|
|
|
+import PopCard from "../../../components/public/popCard.vue";
|
|
|
+import InputRow from "../../../components/public/form/inputRow.vue";
|
|
|
+import dbField_esm from "../../../map/dbField_esm";
|
|
|
+import {apiMap} from "../../../map/apiMap";
|
|
|
+import SearchBox from "../../../components/search/searchBox.vue";
|
|
|
+import {pTypes} from "../../../map/productMap";
|
|
|
+import {newsType} from "../../../map/newMap";
|
|
|
+import {toNumber,isEmpty} from "../../../until/typeTool";
|
|
|
+
|
|
|
+export default defineComponent({
|
|
|
+ name: 'showing',
|
|
|
+ computed: {
|
|
|
+ dbField_esm() {
|
|
|
+ return dbField_esm
|
|
|
+ },
|
|
|
+ productTypes(){
|
|
|
+ let arr = this.$store.getters.productTypes;
|
|
|
+ // 添加 all
|
|
|
+ arr.unshift({text: '全部', key: 'all' });
|
|
|
+ return arr;
|
|
|
+ },
|
|
|
+ newsTypes(){// 添加 all
|
|
|
+ let arr = this.$store.getters.allNewsTypes;
|
|
|
+ arr.unshift({text: '全部', key: 'all' });
|
|
|
+ return arr;
|
|
|
+ },
|
|
|
+ },
|
|
|
+ components: {SearchBox, InputRow, PopCard, Pop, ImageTable, ImageViewer, RoundedTitle},
|
|
|
+ async asyncData(ctx){
|
|
|
+ // 加载展示块数据
|
|
|
+ let [err,res] = await handle(axios.get(apiMap.showBlocksList.path));
|
|
|
+ if(err){
|
|
|
+ return {};
|
|
|
+ }
|
|
|
+ let result = res.data;
|
|
|
+ if(result.code === rCode.OK){
|
|
|
+ return {showBlockList: result.data}
|
|
|
+ }else{
|
|
|
+ this.$message.error(result.msg);
|
|
|
+ return {}
|
|
|
+ }
|
|
|
+ return {}
|
|
|
+ },
|
|
|
+ data(){
|
|
|
+ return {
|
|
|
+ limit: 10,
|
|
|
+ loading: false,
|
|
|
+ showBlockList: [],
|
|
|
+ popShow: false,
|
|
|
+ popLoading: false,
|
|
|
+ showBlockPopShow: false,
|
|
|
+ showBlockPopLoading: false,
|
|
|
+ isEditShowBlock: false,
|
|
|
+ showBlockData: {},
|
|
|
+ form: {
|
|
|
+ // 排序
|
|
|
+ sort: {
|
|
|
+ val:0,
|
|
|
+ init: 0,
|
|
|
+ msg: '',
|
|
|
+ state: 0,
|
|
|
+ },
|
|
|
+ // 状态 0:禁用,1:启用
|
|
|
+ state: {
|
|
|
+ val: dbField_esm.db_base.carouselState.disable,
|
|
|
+ init: dbField_esm.db_base.carouselState.disable,
|
|
|
+ msg: '',
|
|
|
+ state: 0,
|
|
|
+ options: [
|
|
|
+ {label: '禁用', value: dbField_esm.db_base.carouselState.disable},
|
|
|
+ {label: '启用', value: dbField_esm.db_base.carouselState.enable},
|
|
|
+ ]
|
|
|
+ },
|
|
|
+ // 展示块类型 '0:product','1:news','2:page','3:href'
|
|
|
+ type: {
|
|
|
+ val: 0,
|
|
|
+ init: 0,
|
|
|
+ msg: '',
|
|
|
+ state: 0,
|
|
|
+ options: [
|
|
|
+ {label: '直接链接', value: 0,checkField: 'href'},
|
|
|
+ {label: '内部产品', value: 1,checkField: 'productId'},
|
|
|
+ {label: '指向新闻', value: 2,checkField: 'newsId'},
|
|
|
+ ],
|
|
|
+ },
|
|
|
+ // 具体值
|
|
|
+ value: {
|
|
|
+ val: '',
|
|
|
+ init: '',
|
|
|
+ msg: '',
|
|
|
+ state: 0,
|
|
|
+ // 依赖字段
|
|
|
+ depend: 'type',
|
|
|
+ showText: '',// 展示用字段
|
|
|
+ oldShowText: '',
|
|
|
+ },
|
|
|
+ // 标题
|
|
|
+ title: {
|
|
|
+ val: '',
|
|
|
+ init: '',
|
|
|
+ msg: '',
|
|
|
+ state: 0,
|
|
|
+ },
|
|
|
+ // 副标题
|
|
|
+ subTitle: {
|
|
|
+ val: '',
|
|
|
+ init: '',
|
|
|
+ msg: '',
|
|
|
+ state: 0,
|
|
|
+ },
|
|
|
+ // file
|
|
|
+ fileData: {
|
|
|
+ val: '',
|
|
|
+ init: '',
|
|
|
+ msg: '',
|
|
|
+ state: 0,
|
|
|
+ showText: '',// 展示用字段
|
|
|
+ oldShowText: '',
|
|
|
+ },
|
|
|
+ },
|
|
|
+ productSelectVisible: false,
|
|
|
+ productSearch: {
|
|
|
+ type: {
|
|
|
+ val: '',
|
|
|
+ oldVal: '',
|
|
|
+ init: '',
|
|
|
+ msg: '',
|
|
|
+ options: [],
|
|
|
+ }
|
|
|
+ },
|
|
|
+ newsSelectVisible: false,
|
|
|
+ newsVisible: false,
|
|
|
+ newsSearch: {
|
|
|
+ type: {
|
|
|
+ val: '',
|
|
|
+ oldVal: '',
|
|
|
+ init: '',
|
|
|
+ msg: '',
|
|
|
+ options: [],
|
|
|
+ }
|
|
|
+ },
|
|
|
+ imageSelectVisible: false,
|
|
|
+
|
|
|
+ }
|
|
|
+ },
|
|
|
+ mounted() {
|
|
|
+ if(this.showBlockList.length === 0){
|
|
|
+ this.getShowBlockList();
|
|
|
+ }
|
|
|
+ },
|
|
|
+ methods: {
|
|
|
+ async getShowBlockList(){
|
|
|
+ this.loading = true;
|
|
|
+ let [err,res] = await handle(this.$axios.get(apiMap.showBlocksList.path));
|
|
|
+ this.loading = false;
|
|
|
+ if(err){
|
|
|
+ if(this.NotificationKey){
|
|
|
+ this.$notification.close(this.NotificationKey);
|
|
|
+ }
|
|
|
+ this.NotificationKey = `open${Date.now()}`;
|
|
|
+ return this.$notification.error({
|
|
|
+ message: '展示块数据加载失败',
|
|
|
+ description:`异常: ${err.message}`,
|
|
|
+ duration: 0,
|
|
|
+ btn: h => {
|
|
|
+ return h(
|
|
|
+ 'a-button',
|
|
|
+ {
|
|
|
+ props: {
|
|
|
+ type: 'primary',
|
|
|
+ size: 'small',
|
|
|
+ },
|
|
|
+ on: {
|
|
|
+ click: () => {
|
|
|
+ this.$notification.close(this.NotificationKey);
|
|
|
+ this.getShowBlockList();
|
|
|
+ },
|
|
|
+ },
|
|
|
+ },
|
|
|
+ '重试',
|
|
|
+ );
|
|
|
+ },
|
|
|
+ key:this.NotificationKey,
|
|
|
+ onClose: close,
|
|
|
+ });
|
|
|
+ }
|
|
|
+ let result = res.data;
|
|
|
+ if(result.code === rCode.OK){
|
|
|
+ this.showBlockList = result.data;
|
|
|
+ return {showBlockList: result.data}
|
|
|
+ }else{
|
|
|
+ this.$message.error(result.msg);
|
|
|
+ return {}
|
|
|
+ }
|
|
|
+ },
|
|
|
+ // 搜索产品,只需要产品名等信息
|
|
|
+ async getProductSearch(searchParam){
|
|
|
+ console.log(searchParam)
|
|
|
+ if(this.productSearch.type.val !== this.productSearch.type.oldVal){
|
|
|
+ searchParam.p = 1;
|
|
|
+ }
|
|
|
+ searchParam.type = this.productSearch.type.val;
|
|
|
+ searchParam.l = this.limit;
|
|
|
+ searchParam.p = searchParam.page;
|
|
|
+ let [err,res] = await handle(
|
|
|
+ this.$axios.get(
|
|
|
+ apiMap.searchProductMini.path,
|
|
|
+ {params:searchParam})
|
|
|
+ );
|
|
|
+ if(err){
|
|
|
+ console.log(err);
|
|
|
+ return [{message:'请求数据失败'},null];
|
|
|
+ }
|
|
|
+
|
|
|
+ let result = res.data;
|
|
|
+ if(result.code === rCode.OK){
|
|
|
+ this.productSearch.type.oldVal = this.productSearch.type.val;
|
|
|
+ // data 转换
|
|
|
+ result.data = result.data.map(item=>{
|
|
|
+ item.showText = item.name;
|
|
|
+ return item;
|
|
|
+ });
|
|
|
+ return [null,result];
|
|
|
+ }else{
|
|
|
+ // 可捕获的服务器错误
|
|
|
+ return [{message:result.msg},null];
|
|
|
+ }
|
|
|
+ },
|
|
|
+ // 加载展示块默认数据
|
|
|
+ async getNewsSearch(searchParam){
|
|
|
+ console.log(searchParam)
|
|
|
+ if(this.newsSearch.type.val !== this.newsSearch.type.oldVal){
|
|
|
+ searchParam.p = 1;
|
|
|
+ }
|
|
|
+ searchParam.type = this.newsSearch.type.val;
|
|
|
+ searchParam.l = this.limit;
|
|
|
+ searchParam.p = searchParam.page;
|
|
|
+ let [err,res] = await handle(
|
|
|
+ this.$axios.get(
|
|
|
+ apiMap.searchNewsMini.path,
|
|
|
+ {params:searchParam})
|
|
|
+ );
|
|
|
+ if(err){
|
|
|
+ console.log(err);
|
|
|
+ return [{message:'请求数据失败'},null];
|
|
|
+ }
|
|
|
+
|
|
|
+ let result = res.data;
|
|
|
+ if(result.code === rCode.OK){
|
|
|
+ this.newsSearch.type.oldVal = this.newsSearch.type.val;
|
|
|
+ // data 转换
|
|
|
+ result.data = result.data.map(item=>{
|
|
|
+ item.showText = item.name;
|
|
|
+ return item;
|
|
|
+ });
|
|
|
+ return [null,result];
|
|
|
+ }else{
|
|
|
+ // 可捕获的服务器错误
|
|
|
+ return [{message:result.msg},null];
|
|
|
+ }
|
|
|
+ },
|
|
|
+
|
|
|
+ checkFormItem(field,enumOptions,reCheckField){
|
|
|
+ let formItem = this.form[field];
|
|
|
+ if (formItem){
|
|
|
+ if (enumOptions){
|
|
|
+ // 遍历枚举
|
|
|
+ for (let i = 0; i < enumOptions.length; i++) {
|
|
|
+ let enumOption = enumOptions[i];
|
|
|
+ if (enumOption.value === formItem.val){
|
|
|
+ return true;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ formItem.msg = '选项不在范围内';
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+ if(reCheckField){
|
|
|
+ // 检查用字段
|
|
|
+ formItem.msg = fieldIsAllow({
|
|
|
+ [reCheckField]:formItem.val,
|
|
|
+ })
|
|
|
+ }else{
|
|
|
+ formItem.msg = fieldIsAllow({
|
|
|
+ [field]:formItem.val,
|
|
|
+ })
|
|
|
+ }
|
|
|
+ }else{
|
|
|
+ let r = true;
|
|
|
+ for (const fieldKey in this.form) {
|
|
|
+ formItem = this.form[fieldKey];
|
|
|
+ let depend = this.form[formItem.depend];
|
|
|
+ let checkField = fieldKey;
|
|
|
+
|
|
|
+ if(formItem.reCheckField){
|
|
|
+ checkField = formItem.reCheckField;
|
|
|
+ }
|
|
|
+ // 枚举值判断
|
|
|
+ if(formItem.options){
|
|
|
+ // 有枚举字段,只判断是否在枚举中
|
|
|
+ if(formItem.options.findIndex(item=>item.value == formItem.val) === -1){
|
|
|
+ formItem.msg = '选项不在范围内';
|
|
|
+ r = false;
|
|
|
+ }
|
|
|
+ // 枚举值判断完毕,继续下一个字段
|
|
|
+ continue;
|
|
|
+ }
|
|
|
+
|
|
|
+ // 判断是否有依赖字段
|
|
|
+ if(depend){
|
|
|
+ if(depend.options){
|
|
|
+ // 依赖的对象有枚举类型,检查该枚举类型是否有有检测值
|
|
|
+ let optionItem = depend.options.find(item=>item.value == depend.val);
|
|
|
+ if(!optionItem){
|
|
|
+ depend.msg = '选项不在范围内';
|
|
|
+ formItem.msg = '该值依赖项输入异常';
|
|
|
+ r = false;
|
|
|
+ continue;
|
|
|
+ }
|
|
|
+ if(optionItem.checkField){
|
|
|
+ console.log(`采用依赖项的检测字段${optionItem.checkField}`)
|
|
|
+ checkField = optionItem.checkField;
|
|
|
+ }
|
|
|
+
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ console.log(`检测字段:${checkField},值:${formItem.val}`);
|
|
|
+ formItem.msg = fieldIsAllow({
|
|
|
+ [checkField]:formItem.val,
|
|
|
+ })
|
|
|
+ if (formItem.msg){
|
|
|
+ r = false;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ return r
|
|
|
+ }
|
|
|
+ },
|
|
|
+ initShowBlockForm(){
|
|
|
+ this.showBlockData = {};
|
|
|
+ let keys = Object.keys(this.form);
|
|
|
+ for(let i = 0; i < keys.length; i++){
|
|
|
+ let key = keys[i];
|
|
|
+ this.form[key].val = this.form[key].init;
|
|
|
+ this.form[key].msg = '';
|
|
|
+ this.form[key].state = 0;
|
|
|
+ this.form.value.showText = '';
|
|
|
+ }
|
|
|
+ },
|
|
|
+ openAddShowBlockModal(){
|
|
|
+ // 初始化表单
|
|
|
+ this.initShowBlockForm();
|
|
|
+ this.showBlockPopShow = true;
|
|
|
+ this.isEditShowBlock = false;
|
|
|
+ this.$nextTick(()=>{
|
|
|
+ // 打开弹窗. 选择图片,填写链接地址,排序
|
|
|
+ this.productSearch.type.options = this.productTypes;
|
|
|
+ this.newsSearch.type.options = this.newsTypes;
|
|
|
+ // 默认值设置
|
|
|
+ this.productSearch.type.val = this.productTypes[0].key;
|
|
|
+ this.productSearch.type.oldVal = this.productTypes[0].key;
|
|
|
+ this.productSearch.type.init = this.productTypes[0].key;
|
|
|
+
|
|
|
+ this.newsSearch.type.val = this.newsTypes[0].key;
|
|
|
+ this.newsSearch.type.oldVal = this.newsTypes[0].key;
|
|
|
+ this.newsSearch.type.init = this.newsTypes[0].key;
|
|
|
+ });
|
|
|
+ },
|
|
|
+ onPopOkClickHandle(){
|
|
|
+ if(this.isEditShowBlock){
|
|
|
+ console.log('保存修改后的展示块数据');
|
|
|
+ this.updateShowBlockExecute();
|
|
|
+ }else{
|
|
|
+ console.log('新增展示块');
|
|
|
+ this.addShowBlockExecute();
|
|
|
+ }
|
|
|
+ },
|
|
|
+ async addShowBlockExecute(){
|
|
|
+ // 生成新数据表单
|
|
|
+ let showBlockData = {};
|
|
|
+ let isPass = this.checkFormItem();
|
|
|
+ if(!isPass){
|
|
|
+ return console.log('数据验证不通过');
|
|
|
+ }
|
|
|
+ console.log('开始生成新数据表单');
|
|
|
+ showBlockData.sort = this.form.sort.val;
|
|
|
+ showBlockData.type = this.form.type.val;
|
|
|
+ showBlockData.value = this.form.value.val;
|
|
|
+ showBlockData.title = this.form.title.val;
|
|
|
+ showBlockData.subTitle = this.form.subTitle.val;
|
|
|
+ showBlockData.fileId = this.form.fileData.val;
|
|
|
+ showBlockData.state = this.form.state.val;
|
|
|
+ // 生成新数据表单完毕
|
|
|
+ console.log('生成新数据表单完毕');
|
|
|
+ this.showBlockPopLoading = true;
|
|
|
+ let [err,res] = await handle(this.$axios.put(apiMap.baseAddShowBlock.path,showBlockData));
|
|
|
+ this.showBlockPopLoading = false;
|
|
|
+ if(err){
|
|
|
+ console.log(err);
|
|
|
+ return this.$message.error('新增展示块失败');
|
|
|
+ }
|
|
|
+ this.$message.success('新增展示块成功');
|
|
|
+ this.showBlockPopShow = false;
|
|
|
+ await this.getShowBlockList();
|
|
|
+
|
|
|
+ },
|
|
|
+ async updateShowBlockExecute(){
|
|
|
+ let showBlockData = {};
|
|
|
+ let isPass = this.checkFormItem();
|
|
|
+ if(!isPass){
|
|
|
+ return console.log('数据验证不通过');
|
|
|
+ }
|
|
|
+ // 获取更新项
|
|
|
+ console.log(`获取更新项`);
|
|
|
+ let updateItems = {};
|
|
|
+ console.log(this.showBlockData);
|
|
|
+ let blockId = this.showBlockData.id;
|
|
|
+ if(this.form.sort.val != toNumber(this.showBlockData.sort)){
|
|
|
+ updateItems.sort = this.form.sort.val;
|
|
|
+ }
|
|
|
+ if(this.form.type.val != toNumber(this.showBlockData.type)){
|
|
|
+ updateItems.type = this.form.type.val;
|
|
|
}
|
|
|
+ if(this.form.value.val != this.showBlockData.value){
|
|
|
+ updateItems.value = this.form.value.val;
|
|
|
+ }
|
|
|
+ if(this.form.title.val != this.showBlockData.title){
|
|
|
+ updateItems.title = this.form.title.val;
|
|
|
+ }
|
|
|
+ if(this.form.subTitle.val != this.showBlockData.subTitle){
|
|
|
+ updateItems.subTitle = this.form.subTitle.val;
|
|
|
+ }
|
|
|
+ if(toNumber(this.form.fileData.val) != this.showBlockData.fileId){
|
|
|
+ updateItems.fileId = this.form.fileData.val;
|
|
|
+ }
|
|
|
+ if(this.form.state.val != this.showBlockData.state){
|
|
|
+ updateItems.state = this.form.state.val;
|
|
|
+ }
|
|
|
+ if(isEmpty(updateItems)){
|
|
|
+ return this.$message.warn('未修改任何数据');
|
|
|
+ }
|
|
|
+ console.log(`更新展示块数据,更新数量: ${Object.keys(updateItems).length} 更新字段: [${Object.keys(updateItems).join(',')}]`);
|
|
|
+ this.showBlockPopLoading = true;
|
|
|
+ let [err,res] = await handle(this.$axios.post(apiMap.baseUpdateShowBlock.path,{
|
|
|
+ blockId,
|
|
|
+ updateItems
|
|
|
+ }));
|
|
|
+ this.showBlockPopLoading = false;
|
|
|
+ if(err){
|
|
|
+ console.log(err);
|
|
|
+ return this.$message.error('更新展示块失败');
|
|
|
+ }
|
|
|
+ let result = res.data;
|
|
|
+ if (result.code === rCode.OK){
|
|
|
+ this.$message.success('更新展示块成功');
|
|
|
+ this.showBlockPopShow = false;
|
|
|
+ await this.getShowBlockList();
|
|
|
+ }else{
|
|
|
+ this.$message.error(`更新展示块失败,${result.msg}`);
|
|
|
+ }
|
|
|
+
|
|
|
+ },
|
|
|
+
|
|
|
+ getShowBlockTypeText(type){
|
|
|
+ type = toNumber(type);
|
|
|
+ let typeText = '';
|
|
|
+ if(type === dbField_esm.db_base.carouselType.production){
|
|
|
+ typeText = '产品';
|
|
|
+ }else if(type === dbField_esm.db_base.carouselType.news){
|
|
|
+ typeText = '文章';
|
|
|
+ }else if(type === dbField_esm.db_base.carouselType.href){
|
|
|
+ typeText = '直接链接';
|
|
|
+ }else{
|
|
|
+ typeText = '暂未支持类型';
|
|
|
+ }
|
|
|
+ return typeText
|
|
|
+ },
|
|
|
+ getShowBlockStateText(state){
|
|
|
+ // state = toNumber(state);
|
|
|
+ let typeText = '';
|
|
|
+ if(state === dbField_esm.db_base.carouselState.enable){
|
|
|
+ typeText = '启用';
|
|
|
+ }else if(state === dbField_esm.db_base.carouselState.disable){
|
|
|
+ typeText = '禁用';
|
|
|
+ }else{
|
|
|
+ typeText = '未知状态';
|
|
|
+ }
|
|
|
+ return typeText
|
|
|
+ },
|
|
|
+ cancelPop(){
|
|
|
+ this.imageSelectVisible = false;
|
|
|
+ },
|
|
|
+ okHandle(fileItem){
|
|
|
+ console.log('文件列表');
|
|
|
+ console.log(fileItem);
|
|
|
+ this.cancelPop();
|
|
|
+ this.$nextTick(()=>{
|
|
|
+ this.form.fileData.val = fileItem.fileId;
|
|
|
+ this.form.fileData.state = 1;
|
|
|
+ this.form.fileData.msg = '';
|
|
|
+ this.form.fileData.showText = fileItem.filePath;
|
|
|
+ })
|
|
|
+ },
|
|
|
+ onProductSearchHandle(e){
|
|
|
+ console.log(`onProductSearchHandle ${e}`);
|
|
|
+ console.log(e);
|
|
|
+ console.log(this.productSearch.type.val);
|
|
|
+ },
|
|
|
+ onSelectedItemHandle(item){
|
|
|
+ console.log(`selected item ${item}`);
|
|
|
+ console.log(item);
|
|
|
+ this.form.value.val = item.id;
|
|
|
+ this.form.value.showText = item.showText;
|
|
|
+ this.form.value.msg = '';
|
|
|
+ },
|
|
|
+ onTypeChangeHandle(e){
|
|
|
+ console.log(`type change ${e}`);
|
|
|
+ // 清除其他值
|
|
|
+ this.form.value.val = '';
|
|
|
+ this.form.value.msg = '';
|
|
|
+ this.form.value.showText = '';
|
|
|
+ },
|
|
|
+
|
|
|
+ onNewsSearchHandle(e){
|
|
|
+ console.log(`onProductSearchHandle ${e}`);
|
|
|
+ console.log(e);
|
|
|
+ console.log(this.productSearch.type.val);
|
|
|
+ },
|
|
|
+ onClickEditHandle(item){
|
|
|
+ console.log(`点击编辑展示块`);
|
|
|
+ console.log(item);
|
|
|
+ if(!item || !item.id){
|
|
|
+ return this.$message.warn('展示块数据获取异常,已经取消编辑');
|
|
|
+ }
|
|
|
+ this.initShowBlockForm();
|
|
|
+
|
|
|
+ this.isEditShowBlock = true;
|
|
|
+ this.showBlockData = item;
|
|
|
+ this.showBlockPopShow = true;
|
|
|
+ this.showBlockPopLoading = true;
|
|
|
+ this.form.sort.val = toNumber(item.sort);
|
|
|
+ this.form.sort.init = toNumber(item.sort);
|
|
|
+ this.form.type.val = toNumber(item.type);
|
|
|
+ this.form.type.init = toNumber(item.type);
|
|
|
+ this.form.value.val = item.value;
|
|
|
+ this.form.value.init = item.value;
|
|
|
+ this.form.value.showText = item.valueShowText;
|
|
|
+ this.form.value.oldShowText = item.oldShowText;
|
|
|
+ this.form.title.val = item.title;
|
|
|
+ this.form.title.init = item.title;
|
|
|
+ this.form.subTitle.val = item.subTitle;
|
|
|
+ this.form.subTitle.init = item.subTitle;
|
|
|
+ this.form.fileData.val = item.fileId;
|
|
|
+ this.form.fileData.init = item.fileId;
|
|
|
+ this.form.fileData.showText = item.filePath;
|
|
|
+ this.form.fileData.oldShowText = item.filePath;
|
|
|
+ this.form.state.val = item.state;
|
|
|
+ this.showBlockPopLoading = false;
|
|
|
+
|
|
|
}
|
|
|
- }
|
|
|
+
|
|
|
+ },
|
|
|
+
|
|
|
+})
|
|
|
</script>
|
|
|
|
|
|
<template>
|
|
|
- <div class="w-full p-2">
|
|
|
- 该板块正在调整中
|
|
|
- </div>
|
|
|
+<div class="w-full p-2">
|
|
|
+ <rounded-title>展示块管理</rounded-title>
|
|
|
+ <div class="mt-2 rounded bg-white p-2">
|
|
|
+ <div class="mt-2 rounded bg-white p-2">
|
|
|
+ <div class="py-1 border-b border-cyan-300 flex justify-between">
|
|
|
+ 点击下方块进行管理展示块数据
|
|
|
+ <div class="px-2 flex"><!-- 刷新按钮-->
|
|
|
+ <a-button type="primary" class="ant-icon-btn " icon="reload" @click="getShowBlockList" :loading="loading"></a-button>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+
|
|
|
+ <div class="w-full h-auto transition">
|
|
|
+ <div v-show="loading" class="w-full h-64 flex justify-center items-center ">
|
|
|
+ <a-spin size="large" />
|
|
|
+ </div>
|
|
|
+
|
|
|
+ <!-- 展示块预览区域,保持与 showingStand.vue 一致的布局 -->
|
|
|
+ <div class="container mx-auto showing">
|
|
|
+ <div
|
|
|
+ v-for="(item,i) in showBlockList"
|
|
|
+ :class="`chunk imgBox chunk${(i+1)}`"
|
|
|
+ :key="item.id"
|
|
|
+ >
|
|
|
+ <!-- 实时管理(物联网) -->
|
|
|
+ <img :src="item.filePath" alt="item.title">
|
|
|
+ <p class="chunkText">
|
|
|
+ <span class="title">{{item.title}}</span>
|
|
|
+ <span class="subTitle">{{item.subTitle}}</span>
|
|
|
+ </p>
|
|
|
+ <div class="absolute inset-0 flex items-center justify-center opacity-0 hover:opacity-100 transition-opacity bg-black bg-opacity-30">
|
|
|
+ <a-button @click="onClickEditHandle(item)" type="primary">编辑</a-button>
|
|
|
+ </div>
|
|
|
+
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+
|
|
|
+ <pop :show="showBlockPopShow" :loading="showBlockPopLoading">
|
|
|
+ <pop-card>
|
|
|
+<!-- <template slot="header" class="w-full">-->
|
|
|
+<!-- 编辑展示块-->
|
|
|
+<!-- </template>-->
|
|
|
+ <template slot="close-group">
|
|
|
+ <a-button icon="close" @click="showBlockPopShow = false"></a-button>
|
|
|
+ </template>
|
|
|
+ <div class="w-full">
|
|
|
+ <input-row :msg="form.sort.msg"
|
|
|
+ label="排序">
|
|
|
+ <a-input-number v-model="form.sort.val"
|
|
|
+ @focus="form.sort.msg=''"
|
|
|
+ :min="0"
|
|
|
+ @blur="checkFormItem('sort')"
|
|
|
+ />
|
|
|
+ </input-row>
|
|
|
+
|
|
|
+ <input-row :msg="form.state.msg"
|
|
|
+ label="状态">
|
|
|
+ <a-radio-group v-model="form.state.val">
|
|
|
+ <a-radio-button v-for="opt in form.state.options"
|
|
|
+ :key="'cState'+opt.value"
|
|
|
+ :value="opt.value">
|
|
|
+ {{ opt.label }}
|
|
|
+ </a-radio-button>
|
|
|
+ </a-radio-group>
|
|
|
+ </input-row>
|
|
|
+
|
|
|
+ <input-row :msg="form.title.msg"
|
|
|
+ label="标题">
|
|
|
+ <a-input v-model="form.title.val"
|
|
|
+ placeholder="请输入标题"
|
|
|
+ @focus="form.title.msg=''"
|
|
|
+ @blur="checkFormItem('title')"
|
|
|
+ />
|
|
|
+ </input-row>
|
|
|
+
|
|
|
+ <input-row :msg="form.subTitle.msg"
|
|
|
+ label="副标题">
|
|
|
+ <a-textarea v-model="form.subTitle.val"
|
|
|
+ placeholder="请输入副标题"
|
|
|
+ :rows="2"
|
|
|
+ @focus="form.subTitle.msg=''"
|
|
|
+ @blur="checkFormItem('subTitle')"
|
|
|
+ />
|
|
|
+ </input-row>
|
|
|
+
|
|
|
+<!-- 展示块类型选择 -->
|
|
|
+ <input-row :msg="form.type.msg"
|
|
|
+ label="展示块类型">
|
|
|
+ <a-radio-group v-model="form.type.val" @change="onTypeChangeHandle">
|
|
|
+ <a-radio-button v-for="opt in form.type.options"
|
|
|
+ :key="'cType'+opt.value"
|
|
|
+ :value="opt.value">
|
|
|
+ {{ opt.label }}
|
|
|
+ </a-radio-button>
|
|
|
+ </a-radio-group>
|
|
|
+ </input-row>
|
|
|
+
|
|
|
+<!-- 展示块具体值 -->
|
|
|
+<!-- 链接-->
|
|
|
+ <input-row
|
|
|
+ v-show="form.type.val === dbField_esm.db_base.carouselType.href"
|
|
|
+ :msg="form.value.msg"
|
|
|
+ label="输入链接">
|
|
|
+ <a-input v-model="form.value.val"
|
|
|
+ placeholder="输入要指向的链接地址"
|
|
|
+ @focus="form.value.msg=''"
|
|
|
+ @blur="checkFormItem('value', null,'href')"
|
|
|
+ />
|
|
|
+ </input-row>
|
|
|
+<!-- 产品选择-->
|
|
|
+ <input-row
|
|
|
+ v-show="form.type.val === dbField_esm.db_base.carouselType.production"
|
|
|
+ :msg="form.value.msg"
|
|
|
+ label="选择产品">
|
|
|
+ {{ form.value.showText }}
|
|
|
+ <a-popover v-model="productSelectVisible" title="选择产品" trigger="click">
|
|
|
+ <div slot="content" class="searchBox" >
|
|
|
+ <search-box
|
|
|
+ class="h-72"
|
|
|
+ :loadDataApi="getProductSearch"
|
|
|
+ :limit="limit"
|
|
|
+ search-placeholder="请输入产品名称关键字"
|
|
|
+ loadTip="正在搜索产品中..."
|
|
|
+ @onSelectedItem="onSelectedItemHandle"
|
|
|
+ >
|
|
|
+ <div class="w-full" slot="otherSearchItem">
|
|
|
+ <a-radio-group v-model="productSearch.type.val"
|
|
|
+ @change="onProductSearchHandle">
|
|
|
+ <a-radio-button v-for="opt in productSearch.type.options"
|
|
|
+ :key="'cType'+opt.key"
|
|
|
+ :value="opt.key">
|
|
|
+ {{ opt.text }}
|
|
|
+ </a-radio-button>
|
|
|
+ </a-radio-group>
|
|
|
+ </div>
|
|
|
+ </search-box>
|
|
|
+ </div>
|
|
|
+ <a-button type="primary" >
|
|
|
+ 选择产品
|
|
|
+ </a-button>
|
|
|
+ </a-popover>
|
|
|
+ </input-row>
|
|
|
+<!-- 新闻选择-->
|
|
|
+ <input-row
|
|
|
+ v-show="form.type.val === dbField_esm.db_base.carouselType.news"
|
|
|
+ :msg="form.value.msg"
|
|
|
+ label="文章选择">
|
|
|
+ {{ form.value.showText }}
|
|
|
+ <a-popover v-model="newsSelectVisible" title="选择你需要的文章" trigger="click">
|
|
|
+ <div slot="content" class="searchBox" >
|
|
|
+ <search-box
|
|
|
+ class="h-72"
|
|
|
+ :loadDataApi="getNewsSearch"
|
|
|
+ :limit="limit"
|
|
|
+ search-placeholder="请输入文章名称关键字"
|
|
|
+ loadTip="正在搜索文章中..."
|
|
|
+ ref="productSearch"
|
|
|
+ @onSelectedItem="onSelectedItemHandle"
|
|
|
+ >
|
|
|
+ <div class="w-full" slot="otherSearchItem">
|
|
|
+ <a-radio-group v-model="newsSearch.type.val"
|
|
|
+ @change="onNewsSearchHandle">
|
|
|
+ <a-radio-button v-for="opt in newsSearch.type.options"
|
|
|
+ :key="'cType'+opt.key"
|
|
|
+ :value="opt.key">
|
|
|
+ {{ opt.text }}
|
|
|
+ </a-radio-button>
|
|
|
+ </a-radio-group>
|
|
|
+ </div>
|
|
|
+ </search-box>
|
|
|
+ </div>
|
|
|
+ <a-button type="primary">
|
|
|
+ 选择文章
|
|
|
+ </a-button>
|
|
|
+ </a-popover>
|
|
|
+ </input-row>
|
|
|
+
|
|
|
+<!-- 选择图片 -->
|
|
|
+ <input-row label="展示图片"
|
|
|
+ :msg="form.fileData.msg">
|
|
|
+
|
|
|
+ <div class="w-full h-60 rounded relative" @click="imageSelectVisible = true">
|
|
|
+ <image-viewer class="" :src="form.fileData.showText"></image-viewer>
|
|
|
+ <div class="absolute w-full h-full left-0 top-0
|
|
|
+ justify-center text-white bg-gray-400
|
|
|
+ items-center text-2xl flex opacity-0 hover:opacity-70">
|
|
|
+ 点击选择图片
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+
|
|
|
+ </input-row>
|
|
|
+ </div>
|
|
|
+ <template class="w-full" slot="footer">
|
|
|
+ <a-button @click="onPopOkClickHandle">{{isEditShowBlock? '保存': '新增'}}</a-button>
|
|
|
+ </template>
|
|
|
+ </pop-card>
|
|
|
+ </pop>
|
|
|
+
|
|
|
+ <pop :show="imageSelectVisible">
|
|
|
+
|
|
|
+ <image-table class="w-5/12 h-1/2"
|
|
|
+ @cancel="imageSelectVisible = false"
|
|
|
+ @ok="okHandle"></image-table>
|
|
|
+ </pop>
|
|
|
+</div>
|
|
|
</template>
|
|
|
|
|
|
<style scoped>
|
|
|
+.searchBox{
|
|
|
+ width: 420px;
|
|
|
+ height: 520px;
|
|
|
+}
|
|
|
+
|
|
|
+.showing{
|
|
|
+ display: flex;
|
|
|
+ flex-direction: column;
|
|
|
+ align-items: center;
|
|
|
+}
|
|
|
+.showing .chunk {
|
|
|
+ box-shadow: 1px 1px 3px black;
|
|
|
+ /*box-sizing: border-box;*/
|
|
|
+ /*padding:5px;*/
|
|
|
+ position: relative;
|
|
|
+ overflow: hidden;
|
|
|
+ cursor: pointer;
|
|
|
+ width: 96%;
|
|
|
+ aspect-ratio:500/350;
|
|
|
+ margin-bottom: 10px;
|
|
|
+}
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+.showing .chunk:hover > img{
|
|
|
+ left: -20px;
|
|
|
+ top: -20px;
|
|
|
+ max-width: calc(100% + 40px);
|
|
|
+ width: calc(100% + 40px);
|
|
|
+ height: calc(100% + 40px);
|
|
|
+}
|
|
|
+.showing .chunk .chunkText{
|
|
|
+ display: block;
|
|
|
+ position: absolute;
|
|
|
+ width: 100%;
|
|
|
+ height: 150px;
|
|
|
+ bottom: -50px;
|
|
|
+ /*background: #000;*/
|
|
|
+ color: white;
|
|
|
+ transition: all .5s;
|
|
|
+ padding: 0 15px;
|
|
|
+ background-image: linear-gradient(rgba(0,0,0,0) 0,rgba(0,0,0,0.5) 75% );
|
|
|
+}
|
|
|
+.showing .chunk:hover .chunkText{
|
|
|
+ bottom: 0;
|
|
|
+ background-image: linear-gradient(rgba(0,0,0,0) 0,rgba(0,0,0,0.66) 66% 15% 80% );
|
|
|
+}
|
|
|
+.showing .chunk .chunkText .title{
|
|
|
+ height: 40px;
|
|
|
+ font-size: 1.5em;
|
|
|
+ display: flex;
|
|
|
+ /*justify-content: center;*/
|
|
|
+ align-items: center;
|
|
|
+}
|
|
|
+.showing .chunk .chunkText .subTitle{
|
|
|
+ padding: 5px 0;
|
|
|
+ min-height: 35px;
|
|
|
+ max-height: 80px;
|
|
|
+ font-size: 1.2em;
|
|
|
+}
|
|
|
+.showing .chunk .chunkText .chunkMore{
|
|
|
+ margin-top: 20px;
|
|
|
+ height: 30px;
|
|
|
+ font-size: 0.9em;
|
|
|
+ color: #ff6e3f;
|
|
|
+}
|
|
|
+.showing .chunk .chunkText .chunkMore:hover{
|
|
|
+ color: orangered;
|
|
|
+}
|
|
|
+
|
|
|
+.showing .chunk .chunkText > *{
|
|
|
+ display: block;
|
|
|
+}
|
|
|
+.showing .chunk1 {
|
|
|
+ grid-area: a;
|
|
|
+}
|
|
|
+.showing .chunk2{
|
|
|
+ grid-area: b;
|
|
|
+}
|
|
|
+.showing .chunk3{
|
|
|
+ grid-area: c;
|
|
|
+ aspect-ratio:500/810;
|
|
|
+}
|
|
|
+.showing .chunk4{
|
|
|
+ grid-area: d;
|
|
|
+ aspect-ratio:870/400;
|
|
|
+}
|
|
|
+.showing .chunk5{
|
|
|
+ grid-area: e;
|
|
|
+}
|
|
|
+.showing .chunk6{
|
|
|
+ grid-area: f;
|
|
|
+}
|
|
|
+.showing .chunk7{
|
|
|
+ grid-area: g;
|
|
|
+}
|
|
|
+@media screen and (min-width: 1024px) {
|
|
|
+ /* 其他针对移动设备的样式 */
|
|
|
+ .showing{
|
|
|
+ display: grid;
|
|
|
+ grid-template-columns: repeat(3, 500px);
|
|
|
+ grid-template-rows: repeat(3, 410px);
|
|
|
+ grid-template-areas:
|
|
|
+ 'a b c'
|
|
|
+ 'd d c'
|
|
|
+ 'e f g';
|
|
|
+ grid-gap: 20px;
|
|
|
+ }
|
|
|
+ .showing .chunk {
|
|
|
+ box-shadow: 1px 1px 3px black;
|
|
|
+ box-sizing: border-box;
|
|
|
+ /*padding:5px;*/
|
|
|
+ position: relative;
|
|
|
+ overflow: hidden;
|
|
|
+ cursor: pointer;
|
|
|
+ aspect-ratio:500/410;
|
|
|
+ margin-bottom: 0;
|
|
|
+ width: 100%;
|
|
|
+ }
|
|
|
|
|
|
+ .showing .chunk:hover{
|
|
|
+ box-shadow: 1px 1px 3px deepskyblue;
|
|
|
+ }
|
|
|
+ .showing .chunk3{
|
|
|
+ grid-area: c;
|
|
|
+ aspect-ratio:500/840;
|
|
|
+ }
|
|
|
+ .showing .chunk4{
|
|
|
+ grid-area: d;
|
|
|
+ aspect-ratio:870/350;
|
|
|
+ }
|
|
|
+}
|
|
|
+.showing .chunk .chunkText .title{
|
|
|
+ height: 40px;
|
|
|
+ font-size: 1.5em;
|
|
|
+ display: flex;
|
|
|
+ align-items: center;
|
|
|
+}
|
|
|
+.showing .chunk .chunkText .subTitle{
|
|
|
+ padding: 5px 0;
|
|
|
+ min-height: 35px;
|
|
|
+ max-height: 80px;
|
|
|
+ font-size: 1.2em;
|
|
|
+}
|
|
|
+.showing .chunk1 {
|
|
|
+ grid-area: a;
|
|
|
+}
|
|
|
+.showing .chunk2{
|
|
|
+ grid-area: b;
|
|
|
+}
|
|
|
+.showing .chunk3{
|
|
|
+ grid-area: c;
|
|
|
+ aspect-ratio:500/810;
|
|
|
+}
|
|
|
+.showing .chunk4{
|
|
|
+ grid-area: d;
|
|
|
+ aspect-ratio:870/400;
|
|
|
+}
|
|
|
+.showing .chunk5{
|
|
|
+ grid-area: e;
|
|
|
+}
|
|
|
+.showing .chunk6{
|
|
|
+ grid-area: f;
|
|
|
+}
|
|
|
+.showing .chunk7{
|
|
|
+ grid-area: g;
|
|
|
+}
|
|
|
+@media screen and (min-width: 1024px) {
|
|
|
+ .showing{
|
|
|
+ display: grid;
|
|
|
+ grid-template-columns: repeat(3, 500px);
|
|
|
+ grid-template-rows: repeat(3, 410px);
|
|
|
+ grid-template-areas:
|
|
|
+ 'a b c'
|
|
|
+ 'd d c'
|
|
|
+ 'e f g';
|
|
|
+ grid-gap: 20px;
|
|
|
+ }
|
|
|
+ .showing .chunk {
|
|
|
+ box-shadow: 1px 1px 3px black;
|
|
|
+ position: relative;
|
|
|
+ overflow: hidden;
|
|
|
+ cursor: pointer;
|
|
|
+ aspect-ratio:500/410;
|
|
|
+ margin-bottom: 0;
|
|
|
+ width: 100%;
|
|
|
+ }
|
|
|
+
|
|
|
+ .showing .chunk:hover{
|
|
|
+ box-shadow: 1px 1px 3px deepskyblue;
|
|
|
+ }
|
|
|
+ .showing .chunk3{
|
|
|
+ grid-area: c;
|
|
|
+ aspect-ratio:500/840;
|
|
|
+ }
|
|
|
+ .showing .chunk4{
|
|
|
+ grid-area: d;
|
|
|
+ aspect-ratio:870/350;
|
|
|
+ }
|
|
|
+}
|
|
|
</style>
|