跳到主要内容

自定义页面结合日历图实现任务看板

1. 使用场景

本例介绍一下在宜搭自定义页面中如何实现【日视图】及【周视图】的任务看板。

2. 实现功能

2.1. 创建页面存储任务及任务执行人

2.1.1. 任务录入

流程页面,在当前页发布任务详情数据;

2.1.2. 任务执行人

流程页面,录入任务执行人基础数据;

2.2. 创建自定义页面

2.3. 配置数据源及变量

2.3.1. 配置远程数据源

获取任务/任务执行人,接口配置如下图:

`/dingtalk/web/${window.pageConfig.appType || window.g_config.appKey}/query/formProcInstData/getInstanceDatasLight.json`

【任务录入】发起,接口配置如下图:

参考文档:流程发起

`/${window.pageConfig.appType || window.g_config.appKey}/v1/process/startInstance.json`

2.4. 配置变量

2.4.1. 当前视图类型

2.4.2. 任务执行人数据

2.4.3. 任务接收人查询参数

2.4.4. 任务查询参数

2.4.5. 每页实例数

2.4.6. 当前页码

2.4.7. 加载状态

2.4.8. 头部时间轴(周一至周日)数据

2.4.9. 「日视图」任务时间单元格数据

2.4.10. 「日视图」任务单元格时间刻度

2.4.11. 「周视图」任务单元格时间刻度

2.4.12. 「周视图」任务时间单元格数据

2.4.13. 任务日期查询参数

2.4.14. 任务单元格时间刻度类型

2.4.15. 任务详情数据

2.4.16. 日历图数据

2.4.17. 「日历」图中日期选择查询参数

this.utils.formatter('date',Date.now(),'YYYY-M-D')

2.4.18. 「日历」图显示年份

2.4.19. 「日历」图显示月份

2.5. 头部切换面板配置

2.5.1. 通过自定义样式类,将任务的状态渲染成不同的颜色呈现说明

任务为「进行中」,绑定「running」;

任务为「已完成」,绑定「finish」;

页面属性 - 样式,配置任务在不同状态下样式,如下图:

2.5.2. 视图类型切换,默认【日视图】,绑定回调事件,渲染不同类型的任务视图

通过绑定自定义样式类,显示任务视图选中状态;

state.boardType === 'day' ? 'boardTypeSelected' : ''

选中状态样式配置,如下图:

state.boardType === 'week' ? 'boardTypeSelected' : ''

点击「更多」,配置回调事件;

// 切换面板显示类型
export function onBoardTypeChange() {
const { type } = this.params;
if (type === 'much') {
// 更多--跳转到【任务报表】查看任务数据
this.utils.router.push('/alibaba/web/APP_U3S2ETH1VNEUVT5H0IM8/report/vigoTopicview?isPreview=true&topicId=8770692&formUuid=REPORT-S9866D91J35FS450FVDK86VZULXJ232B6K6OLIQ', {}, true, true);
return;
}
const { boardType } = this.state;
if (type === boardType) {
return;
}
this.setState({
boardType: type,
});
this.getDateList();
this.onSubmit();//执行筛选框搜索
}

2.5.3. 切换时间类型,渲染不同类型的时间cell

默认时间类型:8-22;通过绑定自定义样式类,渲染时间类型选中状态;

state.dateType === '8-22' ? 'switchSelected' : ''

配置动作面板中8-22时间类型参数

时间类型-全天

state.dateType === '8-22' ? '' : 'switchSelected'

时间类型切换绑定回调事件,如下图:


// 切换日期类型
export function onDateTypeChange() {
const { type } = this.params;
const { dateType } = this.state;
if (type === dateType) {
return;
}
this.setState({
dateType: type,
});
this.getDateList();
}

2.6. 头部时间轴渲染

「页面JS」头部时间轴数据获取

