carousel.vue 24 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760
  1. <script>
  2. import axios from "axios";
  3. import {defineComponent} from "vue";
  4. import fieldIsAllow from "../../../until/fieldIsAllow"
  5. import RoundedTitle from "../../../components/public/roundedTitle.vue";
  6. import {rCode} from "../../../map/rcodeMap_esm";
  7. import {handle} from "../../../until/handle";
  8. import ImageViewer from "../../../components/public/imageViewer.vue";
  9. import ImageTable from "../../../components/public/imageTable.vue";
  10. import Pop from "../../../components/public/pop.vue";
  11. import PopCard from "../../../components/public/popCard.vue";
  12. import InputRow from "../../../components/public/form/inputRow.vue";
  13. import dbField_esm from "../../../map/dbField_esm";
  14. import {apiMap} from "../../../map/apiMap";
  15. import SearchBox from "../../../components/search/searchBox.vue";
  16. import {pTypes} from "../../../map/productMap";
  17. import {newsType} from "../../../map/newMap";
  18. import {toNumber,isEmpty} from "../../../until/typeTool";
  19. export default defineComponent({
  20. name: 'carousel',
  21. computed: {
  22. dbField_esm() {
  23. return dbField_esm
  24. },
  25. productTypes(){
  26. let arr = this.$store.getters.productTypes;
  27. // 添加 all
  28. arr.unshift({text: '全部', key: 'all' });
  29. return arr;
  30. },
  31. newsTypes(){// 添加 all
  32. let arr = this.$store.getters.allNewsTypes;
  33. arr.unshift({text: '全部', key: 'all' });
  34. return arr;
  35. },
  36. },
  37. components: {SearchBox, InputRow, PopCard, Pop, ImageTable, ImageViewer, RoundedTitle},
  38. async asyncData(ctx){
  39. // 加载轮播图数据
  40. let [err,res] = await handle(axios.get(apiMap.carouselList.path));
  41. if(err){
  42. return {};
  43. }
  44. let result = res.data;
  45. if(result.code === rCode.OK){
  46. return {carouselList: result.data}
  47. }else{
  48. this.$message.error(result.msg);
  49. return {}
  50. }
  51. return {}
  52. },
  53. data(){
  54. return {
  55. limit: 10,
  56. loading: false,
  57. carouselList: [],
  58. popShow: false,
  59. popLoading: false,
  60. carouselPopShow: false,
  61. carouselPopLoading: false,
  62. isEditCarousel: false,
  63. carouselData: {},
  64. form: {
  65. // 排序
  66. sort: {
  67. val:0,
  68. init: 0,
  69. msg: '',
  70. state: 0,
  71. },
  72. // 状态 0:禁用,1:启用
  73. state: {
  74. val: dbField_esm.db_base.carouselState.disable,
  75. init: dbField_esm.db_base.carouselState.disable,
  76. msg: '',
  77. state: 0,
  78. options: [
  79. {label: '禁用', value: dbField_esm.db_base.carouselState.disable},
  80. {label: '启用', value: dbField_esm.db_base.carouselState.enable},
  81. ]
  82. },
  83. // 轮播类型 '0:product','1:news','2:page','3:href'
  84. type: {
  85. val: 0,
  86. init: 0,
  87. msg: '',
  88. state: 0,
  89. options: [
  90. {label: '直接链接', value: 0,checkField: 'href'},
  91. {label: '内部产品', value: 1,checkField: 'productId'},
  92. {label: '指向新闻', value: 2,checkField: 'newsId'},
  93. ],
  94. },
  95. // 具体值
  96. value: {
  97. val: '',
  98. init: '',
  99. msg: '',
  100. state: 0,
  101. // 依赖字段
  102. depend: 'type',
  103. showText: '',// 展示用字段
  104. oldShowText: '',
  105. },
  106. // file
  107. fileData: {
  108. val: '',
  109. init: '',
  110. msg: '',
  111. state: 0,
  112. showText: '',// 展示用字段
  113. oldShowText: '',
  114. },
  115. },
  116. productSelectVisible: false,
  117. productSearch: {
  118. type: {
  119. val: '',
  120. oldVal: '',
  121. init: '',
  122. msg: '',
  123. options: [],
  124. }
  125. },
  126. newsSelectVisible: false,
  127. newsVisible: false,
  128. newsSearch: {
  129. type: {
  130. val: '',
  131. oldVal: '',
  132. init: '',
  133. msg: '',
  134. options: [],
  135. }
  136. },
  137. imageSelectVisible: false,
  138. }
  139. },
  140. mounted() {
  141. if(this.carouselList.length === 0){
  142. this.getCarouselList();
  143. }
  144. },
  145. methods: {
  146. async getCarouselList(){
  147. this.loading = true;
  148. let [err,res] = await handle(this.$axios.get(apiMap.carouselAllList.path));
  149. this.loading = false;
  150. if(err){
  151. if(this.NotificationKey){
  152. this.$notification.close(this.NotificationKey);
  153. }
  154. this.NotificationKey = `open${Date.now()}`;
  155. return this.$notification.error({
  156. message: '轮播数据加载失败',
  157. description:`异常: ${err.message}`,
  158. duration: 0,
  159. btn: h => {
  160. return h(
  161. 'a-button',
  162. {
  163. props: {
  164. type: 'primary',
  165. size: 'small',
  166. },
  167. on: {
  168. click: () => {
  169. this.$notification.close(this.NotificationKey);
  170. this.getCarouselList();
  171. },
  172. },
  173. },
  174. '重试',
  175. );
  176. },
  177. key:this.NotificationKey,
  178. onClose: close,
  179. });
  180. }
  181. let result = res.data;
  182. if(result.code === rCode.OK){
  183. this.carouselList = result.data;
  184. return {carouselList: result.data}
  185. }else{
  186. this.$message.error(result.msg);
  187. return {}
  188. }
  189. },
  190. // 搜索产品,只需要产品名等信息
  191. async getProductSearch(searchParam){
  192. console.log(searchParam)
  193. if(this.productSearch.type.val !== this.productSearch.type.oldVal){
  194. searchParam.p = 1;
  195. }
  196. searchParam.type = this.productSearch.type.val;
  197. searchParam.l = this.limit;
  198. searchParam.p = searchParam.page;
  199. let [err,res] = await handle(
  200. this.$axios.get(
  201. apiMap.searchProductMini.path,
  202. {params:searchParam})
  203. );
  204. if(err){
  205. console.log(err);
  206. return [{message:'请求数据失败'},null];
  207. }
  208. let result = res.data;
  209. if(result.code === rCode.OK){
  210. this.productSearch.type.oldVal = this.productSearch.type.val;
  211. // data 转换
  212. result.data = result.data.map(item=>{
  213. item.showText=item.name;
  214. return item;
  215. });
  216. return [null,result];
  217. }else{
  218. // 可捕获的服务器错误
  219. return [{message:result.msg},null];
  220. }
  221. },
  222. // 加载轮播默认数据
  223. async getNewsSearch(searchParam){
  224. console.log(searchParam)
  225. if(this.newsSearch.type.val !== this.newsSearch.type.oldVal){
  226. searchParam.p = 1;
  227. }
  228. searchParam.type = this.newsSearch.type.val;
  229. searchParam.l = this.limit;
  230. searchParam.p = searchParam.page;
  231. let [err,res] = await handle(
  232. this.$axios.get(
  233. apiMap.searchNewsMini.path,
  234. {params:searchParam})
  235. );
  236. if(err){
  237. console.log(err);
  238. return [{message:'请求数据失败'},null];
  239. }
  240. let result = res.data;
  241. if(result.code === rCode.OK){
  242. this.newsSearch.type.oldVal = this.newsSearch.type.val;
  243. // data 转换
  244. result.data = result.data.map(item=>{
  245. item.showText=item.name;
  246. return item;
  247. });
  248. return [null,result];
  249. }else{
  250. // 可捕获的服务器错误
  251. return [{message:result.msg},null];
  252. }
  253. },
  254. checkFormItem(field,enumOptions,reCheckField){
  255. let formItem = this.form[field];
  256. if (formItem){
  257. if (enumOptions){
  258. // 遍历枚举
  259. for (let i = 0; i < enumOptions.length; i++) {
  260. let enumOption = enumOptions[i];
  261. if (enumOption.value === formItem.val){
  262. return true;
  263. }
  264. }
  265. formItem.msg = '选项不在范围内';
  266. return false;
  267. }
  268. if(reCheckField){
  269. // 检查用字段
  270. formItem.msg = fieldIsAllow({
  271. [reCheckField]:formItem.val,
  272. })
  273. }else{
  274. formItem.msg = fieldIsAllow({
  275. [field]:formItem.val,
  276. })
  277. }
  278. }else{
  279. let r = true;
  280. for (const fieldKey in this.form) {
  281. formItem = this.form[fieldKey];
  282. let depend = this.form[formItem.depend];
  283. let checkField = fieldKey;
  284. if(formItem.reCheckField){
  285. checkField = formItem.reCheckField;
  286. }
  287. // 枚举值判断
  288. if(formItem.options){
  289. // 有枚举字段,只判断是否在枚举中
  290. if(formItem.options.findIndex(item=>item.value == formItem.val) === -1){
  291. formItem.msg = '选项不在范围内';
  292. r = false;
  293. }
  294. // 枚举值判断完毕,继续下一个字段
  295. continue;
  296. }
  297. // 判断是否有依赖字段
  298. if(depend){
  299. if(depend.options){
  300. // 依赖的对象有枚举类型,检查该枚举类型是否有有检测值
  301. let optionItem = depend.options.find(item=>item.value == depend.val);
  302. if(!optionItem){
  303. depend.msg = '选项不在范围内';
  304. formItem.msg = '该值依赖项输入异常';
  305. r = false;
  306. continue;
  307. }
  308. if(optionItem.checkField){
  309. console.log(`采用依赖项的检测字段${optionItem.checkField}`)
  310. checkField = optionItem.checkField;
  311. }
  312. }
  313. }
  314. console.log(`检测字段:${checkField},值:${formItem.val}`);
  315. formItem.msg = fieldIsAllow({
  316. [checkField]:formItem.val,
  317. })
  318. if (formItem.msg){
  319. r = false;
  320. }
  321. }
  322. return r
  323. }
  324. },
  325. initCarouseForm(){
  326. this.carouselData = {};
  327. let keys = Object.keys(this.form);
  328. for(let i = 0; i < keys.length; i++){
  329. let key = keys[i];
  330. this.form[key].val = this.form[key].init;
  331. this.form[key].msg = '';
  332. this.form[key].state = 0;
  333. this.form.value.showText = '';
  334. }
  335. },
  336. openAddCarouselModal(){
  337. // 初始化表单
  338. this.initCarouseForm();
  339. this.carouselPopShow = true;
  340. this.isEditCarousel = false;
  341. this.$nextTick(()=>{
  342. // 打开弹窗. 选择图片,填写链接地址,排序
  343. this.productSearch.type.options = this.productTypes;
  344. this.newsSearch.type.options = this.newsTypes;
  345. // 默认值设置
  346. this.productSearch.type.val = this.productTypes[0].key;
  347. this.productSearch.type.oldVal = this.productTypes[0].key;
  348. this.productSearch.type.init = this.productTypes[0].key;
  349. this.newsSearch.type.val = this.newsTypes[0].key;
  350. this.newsSearch.type.oldVal = this.newsTypes[0].key;
  351. this.newsSearch.type.init = this.newsTypes[0].key;
  352. });
  353. },
  354. onPopOkClickHandle(){
  355. if(this.isEditCarousel){
  356. console.log('保存修改后的轮播数据');
  357. this.updateCarouselExecute();
  358. }else{
  359. console.log('新增轮播图');
  360. this.addCarouselExecute();
  361. }
  362. },
  363. async addCarouselExecute(){
  364. // 生成新数据表单
  365. let carouselData = {};
  366. let isPass = this.checkFormItem();
  367. if(!isPass){
  368. return console.log('数据验证不通过');
  369. }
  370. console.log('开始生成新数据表单');
  371. carouselData.sort = this.form.sort.val;
  372. carouselData.type = this.form.type.val;
  373. carouselData.value = this.form.value.val;
  374. carouselData.fileId = this.form.fileData.val;
  375. carouselData.state = this.form.state.val;
  376. // 生成新数据表单完毕
  377. console.log('生成新数据表单完毕');
  378. this.carouselPopLoading = true;
  379. let [err,res] = await handle(this.$axios.put(apiMap.baseAddCarousel.path,carouselData));
  380. this.carouselPopLoading = false;
  381. if(err){
  382. console.log(err);
  383. return this.$message.error('新增轮播图失败');
  384. }
  385. this.$message.success('新增轮播成功');
  386. this.carouselPopShow = false;
  387. await this.getCarouselList();
  388. },
  389. async updateCarouselExecute(){
  390. let carouselData = {};
  391. let isPass = this.checkFormItem();
  392. if(!isPass){
  393. return console.log('数据验证不通过');
  394. }
  395. // 获取更新项
  396. console.log(`获取更新项`);
  397. let updateItems = {};
  398. console.log(this.carouselData);
  399. let carouselId = this.carouselData.id;
  400. if(this.form.sort.val != toNumber(this.carouselData.sort)){
  401. updateItems.sort = this.form.sort.val;
  402. }
  403. if(this.form.type.val != toNumber(this.carouselData.type)){
  404. updateItems.type = this.form.type.val;
  405. }
  406. if(this.form.value.val != this.carouselData.value){
  407. updateItems.value = this.form.value.val;
  408. }
  409. if(toNumber(this.form.fileData.val) != this.carouselData.fileId){
  410. updateItems.fileId = this.form.fileData.val;
  411. }
  412. if(this.form.state.val != this.carouselData.state){
  413. updateItems.state = this.form.state.val;
  414. }
  415. if(isEmpty(updateItems)){
  416. return this.$message.warn('未修改任何数据');
  417. }
  418. console.log(`更新轮播数据,更新数量: ${Object.keys(updateItems).length} 更新字段: [${Object.keys(updateItems).join(',')}]`);
  419. this.carouselPopLoading = true;
  420. let [err,res] = await handle(this.$axios.post(apiMap.baseUpdateCarousel.path,{
  421. carouselId,
  422. updateItems
  423. }));
  424. this.carouselPopLoading = false;
  425. if(err){
  426. console.log(err);
  427. return this.$message.error('更新轮播图失败');
  428. }
  429. let result = res.data;
  430. if (result.code === rCode.OK){
  431. this.$message.success('更新轮播成功');
  432. this.carouselPopShow = false;
  433. await this.getCarouselList();
  434. }else{
  435. this.$message.error(`更新轮播失败,${result.msg}`);
  436. }
  437. },
  438. getCarouselTypeText(type){
  439. type = toNumber(type);
  440. let typeText = '';
  441. if(type === dbField_esm.db_base.carouselType.production){
  442. typeText = '产品';
  443. }else if(type === dbField_esm.db_base.carouselType.news){
  444. typeText = '文章';
  445. }else if(type === dbField_esm.db_base.carouselType.href){
  446. typeText = '直接链接';
  447. }else{
  448. typeText = '暂未支持类型';
  449. }
  450. return typeText
  451. },
  452. getCarouselStateText(state){
  453. // state = toNumber(state);
  454. let typeText = '';
  455. if(state === dbField_esm.db_base.carouselState.enable){
  456. typeText = '启用';
  457. }else if(state === dbField_esm.db_base.carouselState.disable){
  458. typeText = '禁用';
  459. }else{
  460. typeText = '未知状态';
  461. }
  462. return typeText
  463. },
  464. cancelPop(){
  465. this.imageSelectVisible = false;
  466. },
  467. okHandle(fileItem){
  468. console.log('文件列表');
  469. console.log(fileItem);
  470. this.cancelPop();
  471. this.$nextTick(()=>{
  472. this.form.fileData.val = fileItem.fileId;
  473. this.form.fileData.state = 1;
  474. this.form.fileData.msg = '';
  475. this.form.fileData.showText = fileItem.filePath;
  476. })
  477. },
  478. onProductSearchHandle(e){
  479. console.log(`onProductSearchHandle ${e}`);
  480. console.log(e);
  481. console.log(this.productSearch.type.val);
  482. },
  483. onSelectedItemHandle(item){
  484. console.log(`selected item ${item}`);
  485. console.log(item);
  486. this.form.value.val = item.id;
  487. this.form.value.showText = item.showText;
  488. this.form.value.msg = '';
  489. },
  490. onTypeChangeHandle(e){
  491. console.log(`type change ${e}`);
  492. // 清除其他值
  493. this.form.value.val = '';
  494. this.form.value.msg = '';
  495. this.form.value.showText = '';
  496. },
  497. onNewsSearchHandle(e){
  498. console.log(`onProductSearchHandle ${e}`);
  499. console.log(e);
  500. console.log(this.productSearch.type.val);
  501. },
  502. onClickEditHandle(item){
  503. console.log(`点击编辑轮播图`);
  504. console.log(item);
  505. if(!item || !item.id){
  506. return this.$message.warn('轮播数据获取异常,已经取消编辑');
  507. }
  508. this.initCarouseForm();
  509. this.isEditCarousel = true;
  510. this.carouselData = item;
  511. this.carouselPopShow = true;
  512. this.carouselPopLoading = true;
  513. this.form.sort.val = toNumber(item.sort);
  514. this.form.sort.init = toNumber(item.sort);
  515. this.form.type.val = toNumber(item.type);
  516. this.form.type.init = toNumber(item.type);
  517. this.form.value.val = item.value;
  518. this.form.value.init = item.value;
  519. this.form.value.showText = item.valueShowText;
  520. this.form.value.oldShowText = item.oldShowText;
  521. this.form.fileData.val = item.fileId;
  522. this.form.fileData.init = item.fileId;
  523. this.form.fileData.showText = item.filePath;
  524. this.form.fileData.oldShowText = item.filePath;
  525. this.form.state.val = item.state;
  526. this.carouselPopLoading = false;
  527. }
  528. },
  529. })
  530. </script>
  531. <template>
  532. <div class="w-full p-2">
  533. <rounded-title>轮播图管理</rounded-title>
  534. <div class="mt-2 rounded bg-white p-2">
  535. <!-- 轮播图list , 左侧轮播图片, 右侧 轮播信息 -->
  536. <div class="mt-2 rounded bg-white p-2">
  537. <div class="py-1 border-b border-cyan-300 flex justify-between">
  538. 点击下方快进行管理轮播图数据,一次性不要添加过多轮播图
  539. <div class="px-2 flex">
  540. <!-- 新增按钮-->
  541. <a-button type="primary" class="ant-icon-btn mr-2" icon="plus" @click="openAddCarouselModal" :loading="loading"></a-button>
  542. <!-- 刷新按钮-->
  543. <a-button type="primary" class="ant-icon-btn " icon="reload" @click="getCarouselList" :loading="loading"></a-button>
  544. </div>
  545. </div>
  546. <div class="w-full h-auto transition">
  547. <div v-show="loading" class="w-full h-64 flex justify-center items-center ">
  548. <a-spin size="large" />
  549. </div>
  550. <div
  551. v-for="(item,index) in carouselList"
  552. :key="'carouse-'+index"
  553. class="mt-2 rounded border flex h-72 overflow-hidden"
  554. >
  555. <div class="media w-1/2 h-full">
  556. <image-viewer :src="item.filePath"></image-viewer>
  557. </div>
  558. <div class="w-1/2 h-full box-border pl-2">
  559. <div class="w-full py-2 border-bottom border-gray-400">
  560. 排序: {{item.sort}}
  561. </div>
  562. <div class="w-full py-2 border-bottom border-gray-400">
  563. {{getCarouselTypeText(item.type)}}: {{item.valueShowText}}
  564. </div>
  565. <div class="w-full py-2 border-bottom border-gray-400">
  566. 状态: {{getCarouselStateText(item.state)}}
  567. </div>
  568. <a-button @click="onClickEditHandle(item)">编辑</a-button>
  569. </div>
  570. </div>
  571. </div>
  572. </div>
  573. </div>
  574. <pop :show="carouselPopShow" :loading="carouselPopLoading">
  575. <pop-card>
  576. <template slot="header" class="w-full">
  577. {{isEditCarousel ? '编辑轮播图' : '新增轮播图'}}
  578. </template>
  579. <template slot="close-group">
  580. <a-button icon="close" @click="carouselPopShow = false"></a-button>
  581. </template>
  582. <div class="w-full">
  583. <input-row :msg="form.sort.msg"
  584. label="排序">
  585. <a-input-number v-model="form.sort.val"
  586. @focus="form.sort.msg=''"
  587. :min="0"
  588. @blur="checkFormItem('sort')"
  589. />
  590. </input-row>
  591. <input-row :msg="form.state.msg"
  592. label="状态">
  593. <a-radio-group v-model="form.state.val">
  594. <a-radio-button v-for="opt in form.state.options"
  595. :key="'cState'+opt.value"
  596. :value="opt.value">
  597. {{ opt.label }}
  598. </a-radio-button>
  599. </a-radio-group>
  600. </input-row>
  601. <!-- 轮播类型选择 -->
  602. <input-row :msg="form.type.msg"
  603. label="轮播类型">
  604. <a-radio-group v-model="form.type.val" @change="onTypeChangeHandle">
  605. <a-radio-button v-for="opt in form.type.options"
  606. :key="'cType'+opt.value"
  607. :value="opt.value">
  608. {{ opt.label }}
  609. </a-radio-button>
  610. </a-radio-group>
  611. </input-row>
  612. <!-- 轮播具体值 -->
  613. <!-- 链接-->
  614. <input-row
  615. v-show="form.type.val === dbField_esm.db_base.carouselType.href"
  616. :msg="form.value.msg"
  617. label="输入链接">
  618. <a-input v-model="form.value.val"
  619. placeholder="输入要指向的链接地址"
  620. @focus="form.value.msg=''"
  621. @blur="checkFormItem('value', null,'href')"
  622. />
  623. </input-row>
  624. <!-- 产品选择-->
  625. <input-row
  626. v-show="form.type.val === dbField_esm.db_base.carouselType.production"
  627. :msg="form.value.msg"
  628. label="选择产品">
  629. {{ form.value.showText }}
  630. <a-popover v-model="productSelectVisible" title="选择产品" trigger="click">
  631. <div slot="content" class="searchBox" >
  632. <search-box
  633. class="h-72"
  634. :loadDataApi="getProductSearch"
  635. :limit="limit"
  636. search-placeholder="请输入产品名称关键字"
  637. loadTip="正在搜索产品中..."
  638. @onSelectedItem="onSelectedItemHandle"
  639. >
  640. <div class="w-full" slot="otherSearchItem">
  641. <a-radio-group v-model="productSearch.type.val"
  642. @change="onProductSearchHandle">
  643. <a-radio-button v-for="opt in productSearch.type.options"
  644. :key="'cType'+opt.key"
  645. :value="opt.key">
  646. {{ opt.text }}
  647. </a-radio-button>
  648. </a-radio-group>
  649. </div>
  650. </search-box>
  651. </div>
  652. <a-button type="primary" >
  653. 选择产品
  654. </a-button>
  655. </a-popover>
  656. </input-row>
  657. <!-- 新闻选择-->
  658. <input-row
  659. v-show="form.type.val === dbField_esm.db_base.carouselType.news"
  660. :msg="form.value.msg"
  661. label="文章选择">
  662. {{ form.value.showText }}
  663. <a-popover v-model="newsSelectVisible" title="选择你需要的文章" trigger="click">
  664. <div slot="content" class="searchBox" >
  665. <search-box
  666. class="h-72"
  667. :loadDataApi="getNewsSearch"
  668. :limit="limit"
  669. search-placeholder="请输入产品名称关键字"
  670. loadTip="正在搜索产品中..."
  671. ref="productSearch"
  672. @onSelectedItem="onSelectedItemHandle"
  673. >
  674. <div class="w-full" slot="otherSearchItem">
  675. <a-radio-group v-model="newsSearch.type.val"
  676. @change="onNewsSearchHandle">
  677. <a-radio-button v-for="opt in newsSearch.type.options"
  678. :key="'cType'+opt.key"
  679. :value="opt.key">
  680. {{ opt.text }}
  681. </a-radio-button>
  682. </a-radio-group>
  683. </div>
  684. </search-box>
  685. </div>
  686. <a-button type="primary">
  687. 选择文章
  688. </a-button>
  689. </a-popover>
  690. </input-row>
  691. <!-- 选择图片 -->
  692. <input-row label="轮播图片"
  693. :msg="form.fileData.msg">
  694. <a-popover v-model="imageSelectVisible"
  695. class="w-full"
  696. trigger="click">
  697. <image-table slot="content"
  698. class="w-full h-full"
  699. @cancel="imageSelectVisible = false"
  700. @ok="okHandle"></image-table>
  701. <div class="w-full h-60 rounded relative">
  702. <image-viewer class="" :src="form.fileData.showText"></image-viewer>
  703. <div class="absolute w-full h-full left-0 top-0
  704. justify-center text-white bg-gray-400
  705. items-center text-2xl flex opacity-0 hover:opacity-70">
  706. 点击选择图片
  707. </div>
  708. </div>
  709. </a-popover>
  710. </input-row>
  711. </div>
  712. <template class="w-full" slot="footer">
  713. <a-button @click="onPopOkClickHandle">{{isEditCarousel? '保存': '新增'}}</a-button>
  714. </template>
  715. </pop-card>
  716. </pop>
  717. </div>
  718. </template>
  719. <style scoped>
  720. .searchBox{
  721. width: 420px;
  722. height: 520px;
  723. }
  724. </style>