const schema = { type: 'page', body: [ { type: 'form', id: 'u:90c6fa536042', mode: 'inline', name: 'filter', title: '表单', className: 'm-b-sm', submitOnChange: true, submitOnInit: true, reload: 'group?course_id=$course_id&class_ids=$class_ids&studentgroup_ids=$studentgroup_ids', wrapWithPanel: false, body: [ { type: 'group', body: [ { type: 'select', mode: 'inline', label: '课程', name: 'course_id', source: { method: 'get', url: 'rest/courses?organization_id=eq.$centre_id&semester_id=eq.$currentSemester&order=code', adaptor: 'return {\r\n ...payload,\r\n data: payload.data.items.map(item => {\r\n return {\r\n label: `${item.name}(${item.code})`,\r\n value: item.id\r\n }\r\n })\r\n}', }, size: 'md', searchable: true, className: 'm-l-sm', inputClassName: 'm-l-xs', id: 'u:23277f1965f7', }, ], id: 'u:8575c6f7cefc', }, { type: 'group', body: [ { type: 'tree-select', label: '班级', name: 'class_ids', mode: 'horizontal', multiple: true, joinValues: false, extractValue: true, onlyChildren: true, clearable: true, searchable: true, source: { method: 'get', url: 'rest/orgs?select=*,dicts:dicts!organization_type_fkey(*),course2orgs(*)&path=cd.root&course2orgs.course_id=eq.${course_id}&order=name', adaptor: "const recursive = id => {\r\n const nodes = payload.data.items.filter(item => {\r\n return item.parent === id && (\r\n (item.type === 'class' ||\r\n item.type === 'reelectclass') &&\r\n item.course2orgs.length ||\r\n item.type !== 'class' &&\r\n item.type !== 'reelectclass' &&\r\n item.type !== 'studentgroup'\r\n )\r\n })\r\n const result = []\r\n\r\n if (nodes.length) {\r\n nodes.forEach(item => {\r\n const children = recursive(item.id)\r\n\r\n if (children)\r\n result.push({\r\n ...item,\r\n label: item.name,\r\n children,\r\n })\r\n else if (\r\n item.type === 'class' ||\r\n item.type === 'reelectclass'\r\n ) result.push({\r\n ...item,\r\n label: item.name,\r\n value: item.id,\r\n })\r\n })\r\n\r\n if (result.length) return result\r\n } else return null\r\n}\r\n\r\nlet school = payload.data.items.find(x => x.type === 'school')\r\n\r\nreturn {\r\n ...payload,\r\n data: recursive(school.id)\r\n}\r\n", requestAdaptor: 'if (api.query.course2orgs.course_id === "eq.") {\r\n \n api.url = api.url.replace("&course2orgs[course_id]=eq.", "")\r\n}\r\nif (api.query.course2orgs.course_id === "eq.undefined") {\r\n api.url = api.url.replace("&course2orgs[course_id]=eq.undefined", "")\r\n}', sendOn: 'course_id', messages: {}, }, withChildren: true, initiallyOpen: false, id: 'u:42ede681efa8', autoCheckChildren: true, enableNodePath: false, showIcon: true, heightAuto: true, virtualThreshold: false, }, ], id: 'u:f2885926e84d', }, { type: 'group', body: [ { type: 'tree-select', label: '分组', name: 'studentgroup_ids', mode: 'horizontal', multiple: true, joinValues: false, extractValue: true, onlyChildren: true, clearable: true, searchable: true, source: { method: 'get', url: 'rest/orgs?select=*,dicts:dicts!organization_type_fkey(*),course2orgs(*)&path=cd.root&course2orgs.course_id=eq.${course_id}&order=name', adaptor: "const recursive = id => {\r\n const nodes = payload.data.items.filter(item => {\r\n return item.parent === id && (\r\n item.type === 'studentgroup' &&\r\n item.course2orgs.length ||\r\n item.type !== 'class' &&\r\n item.type !== 'reelectclass' &&\r\n item.type !== 'studentgroup'\r\n )\r\n })\r\n const result = []\r\n\r\n if (nodes.length) {\r\n nodes.forEach(item => {\r\n const children = recursive(item.id)\r\n\r\n if (children)\r\n result.push({\r\n ...item,\r\n label: item.name,\r\n children,\r\n })\r\n else if (item.type === 'studentgroup')\r\n result.push({\r\n ...item,\r\n label: item.name,\r\n value: item.id,\r\n })\r\n })\r\n\r\n if (result.length) return result\r\n } else return null\r\n}\r\n\r\nlet school = payload.data.items.find(x => x.type === 'school')\r\n\r\nreturn {\r\n ...payload,\r\n data: recursive(school.id)\r\n}\r\n", requestAdaptor: 'if (api.query.course2orgs.course_id === "eq.") {\r\n \n api.url = api.url.replace("&course2orgs[course_id]=eq.", "")\r\n}\r\nif (api.query.course2orgs.course_id === "eq.undefined") {\r\n api.url = api.url.replace("&course2orgs[course_id]=eq.undefined", "")\r\n}', sendOn: 'course_id', messages: {}, }, withChildren: true, initiallyOpen: false, id: 'u:42ede681efa8', autoCheckChildren: true, enableNodePath: false, showIcon: true, heightAuto: true, virtualThreshold: false, }, ], id: 'u:bfa2b4c7ed01', }, ], feat: 'Insert', }, { type: 'divider', lineStyle: 'solid', id: 'u:e807ff502b0a', }, { type: 'crud', messages: {}, api: { method: 'get', url: 'rest/groupusers?semester_id=eq.$currentSemester&course_id=eq.$course_id&or=(class_id.in.($class_ids),studentgroup_id.in.($studentgroup_ids))&order=student_code', sendOn: 'this.course_id && (this.class_ids || this.studentgroup_ids)', data: { orderBy: '$orderBy', orderDir: '$orderDir', }, requestAdaptor: "if (api.query.orderDir) {\r\n api.url = api.url.replace('&order=student_code', '');\r\n api.url = api.url.replace('&orderBy=' + api.query.orderBy + '&orderDir=' + api.query.orderDir, '&order=' + api.query.orderBy + '.' + api.query.orderDir);\r\n} else if (api.query.orderBy) {\r\n api.url = api.url.replace('&order=student_code', '');\r\n api.url = api.url.replace('&orderBy=' + api.query.orderBy + '&orderDir=', '&order=' + api.query.orderBy);\r\n} else {\r\n api.url = api.url.replace('&orderBy=&orderDir=', '');\r\n}\r\n\r\nreturn api;", adaptor: 'return {\r\n ...payload,\r\n data: {\r\n ...payload.data,\r\n items: payload.data.items.map((item, index) => {\r\n return {\r\n ...item,\r\n n: index + 1\r\n }\r\n })\r\n }\r\n}', }, headerToolbar: [ { type: 'button', align: 'right', label: '导入分组', icon: 'fa fa-upload', level: 'warning', id: 'u:ce034375ceff', onEvent: { click: { weight: 0, actions: [ { ignoreError: false, actionType: 'dialog', dialog: { type: 'dialog', title: '分组导入', size: 'xl', body: [ { type: 'form', title: '表单', body: [ { type: 'select', mode: 'inline', label: '课程', name: 'course_id', source: { method: 'get', url: 'rest/courses?organization_id=eq.$centre_id&semester_id=eq.$currentSemester&order=code', adaptor: 'return {\r\n ...payload,\r\n data: payload.data.items.map(item => {\r\n return {\r\n label: `${item.name}(${item.code})`,\r\n value: item.id\r\n }\r\n })\r\n}', }, size: 'md', searchable: true, className: 'm-l-sm', inputClassName: 'm-l-xs', id: 'u:7cfa89be2243', }, { type: 'tree-select', label: '上级部门', name: 'parent_id', mode: 'inline', extractValue: true, onlyChildren: true, source: { method: 'get', url: 'rest/orgs?select=*&or=(type.eq.school,type.eq.faculty,type.eq.centre)&path=cd.root&order=code', adaptor: "const recursive = id => {\r\n let nodes = payload.data.items.filter(x => {\r\n return x.parent === id\r\n })\r\n\r\n return nodes.map(item => {\r\n return {\r\n ...item,\r\n label: item.name,\r\n value: `${item.id}`,\r\n children: recursive(item.id)\r\n }\r\n })\r\n}\r\n\r\nlet school = payload.data.items.find(x => x.type === 'school')\r\n\r\nreturn {\r\n ...payload,\r\n data: recursive(school.id)\r\n}\r\n", sendOn: '', }, withChildren: true, initiallyOpen: false, searchable: true, clearable: false, heightAuto: true, virtualThreshold: false, id: 'u:37ca2401871c', }, { type: 'excel-import-group', name: 'groups', label: '', mode: 'normal', hiddenOn: '${!course_id || !parent_id}', id: 'u:a8c9dbf3d073', }, { type: 'input-table', name: 'groups', label: '', columns: [ { label: 'Excel 行号', name: 'no', id: 'u:a31efd3393b0', }, { name: 'user_code', label: '*学号', classNameExpr: "<%= data.no && !data.user_id ? 'bg-danger' : '' %>", id: 'u:8d68435bf70e', }, { label: '姓名', name: 'user_name', id: 'u:fc9cb5a03b8f', }, { label: '分组', name: 'group', classNameExpr: "<%= !data.no ? 'bg-secondary' : !data.group ? 'bg-danger' : '' %>", id: 'u:ca487d89fd7c', }, ], mode: 'normal', visibleOn: 'this.groups', strictMode: true, removable: true, editable: false, clearValueOnHidden: true, id: 'u:625db3dac0ec', }, ], reload: 'grp', initApi: { method: 'get', url: 'rest/report_check_items?organization_id=eq.$centre_id&order=type_order,type,display_order,comment', }, id: 'u:ccd0d1410b18', actions: [ { type: 'submit', label: '提交', primary: true, }, ], feat: 'View', }, ], closeOnEsc: true, closeOnOutside: false, showCloseButton: true, actions: [], id: 'u:d85ab95adb25', }, }, ], }, }, }, { type: 'export-excel', align: 'right', label: '导出', icon: 'fa fa-download', level: 'primary', hiddenOn: '${!class_ids && !studentgroup_ids}', api: { method: 'get', url: 'rest/groupusers?semester_id=eq.$currentSemester&course_id=eq.$course_id&or=(class_id.in.($class_ids),studentgroup_id.in.($studentgroup_ids))&order=student_code', data: { orderBy: '$orderBy', orderDir: '$orderDir', }, requestAdaptor: "if (api.query.orderDir) {\r\n api.url = api.url.replace('&order=student_code', '');\r\n api.url = api.url.replace('&orderBy=' + api.query.orderBy + '&orderDir=' + api.query.orderDir, '&order=' + api.query.orderBy + '.' + api.query.orderDir);\r\n} else if (api.query.orderBy) {\r\n api.url = api.url.replace('&order=student_code', '');\r\n api.url = api.url.replace('&orderBy=' + api.query.orderBy + '&orderDir=', '&order=' + api.query.orderBy);\r\n} else {\r\n api.url = api.url.replace('&orderBy=&orderDir=', '');\r\n}\r\n\r\nreturn api;", adaptor: 'return {\r\n ...payload,\r\n data: {\r\n ...payload.data,\r\n items: payload.data.items.map((item, index) => {\r\n return {\r\n ...item,\r\n n: index + 1\r\n }\r\n })\r\n }\r\n}', }, filename: '分组', exportColumns: [ { label: '*学号', name: 'student_code', }, { label: '姓名', name: 'student_name', }, { label: '*分组', name: 'studentgroup_name', }, ], id: 'u:a44ab3164746', }, { type: 'bulk-actions', }, ], bulkActions: [ { label: '批量设置', type: 'button', id: 'u:99fa372537dc', onEvent: { click: { weight: 0, actions: [ { ignoreError: false, actionType: 'dialog', dialog: { type: 'dialog', title: '批量设置', body: [ { type: 'form', title: '表单', api: { method: 'post', url: 'rest/rpc/batch_group', data: { org_id: '$org_id', selectedItems: '$selectedItems', }, heades: { Prefer: 'params=single-object', }, requestAdaptor: 'const user2org = api.data.selectedItems.map(item => ({\r\n user_id: item.student_id,\r\n old_org_id: item.studentgroup_id,\r\n new_org_id: api.data.org_id,\r\n}))\r\n\r\napi.data = { user2org }\r\n\r\nreturn api', }, body: [ { type: 'select', label: '分组', name: 'org_id', mode: 'normal', cascade: true, searchable: true, required: true, source: { method: 'get', url: 'rest/orgs?select=*,course2orgs!inner(*),dicts:dicts!organization_type_fkey(*)&type=eq.studentgroup&path=cd.root.1&course2orgs.course_id=eq.${course_id}&order=name', requestAdaptor: 'if (api.query.course2orgs.course_id === "eq.") {\r\n api.url = api.url.replace("&course2orgs[course_id]=eq.", "")\r\n}\r\nif (api.query.course2orgs.course_id === "eq.undefined") {\r\n api.url = api.url.replace("&course2orgs[course_id]=eq.undefined", "")\r\n}', adaptor: 'return {\r\n data: payload.data.items.map(item => {\r\n return {\r\n label: item.name,\r\n value: item.id\r\n }\r\n })\r\n}', sendOn: 'course_id', }, extractValue: true, id: 'u:8527f8d399e6', }, ], id: 'u:e9215f23110f', actions: [ { type: 'submit', label: '提交', primary: true, }, ], feat: 'Insert', dsType: 'api', onEvent: { submitSucc: { weight: 0, actions: [ { componentId: 'u:148f700a4963', ignoreError: false, actionType: 'reload', args: { resetPage: false, }, }, ], }, }, }, ], closeOnEsc: true, showCloseButton: true, id: 'u:ce48989de1f9', actions: [ { type: 'button', actionType: 'cancel', label: '取消', id: 'u:f8c9f57fa665', }, { type: 'button', actionType: 'confirm', label: '确定', primary: true, id: 'u:8cccdee1e21b', }, ], }, }, ], }, }, }, { label: '批量清除', confirmText: '确认清除分组吗?', type: 'button', id: 'u:5eb51d3e6692', onEvent: { click: { weight: 0, actions: [ { ignoreError: false, outputVar: 'responseResult', actionType: 'ajax', options: {}, api: { url: 'rest/user_orgs', method: 'delete', requestAdaptor: 'api.url = api.url + `?id=in.(${api.data.selectedItems.filter(item => item.user_studentgroup_id).map(item => item.user_studentgroup_id).toString()})`\r\ndelete api.data.selectedItems\r\n\r\nreturn api', adaptor: '', messages: {}, data: { selectedItems: '$selectedItems', }, }, }, { componentId: 'u:148f700a4963', ignoreError: false, actionType: 'reload', args: { resetPage: false, }, }, ], }, }, }, { label: '批量分组', type: 'button', id: 'u:0371266b981c', onEvent: { click: { weight: 0, actions: [ { ignoreError: false, actionType: 'dialog', dialog: { type: 'dialog', title: '批量分组', body: [ { type: 'form', title: '表单', id: 'u:f39e60c373bc', body: [ { type: 'tree-select', label: '上级部门', name: 'parent', mode: 'normal', extractValue: true, onlyChildren: true, source: { method: 'get', url: 'rest/orgs?select=*&or=(type.eq.school,type.eq.faculty,type.eq.centre)&path=cd.root&order=code', adaptor: "const recursive = id => {\r\n let nodes = payload.data.items.filter(x => {\r\n return x.parent === id\r\n })\r\n\r\n return nodes.map(item => {\r\n return {\r\n ...item,\r\n label: item.name,\r\n value: `${item.id}`,\r\n children: recursive(item.id)\r\n }\r\n })\r\n}\r\n\r\nlet school = payload.data.items.find(x => x.type === 'school')\r\n\r\nreturn {\r\n ...payload,\r\n data: recursive(school.id)\r\n}\r\n", sendOn: '', }, withChildren: true, required: true, initiallyOpen: false, searchable: true, clearable: false, heightAuto: true, virtualThreshold: false, id: 'u:1efc22d916f7', }, { name: 'groups', label: '新分组', type: 'input-array', items: { type: 'input-text', }, removable: true, required: true, mode: 'normal', id: 'u:0a41abbda787', }, { label: '选择分组方式', type: 'select', name: 'way', required: true, mode: 'normal', options: [ { label: '顺序分组', value: 'order', }, { label: '随机分组', value: 'random', }, ], id: 'u:436b4893fdfc', }, { type: 'batch-group', label: false, id: 'u:04fbf3b1b31c', }, ], actions: [ { type: 'submit', label: '提交', primary: true, }, ], feat: 'Insert', dsType: 'api', onEvent: { submitSucc: { weight: 0, actions: [ { componentId: 'u:148f700a4963', ignoreError: false, actionType: 'reload', args: { resetPage: false, }, }, ], }, }, }, ], actions: [ { type: 'button', label: '关闭', onEvent: { click: { actions: [ { componentId: 'u:148f700a4963', actionType: 'reload', data: null, }, { actionType: 'closeDialog', }, ], }, }, id: 'u:f7831022039a', }, ], id: 'u:3ead95907fbd', }, }, ], }, }, }, ], syncLocation: false, footerToolbar: [], columns: [ { type: 'text', name: 'n', label: '序号', id: 'u:dc3b48ab2a2a', }, { type: 'text', name: 'student_code', sortable: true, label: '学号', id: 'u:9233f140d314', }, { type: 'text', name: 'student_name', sortable: true, label: '姓名', id: 'u:cb913014ed05', }, { type: 'text', sortable: true, label: '班级', name: 'class_name', id: 'u:d0de67b68472', }, { type: 'text', label: '课程', name: 'course_name', id: 'u:ecd0d94b6c58', }, { type: 'text', sortable: true, label: '分组', name: 'studentgroup_name', id: 'u:de1610df96e6', }, { type: 'button-group', label: '操作', buttons: [ { type: 'button', level: 'link', icon: 'fa fa-cog text-info', size: 'md', tooltip: '设置分组', tooltipPlacement: 'top', iconClassName: 'pull-left', className: 'p-r-none p-l-none', hiddenOn: '${studentgroup_id}', id: 'u:ccec6786dabf', onEvent: { click: { weight: 0, actions: [ { ignoreError: false, actionType: 'dialog', dialog: { title: '设置分组', body: [ { type: 'form', title: '表单', api: { method: 'post', url: 'rest/user_orgs', data: { user_id: '$student_id', organization_id: '$group_id', }, dataType: 'json', }, id: 'u:a20070f8b13c', body: [ { type: 'select', label: '分组', name: 'group_id', mode: 'normal', cascade: true, searchable: true, required: true, source: { method: 'get', url: 'rest/orgs?select=*,course2orgs!inner(*),dicts:dicts!organization_type_fkey(*)&type=eq.studentgroup&path=cd.root.1&course2orgs.course_id=eq.${course_id}&order=name', requestAdaptor: 'if (api.query.course2orgs.course_id === "eq.") {\r\n api.url = api.url.replace("&course2orgs[course_id]=eq.", "")\r\n}\r\nif (api.query.course2orgs.course_id === "eq.undefined") {\r\n api.url = api.url.replace("&course2orgs[course_id]=eq.undefined", "")\r\n}', adaptor: 'return {\r\n data: payload.data.items.map(item => {\r\n return {\r\n label: item.name,\r\n value: item.id\r\n }\r\n })\r\n}', sendOn: 'course_id', }, extractValue: true, id: 'u:75a5e1ef2a35', }, ], actions: [ { type: 'submit', label: '提交', primary: true, }, ], feat: 'Insert', dsType: 'api', onEvent: { submitSucc: { weight: 0, actions: [ { componentId: 'u:148f700a4963', ignoreError: false, actionType: 'reload', args: { resetPage: false, }, }, ], }, }, }, ], type: 'dialog', closeOnEsc: true, showCloseButton: true, id: 'u:05921ba2d106', actions: [ { type: 'button', actionType: 'cancel', label: '取消', id: 'u:5a3bed9137d5', }, { type: 'button', actionType: 'confirm', label: '确定', primary: true, id: 'u:9982eb0126f2', }, ], }, }, ], }, }, }, { type: 'button', level: 'link', icon: 'fa fa-pencil text-warning', size: 'md', tooltip: '修改分组', tooltipPlacement: 'top', hiddenOn: '${!studentgroup_id}', iconClassName: 'pull-left', className: 'p-r-none p-l-none', id: 'u:b1bda5ad847a', onEvent: { click: { weight: 0, actions: [ { ignoreError: false, actionType: 'dialog', dialog: { title: '修改分组', body: [ { type: 'form', title: '表单', api: { method: 'patch', url: 'rest/user_orgs?user_id=eq.$student_id&organization_id=eq.$studentgroup_id', data: { organization_id: '$group_id', }, dataType: 'json', }, id: 'u:2b0b7a8f5877', body: [ { type: 'tree-select', label: '原分组', name: 'studentgroup_id', searchable: true, readOnly: true, onlyChildren: true, source: { method: 'get', url: 'rest/orgs?select=*&or=(type.eq.school,type.eq.faculty,type.eq.centre,type.eq.studentgroup)&path=cd.root&order=code', adaptor: "const recursive = id => {\r\n let nodes = payload.data.items.filter(x => {\r\n return x.parent === id\r\n })\r\n\r\n return nodes.map(item => {\r\n return {\r\n ...item,\r\n label: item.name,\r\n value: item.id,\r\n children: recursive(item.id)\r\n }\r\n })\r\n}\r\n\r\nlet school = payload.data.items.find(x => x.type === 'school')\r\n\r\nreturn {\r\n ...payload,\r\n data: recursive(school.id)\r\n}\r\n", }, withChildren: true, initiallyOpen: false, heightAuto: true, virtualThreshold: false, id: 'u:9b803b7fffbe', }, { type: 'select', label: '新分组', name: 'group_id', mode: 'normal', cascade: true, searchable: true, required: true, source: { method: 'get', url: 'rest/orgs?select=*,course2orgs!inner(*),dicts:dicts!organization_type_fkey(*)&type=eq.studentgroup&path=cd.root.1&course2orgs.course_id=eq.${course_id}&order=name', requestAdaptor: 'if (api.query.course2orgs.course_id === "eq.") {\r\n api.url = api.url.replace("&course2orgs[course_id]=eq.", "")\r\n}\r\nif (api.query.course2orgs.course_id === "eq.undefined") {\r\n api.url = api.url.replace("&course2orgs[course_id]=eq.undefined", "")\r\n}', adaptor: 'return {\r\n data: payload.data.items.map(item => {\r\n return {\r\n label: item.name,\r\n value: item.id\r\n }\r\n })\r\n}', sendOn: 'course_id', }, extractValue: true, id: 'u:fd14fbccb8fc', }, ], actions: [ { type: 'submit', label: '提交', primary: true, }, ], feat: 'Insert', dsType: 'api', onEvent: { submitSucc: { weight: 0, actions: [ { componentId: 'u:148f700a4963', ignoreError: false, actionType: 'reload', args: { resetPage: false, }, }, ], }, }, }, ], type: 'dialog', closeOnEsc: true, showCloseButton: true, id: 'u:94b2f1f09462', actions: [ { type: 'button', actionType: 'cancel', label: '取消', id: 'u:0c74d636f491', }, { type: 'button', actionType: 'confirm', label: '确定', primary: true, id: 'u:2e60b730d920', }, ], }, }, ], }, }, }, { type: 'button', confirmText: '确认清除分组吗?', level: 'link', icon: 'fa fa-trash text-danger', size: 'md', tooltip: '清除分组', tooltipPlacement: 'top', hiddenOn: '${!studentgroup_id}', iconClassName: 'pull-left', className: 'p-r-none p-l-none', id: 'u:e719d85aa542', onEvent: { click: { weight: 0, actions: [ { ignoreError: false, outputVar: 'responseResult', actionType: 'ajax', options: {}, api: { url: 'rest/user_orgs?user_id=eq.$student_id&organization_id=eq.$studentgroup_id', method: 'delete', requestAdaptor: '', adaptor: '', messages: {}, }, }, { componentId: 'u:148f700a4963', ignoreError: false, actionType: 'reload', args: { resetPage: false, }, }, ], }, }, }, ], placeholder: '-', width: 200, id: 'u:b59ecbce78a6', }, ], name: 'grp', bodyClassName: '', title: '', initFetch: true, columnsTogglable: true, id: 'u:148f700a4963', }, ], title: '', messages: {}, id: 'u:9e76719da6ac', }; export { schema };