// 创建头部时间轴
export function getDateLine(startTimeCurrent = Date.now()) {
const dayCount = 7; // 显示 7 天
const dateLine = [];
const weekChinese = ['周一', '周二', '周三', '周四', '周五', '周六', '周日'];
const startTimeWeekNum = new Date(startTimeCurrent).getDay() === 0 ? 7 : new Date(startTimeCurrent).getDay();
for (let i = 0; i < dayCount; i++) {
const timeCurrent = i <= startTimeWeekNum ? (startTimeCurrent - (startTimeWeekNum - (i + 1)) * 24 * 3600000) :
(startTimeCurrent + ((i + 1) - startTimeWeekNum) * 24 * 3600000);
dateLine.push({
isToday: this.utils.formatter('date', timeCurrent, 'YYYYMMDD') ===
this.utils.formatter('date', Date.now(), 'YYYYMMDD'),
isWeekend: new Date(timeCurrent).getDay() === 0 || new Date(timeCurrent).getDay() === 6,
year: new Date(timeCurrent).getFullYear(),
month: new Date(timeCurrent).getMonth() + 1,
day: new Date(timeCurrent).getDate(),
dateString: this.utils.formatter('date', timeCurrent, 'YYYY-MM-DD'),
weekNum: new Date(timeCurrent).getDay(),
weekString: weekChinese[(new Date(timeCurrent).getDay() === 0 ? 6 : new Date(timeCurrent).getDay() - 1)],
});
}
this.setState({
dateLine,
selectedDay: dateLine[startTimeWeekNum - 1],
});
}

头部时间轴数据源绑定,如下图:

渲染日期

将日期为「周六日」的时间框,通过绑定自定义样式类,与工作日做样式区分;

配置头部时间轴-日期单元格,点击时的回调事件;

// 选择日期
export function onSelectDay() {
const { selectedDay, boardType } = this.state;
const { dateString } = this.item;
if (boardType === 'day') {
if (dateString === selectedDay.dateString) {
return;
}
this.setState({
selectedDay: this.item,
});
this.getDateList();
this.getViewMainData();
}
}

判断时间框内的日期是否为当前日期,通过自定义样式类,区分当日;

点击更多,「日历」弹窗显示并加载日历图;

// 更多日期
export function onClickMoreMonth() {
this.$('日历弹窗唯一标识').show(() => {
this.renderCalendar();
});
}
// 日历渲染
export function renderCalendar() {
const { year, month } = this.state;
const nowMonthStartDayWeekNum = new Date(year, month - 1, 1).getDay(); // 获取当前月第一天星期数
const nowMonthEndDayWeekNum = new Date(year, month, 0).getDay(); // 获取当前月最后一天星期数
const nowMonthEndDayNum = new Date(year, month, 0).getDate(); // 获取当前月最后一天天数
const lastMonthEndDayNum = new Date(year, month - 1, 0).getDate(); // 获取上个月最后一天天数
const lastMonthDateList = _.range(lastMonthEndDayNum - nowMonthStartDayWeekNum + 1, lastMonthEndDayNum + 1, 1).map((item) => {
return {
type: 'lastMonth',
isToday: false,
year: month - 1 > 0 ? year : year - 1,
month: month - 1 > 0 ? month - 1 : 12,
day: item,
dateString: `${month - 1 > 0 ? year : year - 1}-${month - 1 > 0 ? month - 1 : 12}-${item}`,
};
}); // 上月日期序列
const nowMonthDateList = _.range(1, nowMonthEndDayNum + 1, 1).map((item) => {
return {
type: 'nowMonth',
isToday: item === new Date().getDate() && month === new Date().getMonth() + 1 && year === new Date().getFullYear(),
year,
month,
day: item,
dateString: `${year}-${month}-${item}`,
};
}); // 本月日期序列
const nextMonthDateList = _.range(1, 7 - nowMonthEndDayWeekNum, 1).map((item) => {
return {
type: 'nextMonth',
isToday: false,
year: month - 1 < 13 ? year : +year + 1,
month: +month + 1 < 13 ? +month + 1 : 1,
day: item,
dateString: `${month - 1 < 13 ? year : +year + 1}-${+month + 1 < 13 ? +month + 1 : 1}-${item}`,
};
}); // 下月日期序列
this.setState({
calendarDateList: [...lastMonthDateList, ...nowMonthDateList, ...nextMonthDateList],
});
}

// 切换年月
export function changeYearOrMonth() {
const { type } = this.params;
const { year, month } = this.state;
switch (type) {
case 'lastYear':
this.setState({
year: year - 1,
});
break;
case 'nextYear':
this.setState({
year: +year + 1,
});
break;
case 'lastMonth':
this.setState({
month: month - 1 > 0 ? month - 1 : 12,
year: month - 1 > 0 ? year : year - 1,
});
break;
case 'nextMonth':
this.setState({
month: +month + 1 < 13 ? +month + 1 : 1,
year: +month + 1 < 13 ? year : +year + 1,
});
break;
case 'nowMonth':
this.setState({
month: new Date().getMonth() + 1,
year: new Date().getFullYear(),
clickValue: this.utils.formatter('date', Date.now(), 'YYYY-M-D'),
});
break;
default:
// console.log('无效的状态');
break;
}
this.renderCalendar();
}

