メインコンテンツまでスキップ

カスタムページとカレンダー図を組み合わせてタスク看板を実現

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. 1ページあたりのインスタンス数​

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を変更してください。変更しないと、「ページとプロセスの関連関係が存在しません」というエラーが発生します。

パスの表示: アプリケーション設定-> 輸送次元の導入-> タスク入力-> プロセスコード

5. オンラインで試遊する​

この文書は機械翻訳により生成されています。翻訳により生じた齟齬や相違点は拘束力を持たず、コンプライアンスや執行目的において法的効力はありません。
© DingTalk (Singapore) Private Limited