高级页面
高级页面通过拖拽、布局组件,并进行相关属性配置即可快速搭建应用。高级页面主要用于开发应用中较复杂的前端页面,例如包含图片、图表、视频、地图等元素的页面。
高级页面提供了常用组件,组件包含了预置的样式,并封装了基础事件代码,实现了开箱即用。
场景描述
本节以使用智能排班模型BO中工作日历信息表(ISDP__workCalendarInfo__CST)和工作日历管理开放的接口开发一个标高级页面(工作日历管理)为例,描述高级页面的开发过程。
工作日历管理,支持按年设置整年每个月份的工作日和非工作,同时支持单个调整工作日、非工作和节假日。
高级页面中预置的组件,无法满足页面要求,需要自定义开发组件。
操作步骤
- 下载组件模板。
系统预置了以下几种组件模板:
组件模板名称
功能
widgetVueTemplate
当自定义组件需要使用Vue库时,请选用该模板。
widgetPropertyTemplate
当自定义组件需要通过自定义属性栏配置属性时,请选用该模板。
widgetActionTemplate
自定义组件需要添加动作属性时,请选用该模板。
widgetEventTemplate
当自定义组件需要添加事件属性时,请选用该模板。
widgetBridgeTemplate
当自定义组件需要通过桥接器调用后台数据时,请选用该模板。
widgetPageMacroTemplate
当需要使用页面宏来存储变量时,请选用该模板。
- 在左侧导航栏中,单击,选择“高级页面 > 组件模板”。
- 根据选择模板(widgetBridgeTemplate),在组件模板详情页中单击“下载”按钮,在“下载组件模板”弹窗中输入组件名称(例如:CalendarInfoManagement),单击“保存”按钮即可。
图2 选择模板
图3 下载组件模板
若选择“下载原始模板按钮”,下载到本地的包中组件名称不会被修改。
- 将下载到本地的组件包进行解压,使用开发工具进行开发。
此处以CalendarInfoManagement这个组件为例,说明zip包中的文件以及文件的功能。
文件名
文件说明
CalendarInfoManagement.js
整个组件的渲染核心JS,在组件编辑状态和页面最终的发布运行态都会被加载执行。主要包含2个预置的方法init和render。
- init方法主要包含组件渲染需要初始化数据的入口函数。
- render方法负责整个组件渲染的逻辑方法。
CalendarInfoManagement.editor.js
负责组件在编辑状态时需要渲染的界面和逻辑。*.editor.js只在组件编辑状态被加载。主要包含2个方法。
- propertiesConfig方法主要负责组件配置页面中的property配置逻辑。
- create方法仅在组件首次被创建时调用一次。
CalendarInfoManagement.css
组件自身涉及的css文件,可以在此编写,需要是引入的外部第三方的css,则可以通过lib的方式引入。不需要将外部的css拷贝到此文件中。
CalendarInfoManagement.ftl
需要在服务端提前渲染的部分可以写在此文件中。相当于HTML文件,负责样式展示。
packageinfo.json
组件的元数据描述文件,主要包含组件的名字、描述信息以及作者信息。这里还可以配置本地路径,供本地调测使用。
- 新增messages-zh/messages-en.json文件(功能:组件的国际化资源文件,用于配置多语言),本模板中没有,新增这2个文件。
- messages-zh.json,内容:
{ "zh-CN": { "key" : "value" } }
- messages-en.json,内容:
{ "en-US": { "key" : "value" } }
- messages-zh.json,内容:
- 修改“packageinfo.json”,增加组件必要依赖,例如多语言文件、库文件等。
例如本组件需要依赖库文件Vue、VueI18n、Element,其中库文件名称和版本号需要在App开发界面左侧列表单击,选择“高级页面 > 库”中进行获取。
增加如下加粗代码:
{ "widgetApi": [ { "name": "CalendarInfoManagement" } ], "widgetDescription": "日历配置", "authorName": "XXX", "localFileBasePath": "", "i18n": [ { "name": "messages-en" }, { "name": "messages-zh" } ], "requires": [ { "name": "global_Vue", "version": "100.7" }, { "name": "global_VueI18n", "version": "100.7" }, { "name": "global_Element", "version": "100.8" } ] }
- 开发JS代码,修改“CalendarInfoManagement.js”。
JS代码主要实现以下几个业务功能:
- 通过接口“queryWorkCalendarInfo”实现查询工作日历数据,展示在工作日历页面。
- 通过接口“batchAddWorkCalendarInfo”实现保存对工作日历数据的配置。
- 通过接口“getSysParameter”和“setParameter”实现获取和修改系统参数的值。
var CalendarInfoManagement = StudioWidgetWrapper.extend({ /* * Triggered when initializing a widget and will have the code that invokes rendering of the widget * setParentContainer(JQueryParentContainerDOM) - binds event to this container * setItemContainer(JQueryItemContainerDOM) - binds studio item events for respective item containers * bindEvents() - binds the studio event to this widget */ init: function () { var thisObj = this; thisObj._super.apply(thisObj, arguments); thisObj.render(); if ((typeof (Studio) != "undefined") && Studio) { } }, /* * Triggered from init method and is used to render the widget */ render: function () { var thisObj = this; var widgetProperties = thisObj.getProperties(); var elem = thisObj.getContainer(); var items = thisObj.getItems(); var connectorProperties = thisObj.getConnectorProperties(); /* * API to get base path of your uploaded widget API file */ var widgetBasePath = thisObj.getWidgetBasePath(); if (elem) { var containerDiv = $(".scfClientRenderedContainer", elem); if (containerDiv.length) { $(containerDiv).empty(); } else { containerDiv = document.createElement('div'); containerDiv.className = "scfClientRenderedContainer"; $(elem).append(containerDiv); } var i18n = HttpUtils.getI18n({ locale: HttpUtils.getLocale(), messages: thisObj.getMessages() }); thisObj.vm = new Vue({ el: $("#CalendarInfoManagement", elem)[0], i18n: i18n, data: { calendarLoading: true, activeNames: ['1', '2'], ruleForm: { type: [] }, year: new Date().getFullYear(), weeks: ["一", "二", "三", "四", "五", "六", "日"], yearData: [], typeDateList: [], recordDataList: [] }, watch: { 'ruleForm.type'(val, oldVal) { let typeDateList = []; for (let i = 0; i < val.length; i++) { typeDateList.push(this.formatDateType(val[i])); } this.typeDateList = typeDateList; this.typeDateList.sort((a, b) => a - b); let oldList = []; for (let i = 0; i < oldVal.length; i++) { oldList.push(this.formatDateType(oldVal[i])); } oldList.sort((a, b) => a - b); if (this.yearData.length > 0) { this.yearData.map((yItem, yIndex) => { yItem.monthData.map((mItem, mIndex) => { mItem.map((dItem, dIndex) => { if (dItem.type == 0) { // 如果现在勾选的多选组里有,但是旧的多选组里没有,说明是新选中的工作日 if (this.typeDateList.includes(dItem.week) && !oldList.includes(dItem.week)) { dItem.dayType = 'W'; } // 如果现在勾选的多选组里没有,但是旧的多选组里有,说明是新取消的工作日 if (!this.typeDateList.includes(dItem.week) && oldList.includes(dItem.week)) { dItem.dayType = 'R'; } } }) }) }); } } }, async created() { await ISDPBaseSDK.initISDPLogin(true, () => { this.init(); }) // this.init(); }, methods: { // 初始化方法 async init() { await this.getSysParameter(['ISDP__workDate']); let typeList = []; for (let i = 0; i < this.typeDateList.length; i++) { typeList.push(this.formatDateNum(this.typeDateList[i])); } this.ruleForm.type = typeList; this.queryData(); }, // 查询工作日历数据 queryData() { let _this = this; let params = { pageStart: 0, pageSize: 500, deleteFlag: 0, year: String(this.year) } let connector = thisObj.getConnectorInstanceByName('queryWorkCalendarInfo'); if (connector) { connector.query(params).done(res => { if (res && res.resp && res.resp.code == "0" && res.data && res.data.records) { _this.recordDataList = res.data.records || []; _this.setYearMonthInfos(); } else { _this.$message.error('查询工作日历数据失败') } _this.calendarLoading = false; }).fail(function (error) { let msg = error.response.resMsg ? error.response.resMsg : '请求失败,请联系管理员' _this.$message.error(msg) _this.calendarLoading = false; }) } }, saveData() { // 保存工作日系统参数 let _this = this; _this.calendarLoading = true; let param = { name: 'ISDP__workDate', value: this.typeDateList ? this.typeDateList.join(';') : '' } this.setParameter(param); let yearData = this.yearData; let serveDate = []; yearData.map((yItem, yIndex) => { yItem.monthData.map((mItem, mIndex) => { mItem.map((dItem, dIndex) => { if (dItem.type == 0) { serveDate.push({ basicInfo: { date: this.timestampToDate(dItem.date), workdaysFlag: dItem.dayType, } }) } }) }) }); let connector = thisObj.getConnectorInstanceByName('batchAddWorkCalendarInfo'); if (connector) { connector.query({ workCalendarInfoList: serveDate }).done(res => { if (res && res.resp && res.resp.code == "0") { _this.$message.success('保存成功') } else { _this.$message.error('保存失败') } _this.calendarLoading = false; }).fail(function (error) { let msg = error.response.resMsg ? error.response.resMsg : '请求失败,请联系管理员' _this.$message.error(msg) _this.calendarLoading = false; }) } }, // 手动单独修改某日的类型 changeDayType(d, str, yIndex, mIndex, dIndex) { d.dayType = str; this.$refs['dateTypeBox' + yIndex + mIndex + dIndex][0].showPopper = false; }, preYear() { this.year -= 1; this.ruleForm.type = []; this.init(); }, nextYear() { this.year += 1; this.ruleForm.type = []; this.init(); }, getCellColor(d) { let color = d.type == -1 ? '#c0c4cc' : (d.type == 1 ? '#c0c4cc ' : '') return color; }, getBackground(d) { let bgColor = '' if (d.dayType == 'W') { //工作日 bgColor = '#B1D8FF'; } else if (d.dayType == 'R') { //休息日 bgColor = '#FFE6B5'; } else if (d.dayType == 'H') { //假日 bgColor = '#E1E1E1'; } return bgColor; }, setYearMonthInfos() { this.yearData = []; for (let i = 0; i < 12; i++) { let temp = { month: i + 1, monthData: this.generateMonth(new Date(this.year + '-' + (i + 1) + '-01 00:00:00')) } this.yearData.push(temp); } // 如果该年数据没有存库,切换后默认调保存接口存储下当前根据工作设定数组展示出来的数据 if (this.recordDataList.length === 0) { this.autoSaveData(); } }, // 如果该年数据没有存库,切换后默认调保存接口存储下当前根据工作设定数组展示出来的数据 autoSaveData() { let _this = this; let yearData = this.yearData; let serveDate = []; yearData.map((yItem, yIndex) => { yItem.monthData.map((mItem, mIndex) => { mItem.map((dItem, dIndex) => { if (dItem.type == 0) { serveDate.push({ basicInfo: { date: this.timestampToDate(dItem.date), workdaysFlag: dItem.dayType, } }) } }) }) }); let connector = thisObj.getConnectorInstanceByName('batchAddWorkCalendarInfo'); if (connector) { connector.query({ workCalendarInfoList: serveDate }).done(res => { }).fail(function (error) { }) } }, generateMonth(date) { date.setDate(1) // 星期日为0(默认展示为:星期日 - 星期6;修改展示为:星期1 - 星期日) let weekStart = date.getDay() == 0 ? 6 : date.getDay() - 1; let endDate = new Date(date.getFullYear(), date.getMonth() + 1, 0) let dayEnd = endDate.getDate() let weeEnd = endDate.getDay() let milsStart = date.getTime() let dayMils = 24 * 60 * 60 * 1000 let milsEnd = endDate.getTime() + dayMils let monthDatas = [] let current; // 上个月的几天 for (let i = 0; i < weekStart; i++) { current = new Date(milsStart - (weekStart - i) * dayMils) monthDatas.push({ type: -1, date: current, fullYear: current.getFullYear(), month: current.getMonth() + 1, day: current.getDate(), week: current.getDay(), dayType: '' }) } // 当前月 for (let i = 0; i < dayEnd; i++) { current = new Date(milsStart + i * dayMils) let dayType = 'R'; if (this.recordDataList.length > 0) { for (let j = 0; j < this.recordDataList.length; j++) { let tempDay = this.timestampToDate(current); if (this.recordDataList[j]['ISDP__date__CST'] == tempDay) { dayType = this.recordDataList[j]['ISDP__workdaysFlag__CST'] break; } } } else { if (this.typeDateList.includes(current.getDay())) { dayType = 'W'; } if (!this.typeDateList.includes(current.getDay())) { dayType = 'R'; } } monthDatas.push({ type: 0, date: current, fullYear: current.getFullYear(), month: current.getMonth() + 1, day: current.getDate(), week: current.getDay(), dayType: dayType }) } // 下个月的几天 for (let i = 0; i < (7 - weeEnd); i++) { current = new Date(milsEnd + i * dayMils) monthDatas.push({ type: 1, date: current, fullYear: current.getFullYear(), month: current.getMonth() + 1, day: current.getDate(), week: current.getDay(), dayType: '' }) } let monthData = []; for (let i = 0; i < monthDatas.length; i++) { let mi = i % 7; if (mi == 0) { monthData.push([]) } monthData[Math.floor(i / 7)].push(monthDatas[i]) } // 少于6行,补足6行 if (monthData.length <= 5) { milsStart = current.getTime() let lastLine = [] for (let i = 1; i <= 7; i++) { current = new Date(milsStart + i * dayMils) lastLine.push({ type: 1, date: current, fullYear: current.getFullYear(), month: current.getMonth() + 1, day: current.getDate(), week: current.getDay(), dayType: '' }) } monthData.push(lastLine) } return monthData; }, //时间戳转时间格式 timestampToDate(timestamp) { if (timestamp && timestamp !== '') { var date = new Date(timestamp);//时间戳为10位需*1000,时间戳为13位的话不需乘1000 var Y = date.getFullYear() + '-'; var M = (date.getMonth() + 1 < 10 ? '0' + (date.getMonth() + 1) : date.getMonth() + 1) + '-'; var D = (date.getDate() < 10 ? '0' + date.getDate() : date.getDate()); return Y + M + D; } else { return ''; } }, // 周一到周五转换为数字 formatDateType(str) { let num = 0; switch (str) { case '周一': num = 1; break; case '周二': num = 2; break; case '周三': num = 3; break; case '周四': num = 4; break; case '周五': num = 5; break; case '周六': num = 6; break; case '周日': num = 0; break; } return num; }, // 数字转换为周一到周五 formatDateNum(num) { let str = '周日'; switch (num) { case 1: str = '周一'; break; case 2: str = '周二'; break; case 3: str = '周三'; break; case 4: str = '周四'; break; case 5: str = '周五'; break; case 6: str = '周六'; break; case 0: str = '周日'; break; } return str; }, // 获取系统参数 getSysParameter(paramList) { return new Promise((resolve) => { let _this = this; let connector = thisObj.getConnectorInstanceByName('getSysParameter'); let params = { sysparamsNameList: paramList } if (connector) { connector.query(params).done(res => { if (res.resp.code == "0" && res && res.data && res.data.result) { if (res.data.result['ISDP__workDate'] && res.data.result['ISDP__workDate'] != '') { _this.typeDateList = res.data.result['ISDP__workDate'].split(';').map(Number); } } else { _this.$message.error('获取系统参数失败') } resolve(''); }).fail(function (error) { let msg = error.response.resMsg ? error.response.resMsg : '请求失败,请联系管理员' _this.$message.error(msg) resolve(''); }) } }) }, // 修改系统参数 setParameter(param) { let _this = this; let connector = thisObj.getConnectorInstanceByName('setParameter'); let params = { name: param.name, value: param.value } if (connector) { connector.query(params).done(res => { if (res && res.resp && res.resp.code && res.resp.code == "0") { } else { _this.$message.error('修改系统参数失败') } }).fail(function (error) { let msg = error.response.resMsg ? error.response.resMsg : '请求失败,请联系管理员' _this.$message.error(msg) }) } }, // 提取两个数组中不同的 filterArr(arr1, arr2) { const arr = [...arr1, ...arr2]; const newArr = arr.filter((t) => { return !(arr1.includes(t) && arr2.includes(t)); }); return newArr; }, } }) } /* * API to bind global events to the item DOM, it should not be deleted if there will some events to trigger in this widget. */ thisObj.sksBindItemEvent(); /* * API to refresh the previously bound events when a resize or orientation change occurs. */ $(window).resize(function () { thisObj.sksRefreshEvents(); }); }, });
- 开发ftl代码,修改“CalendarInfoManagement.ftl”。
ftl代码为该功能页面呈现的渲染代码,主要采用element组件实现。
具体代码如下:
<div id="CalendarInfoManagement" v-cloak v-loading="calendarLoading"> <div class="leftBox" v-if="yearData.length > 0"> <div class="cal_con"> <div class="cal_header"> <div class="cal_h_left"> <div class="cal_h_btn" @click="preYear" style="margin-right:10px;"> <i class="el-icon-d-arrow-left"></i> </div> </div> <div> <span class="cal_h_time">{{ year }} 年 </span> </div> <div class="cal_h_left"> <div class="cal_h_btn" @click="nextYear"> <i class="el-icon-d-arrow-right"></i> </div> </div> </div> <div class="leftContent"> <div class="cal_month" v-for="(yItem, yIndex) in yearData" :key="yIndex"> <div class="cal_m_title">{{year}}年{{yItem.month}}月</div> <div class="cal_m_weeks"> <span class="cal_m_day_cell">W</span> <span v-for="w in weeks" :key="w" class="cal_m_day_cell">{{w}}</span> </div> <div class="cal_m_days"> <div v-for="(ds, mIndex) in yItem.monthData" :key="mIndex" style="width: 100%;"> <div class="cal_m_day_line"> <div class="cal_m_day_cell">W{{mIndex+1}}</div> <div v-for="(d, dIndex) in ds" :key="d.day" class="cal_m_day_cell" :style="{color: getCellColor(d), background: getBackground(d)}"> <el-popover v-if="d.type == 0" :ref="'dateTypeBox'+yIndex+mIndex+dIndex" placement="bottom-start" popper-class="dateTypeBox" trigger="click" width="100"> <div class="smallItemBox" @click="changeDayType(d, 'W', yIndex, mIndex, dIndex)"> <div class="smallBox" style="background:#B1D8FF;"></div>工作日 </div> <div class="smallItemBox" @click="changeDayType(d, 'R', yIndex, mIndex, dIndex)"> <div class="smallBox" style="background:#FFE6B5;"></div>休息日 </div> <div class="smallItemBox" @click="changeDayType(d, 'H', yIndex, mIndex, dIndex)"> <div class="smallBox" style="background:#E1E1E1;"></div>节假日 </div> <div slot="reference">{{ d.day }}</div> </el-popover> <div v-if="d.type != 0">{{ d.day }}</div> </div> </div> </div> </div> </div> </div> </div> </div> <div class="rightBox" v-if="yearData.length > 0"> <el-collapse v-model="activeNames" class="ruleCollapse"> <el-collapse-item title="工作日设定" name="1"> <el-form :model="ruleForm" ref="ruleForm" label-width="100px" class="ruleForm"> <el-form-item label="工作日" prop="type"> <el-checkbox-group v-model="ruleForm.type"> <el-checkbox label="周一" name="type"></el-checkbox> <el-checkbox label="周二" name="type"></el-checkbox> <el-checkbox label="周三" name="type"></el-checkbox> <el-checkbox label="周四" name="type"></el-checkbox> <el-checkbox label="周五" name="type"></el-checkbox> <el-checkbox label="周六" name="type"></el-checkbox> <el-checkbox label="周日" name="type"></el-checkbox> </el-checkbox-group> </el-form-item> </el-form> </el-collapse-item> <el-collapse-item title="自定义状态" name="2"> <div class="statusInfo"> <div class="statusBox"> <div class="bgBox" style="background:#B1D8FF;"></div>工作日 </div> <div class="statusBox"> <div class="bgBox" style="background:#FFE6B5;"></div>休息日 </div> <div class="statusBox"> <div class="bgBox" style="background:#E1E1E1;"></div>节假日 </div> <div class="tip"><i class="el-icon-warning-outline"></i> 如果需要手动调整日期类型,可点击左侧日期直接选择更改</div> </div> </el-collapse-item> </el-collapse> </div> <div class="btm_operation"> <el-button type="primary" size="small" @click="saveData">保存</el-button> <!-- <el-button size="small">取消</el-button> --> </div> </div>
- 开发组件在编辑状态时需要渲染的界面和逻辑,修改“CalendarInfoManagement.editor.js”。
在“propertiesConfig”方法中修改“type”为“connectorV2”属性值,使得“name”取值和“CalendarInfoManagement.js”中“thisObj.getConnectorInstanceByName”的取值保持一致。
具体代码如下:
CalendarInfoManagement = CalendarInfoManagement.extend({ /* * Config to define Widget Properties */ propertiesConfig:[{ config: [ { "type": "connectorV2", "name": "getSysParameter", "model": "ViewModel", "label": "获取系统参数", "value": "" }, { "type": "connectorV2", "name": "setParameter", "model": "ViewModel", "label": "修改系统参数", "value": "" }, { "type": "connectorV2", "name": "queryWorkCalendarInfo", "model": "ViewModel", "label": "查询工作日历数据", "value": "" }, { "type": "connectorV2", "name": "batchAddWorkCalendarInfo", "model": "ViewModel", "label": "批量修改工作日历数据", "value": "" }, ] }], /* * Triggered when the user Creates a new widget and used to initialize the widget properties */ create : function(cbk) { if(cbk) { this._super(); cbk(); } } }); var params = {}; Studio.registerWidget("CalendarInfoManagement", "CalendarInfoManagement", params);
- 开发css代码,修改“CalendarInfoManagement.css”,实现CSS样式。
具体代码如下:
[v-cloak]{ display: none } #CalendarInfoManagement { display: flex; background-color: #f5f5f5; height: 100%; } #CalendarInfoManagement .leftBox{ width: calc(100% - 537px); margin-right: 17px; height: calc(100% - 48px); padding-left: 10px; background-color: #fff; } #CalendarInfoManagement .leftContent{ overflow-y: auto; height: calc(100% - 64px); } #CalendarInfoManagement .rightBox{ width: 520px; height: calc(100% - 48px); background-color: #fff; padding: 20px; } #CalendarInfoManagement .ruleForm{ margin: 0; } #CalendarInfoManagement .ruleForm .el-form-item__label{ line-height: 32px; } #CalendarInfoManagement .ruleForm .el-form-item{ margin-bottom: 0 !important; } #CalendarInfoManagement .ruleCollapse .el-collapse-item__content{ padding-bottom: 0; } #CalendarInfoManagement .el-collapse.ruleCollapse{ border: none; } #CalendarInfoManagement .el-collapse.ruleCollapse .el-collapse-item{ position: relative; } #CalendarInfoManagement .el-collapse.ruleCollapse .el-collapse-item .el-collapse-item__header{ padding-left: 16px; border-bottom: none; } #CalendarInfoManagement .el-collapse.ruleCollapse .el-collapse-item .el-collapse-item__arrow{ position: absolute; top: 18px; left: 0; z-index: 1; } #CalendarInfoManagement .el-collapse.ruleCollapse .el-collapse-item__wrap{ border-bottom: none; } #CalendarInfoManagement .statusInfo{ text-align: center; } #CalendarInfoManagement .statusBox { margin-right: 48px; font-size: 14px; line-height: 24px; display: inline-block; } #CalendarInfoManagement .statusBox .bgBox{ width: 24px; height: 24px; border-radius: 4px; display: inline-block; vertical-align: middle; margin-right: 8px; } #CalendarInfoManagement .statusBox:last-child{ margin-right: 0; } #CalendarInfoManagement .statusInfo .tip{ font-size: 14px; color: #333; line-height: 20px; padding: 15px 0; } .el-popper.dateTypeBox{ margin-top: 1px; min-width: 100px; padding: 0; } .smallItemBox{ padding: 0 12px; font-size: 14px; line-height: 32px; cursor: pointer; } .smallItemBox:hover{ background-color: #f5f5f5; } .smallItemBox .smallBox{ width: 12px; height: 12px; border-radius: 2px; display: inline-block; vertical-align: middle; margin-right: 8px; } /**底部按钮信息*/ #CalendarInfoManagement .btm_operation { position: fixed; display: -webkit-box; display: -ms-flexbox; display: flex; -webkit-box-pack: end; -ms-flex-pack: end; justify-content: flex-end; z-index: 10; bottom: 0; width: 100%; background: #fff; opacity: 1; padding-top: 8px; padding-bottom: 8px; padding-right: 24px; -webkit-box-shadow: 2px -2px 6px #d9d9d9; box-shadow: 2px -2px 6px #d9d9d9; border-top: none; } /* 日历组件开始 */ .cal_con { width: 100%; height: 100%; -webkit-user-select: none; -moz-user-select: none; -ms-user-select: none; user-select: none; color: #606266; background: #fff; border-radius: 6px; } .cal_con .cal_header { padding: 30px 15px 30px 5px; font-size: 24px; line-height: 24px; display: flex; justify-content: space-between; justify-items: center; color: #191919; } .cal_con .cal_header .cal_h_time { /* cursor: pointer; */ font-weight: bold; } .cal_con .cal_header .cal_h_left { height: 100%; display: flex; } .cal_con .cal_header .cal_h_left .cal_h_btn { height: 100%; cursor: pointer; font-size: 24px; font-weight: bold; } .cal_con .cal_header .cal_h_left .cal_h_l_icon { height: 8px; width: 12px; margin: 8px auto; } .cal_con .cal_month { font-size: 12px; text-align: center; height: 225px; margin: 0 5px 10px 5px; width: calc(25% - 12px); display: inline-block; border: 1px solid #d5d5d5; border-radius: 4px; padding-bottom: 5px; } .cal_con .cal_month .cal_m_title{ text-align: center; font-size: 16px; color: #191919; line-height: 20px; padding-top: 10px; font-weight: bold; } .cal_con .cal_month .cal_m_weeks { padding: 8px 0 0 0; display: flex; justify-content: center; justify-items: center; } .cal_con .cal_month .cal_m_day_cell { width: 30px; height: 24px; line-height: 24px; cursor: pointer; position: relative; margin: 0 1px; } .cal_con .cal_month .cal_m_day_cell.dayBg1{ background-color: #B1D8FF; } .cal_con .cal_month .cal_m_day_cell.dayBg2{ background-color: #FFE6B5; } .cal_con .cal_month .cal_m_day_cell.dayBg3{ background-color: #E1E1E1; } .cal_con .cal_month .cal_m_days { height: calc(100% - 62px); display: flex; justify-content: center; justify-items: center; align-items: center; flex-wrap: wrap; } .cal_con .cal_month .cal_m_day_line { width: 100%; display: flex; justify-content: center; justify-items: center; align-items: center; border-radius: 10px; } /* 日历组件结束 */
- 上传自定义组件。
- 创建页面。
- 开发页面。
- 预览页面。