点击「日历」中的日期,配置回调事件,如下图:

// 点击日历
export function onCalendarCellClick() {
this.setState({
clickValue: this.item.dateString,
currentPage: 1,
});
this.getDateLine(new Date(`${this.item.year}/${this.item.month}/${this.item.day}`).getTime());
this.getDateList();
this.getViewMainData();//执行获取任务数据
this.$('日历弹窗唯一标识').hide();
}

2.7. 日视图

2.7.1. 时间单元格cell获取及渲染

2.7.1.1. 时间单元格数据获取
// 日视图 - 获取单元格 cell
export function getDateDayList() {
const { dateType, selectedDay } = this.state;
const startHour = dateType === 'all' ? 0 : 8;
const endHour = dateType === 'all' ? 24 : 22;
const dayDateCellList = [];
const dateLabelList = [];
for (let i = startHour; i < endHour; i += 0.5) {
dayDateCellList.push({
hour: parseInt(i, 10),
minute: Number.isInteger(i) ? 0 : 30,
str: `${parseInt(i, 10)}:${Number.isInteger(i) ? '00' : '30'}`,
current: new Date(`${selectedDay.dateString} ${parseInt(i, 10)}:${Number.isInteger(i) ? '00' : '30'}`).getTime(),
});
}
for (let i = startHour; i <= endHour; i++) {
dateLabelList.push(i);
}
this.setState({
dateCellList: dayDateCellList,
dateLabelList,
});
}
// 合并函数 - 获取单元格 cell
export function getDateList() {
const { boardType } = this.state;
switch (boardType) {
case 'day':
this.getDateDayList();//获取日视图-单元格cell
break;
case 'week':
this.getDateWeekList();//获取周视图-单元格cell
break;
default:
break;
}
}
2.7.1.2. 时间单元格数据源绑定;

根据不同时间类型,动态渲染时间刻度显示位置;

// 日视图 - 时间刻度动态定位
export function renderDataLabel() {
const { dateLabelList } = this.state;
return (
dateLabelList.map((item, index) => {
return (
<div
className="date_label"
style={{
left: `${(100 / (dateLabelList.length - 1)) * index}%`,
}}
>
{item}
</div>
);
})
);
}

2.7.2. 任务执行人及任务数据获取并渲染

「页面JS」didmount 调用

获取任务执行人和任务数据;

