## 开发

```bash
# 克隆项目
git clone https://gitee.com/y_project/RuoYi-Vue

# 进入项目目录
cd ruoyi-ui

# 安装依赖
npm install

# 建议不要直接使用 cnpm 安装依赖，会有各种诡异的 bug。可以通过如下操作解决 npm 下载速度慢的问题
npm install --registry=https://registry.npmmirror.com

# 启动服务
npm run dev
```

浏览器访问 http://localhost:80

## 发布

```bash
# 构建测试环境
npm run build:stage

# 构建生产环境
npm run build:prod
```

## 组件使用
```bash
#form组件
组件位置/src/components/element/form下
<card-form>页面上半部分
例如：
    <card-table :modalData="roleList" labelWidth="120px" :searchParams="queryParams" @pagination="getList"
                @selection-change="handleSelectionChange" :loading="loading" :tableSearch="true" @columnSearch="handleQuery"
                :delProp= "['createTime']">
      <template #searchFix="{ params }">
      
       //固定查询列
       
      </template>
      <template #search="{ params }">
      
       //可隐藏查询列
       
      </template>
   </card-form>
   1.getList为查询列表方法回调
   2.delProp为查询时对查询参数的处理，填入会在查询时删除查询条件中的对应属性
   3.resetList为重置方法
   4.组件js中还存在其他方法，可以去代码中查看
   
<card-table>页面下半部分，包含按钮，列表，分页
例如
 <card-table :modalData="roleList" labelWidth="120px" :searchParams="queryParams" 
 @pagination="getListNew" @selection-change="handleSelectionChange" :loading="loading"
 @columnSearch="getListNew" >
      <template #operations="{ selections }">
      
      //操作按钮列，如新增修改（可直接复制原vue文件中的代码）
      
      </template>
      <template #default="{ list }">
      
      //table数据列
      
      </template>
 </card-table>
  1.modalData为传入table数据集。
  2.labelWidth为列宽，可不传
  3.searchParams为form查询条件，传入card-form的v-model即可。
  4.pagination为切换页码查询事件，绑定getlist查询事件，需将total，pageSize,pageNum设置在查询条件中
  5.selection-change为选中列切换事件，需开启列选择功能
  6.loading为列表loading传入true/false
  7.template上 #operations="{ selections }" 次为插槽回传数据，selections代表选中列集合。
  此处回传数据在组件中自行设置
  8.tableSearch为开启列表筛选的控制开关，开启时需设置columnSearch返回查询方法，若查询实体存在需要删除的参数。需额外设置delProp字段，此处与card-form用法相同
  
  9.查询列表事件修改
  原方法：
   /** 查询角色列表 */
      getList() {
        this.loading = true;
        listRole(this.addDateRange(this.queryParams, this.dateRange)).then(response => {
            this.roleList = response.rows;
            this.total = response.total;
            this.queryParams.total = response.total;
            this.loading = false;
          }
        );
      },
   修改方法1：@columnSearch @pagination 方法自带返回参数（参数就是查询实体）
   ，需要用查询实体作为getList查询参数。
   例如：
   getListNew(param) {
         this.loading = true;
         listRole(param).then(response => {
             this.roleList = response.rows;
             this.total = response.total;
             this.queryParams.total = response.total;
             this.loading = false;
           }
         );
       },
     
     方法2：使用方法2无需再次定义@delProp字段，在getList时自定义查询实体。
     例如
     getList() {
       let params;
       this.loading = true;
       params = {
         pageNum:this.queryParams.pageNum,
         pageSize:this.queryParams.pageSize,
         language:this.queryParams.language,
         beginTime: this.queryParams.beginTime,
         endTime: this.queryParams.endTime,
       }
       listFollow(params).then(response => {
         this.followList = response.rows;
         this.total = response.total;
         this.queryParams.total = response.total;
         this.loading = false;
       });
     },
   


<Column>组件
此组件配合card-table一起使用，主要用于完成列表搜索功能
详细代码参考角色管理页面

例如：
 <Column label="显示顺序" prop="roleSort"/>
 <Column label="权限字符" prop="roleKey"  :searchParams="queryParams" :showSearch="true"/>
 <Column label="状态" prop="status" :searchParams="queryParams" :showSearch="true" searchType="select" :searchDict="dict.type.sys_normal_disable">    
 <Column label="创建时间" prop="createTime" :searchParams="queryParams" :showSearch="true" searchType="dateRange">
 <Column label="操作" :min-width="200" fixed="right" :showSearch="true" searchType="operate">

1.字段正常显示时，只需传入label和prop 
2.需要开启字段搜索时，需把showSearch设置为true，同时设置searchParams为搜索条件实体。
3.searchType默认为input，如果该搜索框为其他下拉框或时间。searchType设置为select/dateRange。
4.searchType为select时，需设置下拉数据 searchDict。若key-value不是默认的labl-value，需设置字段labelProp - valueProp。
5.若为时间类型，需额外设置dateType，dateType默认为daterange，搜索日期段，若需搜索月份，则改为monthrange。
  此外时间段选中默认赋值起止日期到 beginTime-endTime,如需修改则设置propStart-propEnd。使用日期控件需设置delProp字段
6.如果设置:selectMore="true"，则代表select可以多选，此时需传入字段selectProp="statusStr"用于接收多选拼接的字段。、
注意此时需和日期一样设置delProp字段，防止查询时异常

7.Column组件已优化，开启字段搜索时，searchParams无需作为必传条件。
                    
```

## 前端获取当前用户权限字符
```bash
this.$store.state.user.permissionChar
// 或者

import { mapState } from 'vuex'

computed: {
  ...mapState({
    permissionChar: state => state.user.permissionChar
  })
},
```

## 时间格式化（涉及到时区）
```bash
  import {getLocalTime} from "@/utils/data/dataUtils"
  调用 getLocalTime(需要格式化的时间，格式)
```


## 下拉框选项远程检索
```bash
例：
     <el-select  v-model="form.businessId" :disabled="!contentEditable || !editAnbledFlad"  style="width: 257%" required
                            filterable remote :remote-method="remoteMethod"
 注意：必须追加 filterable remote :remote-method="remoteMethod"
 
     remoteMethod(query){
      this.options = [];
      if (query !== '' && query.length > 2) {
        const loading = this.$loading({});
          
          **********************************
          用query检索相应的下拉框选项
          ***********************************
        
        loading.close();
      }
```

### AppMain 注意事项
```bash
   全局 ”chatRoomImage“ class类不可额外定义，已经服务于聊天室图片预览，对于这个类的dom元素添加click监听事件，阻止了click事件传递；
  messagePreview 方法不能删除
```


