已重命名1个文件
已修改3个文件
已添加13个文件
¶Ô±ÈÐÂÎļþ |
| | |
| | | package org.ruoyi.pageDesigner.controller; |
| | | |
| | | import jakarta.validation.Valid; |
| | | import lombok.RequiredArgsConstructor; |
| | | import org.ruoyi.common.core.domain.R; |
| | | import org.ruoyi.common.web.core.BaseController; |
| | | import org.ruoyi.core.page.PageQuery; |
| | | import org.ruoyi.core.page.TableDataInfo; |
| | | import org.ruoyi.pageDesigner.domain.*; |
| | | import org.ruoyi.pageDesigner.service.PageDesignerTemplateService; |
| | | import org.springframework.validation.annotation.Validated; |
| | | import org.springframework.web.bind.annotation.*; |
| | | |
| | | import java.util.List; |
| | | |
| | | /** |
| | | * @author kanglujie |
| | | * @date 2025-06-23 14:41:24 |
| | | */ |
| | | @Validated |
| | | @RequiredArgsConstructor |
| | | @RestController |
| | | @RequestMapping("/page-designer-template") |
| | | public class PageDesignerTemplateController extends BaseController { |
| | | |
| | | private final PageDesignerTemplateService service; |
| | | |
| | | /** |
| | | * è·å页é¢è®¾è®¡å表 |
| | | */ |
| | | @GetMapping("/list") |
| | | public TableDataInfo<PageDesignerTemplateVo> list(PageDesignerTemplateDTO dto, PageQuery pageQuery) { |
| | | return service.selectPagelistAll(dto, pageQuery); |
| | | } |
| | | |
| | | /** |
| | | * è·å页é¢è®¾è®¡è¯¦æ
|
| | | */ |
| | | @GetMapping("/{id}") |
| | | public R<PageDesignerTemplate> getInfo(@PathVariable Long id) { |
| | | return R.ok(service.getDetail(id)); |
| | | } |
| | | |
| | | /** |
| | | * æ°å¢é¡µé¢è®¾è®¡ |
| | | */ |
| | | @PostMapping |
| | | public R<Void> add(@Valid @RequestBody PageDesignerTemplateDTO dto) { |
| | | service.add(dto); |
| | | return R.ok("æ°å¢æå"); |
| | | } |
| | | |
| | | /** |
| | | * ä¿®æ¹é¡µé¢è®¾è®¡ |
| | | */ |
| | | @PutMapping |
| | | public R<Void> update(@Valid @RequestBody PageDesignerTemplateDTO dto) { |
| | | service.updatePage(dto); |
| | | return R.ok("ä¿®æ¹æå"); |
| | | } |
| | | |
| | | /** |
| | | * å é¤é¡µé¢è®¾è®¡ |
| | | */ |
| | | @DeleteMapping |
| | | public R<Void> remove(@RequestBody List<Long> ids) { |
| | | service.deleteByIds(ids); |
| | | return R.ok("å 餿å"); |
| | | } |
| | | } |
| | |
| | | import lombok.EqualsAndHashCode; |
| | | import lombok.NoArgsConstructor; |
| | | import org.ruoyi.core.domain.BaseEntity; |
| | | import org.ruoyi.system.domain.SysUser; |
| | | |
| | | import java.util.List; |
| | | |
| | | /** |
| | | * @author kanglujie |
¶Ô±ÈÐÂÎļþ |
| | |
| | | package org.ruoyi.pageDesigner.domain; |
| | | |
| | | import com.baomidou.mybatisplus.annotation.TableField; |
| | | import com.baomidou.mybatisplus.annotation.TableId; |
| | | import com.baomidou.mybatisplus.annotation.TableLogic; |
| | | import com.baomidou.mybatisplus.annotation.TableName; |
| | | import lombok.Data; |
| | | import lombok.EqualsAndHashCode; |
| | | import org.ruoyi.core.domain.BaseEntity; |
| | | |
| | | /** |
| | | * @author kanglujie |
| | | * @date 2025-06-23 17:24:05 |
| | | */ |
| | | @Data |
| | | @EqualsAndHashCode(callSuper = true) |
| | | @TableName("PAGE_DESIGNER_TEMPLATE") |
| | | public class PageDesignerTemplate extends BaseEntity { |
| | | @TableId(value = "ID") |
| | | private Long id; |
| | | @TableField(value = "PAGE_ID") |
| | | private Long pageId; |
| | | @TableField("FORM_DATA") |
| | | private String formData; |
| | | @TableField(value = "DEL_FLAG") |
| | | @TableLogic |
| | | private String delFlag; |
| | | } |
¶Ô±ÈÐÂÎļþ |
| | |
| | | package org.ruoyi.pageDesigner.domain; |
| | | |
| | | import io.github.linpeilie.annotations.AutoMapper; |
| | | import lombok.Data; |
| | | import lombok.EqualsAndHashCode; |
| | | import lombok.NoArgsConstructor; |
| | | import org.ruoyi.core.domain.BaseEntity; |
| | | |
| | | /** |
| | | * @author kanglujie |
| | | * @date 2025-06-23 17:23:35 |
| | | */ |
| | | @Data |
| | | @NoArgsConstructor |
| | | @EqualsAndHashCode(callSuper = true) |
| | | @AutoMapper(target = PageDesignerTemplate.class, reverseConvertGenerate = false) |
| | | public class PageDesignerTemplateDTO extends BaseEntity { |
| | | private Long id; |
| | | private Long pageId; |
| | | private String formData; |
| | | private String delFlag; |
| | | } |
¶Ô±ÈÐÂÎļþ |
| | |
| | | package org.ruoyi.pageDesigner.domain; |
| | | |
| | | import io.github.linpeilie.annotations.AutoMapper; |
| | | import lombok.Data; |
| | | |
| | | import java.io.Serializable; |
| | | |
| | | /** |
| | | * @author kanglujie |
| | | * @date 2025-06-23 17:23:35 |
| | | */ |
| | | @Data |
| | | @AutoMapper(target = PageDesignerTemplate.class) |
| | | public class PageDesignerTemplateVo implements Serializable { |
| | | private Long id; |
| | | private Long pageId; |
| | | private String formData; |
| | | private String delFlag; |
| | | } |
| | |
| | | |
| | | import io.github.linpeilie.annotations.AutoMapper; |
| | | import lombok.Data; |
| | | import org.ruoyi.core.domain.BaseEntity; |
| | | import org.ruoyi.system.domain.vo.SysMenuVo; |
| | | |
| | | import java.io.Serializable; |
¶Ô±ÈÐÂÎļþ |
| | |
| | | package org.ruoyi.pageDesigner.mapper; |
| | | |
| | | import com.baomidou.mybatisplus.core.conditions.Wrapper; |
| | | import com.baomidou.mybatisplus.core.mapper.BaseMapper; |
| | | import com.baomidou.mybatisplus.core.toolkit.Constants; |
| | | import com.baomidou.mybatisplus.extension.plugins.pagination.Page; |
| | | import org.apache.ibatis.annotations.Mapper; |
| | | import org.apache.ibatis.annotations.Param; |
| | | import org.ruoyi.pageDesigner.domain.PageDesignerTemplate; |
| | | import org.ruoyi.pageDesigner.domain.PageDesignerTemplateVo; |
| | | |
| | | /** |
| | | * @author kanglujie |
| | | * @date 2025-06-23 17:34:48 |
| | | */ |
| | | @Mapper |
| | | public interface PageDesignerTemplateMapper extends BaseMapper<PageDesignerTemplate> { |
| | | Page<PageDesignerTemplateVo> selectPagelistAll(@Param("page") Page<PageDesignerTemplate> page, @Param(Constants.WRAPPER) Wrapper<PageDesignerTemplate> queryWrapper); |
| | | |
| | | } |
¶Ô±ÈÐÂÎļþ |
| | |
| | | package org.ruoyi.pageDesigner.service; |
| | | |
| | | import com.baomidou.mybatisplus.extension.service.IService; |
| | | import org.ruoyi.core.page.PageQuery; |
| | | import org.ruoyi.core.page.TableDataInfo; |
| | | import org.ruoyi.pageDesigner.domain.*; |
| | | |
| | | import java.util.List; |
| | | |
| | | /** |
| | | * @author kanglujie |
| | | * @date 2025-06-23 17:35:56 |
| | | */ |
| | | public interface PageDesignerTemplateService extends IService<PageDesignerTemplate> { |
| | | |
| | | void add(PageDesignerTemplateDTO dto); |
| | | |
| | | void updatePage(PageDesignerTemplateDTO dto); |
| | | |
| | | List<PageDesignerTemplate> listAll(String keyword); |
| | | |
| | | PageDesignerTemplate getDetail(Long id); |
| | | |
| | | void deleteByIds(List<Long> ids); |
| | | |
| | | TableDataInfo<PageDesignerTemplateVo> selectPagelistAll(PageDesignerTemplateDTO dto, PageQuery pageQuery); |
| | | } |
| | |
| | | return TableDataInfo.build(page); |
| | | } |
| | | private Wrapper<PageDesigner> buildQueryWrapper(PageDesignerDTO pageDesignerDTO) { |
| | | //Map<String, Object> params = pageDesignerDTO.getParams(); |
| | | Map<String, Object> params = pageDesignerDTO.getParams(); |
| | | QueryWrapper<PageDesigner> wrapper = Wrappers.query(); |
| | | //wrapper.eq("del_flag", UserConstants.USER_NORMAL) |
| | | // .eq(ObjectUtil.isNotNull(pageDesignerDTO.getId()), "id", pageDesignerDTO.getId()) |
| | | // .like(StringUtils.isNotBlank(pageDesignerDTO.getName()), "name", pageDesignerDTO.getName()) |
| | | // .eq(StringUtils.isNotBlank(pageDesignerDTO.getStatus()), "status", pageDesignerDTO.getStatus()) |
| | | // .between(params.get("beginTime") != null && params.get("endTime") != null, |
| | | // "create_time", params.get("beginTime"), params.get("endTime")) |
| | | //; |
| | | wrapper.eq("del_flag", UserConstants.USER_NORMAL) |
| | | .eq(ObjectUtil.isNotNull(pageDesignerDTO.getId()), "id", pageDesignerDTO.getId()) |
| | | .like(StringUtils.isNotBlank(pageDesignerDTO.getName()), "name", pageDesignerDTO.getName()) |
| | | .eq(StringUtils.isNotBlank(pageDesignerDTO.getStatus()), "status", pageDesignerDTO.getStatus()) |
| | | .between(params.get("beginTime") != null && params.get("endTime") != null, |
| | | "create_time", params.get("beginTime"), params.get("endTime")) |
| | | ; |
| | | return wrapper; |
| | | } |
| | | @Override |
¶Ô±ÈÐÂÎļþ |
| | |
| | | package org.ruoyi.pageDesigner.service.impl; |
| | | |
| | | import com.baomidou.mybatisplus.core.conditions.Wrapper; |
| | | import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; |
| | | import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; |
| | | import com.baomidou.mybatisplus.core.toolkit.Wrappers; |
| | | import com.baomidou.mybatisplus.extension.plugins.pagination.Page; |
| | | import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; |
| | | import com.fasterxml.jackson.databind.ObjectMapper; |
| | | import lombok.RequiredArgsConstructor; |
| | | import org.ruoyi.core.page.PageQuery; |
| | | import org.ruoyi.core.page.TableDataInfo; |
| | | import org.ruoyi.pageDesigner.domain.*; |
| | | import org.ruoyi.pageDesigner.mapper.PageDesignerMapper; |
| | | import org.ruoyi.pageDesigner.mapper.PageDesignerTemplateMapper; |
| | | import org.ruoyi.pageDesigner.service.PageDesignerService; |
| | | import org.ruoyi.pageDesigner.service.PageDesignerTemplateService; |
| | | import org.springframework.stereotype.Service; |
| | | |
| | | import java.util.List; |
| | | |
| | | /** |
| | | * @author kanglujie |
| | | * @date 2025-06-23 17:36:29 |
| | | */ |
| | | @Service |
| | | @RequiredArgsConstructor |
| | | public class PageDesignerTemplateServiceImpl extends ServiceImpl<PageDesignerTemplateMapper, PageDesignerTemplate> |
| | | implements PageDesignerTemplateService { |
| | | |
| | | private final ObjectMapper objectMapper; |
| | | |
| | | @Override |
| | | public void add(PageDesignerTemplateDTO dto) { |
| | | PageDesignerTemplate entity = convertToEntity(dto); |
| | | this.save(entity); |
| | | } |
| | | |
| | | @Override |
| | | public void updatePage(PageDesignerTemplateDTO dto) { |
| | | PageDesignerTemplate entity = convertToEntity(dto); |
| | | this.updateById(entity); |
| | | } |
| | | |
| | | @Override |
| | | public TableDataInfo<PageDesignerTemplateVo> selectPagelistAll(PageDesignerTemplateDTO dto, PageQuery pageQuery) { |
| | | Page<PageDesignerTemplateVo> page = baseMapper.selectPagelistAll(pageQuery.build(), this.buildQueryWrapper(dto)); |
| | | return TableDataInfo.build(page); |
| | | } |
| | | private Wrapper<PageDesignerTemplate> buildQueryWrapper(PageDesignerTemplateDTO dto) { |
| | | //Map<String, Object> params = pageDesignerDTO.getParams(); |
| | | QueryWrapper<PageDesignerTemplate> wrapper = Wrappers.query(); |
| | | //wrapper.eq("del_flag", UserConstants.USER_NORMAL) |
| | | // .eq(ObjectUtil.isNotNull(pageDesignerDTO.getId()), "id", pageDesignerDTO.getId()) |
| | | // .like(StringUtils.isNotBlank(pageDesignerDTO.getName()), "name", pageDesignerDTO.getName()) |
| | | // .eq(StringUtils.isNotBlank(pageDesignerDTO.getStatus()), "status", pageDesignerDTO.getStatus()) |
| | | // .between(params.get("beginTime") != null && params.get("endTime") != null, |
| | | // "create_time", params.get("beginTime"), params.get("endTime")) |
| | | //; |
| | | return wrapper; |
| | | } |
| | | @Override |
| | | public List<PageDesignerTemplate> listAll(String keyword) { |
| | | LambdaQueryWrapper<PageDesignerTemplate> wrapper = new LambdaQueryWrapper<>(); |
| | | wrapper.like(keyword != null, PageDesignerTemplate::getPageId, keyword); |
| | | return this.list(wrapper); |
| | | } |
| | | |
| | | @Override |
| | | public PageDesignerTemplate getDetail(Long id) { |
| | | return this.getById(id); |
| | | } |
| | | |
| | | @Override |
| | | public void deleteByIds(List<Long> ids) { |
| | | this.removeByIds(ids); |
| | | } |
| | | |
| | | private PageDesignerTemplate convertToEntity(PageDesignerTemplateDTO dto) { |
| | | PageDesignerTemplate entity = new PageDesignerTemplate(); |
| | | entity.setId(dto.getId()); |
| | | entity.setFormData(dto.getFormData()); |
| | | entity.setDelFlag(dto.getDelFlag()); |
| | | entity.setPageId(dto.getPageId()); |
| | | return entity; |
| | | } |
| | | } |
¶Ô±ÈÐÂÎļþ |
| | |
| | | <?xml version="1.0" encoding="UTF-8" ?> |
| | | <!DOCTYPE mapper |
| | | PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" |
| | | "http://mybatis.org/dtd/mybatis-3-mapper.dtd"> |
| | | <mapper namespace="org.ruoyi.pageDesigner.mapper.PageDesignerTemplateMapper"> |
| | | |
| | | <!-- ç»ææ å° --> |
| | | <resultMap type="org.ruoyi.pageDesigner.domain.PageDesignerTemplateVo" id="PageDesignerTemplateResult"> |
| | | <id property="id" column="id"/> |
| | | <result property="pageId" column="page_id"/> |
| | | <result property="formData" column="form_data"/> |
| | | <result property="delFlag" column="del_flag"/> |
| | | </resultMap> |
| | | |
| | | <select id="selectPagelistAll" resultMap="PageDesignerTemplateResult"> |
| | | SELECT |
| | | id, |
| | | page_id, |
| | | form_data, |
| | | del_flag |
| | | FROM page_designer_template |
| | | <where> |
| | | ${ew.sqlSegment} |
| | | </where> |
| | | </select> |
| | | |
| | | </mapper> |
¶Ô±ÈÐÂÎļþ |
| | |
| | | import { requestClient } from '#/api/request'; |
| | | import type { Template } from './model'; |
| | | |
| | | enum Api { |
| | | templateAdd = '/page-designer-template', |
| | | templateUpdate = '/page-designer-template', |
| | | templateList = '/page-designer-template/list', |
| | | templateInfo = '/page-designer-template', |
| | | templateRemove = '/page-designer-template', |
| | | } |
| | | |
| | | /** |
| | | * æ°å¢é¡µé¢è®¾è®¡ |
| | | */ |
| | | export function templateAdd(data: any) { |
| | | return requestClient.post(Api.templateAdd, data); |
| | | } |
| | | |
| | | /** |
| | | * ä¿®æ¹é¡µé¢è®¾è®¡ |
| | | */ |
| | | export function templateUpdate(data: any) { |
| | | return requestClient.put(Api.templateUpdate, data); |
| | | } |
| | | |
| | | /** |
| | | * è·å页é¢è®¾è®¡å表 |
| | | */ |
| | | export function templateList(params?: any) { |
| | | return requestClient.get(Api.templateList, { params }); |
| | | } |
| | | |
| | | /** |
| | | * è·å页é¢è®¾è®¡è¯¦æ
|
| | | */ |
| | | export function templateInfo(id: string | number) { |
| | | return requestClient.get(`${Api.templateInfo}/${id}`); |
| | | } |
| | | |
| | | /** |
| | | * å é¤é¡µé¢è®¾è®¡ |
| | | */ |
| | | export function templateRemove(ids: string[] | number[]) { |
| | | return requestClient.delete(Api.templateRemove, { data: ids }); |
| | | } |
¶Ô±ÈÐÂÎļþ |
| | |
| | | export interface Template { |
| | | id?: string | number; // ä¸»é® |
| | | formData: string; // 模çåç§° |
| | | pageDesignId: string | number; // å
³èç页é¢è®¾è®¡ID |
| | | createTime?: string; // å建æ¶é´ |
| | | updateTime?: string; // æ´æ°æ¶é´ |
| | | pageDesign?: { // å
³èç页é¢è®¾è®¡ä¿¡æ¯ |
| | | id: string | number; |
| | | name: string; |
| | | formJson?: string; |
| | | showColumn?: string; |
| | | actionsFunc?: string; |
| | | } | null; |
| | | } |
¶Ô±ÈÐÂÎļþ |
| | |
| | | import type { FormSchemaGetter } from '#/adapter/form'; |
| | | import type { VxeGridProps } from '#/adapter/vxe-table'; |
| | | |
| | | export const querySchema: FormSchemaGetter = () => [ |
| | | { |
| | | component: 'Input', |
| | | fieldName: 'name', |
| | | label: '模çåç§°', |
| | | }, |
| | | { |
| | | component: 'Select', |
| | | componentProps: { |
| | | options: [ |
| | | { label: 'æ£å¸¸', value: '1' }, |
| | | { label: 'åç¨', value: '0' }, |
| | | ], |
| | | }, |
| | | fieldName: 'status', |
| | | label: '模çç¶æ', |
| | | }, |
| | | ]; |
| | | |
| | | export const columns = [ |
| | | { |
| | | title: 'å§å', |
| | | dataIndex: 'name', |
| | | auth: 'test', // æ ¹æ®æéæ§å¶æ¯å¦æ¾ç¤º: æ æéï¼ä¸æ¾ç¤º |
| | | } |
| | | ]; |
| | | |
| | | export const drawerSchema = () => [ |
| | | { |
| | | component: 'Input', |
| | | fieldName: 'name', |
| | | label: '模çåç§°', |
| | | rules: 'required', |
| | | }, |
| | | { |
| | | component: 'Select', |
| | | fieldName: 'pageDesignId', |
| | | label: '页é¢è®¾è®¡', |
| | | componentProps: { |
| | | allowClear: true, |
| | | showSearch: true, |
| | | filterOption: (input: string, option: any) => { |
| | | return option.label.toLowerCase().indexOf(input.toLowerCase()) >= 0; |
| | | }, |
| | | }, |
| | | rules: 'selectRequired', |
| | | }, |
| | | { |
| | | component: 'Select', |
| | | fieldName: 'templateType', |
| | | label: '模çç±»å', |
| | | componentProps: { |
| | | options: [ |
| | | { label: 'å表页', value: 'list' }, |
| | | { label: '表å页', value: 'form' }, |
| | | { label: '详æ
页', value: 'detail' }, |
| | | { label: '仪表æ¿', value: 'dashboard' }, |
| | | ], |
| | | }, |
| | | rules: 'selectRequired', |
| | | }, |
| | | { |
| | | component: 'Select', |
| | | fieldName: 'status', |
| | | label: 'ç¶æ', |
| | | componentProps: { |
| | | options: [ |
| | | { label: 'æ£å¸¸', value: '1' }, |
| | | { label: 'åç¨', value: '0' }, |
| | | ], |
| | | }, |
| | | rules: 'selectRequired', |
| | | }, |
| | | { |
| | | component: 'Input', |
| | | fieldName: 'remark', |
| | | label: '夿³¨', |
| | | componentProps: { |
| | | type: 'textarea', |
| | | rows: 2, |
| | | }, |
| | | }, |
| | | ]; |
¶Ô±ÈÐÂÎļþ |
| | |
| | | <template> |
| | | <Page v-if="isAdmin" :auto-content-height="true"> |
| | | <BasicTable |
| | | :key="tableKey" |
| | | :table-title="pageDesignDetail?.name || '模æ¿å表'" |
| | | :grid-options="gridOptions" |
| | | > |
| | | <template #toolbar-tools> |
| | | <Space> |
| | | <a-button v-if="showAction('add')" type="primary" @click="handleAdd">æ°å¢</a-button> |
| | | </Space> |
| | | </template> |
| | | <template #action="{ row }"> |
| | | <Space> |
| | | <ghost-button v-if="showAction('edit')" @click="handleEdit(row)">ç¼è¾</ghost-button> |
| | | <Popconfirm v-if="showAction('delete')" :get-popup-container="getVxePopupContainer" placement="left" title="确认å é¤ï¼" @confirm="handleDelete(row)"> |
| | | <ghost-button danger @click.stop="">å é¤</ghost-button> |
| | | </Popconfirm> |
| | | </Space> |
| | | </template> |
| | | </BasicTable> |
| | | <TemplateDrawer ref="templateModalRef" @reload="tableApi.query()" /> |
| | | </Page> |
| | | <Fallback v-else description="æ¨æ²¡æé¡µé¢çè®¿é®æé" status="403" /> |
| | | </template> |
| | | |
| | | <script setup lang="ts"> |
| | | import type { VbenFormProps } from '@vben/common-ui'; |
| | | import type { VxeGridProps } from '#/adapter/vxe-table'; |
| | | import { computed, ref, onMounted, watch } from 'vue'; |
| | | import { useRoute, useRouter } from 'vue-router'; |
| | | import { useAccess } from '@vben/access'; |
| | | import { Fallback, Page } from '@vben/common-ui'; |
| | | import { getVxePopupContainer } from '@vben/utils'; |
| | | import { Popconfirm, Space, Spin as ASpin } from 'ant-design-vue'; |
| | | import { useVbenVxeGrid } from '#/adapter/vxe-table'; |
| | | import { columns as baseColumns, querySchema } from './data'; |
| | | import TemplateDrawer from './template-drawer.vue'; |
| | | import { templateList, templateRemove } from '#/api/tool/template'; |
| | | import { pageInfo } from '#/api/tool/page-designer'; |
| | | |
| | | const route = useRoute(); |
| | | const router = useRouter(); |
| | | const pageId = ref<string | number>(''); |
| | | const pageDesignDetail = ref<any>(null); // 页é¢è®¾è®¡è¯¦æ
|
| | | const loading = ref(true); // å è½½ä¸ |
| | | |
| | | // 卿columns |
| | | const dynamicColumns = ref([ |
| | | { field: 'id', title: 'ID', width: 100 }, |
| | | { field: 'formData', title: 'è¡¨åæ°æ®', minWidth: 160 }, |
| | | { field: 'action', title: 'æä½', width: 160, slots: { default: 'action' } } |
| | | ]); |
| | | |
| | | // ç¨äºè¡¨æ ¼éæ°æ¸²æç key |
| | | const tableKey = ref(0); |
| | | |
| | | // æ´æ°å¨æåç彿° |
| | | function updateDynamicColumns() { |
| | | if (!pageDesignDetail.value || !pageDesignDetail.value.showColumn || !pageDesignDetail.value.formJson) { |
| | | console.log('使ç¨é»è®¤å'); |
| | | return; |
| | | } |
| | | |
| | | try { |
| | | const showFields = JSON.parse(pageDesignDetail.value.showColumn); |
| | | const formFields = JSON.parse(pageDesignDetail.value.formJson); |
| | | const cols = showFields.map(field => { |
| | | const fieldDef = formFields.find(f => f.field === field); |
| | | return { |
| | | field: field, |
| | | title: fieldDef ? fieldDef.title : field, |
| | | minWidth: 120, |
| | | align: 'center', |
| | | }; |
| | | }); |
| | | |
| | | cols.push({ |
| | | field: 'action', |
| | | title: 'æä½', |
| | | width: 160, |
| | | slots: { default: 'action' }, |
| | | }); |
| | | |
| | | dynamicColumns.value = cols; |
| | | gridOptions.value = { ...gridOptions.value, columns: cols }; |
| | | tableKey.value++; |
| | | } catch (error) { |
| | | const fallbackCols = [ |
| | | { field: 'id', title: 'ID', width: 100 }, |
| | | { field: 'formData', title: 'è¡¨åæ°æ®', minWidth: 160 }, |
| | | { field: 'action', title: 'æä½', width: 160, slots: { default: 'action' } } |
| | | ]; |
| | | dynamicColumns.value = fallbackCols; |
| | | gridOptions.value = { ...gridOptions.value, columns: fallbackCols }; |
| | | tableKey.value++; |
| | | } |
| | | } |
| | | |
| | | |
| | | // 卿æé® |
| | | function showAction(action: string) { |
| | | if (!pageDesignDetail.value || !pageDesignDetail.value.actionsFunc) { |
| | | return true; |
| | | } |
| | | |
| | | try { |
| | | const actions = JSON.parse(pageDesignDetail.value.actionsFunc); |
| | | if (!Array.isArray(actions)) { |
| | | console.warn('actionsFunc 䏿¯æ°ç»æ ¼å¼:', pageDesignDetail.value.actionsFunc); |
| | | return true; |
| | | } |
| | | |
| | | return actions.includes(action); |
| | | } catch (error) { |
| | | console.error('è§£æ actionsFunc 失败:', error); |
| | | return true; |
| | | } |
| | | } |
| | | |
| | | // è·å pageIdï¼å
¼å®¹ metaãparamsãquery |
| | | function getPageId() { |
| | | const pageId = ( |
| | | (route.meta && (route.meta as any).pageId) || |
| | | route.params.pageId || |
| | | route.query.pageId || |
| | | '' |
| | | ); |
| | | |
| | | // ç¡®ä¿è¿åçæ¯åç¬¦ä¸²ææ°å |
| | | return pageId ? String(pageId) : ''; |
| | | } |
| | | |
| | | onMounted(() => { |
| | | const initialPageId = getPageId(); |
| | | console.log('è·åå°ç pageId:', initialPageId); |
| | | |
| | | if (initialPageId) { |
| | | pageId.value = initialPageId; |
| | | handlePageIdChange(); |
| | | } else { |
| | | loading.value = false; |
| | | } |
| | | }); |
| | | |
| | | // çå¬è·¯ç±ååï¼èªå¨æ´æ° pageId |
| | | watch( |
| | | () => [route.meta.pageId, route.params.pageId, route.query.pageId], |
| | | (newValues, oldValues) => { |
| | | // åªæå½å¼çæ£ååæ¶æå¤ç |
| | | if (JSON.stringify(newValues) !== JSON.stringify(oldValues)) { |
| | | const newPageId = getPageId(); |
| | | console.log('è·¯ç±ååå pageId:', newPageId); |
| | | |
| | | // åªæå½ pageId çæ£ååæ¶ææ´æ° |
| | | if (newPageId !== pageId.value) { |
| | | pageId.value = newPageId; |
| | | handlePageIdChange(); |
| | | tableApi.query(); |
| | | } |
| | | } |
| | | }, |
| | | { deep: true } |
| | | ); |
| | | |
| | | // pageIdååæ¶èªå¨è·å页é¢è®¾è®¡è¯¦æ
|
| | | async function handlePageIdChange() { |
| | | loading.value = true; |
| | | console.log(`[handlePageIdChange] å¼å§å¤ç pageId: ${pageId.value}`); |
| | | try { |
| | | if (pageId.value) { |
| | | const detail = await pageInfo(pageId.value); |
| | | console.log('[handlePageIdChange] è·åå°ç页é¢è®¾è®¡è¯¦æ
(detail):', JSON.parse(JSON.stringify(detail))); |
| | | |
| | | // å¤çæ°æ®ï¼é¿å
循ç¯å¼ç¨ |
| | | const safeDetail = { |
| | | id: detail.id, |
| | | name: detail.name, |
| | | menuId: detail.menuId, |
| | | status: detail.status, |
| | | remark: detail.remark, |
| | | formJson: detail.formJson, |
| | | showColumn: detail.showColumn, |
| | | actionsFunc: detail.actionsFunc, |
| | | createTime: detail.createTime, |
| | | updateTime: detail.updateTime, |
| | | createBy: detail.createBy, |
| | | updateBy: detail.updateBy, |
| | | createDept: detail.createDept |
| | | }; |
| | | |
| | | pageDesignDetail.value = safeDetail; |
| | | console.log('[handlePageIdChange] 设置ç pageDesignDetail.value:', JSON.parse(JSON.stringify(pageDesignDetail.value))); |
| | | updateDynamicColumns(); |
| | | } else { |
| | | pageDesignDetail.value = null; |
| | | updateDynamicColumns(); |
| | | } |
| | | } catch (error) { |
| | | console.error('[handlePageIdChange] è·å页é¢è®¾è®¡è¯¦æ
失败:', error); |
| | | pageDesignDetail.value = null; |
| | | updateDynamicColumns(); |
| | | } finally { |
| | | loading.value = false; |
| | | } |
| | | } |
| | | |
| | | const formOptions: VbenFormProps = { |
| | | commonConfig: { |
| | | labelWidth: 80, |
| | | componentProps: { |
| | | allowClear: true, |
| | | }, |
| | | }, |
| | | schema: querySchema(), |
| | | wrapperClass: 'grid-cols-1 md:grid-cols-2 lg:grid-cols-3 xl:grid-cols-4', |
| | | }; |
| | | |
| | | const gridOptions = ref<VxeGridProps>({ |
| | | columns: dynamicColumns.value, |
| | | height: 'auto', |
| | | keepSource: true, |
| | | pagerConfig: { |
| | | enabled: true, |
| | | }, |
| | | proxyConfig: { |
| | | ajax: { |
| | | query: async ({ page }, formValues = {}) => { |
| | | try { |
| | | console.log('æ¥è¯¢åæ°:', { page, formValues }); |
| | | const queryParams = { |
| | | pageNum: page.currentPage, |
| | | pageSize: page.pageSize, |
| | | ...formValues, |
| | | }; |
| | | if (pageId.value) { |
| | | queryParams.pageDesignId = pageId.value; |
| | | } |
| | | const resp = await templateList(queryParams); |
| | | // å¤çæ¯æ¡ row ç formData |
| | | const rows = (resp.rows || []).map(row => { |
| | | let formData = {}; |
| | | try { |
| | | if (row.formData) { |
| | | formData = JSON.parse(row.formData); |
| | | console.log('è§£æåç formData:', formData); |
| | | // å é¤åå§ç formData åæ®µï¼å 为æä»¬å·²ç»å±å¼å®çå
容 |
| | | const { formData: _, ...restRow } = row; |
| | | // è¿åå±å¼åçæ°æ® |
| | | return { |
| | | ...restRow, |
| | | ...formData |
| | | }; |
| | | } |
| | | } catch (e) { |
| | | console.error('è§£æ formData 失败:', e); |
| | | } |
| | | return row; |
| | | }); |
| | | console.log('å¤çåç rows:', rows); |
| | | return { |
| | | rows, |
| | | total: resp.total || 0, |
| | | }; |
| | | } catch (error) { |
| | | console.error('æ¥è¯¢æ¨¡æ¿å表失败:', error); |
| | | return { |
| | | rows: [], |
| | | total: 0, |
| | | }; |
| | | } |
| | | }, |
| | | }, |
| | | }, |
| | | rowConfig: { |
| | | keyField: 'id', |
| | | }, |
| | | id: 'tool-template-index', |
| | | columnConfig: { resizable: true }, |
| | | }); |
| | | |
| | | const [BasicTable, tableApi] = useVbenVxeGrid({ |
| | | formOptions, |
| | | gridOptions: computed(() => ({ |
| | | ...gridOptions.value, |
| | | columns: dynamicColumns.value |
| | | })), |
| | | }); |
| | | |
| | | const templateModalRef = ref(); |
| | | const generateModalRef = ref(); |
| | | |
| | | function handleAdd() { |
| | | // 妿æ pageIdï¼ä¼ éç»æ°å¢ |
| | | const params: any = { update: false }; |
| | | if (pageId.value) { |
| | | params.pageDesignId = pageId.value; |
| | | } |
| | | // å¨æä¼ éformJsonï¼å
JSON.parseï¼ä¿è¯æ¯çº¯å¯¹è±¡ |
| | | if (pageDesignDetail.value && pageDesignDetail.value.formJson) { |
| | | try { |
| | | const formJson = JSON.parse(pageDesignDetail.value.formJson); |
| | | params.formJson = formJson; |
| | | console.log('ä¼ éå¨æè¡¨ååæ®µ:', formJson); |
| | | } catch (error) { |
| | | console.error('è§£æ formJson 失败:', error); |
| | | params.formJson = undefined; |
| | | } |
| | | } |
| | | templateModalRef.value.open(params); |
| | | } |
| | | |
| | | function handleEdit(record) { |
| | | // ç¼è¾æ¶ä¹ä¼ éformJsonï¼å
JSON.parseï¼ä¿è¯æ¯çº¯å¯¹è±¡ |
| | | const params: any = { |
| | | id: record.id, |
| | | update: true, |
| | | pageDesignId: pageId.value, // ä¼ é页é¢è®¾è®¡ID |
| | | record: record // ä¼ é宿´çè®°å½æ°æ® |
| | | }; |
| | | |
| | | if (pageDesignDetail.value && pageDesignDetail.value.formJson) { |
| | | try { |
| | | const formJson = JSON.parse(pageDesignDetail.value.formJson); |
| | | params.formJson = formJson; |
| | | console.log('ç¼è¾æ¶ä¼ éæ°æ®:', { record, formJson, pageDesignId: pageId.value }); |
| | | } catch (error) { |
| | | console.error('è§£æ formJson 失败:', error); |
| | | params.formJson = undefined; |
| | | } |
| | | } |
| | | templateModalRef.value.open(params); |
| | | } |
| | | |
| | | async function handleDelete(row: any) { |
| | | try { |
| | | await templateRemove([row.id]); |
| | | await tableApi.query(); |
| | | } catch (error) { |
| | | console.error('å 餿¨¡æ¿å¤±è´¥:', error); |
| | | } |
| | | } |
| | | |
| | | function handleGenerate(row) { |
| | | try { |
| | | generateModalRef.value.open(row); |
| | | } catch (error) { |
| | | console.error('æå¼çæé¡µé¢å¤±è´¥:', error); |
| | | } |
| | | } |
| | | |
| | | function handlePreview(row) { |
| | | try { |
| | | // æå¼é¢è§çªå£ |
| | | const url = `/tool/template/preview/${row.id}`; |
| | | window.open(url, '_blank'); |
| | | } catch (error) { |
| | | console.error('æå¼é¢è§å¤±è´¥:', error); |
| | | } |
| | | } |
| | | |
| | | const { hasAccessByRoles } = useAccess(); |
| | | const isAdmin = computed(() => { |
| | | try { |
| | | return hasAccessByRoles(['admin', 'superadmin']); |
| | | } catch (error) { |
| | | console.error('æ£æ¥æé失败:', error); |
| | | return false; |
| | | } |
| | | }); |
| | | |
| | | const isReady = computed(() => { |
| | | try { |
| | | // ç®å夿é»è¾ï¼åå°ä¸å¿
è¦çè®¡ç® |
| | | return !!(pageDesignDetail.value && !loading.value); |
| | | } catch (error) { |
| | | console.error('æ£æ¥é¡µé¢åå¤ç¶æå¤±è´¥:', error); |
| | | return false; |
| | | } |
| | | }); |
| | | </script> |
| | | |
| | | <style scoped> |
| | | .template-page { |
| | | background: #f5f6fa; |
| | | padding: 16px; |
| | | min-height: 100vh; |
| | | height: 100vh; |
| | | overflow: hidden; |
| | | } |
| | | |
| | | /* ç¡®ä¿è¡¨æ ¼å®¹å¨é«åº¦ç¨³å® */ |
| | | :deep(.vxe-table--main-wrapper) { |
| | | height: 600px !important; |
| | | } |
| | | |
| | | /* ç¡®ä¿å页å¨ä½ç½®åºå® */ |
| | | :deep(.vxe-pager) { |
| | | position: sticky; |
| | | bottom: 0; |
| | | background: white; |
| | | z-index: 10; |
| | | } |
| | | </style> |
¶Ô±ÈÐÂÎļþ |
| | |
| | | <script setup lang="ts"> |
| | | import { computed, ref, watch, nextTick } from 'vue'; |
| | | import { Modal, message, FormItem } from 'ant-design-vue'; |
| | | import { $t } from '@vben/locales'; |
| | | import { templateAdd, templateUpdate, templateInfo } from '#/api/tool/template'; |
| | | import { pageList } from '#/api/tool/page-designer'; |
| | | import formCreate from '@form-create/element-ui'; |
| | | |
| | | interface ModalProps { |
| | | id?: number | string; |
| | | update: boolean; |
| | | pageDesignId?: string | number; |
| | | formJson?: any; |
| | | } |
| | | |
| | | const emit = defineEmits<{ reload: [] }>(); |
| | | |
| | | const isUpdate = ref(false); |
| | | const title = computed(() => { |
| | | return isUpdate.value ? $t('pages.common.edit') : $t('pages.common.add'); |
| | | }); |
| | | |
| | | const modalVisible = ref(false); |
| | | const modalLoading = ref(false); |
| | | const currentEditId = ref<string | number>(''); |
| | | const dynamicFormRef = ref(); |
| | | const dynamicFormRule = ref([]); |
| | | const dynamicFormOption = ref({ |
| | | submitBtn: false, |
| | | resetBtn: false |
| | | }); |
| | | const showOkBtn = ref(true); |
| | | const currentPageId = ref(''); |
| | | const formApi = ref(); |
| | | |
| | | // 夿æ¯å¦ææäº¤æé® |
| | | type RuleItem = { type?: string }; |
| | | const hasSubmitBtn = (rules: any[] = []) => { |
| | | return rules.some((item: RuleItem) => item.type === 'submit'); |
| | | }; |
| | | // æ´å½»åºçéå½ç§»é¤ææ submit æé®ï¼æ¯æ childrenãbodyãcolumnsãlistãoptionsãtabs çå®¹å¨ |
| | | function removeSubmitBtn(rules = []) { |
| | | return rules |
| | | .filter(item => item.type !== 'submit') |
| | | .map(item => { |
| | | if (item.children) item.children = removeSubmitBtn(item.children); |
| | | if (item.body) item.body = removeSubmitBtn(item.body); |
| | | if (item.columns) item.columns = item.columns.map(col => ({ |
| | | ...col, |
| | | list: removeSubmitBtn(col.list || []) |
| | | })); |
| | | if (item.list) item.list = removeSubmitBtn(item.list); |
| | | if (item.options && Array.isArray(item.options)) item.options = removeSubmitBtn(item.options); |
| | | if (item.tabs) item.tabs = item.tabs.map(tab => ({ |
| | | ...tab, |
| | | list: removeSubmitBtn(tab.list || []) |
| | | })); |
| | | return item; |
| | | }); |
| | | } |
| | | |
| | | // æå¼å¼¹çª |
| | | const open = async (params: ModalProps = { update: false }) => { |
| | | try { |
| | | console.log('æå¼å¼¹çªï¼åæ°:', params); |
| | | modalVisible.value = true; |
| | | modalLoading.value = true; |
| | | isUpdate.value = params.update; |
| | | currentEditId.value = params.id || ''; |
| | | currentPageId.value = params.pageId || params.pageDesignId || ''; |
| | | |
| | | // è®¾ç½®å¨æè¡¨ååæ®µï¼å§ç»ç§»é¤ææsubmitæé® |
| | | if (params.formJson) { |
| | | console.log('è®¾ç½®å¨æè¡¨åè§å:', params.formJson); |
| | | dynamicFormRule.value = removeSubmitBtn(params.formJson); |
| | | showOkBtn.value = true; // å§ç»æ¾ç¤ºç¡®å®æé® |
| | | } else { |
| | | dynamicFormRule.value = []; |
| | | showOkBtn.value = true; |
| | | } |
| | | |
| | | // ç¼è¾æ¨¡å¼ |
| | | if (params.id && params.update) { |
| | | console.log('ç¼è¾æ¨¡å¼ï¼è·å详æ
æ°æ®'); |
| | | try { |
| | | // è·å详æ
æ°æ® |
| | | const record = await templateInfo(params.id); |
| | | console.log('è·åå°çè®°å½æ°æ®:', record); |
| | | |
| | | // è®¾ç½®å¨æè¡¨åæ°æ® |
| | | if (record.formData) { |
| | | try { |
| | | const dynamicData = JSON.parse(record.formData); |
| | | console.log('è§£æåçè¡¨åæ°æ®:', dynamicData); |
| | | |
| | | await nextTick(); |
| | | if (formApi.value) { |
| | | console.log('åå¤è®¾ç½®è¡¨åæ°æ®å°ç»ä»¶'); |
| | | // ä½¿ç¨ form-create ç API è®¾ç½®å¼ |
| | | Object.keys(dynamicData).forEach(key => { |
| | | formApi.value.setValue(key, dynamicData[key]); |
| | | }); |
| | | console.log('è¡¨åæ°æ®è®¾ç½®å®æ'); |
| | | } else { |
| | | console.warn('表åAPIæªå°±ç»ª'); |
| | | message.error('è¡¨åæªå°±ç»ªï¼è¯·éè¯'); |
| | | } |
| | | } catch (error) { |
| | | console.error('è§£æå¨æåæ®µæ°æ®å¤±è´¥:', error); |
| | | message.error('å è½½è¡¨åæ°æ®å¤±è´¥'); |
| | | } |
| | | } else { |
| | | console.log('è®°å½ä¸æ²¡æ formData æ°æ®'); |
| | | } |
| | | } catch (error) { |
| | | console.error('å¤çè¡¨åæ°æ®å¤±è´¥:', error); |
| | | message.error('å è½½è¡¨åæ°æ®å¤±è´¥ï¼è¯·éè¯'); |
| | | } |
| | | } else { |
| | | // æ°å¢æ¶éç½®æ°æ® |
| | | console.log('æ°å¢æ¨¡å¼ï¼é置表å'); |
| | | await nextTick(); |
| | | if (formApi.value) { |
| | | formApi.value.resetFields && formApi.value.resetFields(); |
| | | } |
| | | } |
| | | } catch (error) { |
| | | console.error('æå¼å¼¹çªå¤±è´¥:', error); |
| | | message.error('å è½½æ°æ®å¤±è´¥'); |
| | | } finally { |
| | | modalLoading.value = false; |
| | | } |
| | | }; |
| | | |
| | | const close = () => { |
| | | modalVisible.value = false; |
| | | }; |
| | | |
| | | defineExpose({ open, close }); |
| | | |
| | | function onFormMounted(api) { |
| | | formApi.value = api; |
| | | } |
| | | |
| | | // handleOk åªè´è´£è§¦å表å submit |
| | | async function handleOk() { |
| | | await nextTick(); |
| | | console.log('handleOk formApi:', formApi.value); |
| | | if (!dynamicFormRule.value || dynamicFormRule.value.length === 0) { |
| | | message.error('表åè§åæªå è½½ï¼æ æ³æäº¤'); |
| | | return; |
| | | } |
| | | if (!formApi.value) { |
| | | message.error('è¡¨åæªæ¸²æå®æï¼è¯·ç¨åéè¯'); |
| | | return; |
| | | } |
| | | try { |
| | | modalLoading.value = true; |
| | | const valid = await formApi.value.validate(); |
| | | if (!valid) { |
| | | modalLoading.value = false; |
| | | return; |
| | | } |
| | | const formData = formApi.value.formData(); |
| | | await onFormSubmit(formData); |
| | | } catch (error) { |
| | | console.error('ä¿å失败:', error); |
| | | message.error('ä¿å失败'); |
| | | modalLoading.value = false; |
| | | } |
| | | } |
| | | |
| | | // form-create ç submit äºä»¶å¤ç |
| | | async function onFormSubmit(dynamicData: any) { |
| | | try { |
| | | modalLoading.value = true; |
| | | // æå»ºä¿åæ°æ® |
| | | const finalData = { |
| | | pageId: currentPageId.value, |
| | | formData: Object.keys(dynamicData).length > 0 ? JSON.stringify(dynamicData) : undefined |
| | | }; |
| | | if (isUpdate.value) { |
| | | finalData.id = currentEditId.value; |
| | | } |
| | | console.log(finalData) |
| | | await (isUpdate.value ? templateUpdate(finalData) : templateAdd(finalData)); |
| | | emit('reload'); |
| | | close(); |
| | | message.success('ä¿åæå'); |
| | | } catch (error) { |
| | | console.error('ä¿å失败:', error); |
| | | message.error('ä¿å失败'); |
| | | } finally { |
| | | modalLoading.value = false; |
| | | } |
| | | } |
| | | |
| | | function handleCancel() { |
| | | close(); |
| | | } |
| | | </script> |
| | | |
| | | <template> |
| | | <a-modal |
| | | v-model:open="modalVisible" |
| | | :title="title" |
| | | :width="'80vw'" |
| | | :confirm-loading="modalLoading" |
| | | @ok="handleOk" |
| | | @cancel="handleCancel" |
| | | :bodyStyle="{ padding: '24px', minHeight: '60vh' }" |
| | | destroyOnClose |
| | | :ok-button-props="{ style: showOkBtn ? {} : { display: 'none' } }" |
| | | > |
| | | <!-- å¨æè¡¨ååºå --> |
| | | <form-create |
| | | ref="dynamicFormRef" |
| | | :rule="dynamicFormRule" |
| | | :option="dynamicFormOption" |
| | | @submit="onFormSubmit" |
| | | @mounted="onFormMounted" |
| | | /> |
| | | </a-modal> |
| | | </template> |