export async function getDayViewData() {
const { pageSize, currentPage, selectedDay, userSearchQuery, taskSearchQuery } = this.state;
this.setState({
loading: true,
});
const userData = await this.dataSourceMap.getData.load({
formUuid: '任务执行人表单formUuid',//任务执行人formUuid
page: currentPage,
limit: pageSize,
pageSize,
currentPage,
searchField: JSON.stringify([...userSearchQuery]),
logicOperator: 'AND',
}).then((res) => {
const { values = [], currentPage, totalCount } = res;
const data = this.formatInstValue(values); // 格式化数据
const userList = data.map((item) => {
return {
formInstId: item.formInstanceId, // 实例 id
name: item.姓名唯一标识, // 执行人姓名
userId: item.userId唯一标识, // 执行人 userId
taskList: [], // 任务列表
};
});
return {
currentPage,
data: userList,
totalCount,
};
}).catch((error) => {
this.utils.toast({
title: error.message,
type: 'error',
});
return {
data: [],
currentPage: 1,
totalCount: 0,
};
});
this.setState({
userData,
loading: false,
});
if (!userData.totalCount) {
return;
}
const taskDataResult = {
data: [],
totalCount: 0,
};
await this.dataSourceMap.getData.load({
formUuid: '任务录入表单的formUuid',//任务录入表单formuuid
page: 1,
limit: 100,
currentPage: 1,
pageSize: 100,
searchField: JSON.stringify([...[
{
key: '开始时间唯一标识',
value: new Date(selectedDay.dateString).setHours(23, 59, 59, 999),
type: 'DOUBLE',
operator: 'le',
componentName: 'DateField',
}, {
key: '结束时间唯一标识',
value: new Date(selectedDay.dateString).setHours(0, 0, 0, 0),
type: 'DOUBLE',
operator: 'ge',
componentName: 'DateField',
}, {
key: '任务执行人唯一标识',
value: userData.data.map((item) => { return item.userId; }),
type: 'STRING',
operator: 'contains',
componentName: 'EmployeeField',
},
], ...taskSearchQuery]),
logicOperator: 'AND',
}).then((res) => {
// 处理每次返回的结果
const { values = [], totalCount } = res;
const taskData = this.formatInstValue(values); // 格式化数据
taskDataResult.data.push(...taskData);
taskDataResult.totalCount = totalCount;
}).catch((error) => {
this.utils.toast({
title: error.message,
type: 'error',
});
});
//接口返回数据超100条处理
if (taskDataResult.totalCount > 100) {
for (let i = 2; i < Math.ceil(taskDataResult.totalCount / 100) + 1; i++) {
const delay = i === 2 ? 0 : 100;
await new Promise((resolve) => {
setTimeout(async () => {
await this.dataSourceMap.getData.load({
formUuid: '任务录入页面formUuid',//任务录入页面formUuid
page: i,
currentPage: i,
limit: 100,
pageSize: 100,
searchField: JSON.stringify([...[
{
key: '开始时间唯一标识',
value: new Date(selectedDay.dateString).setHours(23, 59, 59, 999),
type: 'DOUBLE',
operator: 'le',
componentName: 'DateField',
}, {
key: '结束时间唯一标识',
value: new Date(selectedDay.dateString).setHours(0, 0, 0, 0),
type: 'DOUBLE',
operator: 'ge',
componentName: 'DateField',
}, {
key: '任务执行人唯一标识',
value: userData.data.map((item) => { return item.userId; }),
type: 'STRING',
operator: 'contains',
componentName: 'EmployeeField',
},
], ...taskSearchQuery]),
logicOperator: 'AND',
}).then((res) => {
const { values = [] } = res;
const taskData = this.formatInstValue(values); // 格式化数据
taskDataResult.data.push(...taskData);
});
resolve();
}, delay);
});
}
}
for (let i = 0; i < userData.data.length; i++) {
userData.data[i].taskList = taskDataResult.data.filter((item) => {
return item.textField_llc16ij6 === userData.data[i].userId;
});
}
this.setState({
userData,
});
}
// 合并函数 - 获取数据
export function getViewMainData() {
const { boardType } = this.state;
switch (boardType) {
case 'day':
this.getDayViewData();
break;
case 'week':
this.getWeekViewData();
break;
default:
break;
}
}
// 数据格式化
export function formatInstValue(values = []) {
return values.map((item) => {
const { formInstanceId, formUuid, processInstanceId, instValue = '' } = item;
const formData = {};
if (instValue) {
JSON.parse(instValue).forEach((_item) => {
switch (_item.componentName) {
case 'RadioField':
case 'SelectField':
formData[_item.fieldId] = _item.fieldData.text;
formData[`${_item.fieldId}_id`] = _item.fieldData.value;
break;
default:
formData[_item.fieldId] = _item.fieldData.value;
}
});
}
return {
formInstanceId,
formUuid,
processInstanceId,
...formData,
};
});
}

绑定「任务执行人」数据源

渲染任务执行人姓名

2.7.3. 通过获取的任务结合自定义样式类传参,渲染单元格状态-进行中、已完成

// 日视图 - 单元格状态
export function dateCellStatus(taskList, currentTime) {
if (!taskList || !currentTime) {
return {
taskList: [],
cellClassName: '',
};
}
const filterResult = taskList.filter((f) => {
return currentTime >= f.dateField_llbm0xap && currentTime < f.dateField_llbm0xaq;
});
const taskStatusList = filterResult.map((i) => {
return i.radioField_llbm0xav_id;
});
if (!taskStatusList.length) {
return {
taskList: filterResult,
cellClassName: 'normal',
};
} else {
if (taskStatusList.indexOf('running') !== -1) {
return {
taskList: filterResult,
cellClassName: 'running',
};
}
return {
taskList: filterResult,
cellClassName: 'finish',
};
}
}

2.7.4. 配置任务状态单元格点击回调事件

根据单元格的状态,显示不同的弹窗;

