소스 검색

fullcalendar日程插件

sunlupeng 1 년 전
부모
커밋
8312a9b7dd
3개의 변경된 파일143개의 추가작업 그리고 259개의 파일을 삭제
  1. 4 0
      package.json
  2. 2 21
      src/views/login.vue
  3. 137 238
      src/views/meeting/reserve/index.vue

+ 4 - 0
package.json

@@ -42,6 +42,10 @@
   },
   "dependencies": {
     "@babel/parser": "7.18.4",
+    "@fullcalendar/core": "^6.1.15",
+    "@fullcalendar/interaction": "^6.1.15",
+    "@fullcalendar/timegrid": "^6.1.15",
+    "@fullcalendar/vue": "^6.1.15",
     "@riophae/vue-treeselect": "0.4.0",
     "axios": "0.27.2",
     "benz-amr-recorder": "^1.1.5",

+ 2 - 21
src/views/login.vue

@@ -123,26 +123,7 @@ export default {
       LoginRules: {
         username: [
           {required: true, trigger: "blur", message: "手机号不能为空"},
-          {
-            validator: (rule, value, callback) => {
-              if (/^(?:(?:\+|00)86)?1(?:3[\d]|4[5-79]|5[0-35-9]|6[5-7]|7[0-8]|8[\d]|9[189])\d{8}$/.test(value) === false) {
-                callback(new Error("手机号格式错误"));
-              } else {
-                removeTenantId()
-                getTenantIdByName(value).then(res => {
-                  const tenantId = res.data;
-                  if (tenantId && tenantId >= 0) {
-                    setTenantId(tenantId)
-                    callback();
-                  } else {
-                    callback('该手机号未创建账号,请重新输入');
-                  }
-                });
-              }
-           
-            },
-            trigger: 'blur'
-          }
+          
         ],
         password: [
           {required: true, trigger: "blur", message: "密码不能为空"}
@@ -199,7 +180,7 @@ export default {
             removePassword()
             removeRememberMe()
           }
-          // setTenantId(1)
+          setTenantId(1)
           this.$store.dispatch(this.loginForm.loginType === "sms" ? "SmsLogin" : "Login", this.loginForm).then(() => {
             this.$router.push({path: "/"}).catch(() => {
             });

+ 137 - 238
src/views/meeting/reserve/index.vue

@@ -1,244 +1,143 @@
 <template>
-    <div class="app-container">
-      <el-form :model="queryParams" ref="queryForm" size="small" :inline="true" v-show="showSearch" label-width="68px">
-        <el-form-item label="岗位编码" prop="code">
-          <el-input v-model="queryParams.code" placeholder="请输入岗位编码" clearable @keyup.enter.native="handleQuery"/>
-        </el-form-item>
-        <el-form-item label="岗位名称" prop="name">
-          <el-input v-model="queryParams.name" placeholder="请输入岗位名称" clearable @keyup.enter.native="handleQuery"/>
-        </el-form-item>
-        <el-form-item label="状态" prop="status">
-          <el-select v-model="queryParams.status" placeholder="岗位状态" clearable>
-            <el-option v-for="dict in statusDictDatas" :key="parseInt(dict.value)" :label="dict.label" :value="parseInt(dict.value)"/>
-          </el-select>
-        </el-form-item>
-        <el-form-item>
-          <el-button type="primary" icon="el-icon-search" @click="handleQuery">搜索</el-button>
-          <el-button icon="el-icon-refresh" @click="resetQuery">重置</el-button>
-        </el-form-item>
-      </el-form>
-  
-      <el-row :gutter="10" class="mb8">
-        <el-col :span="1.5">
-          <el-button type="primary" plain icon="el-icon-plus" size="mini" @click="handleAdd"
-                     v-hasPermi="['system:post:create']">新增</el-button>
-        </el-col>
-        <el-col :span="1.5">
-          <el-button type="warning" icon="el-icon-download" size="mini" @click="handleExport" :loading="exportLoading"
-                     v-hasPermi="['system:post:export']">导出</el-button>
-        </el-col>
-        <right-toolbar :showSearch.sync="showSearch" @queryTable="getList"></right-toolbar>
-      </el-row>
-  
-      <el-table v-loading="loading" :data="postList">
-        <el-table-column label="岗位编号" align="center" prop="id" />
-        <el-table-column label="岗位编码" align="center" prop="code" />
-        <el-table-column label="岗位名称" align="center" prop="name" />
-        <el-table-column label="岗位排序" align="center" prop="sort" />
-        <el-table-column label="状态" align="center" prop="status">
-          <template v-slot="scope">
-            <dict-tag :type="DICT_TYPE.COMMON_STATUS" :value="scope.row.status"/>
-          </template>
-        </el-table-column>
-        <el-table-column label="创建时间" align="center" prop="createTime" width="180">
-          <template v-slot="scope">
-            <span>{{ parseTime(scope.row.createTime) }}</span>
-          </template>
-        </el-table-column>
-        <el-table-column label="操作" align="center" class-name="small-padding fixed-width">
-          <template v-slot="scope">
-            <el-button size="mini" type="text" icon="el-icon-edit" @click="handleUpdate(scope.row)"
-                       v-hasPermi="['system:post:update']">修改</el-button>
-            <el-button size="mini" type="text" icon="el-icon-delete" @click="handleDelete(scope.row)"
-                       v-hasPermi="['system:post:delete']">删除</el-button>
-          </template>
-        </el-table-column>
-      </el-table>
-  
-      <pagination v-show="total>0" :total="total" :page.sync="queryParams.pageNo" :limit.sync="queryParams.pageSize"
-                  @pagination="getList"/>
-  
-      <!-- 添加或修改岗位对话框 -->
-      <el-dialog :title="title" :visible.sync="open" width="500px" append-to-body>
-        <el-form ref="form" :model="form" :rules="rules" label-width="80px">
-          <el-form-item label="岗位名称" prop="name">
-            <el-input v-model="form.name" placeholder="请输入岗位名称" />
-          </el-form-item>
-          <el-form-item label="岗位编码" prop="code">
-            <el-input v-model="form.code" placeholder="请输入编码名称" />
-          </el-form-item>
-          <el-form-item label="岗位顺序" prop="sort">
-            <el-input-number v-model="form.sort" controls-position="right" :min="0" />
-          </el-form-item>
-          <el-form-item label="岗位状态" prop="status">
-            <el-radio-group v-model="form.status">
-              <el-radio v-for="dict in statusDictDatas" :key="parseInt(dict.value)" :label="parseInt(dict.value)">
-                {{dict.label}}</el-radio>
-            </el-radio-group>
-          </el-form-item>
-          <el-form-item label="备注" prop="remark">
-            <el-input v-model="form.remark" type="textarea" placeholder="请输入内容" />
-          </el-form-item>
-        </el-form>
-        <div slot="footer" class="dialog-footer">
-          <el-button type="primary" @click="submitForm">确 定</el-button>
-          <el-button @click="cancel">取 消</el-button>
-        </div>
-      </el-dialog>
-    </div>
-  </template>
-  
-  <script>
-  import { listPost, getPost, delPost, addPost, updatePost, exportPost } from "@/api/system/post";
-  
-  import {CommonStatusEnum} from '@/utils/constants'
-  import { getDictDatas, DICT_TYPE } from '@/utils/dict'
-  
-  export default {
-    name: "SystemPost",
-    data() {
-      return {
-        // 遮罩层
-        loading: true,
-        // 导出遮罩层
-        exportLoading: false,
-        // 显示搜索条件
-        showSearch: true,
-        // 总条数
-        total: 0,
-        // 岗位表格数据
-        postList: [],
-        // 弹出层标题
-        title: "",
-        // 是否显示弹出层
-        open: false,
-        // 查询参数
-        queryParams: {
-          pageNo: 1,
-          pageSize: 10,
-          code: undefined,
-          name: undefined,
-          status: undefined
+  <div class="app-container">
+    <el-form :model="queryParams" ref="queryForm" size="small" :inline="true" label-width="68px">
+      <el-form-item label="岗位编码" prop="code">
+        <el-input v-model="queryParams.code" placeholder="请输入岗位编码" clearable @keyup.enter.native="handleQuery" />
+      </el-form-item>
+      <el-form-item label="岗位名称" prop="name">
+        <el-input v-model="queryParams.name" placeholder="请输入岗位名称" clearable @keyup.enter.native="handleQuery" />
+      </el-form-item>
+      <el-form-item label="状态" prop="status">
+        <el-select v-model="queryParams.status" placeholder="岗位状态" clearable>
+          <el-option v-for="dict in this.getDictDatas(DICT_TYPE.COMMON_STATUS)" :key="parseInt(dict.value)"
+            :label="dict.label" :value="parseInt(dict.value)" />
+        </el-select>
+      </el-form-item>
+      <el-form-item>
+        <el-button type="primary" icon="el-icon-search" @click="handleQuery">搜索</el-button>
+        <el-button icon="el-icon-refresh" @click="resetQuery">重置</el-button>
+      </el-form-item>
+    </el-form>
+    <FullCalendar class="fullCalendar" ref="fullCalendar" :options="calendarOptions" />
+  </div>
+</template>
+
+
+<script>
+import FullCalendar from '@fullcalendar/vue'
+import dayGridPlugin from '@fullcalendar/daygrid'
+import interactionPlugin from '@fullcalendar/interaction'
+import timeGridPlugin from '@fullcalendar/timegrid'
+
+export default {
+  components: {
+    FullCalendar  // 像使用自定义组件一样使用
+  },
+  data() {
+    return {
+      // 查询参数
+      queryParams: {
+        pageNo: 1,
+        pageSize: 10,
+        code: undefined,
+        name: undefined,
+        status: undefined
+      },
+      calendarApi: null,
+      calendarOptions: {
+        plugins: [dayGridPlugin, interactionPlugin, timeGridPlugin], // 需要用哪个插件引入后放到这个数组里
+        initialDate: new Date(), // 日历第一次加载时显示的初始日期。可以解析为Date的任何职包括ISO8601日期字符串,例如"2014-02-01"。
+        initialView: 'dayGridMonth', // 日历加载时的初始视图,默认值为'dayGridMonth',可以为任何可用视图的值,如例如'dayGridWeek','timeGridDay','listWeek'
+        locale: 'zh-cn', // 设置日历的语言,中文为 “zh-cn”
+        firstDay: '1', // 设置每周的第一天,默认值取决于当前语言环境,该值为代表星期几的数字,且值必须为整数,星期日=0
+        weekNumberCalculation: 'ISO', // 指定"ISO"结果为ISO8601周数。指定"ISO"将firstDay的默认值更改为1(Monday)
+        buttonText: { // 文本将显示在headerToolbar / footerToolbar的按钮上。不支持HTML注入。所有特殊字符将被转义。
+          today: '今天',
+          month: '月',
+          week: '周',
+          day: '天'
         },
-        // 表单参数
-        form: {},
-        // 表单校验
-        rules: {
-          name: [
-            { required: true, message: "岗位名称不能为空", trigger: "blur" }
-          ],
-          code: [
-            { required: true, message: "岗位编码不能为空", trigger: "blur" }
-          ],
-          sort: [
-            { required: true, message: "岗位顺序不能为空", trigger: "blur" }
-          ]
+        headerToolbar: { // 在日历顶部定义按钮和标题。将headerToolbar选项设置为false不会显示任何标题工具栏。可以为对象提供属性start/center/end或left/center/right。这些属性包含带有逗号/空格分隔值的字符串。用逗号分隔的值将相邻显示。用空格分隔的值之间会显示一个很小的间隙。
+          right: 'prev,next today',
+          center: 'title',
+          left: 'dayGridMonth,dayGridWeek,dayGridDay'
         },
-  
-        // 枚举
-        CommonStatusEnum: CommonStatusEnum,
-        // 数据字典
-        statusDictDatas: getDictDatas(DICT_TYPE.COMMON_STATUS)
-      };
-    },
-    created() {
-      this.getList();
-    },
-    methods: {
-      /** 查询岗位列表 */
-      getList() {
-        this.loading = true;
-        listPost(this.queryParams).then(response => {
-          this.postList = response.data.list;
-          this.total = response.data.total;
-          this.loading = false;
-        });
-      },
-      // 取消按钮
-      cancel() {
-        this.open = false;
-        this.reset();
-      },
-      // 表单重置
-      reset() {
-        this.form = {
-          id: undefined,
-          code: undefined,
-          name: undefined,
-          sort: 0,
-          status: CommonStatusEnum.ENABLE,
-          remark: undefined
-        };
-        this.resetForm("form");
-      },
-      /** 搜索按钮操作 */
-      handleQuery() {
-        this.queryParams.pageNo = 1;
-        this.getList();
-      },
-      /** 重置按钮操作 */
-      resetQuery() {
-        this.resetForm("queryForm");
-        this.handleQuery();
-      },
-      /** 新增按钮操作 */
-      handleAdd() {
-        this.reset();
-        this.open = true;
-        this.title = "添加岗位";
-      },
-      /** 修改按钮操作 */
-      handleUpdate(row) {
-        this.reset();
-        const id = row.id
-        getPost(id).then(response => {
-          this.form = response.data;
-          this.open = true;
-          this.title = "修改岗位";
-        });
-      },
-      /** 提交按钮 */
-      submitForm: function() {
-        this.$refs["form"].validate(valid => {
-          if (valid) {
-            if (this.form.id !== undefined) {
-              updatePost(this.form).then(response => {
-                this.$modal.msgSuccess("修改成功");
-                this.open = false;
-                this.getList();
-              });
-            } else {
-              addPost(this.form).then(response => {
-                this.$modal.msgSuccess("新增成功");
-                this.open = false;
-                this.getList();
-              });
-            }
+        eventTimeFormat: { // 在每个事件上显示的时间的格式
+          hour: 'numeric',
+          minute: '2-digit',
+          hour12: false
+        },
+        events: [ // 将在日历上显示的事件对象, events 可以是数组、json、函数。具体可以查看官方文档
+          {
+            title: '标题',
+            start: '2024-07-17 12:00:00',
+            end: '2024-07-17 15:00:00', // 这里要注意,end为可选参数,无end参数时该事件仅在当天展示
+            backgroundColor: '#FDEBC9', // 该事件的背景颜色
+            borderColor: '#FDEBC9', // 该事件的边框颜色
+            textColor: '#F9AE26' // 该事件的文字颜色
+          },
+        ],
+        customButtons: { // 定义可在headerToolbar / footerToolbar中使用的自定义按钮
+          today: {
+            text: '今天', // 按钮的展示文本
+            click: this.todayClick // 点击按钮触发的事件,这里要注意的是当按钮绑定了事件之后该按钮原本自带的事件将会失效
+          },
+          next: {
+            click: this.nextClick
+          },
+          prev: {
+            click: this.prevClick
           }
-        });
-      },
-      /** 删除按钮操作 */
-      handleDelete(row) {
-        const ids = row.id;
-        this.$modal.confirm('是否确认删除岗位编号为"' + ids + '"的数据项?').then(function() {
-            return delPost(ids);
-          }).then(() => {
-            this.getList();
-            this.$modal.msgSuccess("删除成功");
-        }).catch(() => {});
-      },
-      /** 导出按钮操作 */
-      handleExport() {
-        const queryParams = this.queryParams;
-        this.$modal.confirm('是否确认导出所有岗位数据项?').then(() => {
-            this.exportLoading = true;
-            return exportPost(queryParams);
-          }).then(response => {
-            this.$download.excel(response, '岗位数据.xls');
-            this.exportLoading = false;
-        }).catch(() => {});
+        },
+        eventClick: this.handleDateClick, // 点击事件时,触发该回调
+        eventMouseEnter: this.handleMouseEnter, // 鼠标悬停在事件上时,触发该回调
+        eventMouseLeave: this.handleMouseLeave, // 鼠标移除时,触发该回调
+        dateClick: this.handleDateClick // 当用户单击日期或时间时,触发该回调,触发此回调,您必须加载interaction插件
       }
     }
-  };
-  </script>
-  
+  },
+  mounted() {
+    // 这里有两点要注意,想要调用插件的方法,要在组件上设置ref
+    // 并且在组件未加载的时候this.$refs中是没有fullCalendar的,所以未加载的时候调用方法会报错
+    this.calendarApi = this.$refs.fullCalendar.getApi()
+  },
+  methods: {
+    /** 搜索按钮操作 */
+    handleQuery() {
+      this.queryParams.pageNo = 1;
+      this.getList();
+    },
+    /** 重置按钮操作 */
+    resetQuery() {
+      this.resetForm("queryForm");
+      this.handleQuery();
+    },
+    handleDateClick(dateClickInfo) {
+      console.log(dateClickInfo)
+    },
+    handleMouseEnter(mouseEnterInfo) {
+      console.log(mouseEnterInfo.event.startStr)
+      // 提示:mouseEnterInfo.event.startStr 可以获取当前事件的开始事件
+    },
+    handleMouseLeave(mouseEnterInfo) {
+      console.log(mouseEnterInfo)
+    },
+    todayClick(mouseEvent, htmlElement) {
+      calendarApi.today() // 将日历移动到当前日期。
+      calendarApi.getDate() // 返回日期的日历的当前日期
+    },
+    nextClick(mouseEvent, htmlElement) {
+      calendarApi.next() // 将日历向前移动一步(例如,一个月或一周)。
+      // 如果dayGridMonth查看日历,则将日历向前移动一个月。
+      // 如果日历位于dayGridWeek或中timeGridWeek,则将日历向前移动一周。
+      // 如果日历位于dayGridDay或中timeGridDay,则将日历向前移动一天。
+    },
+    prevClick(mouseEvent, htmlElement) {
+      calendarApi.prev() // 将日历后退一步(例如,一个月或一周)。
+      // 如果dayGridMonth查看日历,则将日历后移一个月。
+      // 如果日历位于dayGridWeek或中timeGridWeek,则将日历后移一周。
+      // 如果日历位于dayGridDay或中timeGridDay,则将日历移回一天。
+    }
+  }
+}
+</script>