// 日视图 - 点击单元格
export function onDateCellClick() {
const { taskList, cellClassName } = this.dateCellStatus(this.item.taskList, this._item.current);
switch (cellClassName) {
case 'finish':
case 'running':
this.setState({
taskDetail: taskList,
});
this.$('任务详情的弹窗唯一标识').show();
break;
default:
this.$('任务指派的弹窗唯一标识').show(() => {
this.$('任务类型唯一标识').reset();
this.$('任务名称唯一标识').reset();
this.$('任务接受人唯一标识').setValue({
label: this.item.name,
value: this.item.userId,
});
});
}
}
2.7.4.1. 单元格状态-运行中、已完成时,「任务详情」弹窗显示

任务详情数据源绑定;

任务详情中,「任务编号」字段内容渲染,如下图:

任务详情中,「任务名称」字段内容渲染,如下图:

任务详情中,「任务类别」字段内容渲染,如下图:

任务详情中,「起止时间」字段内容渲染,如下图:

`${utils.formatter('date', item.dateField_llbm0xap, 'YYYY-MM-DD hh:mm')} ~ ${utils.formatter('date', item.dateField_llbm0xaq, 'YYYY-MM-DD hh:mm')}`

任务详情中,「任务时长」字段内容渲染,如下图:

任务详情中,「任务状态」字段内容渲染,如下图:

任务详情中,「任务执行人」字段内容渲染,如下图:

2.7.4.2. 单元格状态-空闲时,「任务指派」弹窗显示

「任务指派」对话框绑定如下函数:

// 日视图 - 任务指派
export function onCreateTask() {
const fieldList = [
'任务类别唯一标识',
'任务名称唯一标识',
'任务接收人唯一标识',
];
// 调用表单校验函数
this.fieldsValidate(fieldList).then((errorList) => {
setTimeout(() => {
if (errorList.length > 0) {
// 表单校验未通过,可做一些数据错误提示
return;
}
this.$('任务指派弹窗唯一标识').set('confirmState', 'LOADING');
// 表单校验通过,你的后续业务逻辑由此往下写
this.dataSourceMap.startInstance.load({
processCode: '任务录入流程code',//TPROC--K0766T9165CFM3L5DZX5TBBRUUMJ27KB6K6OLQ8
formUuid: '任务录入表单formUuid',
formDataJson: JSON.stringify({
radioField_lldjbq09: '指派', // 提交方式
radioField_llbm0xaf: this.$('任务类别唯一标识').getValue(), // 任务类别
textField_llbm0xai: this.$('任务名称唯一标识').getValue(), // 任务名称
employeeField_llbm0xag: Array.isArray(this.$('任务接收人唯一标识').getValue()) ?
[this.$('任务接收人唯一标识').getValue()[0].value] :
[this.$('任务接收人唯一标识').getValue().value], // 任务接收人
textField_llc16ij5: Array.isArray(this.$('employeeField_llbm0xag').getValue()) ?
this.$('任务接收人唯一标识').getValue()[0].label :
this.$('任务接收人唯一标识').getValue().label, // 任务接收人姓名
textField_llc16ij6: Array.isArray(this.$('employeeField_llbm0xag').getValue()) ?
this.$('任务接收人唯一标识').getValue()[0].value :
this.$('任务接收人唯一标识').getValue().value, // 任务接收人 userId
radioField_llbm0xav: 'running', // 任务状态
}),
}).then(() => {
this.$('任务指派弹窗唯一标识').set('confirmState', 'NORMAL');
this.utils.toast({
title: '任务指派成功',
type: 'success',
});
this.$('任务指派弹窗唯一标识').hide();
}).catch((error) => {
this.$('任务指派弹窗唯一标识').set('confirmState', 'NORMAL');
this.utils.toast({
title: error.message,
type: 'error',
});
});
i});
}, 0);
}
// fieldList:Array,需要校验组件的唯一标识集合
export async function fieldsValidate(fieldList = []) {
const result = [];
for (let i = 0; i < fieldList.length; i++) {
await this.$(fieldList[i]).validate((errors) => {
if (!errors) {
return;
}
result.push({
fieldId: fieldList[i], // 组件标识
errors: this.utils.isMobile() ? errors.errors[fieldList[i]].errors : errors[fieldList[i]].errors, // 校验错误信息
});
});
}
return result;
}

2.7.5. 分页设置

「总条数」、「当前页码」,「每页实例数」绑定变量

切换页码,绑定回调事件

// 日视图 - 切换页码
export function onPaginationChange(currentPagination) {
this.setState({
currentPage: currentPagination,
});
this.getViewMainData();
}

// 日视图 - 切换每页显示数
export function onPageSizeChange(pageSize) {
this.setState({
pageSize,
});
this.getViewMainData();
}

2.8. 周视图

2.8.1. 时间单元格cell获取及渲染

「页面JS」获取时间单元格数据


// 周视图 - 获取单元格 cell
export function getDateWeekList() {
const { dateType, dateLine } = this.state;
const startHour = dateType === 'all' ? 0 : 8;
const endHour = dateType === 'all' ? 24 : 22;
const weekDateCellList = {};
const weekDateLabelList = [];
for (let i = startHour; i < endHour; i += 0.5) {
weekDateCellList[`${parseInt(i, 10)}:${Number.isInteger(i) ? '00' : '30'}`] = [];
dateLine.forEach((item) => {
weekDateCellList[`${parseInt(i, 10)}:${Number.isInteger(i) ? '00' : '30'}`].push({
...item,
current: new Date(`${item.dateString} ${parseInt(i, 10)}:${Number.isInteger(i) ? '00' : '30'}`).getTime(),
});
});
}
for (let i = startHour; i <= endHour; i += 0.5) {
weekDateLabelList.push(`${parseInt(i, 10)}:${Number.isInteger(i) ? '00' : '30'}`);
}
this.setState({
dateWeekCellList: weekDateCellList,
weekDateLabelList,
});
}

绑定时间单元格数据源;

通过时间单元格数据,动态渲染单元格时间刻度位置;

2.8.2. 任务数据获取并渲染

// 周视图 - 获取数据
export async function getWeekViewData() {
const { taskSearchQuery, dateLine } = this.state;
this.setState({
loading: true,
});
const taskDataResult = {
data: [],
totalCount: 0,
};
await this.dataSourceMap.getData.load({
formUuid: 'FORM-S9866D91J35FS450FVDK86VZULXJ232B6K6OLMQ',
page: 1,
limit: 100,
currentPage: 1,
pageSize: 100,
searchField: JSON.stringify([...[
{
key: 'dateField_llbm0xap',
value: new Date(dateLine[dateLine.length - 1].dateString).setHours(23, 59, 59, 999),
type: 'DOUBLE',
operator: 'le',
componentName: 'DateField',
}, {
key: 'dateField_llbm0xaq',
value: new Date(dateLine[0].dateString).setHours(0, 0, 0, 0),
type: 'DOUBLE',
operator: 'ge',
componentName: 'DateField',
},
], ...taskSearchQuery]),
logicOperator: 'AND',
}).then((res) => {
// 处理每次返回的结果
const { values = [], totalCount } = res;
const taskData = this.formatInstValue(values); // 格式化数据
taskDataResult.data.push(...taskData);
taskDataResult.totalCount = totalCount;
}).catch((error) => {
this.utils.toast({
title: error.message,
type: 'error',
});
});
if (taskDataResult.totalCount > 100) {
for (let i = 2; i < Math.ceil(taskDataResult.totalCount / 100) + 1; i++) {
const delay = i === 2 ? 0 : 100;
await new Promise((resolve) => {
setTimeout(async () => {
await this.dataSourceMap.getData.load({
formUuid: '任务录入页面formUuid',//任务录入formUuid
page: i,
currentPage: i,
limit: 100,
pageSize: 100,
searchField: JSON.stringify([...[
{
key: '开始时间',
value: new Date(dateLine[dateLine.length - 1].dateString).setHours(23, 59, 59, 999),
type: 'DOUBLE',
operator: 'le',
componentName: 'DateField',
}, {
key: '结束时间',
value: new Date(dateLine[0].dateString).setHours(0, 0, 0, 0),
type: 'DOUBLE',
operator: 'ge',
componentName: 'DateField',
},
], ...taskSearchQuery]),
logicOperator: 'AND',
}).then((res) => {
const { values = [] } = res;
const taskData = this.formatInstValue(values); // 格式化数据
taskDataResult.data.push(...taskData);
});
resolve();
}, delay);
});
}
}
this.setState({
userData: taskDataResult,
loading: false,
});
}

2.8.3. 渲染时间单元格任务状态

// 周视图 - 单元格状态
export function weekDateCellStatus(currentTime) {
const { userData } = this.state;
if (!userData.totalCount || !currentTime) {
return {
taskList: [],
cellClassName: '',
};
}
const filterResult = userData.data.filter((f) => {
return currentTime >= f.dateField_llbm0xap && currentTime < f.dateField_llbm0xaq;
});
const taskStatusList = filterResult.map((i) => {
return i.radioField_llbm0xav_id;
});
if (!taskStatusList.length) {
return {
taskList: filterResult,
cellClassName: 'normal',
};
} else {
if (taskStatusList.indexOf('running') !== -1) {
return {
taskList: filterResult,
cellClassName: 'running',
};
}
return {
taskList: filterResult,
cellClassName: 'finish',
};
}
}

2.8.4. 单元格任务状态点击回调事件


// 周视图 - 点击单元格
export function onWeekCellClick() {
const { taskList, cellClassName } = this.weekDateCellStatus(this._item.current);
switch (cellClassName) {
case 'finish':
case 'running':
this.setState({
taskDetail: taskList,
});
this.$('任务详情弹窗唯一标识').show();
break;
default:
this.$('任务指派弹窗唯一标识').show(() => {
this.$('任务类别唯一标识').reset(); //清空任务类别
this.$('任务名称唯一标识').reset();//清空任务名称
this.$('任务接收人唯一标识').reset();//清空任务接收人
});
}
}

2.9. 搜索框查询配置

2.9.1. 添加查询组件

2.9.2. 绑定搜索事件


// 搜索
export function onSubmit() {
const { boardType } = this.state;
const values = {
employeeField_llbnstfm: !this.$('employeeField_llbnstfm').getValue() || !this.$('employeeField_llbnstfm').getValue().length ? '' : this.$('employeeField_llbnstfm').getValue(),
selectField_llbnstfn: this.$('selectField_llbnstfn').getValue(),
textField_llbnstfh: this.$('textField_llbnstfh').getValue(),
};
if (boardType === 'day') {
this.setState({
userSearchQuery: [{
key: 'employeeField_lldfain9',
value: values.employeeField_llbnstfm ? values.employeeField_llbnstfm.map((item) => { return item.value; }) : '',
type: 'STRING',
operator: 'contains',
componentName: 'EmployeeField',
}],
taskSearchQuery: [{
key: 'radioField_llbm0xaf',
value: values.selectField_llbnstfn === 'all' ? '' : values.selectField_llbnstfn,
type: 'ARRAY',
operator: 'eq',
componentName: 'RadioField',
}, {
key: 'textField_llbm0xai',
value: values.textField_llbnstfh || '',
type: 'TEXT',
operator: 'ilike',
componentName: 'TextField',
}],
currentPage: 1,
});
}
if (boardType === 'week') {
this.setState({
taskSearchQuery: [{
key: 'radioField_llbm0xaf',
value: values.selectField_llbnstfn === 'all' ? '' : values.selectField_llbnstfn,
type: 'ARRAY',
operator: 'eq',
componentName: 'RadioField',
}, {
key: 'textField_llbm0xai',
value: values.textField_llbnstfh || '',
type: 'TEXT',
operator: 'ilike',
componentName: 'TextField',
}, {
key: 'employeeField_llbm0xag',
value: values.employeeField_llbnstfm ? values.employeeField_llbnstfm.map((item) => { return item.value; }) : '',
type: 'STRING',
operator: 'contains',
componentName: 'EmployeeField',
}],
});
}
this.getViewMainData();
}

2.9.3. 绑定重置事件

// 重置
export function onReset() {
this.$('selectField_llbnstfn').setValue('all');
this.$('textField_llbnstfh').reset();
this.$('employeeField_llbnstfm').reset();
this.setState({
userSearchQuery: {},
taskSearchQuery: [],
currentPage: 1,
});
this.getViewMainData();
}

3. 实现效果

3.1. 日视图

3.2. 周视图

4. 注意事项

特别注意:启用后请先修改任务指派流程 Code,否则会触发报错【页面与流程的关联关系不存在】。

查看路径:应用设置 -> 部署运维 -> 任务录入 -> 流程 Code

5. 在线试玩

Copyright © 2024钉钉(中国)信息技术有限公司和/或其关联公司浙ICP备18037475号-4