import { message } from 'antd'
import * as service from '../services/index'
import URLS from '../constants/url'
import DEFAULT_COLUMN_TYPE from './defaultColumnType.json'

export default {
    namespace: 'dataSource',
    state: {
        newOne: {},
        list: [],
        filterLabel: '',
        invalidSQL: false,
        groupList: [],
        currentGroup: [{
            code: 'all',
            label: '全部分组'
        }],
        groupDirty: false
    },
    reducers: {
        list(state, action) {
            const { list } = action;
            return { ...state, list };
        },
        add(state, action) {
            let newOne = Object.assign({}, state.newOne);
            let list = state.list;
            newOne.key = new Date().getMilliseconds()+(Math.random()*100).toFixed(0);
            newOne.code = new Date().getMilliseconds()+(Math.random()*100).toFixed(0);
            newOne.creator = 'zhuth';
            newOne.createTime = new Date();
            list.push(newOne);
            return Object.assign({}, state, {list});
        },
        modify(state, action) {
            const { newOne } = state;
            let list = state.list;
            for(let i = 0; i < list.length; i++) {
                if(list[i].code === newOne.code) {
                    list[i] = Object.assign({}, newOne);
                    break;
                }
            }
            return Object.assign({}, state, {list});
        },
        delete(state, action) {
            const { model } = action;
            let { list } = state;
            for(let i = 0; i < list.length; i++) {
                if(list[i].code === model.code) {
                    list.splice(i, 1);
                }
            }
            return Object.assign({}, state, {list});

        },
        setNewModelFields(state, action) {
            const { fields } = action;
            let newOne = state.newOne;
            for(let i = 0; i < fields.length; i++) {
                newOne[fields[i]['name']] = fields[i]['value'];
            }
            let obj = Object.assign({}, state, {newOne});
            return obj;
        },
        setNewModelField(state, action) {
            const { name, value } = action;
            let newOne = state.newOne;
            newOne[name] = value;
            let obj = Object.assign({}, state, {newOne});
            return obj;
        },
        setNewModel(state, action) {
            const { model } = action;
            let newOne = Object.assign({}, model);
            return Object.assign({}, state, {newOne});
        },
        resetNewModel(state, action) {
            return Object.assign({}, state, {newOne: {}});
        },
        setFilterLabel(state, action) {
            const { label } = action;
            return Object.assign({}, state, {filterLabel: label});
        },
        setNewModelInvalidSQL(state, action) {
            const { value } = action;
            let newOne = state.newOne;
            newOne.invalidSQL = value;
            return Object.assign({}, state, {newOne});
        },
        groupList(state, action) {
            let data = action.data;
            return Object.assign({}, state, {groupList: data});
        },
        /**
         * 设置数据源过滤用分组
         */
        setCurrentGroup(state, action) {
            const { group1, group2 } = action;
            let g = [group1];
            group2 && g.push(group2);
            return Object.assign({}, state, {currentGroup: g});
        },
        addGroup(state, action) {
            const { group } = action;
            let list = state.groupList;
            list.push(group);
            return Object.assign({}, state, {groupList: list});
        },
        modifyGroup(state, action) {
            const { group } = action;
            let list = state.groupList;
            let dirty = false;
            for(let i = 0; i < list.length; i++) {
                let l = list[i];
                if(l.code === group.code) {
                    for(let k in l) {
                        if(group[k] !== undefined && l[k] !== group[k]) {
                            l[k] = group[k];
                            dirty = true;
                        }
                    }
                    break;
                }
            }
            return Object.assign({}, state, {groupDirty: dirty, groupList: list});
        },
        modifyGroups(state, action) {
            const { groups } = action;
            let list = state.groupList;
            const modifyGroupCodes = groups.map(g => g.code);

            list = list.filter(l => modifyGroupCodes.indexOf(l.code) === -1);
            list = list.concat(groups);

            return Object.assign({}, state, {groupList: list});
        },
        deleteGroup(state, action) {
            const { group } = action;
            let list = state.groupList;
            for(let i = 0; i < list.length; i++) {
                let l = list[i];
                if(l.code === group.code) {
                    list.splice(i, 1);
                    break;
                }
            }
            return Object.assign({}, state, {groupList: list});
        },
        setGroupDirty(state, action) {
            let dirty = action.dirty;
            return Object.assign({}, state, {groupDirty: dirty});
        },
        setDataSourceGroup(state, action) {
            const { dataSourceCode, groupCode } = action;
            let list = state.list;
            for(let i = 0; i < list.length; i++) {
                let l = list[i];
                if(l.code === dataSourceCode) {
                    l.groupCode = groupCode;
                    break;
                }
            }
            return Object.assign({}, state, {list: list});
        }
    },
    effects: {
        *fetchList(action, { select, call, put, takeEvery, takeLatest }) {
            const body = {};
            try {
                const dataSource = yield select(state => state.present.dataSource);
                if(!action.mandatory && dataSource.list.length > 0) {
                    return;
                }
                const res = yield call(service.fetch, {
                    url: URLS.DATASOURCE_LIST,
                    body
                });
                
                console.log('请求数据源列表', body, res);
                if(!res.err && res.data.code > 0) {
                    let list = res.data.data.map((r, i) => {
                        let dbConfig = JSON.parse(r.dbConfig);
                        let tags = JSON.parse(r.dataTag);
                        return {
                            key: r.dataId,
                            code: r.dataId,
                            name: r.dataName,
                            type: r.type || 'database',
                            dbType: dbConfig.databaseType,
                            creator: r.createBy,
                            createTime: new Date(r.createDate),
                            tags: tags,
                            description: r.note,
                            groupCode: r.connectorGroup+''
                        }
                    });
                    yield put({ type: 'list', list });
                }else {
                    message.error('读取数据源列表错误: ' + (res.err || res.data.msg));
                }
            }catch(e) {
                console.log(e);
                message.error('读取数据源列表错误');
            }
            
        },
        *remoteAdd(action, { select, call, put }) {
            const dataSource = yield select(state => state.present.dataSource);
            const model = dataSource.newOne;
            try {
                const data = {
                    dataName: model.name,
                    note: model.description,
                    loadObject: model.target,
                    dataTag: model.tags,
                    type: model.type,
                    createBy: 'admin',
                    dbConfig: {
                        id: model.connectCode,
                        addrass: model.address,
                        port: model.port,
                        databaseType: model.dbType,
                        dataName: model.dbName,
                        userName: model.userName,
                        passWord: model.password
                    },
                    columnConfig: model.columns.map((c, i) => {
                        return {
                            columnName: c.name,
                            columnLable: c.alias || c.description || c.name,
                            dataType: c.dataType,
                            columnType: c.columnType,
                            isGroup: c.groupable?'1':'0',
                            isFilter: c.filterable?'1':'0',
                            isSubsection: c.bucketizable?'1':'0',
                            isOpen: c.using?'1':'0',
                            remarks: c.description
                        }
                    }),
                    connectorGroup: model.group ? model.group : '-1'
                };
                const res = yield call(service.fetch, {
                    url: URLS.DATASOURCE_ADD,
                    body: data
                });
                console.log('新增数据源', data, res);
                if(!res.err && res.data.code > 0) {
                    yield put({ type: 'fetchList', mandatory: true });
                    yield put({ type: 'main/redirect', path: { pathname: '/datasource' } });
                    message.success('新增成功');
                }else {
                    message.error('新增失败: ' + (res.err || res.data.msg));
                }
            }catch(e) {
                message.error('新增失败');

            }
        },
        *remoteDetail(action, { select, call, put }) {
            try {
                const code = action.code;
                const dataSource = yield select(state => state.present.dataSource);
                const model = dataSource.newOne;
                if((code + '') === (model.code + '')) {
                    return;
                }
                const res = yield call(service.fetch, {
                    url: URLS.DATASOURCE_DETAIL,
                    body: code
                });
                console.log('解析数据源', code, res);
                if(!res.err && res.data.code > 0) {
                    let resData = res.data.data;
                    let columnConfig = JSON.parse(resData.columnConfig);
                    let dbConfig = JSON.parse(resData.dbConfig);
                    let tags = JSON.parse(resData.dataTag);
                    let data = {
                        code: resData.dataId,
                        name: resData.dataName,
                        type: resData.type,
                        connectCode: dbConfig.id,
                        dbType: dbConfig.databaseType,
                        dbName: dbConfig.dataName,
                        address: dbConfig.addrass,
                        port: dbConfig.port,
                        target: resData.loadObject,
                        creator: resData.createBy,
                        createTime: new Date(resData.createDate),
                        userName: dbConfig.userName,
                        password: dbConfig.passWord,
                        tags: tags,
                        description: resData.note,
                        group: resData.connectorGroup+'',
                        columns: columnConfig.map((c, i) => {
                            return {
                                key: i,
                                using: c.isOpen==='1'?true:false,
                                name: c.columnName,
                                alias: c.columnLable,
                                dataType: c.dataType,
                                columnType: c.columnType,
                                groupable: c.isGroup==='1'?true:false,
                                filterable: c.isFilter==='1'?true:false,
                                bucketizable: c.isSubsection==='1'?true:false,
                                description: c.remarks
                            }
                        })
                    }
                    yield put({ type: 'setNewModel', model: data });
                }else {
                    message.error('数据源解析错误: ' + (res.err || res.data.msg));
                }
            }catch(e) {
                console.log(e);
                message.error('数据源解析错误');
                yield put({ type: 'list', list: [] });
            }
        },
        *importNewModelColumns(action, { select, call, put }) {
            const dataSource = yield select(state => state.present.dataSource);
            const sqlStr = dataSource.newOne.target;
            let body = {
                id: dataSource.newOne.connectCode,
                strSql: sqlStr
            };
            try{
                const res = yield call(service.fetch, {
                    url: URLS.DATASOURCE_QUERY_SQLCOLUMNS,
                    body: body
                });
    
                const getColumnType = (dataType) => {
                    return DEFAULT_COLUMN_TYPE[dataType] || 'categorical';
                }
    
                console.log('请求列数据', body, res);

                if(!res.err && res.data.code > 0) {
                    let columns = res.data.data.map((d, i) => {
                        return {
                            key: i,
                            using: true,
                            name: d,
                            alias: d.remarks ? d.remarks.substring(0, 10) : (d),
                            dataType: d.columnType,
                            columnType: getColumnType(d.columnType),
                            // groupable: d.columnType === 'VARCHAR2',
                            groupable: true,
                            filterable: true,
                            bucketizable: d.columnType === 'NUMBER',
                            description: d.remarks
                        }
                    });
                    yield put({ type: 'setNewModelInvalidSQL', value: columns.length === 0 });
                    yield put({ type: 'setNewModelField', name: 'columns', value: columns });
                }else {
                    yield put({ type: 'setNewModelInvalidSQL', value: true });
                    yield put({ type: 'setNewModelField', name: 'columns', value: [] });
                }
            }catch(e) {
                yield put({ type: 'setNewModelInvalidSQL', value: true });
                yield put({ type: 'setNewModelField', name: 'columns', value: [] });
                message.error('请求列数据错误');
            }
        },
        *remoteDelete(action, { select, call, put }) {
            const dataSource = yield select(state => state.present.dataSource);
            const code = action.code;
            let list = dataSource.list;
            try {
                const res = yield call(service.fetch, {
                    url: URLS.DATASOURCE_DELETE,
                    body: [code]
                });
                if(!res.err && res.data.code > 0) {
                    for(let i = 0; i < list.length; i++) {
                        if((list[i].code + '') === (code + '')) {
                            list.splice(i, 1);
                            break;
                        }
                    }
                    yield put({ type: 'list', list });
                    message.success('删除成功');
                }else {
                    message.error('删除失败: ' + (res.err || res.data.msg));
                }
            }catch(e) {
                console.log(e);
                message.error('删除失败');
            }
        },
        *remoteModify(action, { select, call, put }) {
            try{
                const dataSource = yield select(state => state.present.dataSource);
                let model = action.model || dataSource.newOne;
                const code = model.code;
    
                let data = {
                    dataId: code,
                    dataName: model.name,
                    note: model.description,
                    loadObject: model.target,
                    dataTag: model.tags,
                    type: model.type,
                    createBy: 'admin',
                    connectorGroup: model.group ? model.group : '-1',
                    dbConfig: model.address ? {
                        addrass: model.address,
                        port: model.port,
                        databaseType: model.dbType,
                        dataName: model.dbName,
                        userName: model.userName,
                        passWord: model.password
                    } : '',
                    columnConfig: model.columns ? model.columns.map((c, i) => {
                        return {
                            columnName: c.name,
                            columnLable: c.alias || c.description || c.name,
                            dataType: c.dataType,
                            columnType: c.columnType,
                            isGroup: c.groupable?'1':'0',
                            isFilter: c.filterable?'1':'0',
                            isSubsection: c.bucketizable?'1':'0',
                            isOpen: c.using?'1':'0',
                            remarks: c.description
                        }
                    }) : '',
                };
                const res = yield call(service.fetch, {
                    url: URLS.DATASOURCE_UPDATE,
                    body: data
                });
                console.log('修改数据源', data, res);
                if(!res.err && res.data.code > 0) {
                    yield put({ type: 'fetchList', mandatory: true });
                    message.success('修改成功');
                }else {
                    message.error('修改失败: ' + (res.err || res.data.msg));
    
                }
            }catch(e) {
                console.log(e);
                message.error('修改失败');
            }
        },

        *remoteGroupList(action, { select, call, put }) {
            try {
                const dataSource = yield select(state => state.present.dataSource);
                if(!action.mandatory && dataSource.groupList.length > 0) {
                    return;
                }
                const res = yield call(service.fetch, {
                    url: URLS.GROUP_DATASOURCE_LIST,
                });
                
                console.log('请求数据源分组列表', res);
                if(!res.err && res.data.code > 0) {
                    const resData = res.data.data;
                    let data = resData.map(d => {
                        return {
                            code: d.id+'',
                            pcode: d.fatherId+'',
                            index: +d.groupIndex,
                            label: d.groupName+'',
                        }
                    });
                    yield put({ type: 'groupList', data });
                }else {
                    message.error('请求数据源列表错误: ' + (res.err || res.data.msg));
                }
            }catch(e) {
                console.log(e);
                message.error('请求数据源列表错误');
            }
        },
        /**
         * 新增分组/子分组，需要传入父节点code
         */
        *remoteAddGroup(action, { select, call, put }) {
            try {
                const dataSource = yield select((state) => state.present.dataSource);
                const group = dataSource.groupList;
                const pgroups = group.filter(g => g.pcode === '-1');
                const cgroups = group.filter(g => g.pcode !== '-1');
                const { pgroup } = action;

                let body = {};
                if(pgroup) {
                    body = {
                        fatherId: pgroup.code,
                        groupName: '新子分组',
                        groupIndex: cgroups.filter(c => c.pcode === pgroup.code).length,
                        createBy: 'zhuth'
                    }
                }else {
                    body = {
                        fatherId: '-1',
                        groupName: '新分组',
                        groupIndex: pgroups.length,
                        createBy: 'zhuth'
                    }
                }
                const res = yield call(service.fetch, {
                    url: URLS.GROUP_DATASOURCE_ADD,
                    body: body
                });
                console.log('新增数据源分组', body, res);
                if(!res.err && res.data.code > 0) {
                    let group = {
                        code: res.data.data + '',
                        pcode: body.fatherId + '',
                        index: body.groupIndex,
                        label: body.groupName+'',
                    }
                    yield put({ type: 'addGroup', group });
                }else {
                    message.error('新增分组失败: ' + (res.err || res.data.msg));
                }
            }catch(e) {
                console.log(e);
                message.error('新增分组失败');
            }
        },
        /**
         * 修改单个分组信息（因为不涉及顺序号的修改，所以一般只用于label的修改）
         */
        *remoteModifyGroup(action, { select, call, put }) {
            try {
                const dataSource = yield select((state) => state.present.dataSource);
                const groupDirty = dataSource.groupDirty;
                const group = action.group;

                if(!groupDirty) { // 如果属性无改动则取消修改请求
                    return;
                }
                let body = {
                    id: group.code,
                    fatherId: group.pcode,
                    groupName: group.label,
                    groupIndex: group.index,
                    createBy: 'zhuth'
                }
                const res = yield call(service.fetch, {
                    url: URLS.GROUP_DATASOURCE_UPDATE,
                    body: body
                });
                console.log('修改数据源分组', body, res);
                if(!res.err && res.data.code > 0) {
                    yield put({ type: 'setGroupDirty', dirty: false });
                }else {
                    message.error('修改分组失败: ' + (res.err || res.data.msg));
                }
            }catch(e) {
                console.log(e);
                message.error('修改分组失败');
            }
        },
        /**
         * 批量修改多个分组信息(在移动位置时用)
         */
        *remoteModifyGroups(action, { select, call, put }) {
            try {
                const groups = action.groups;

                let body = groups.map(g => {
                    return {
                        id: g.code,
                        groupName: g.label,
                        groupIndex: g.index,
                        fatherId: g.pcode,
                        createBy: 'zhuth'
                    }
                });
                const res = yield call(service.fetch, {
                    url: URLS.GROUP_DATASOURCE_LIST_UPDATE,
                    body: body
                });
                
                console.log('批量修改数据源分组', body, res);
                if(!res.err && res.data.code > 0) {
                    yield put({ type: 'modifyGroups', groups: groups });
                }else {
                    message.error('修改分组失败: ' + (res.err || res.data.msg));
                }
            }catch(e) {
                console.log(e);
                message.error('修改分组失败');
            }
        },
        *remoteDeleteGroup(action, { select, call, put }) {
            try {
                const dataSource = yield select((state) => state.present.dataSource);
                const groupList = dataSource.groupList;
                const { group } = action;

                let bgroups = groupList.filter(l => l.pcode === group.pcode);
                bgroups.splice(group.index, 1);
                bgroups = bgroups.map((b, i) => {
                    return { ...b, index: i }
                });

                yield put({ type: 'remoteModifyGroups', groups: bgroups });

                const res = yield call(service.fetch, {
                    url: URLS.GROUP_DATASOURCE_DELETE,
                    body: [group.code]
                });
                
                console.log('删除分组', group.code, res);
                if(!res.err && res.data.code > 0) {
                    yield put({ type: 'deleteGroup', group});
                }else {
                    message.error('删除分组失败: ' + (res.err || res.data.msg));
                }
            }catch(e) {
                console.log(e);
                message.error('删除分组失败');
            }
        },
        *remoteMoveGroup(action, { select, call, put }) {
            try {
                const { dragCode, dropCode, dropPosition } = action;
                const dataSource = yield select((state) => state.present.dataSource);
                let group = dataSource.groupList;

                const dragGroup = group.filter(g => g.code === dragCode)[0];
                const dropGroup = group.filter(g => g.code === dropCode)[0];

                let modifyGroups = [];
                if((dragGroup.pcode === '-1' || dropGroup.pcode === '-1') && (dragGroup.pcode !== dropGroup.pcode)) { // 跨级
                    console.log('跨级');
                    if(dropGroup.pcode !== '-1') { // 从父级到子级
                        console.log('error');
                        return; // 不允许
                    }else { // 从子级到父级
                        if(dragGroup.pcode === dropGroup.code) { // 不跨组
                            if(dropPosition === -1) { // 目标前
                                console.log('before');
                                let dragGroups = group.filter(g => g.pcode === dragGroup.pcode).sort((a, b) => a.index - b.index);
                                let dropGroups = group.filter(g => g.pcode === dropGroup.pcode).sort((a, b) => a.index - b.index);
                                dragGroups.splice(dragGroup.index, 1);
                                dragGroups = dragGroups.map((g, i) => {
                                    return { ...g, index: i }
                                });
                                dropGroups.splice(dropGroup.index, 0, dragGroup);
                                dropGroups = dropGroups.map((g, i) => {
                                    return { ...g, index: i, pcode: dropGroup.pcode }
                                });
                                modifyGroups = modifyGroups.concat(dragGroups, dropGroups);
                            }else if(dropPosition === 0) { // 目标内
                                console.log('nothing');
                                return; // 无变化
                            }else if(dropPosition === 1) { // 目标后
                                console.log('after');
                                let dragGroups = group.filter(g => g.pcode === dragGroup.pcode).sort((a, b) => a.index - b.index);
                                let dropGroups = group.filter(g => g.pcode === dropGroup.pcode).sort((a, b) => a.index - b.index);
                                dragGroups.splice(dragGroup.index, 1);
                                dragGroups = dragGroups.map((g, i) => {
                                    return { ...g, index: i }
                                });
                                dropGroups.splice(dropGroup.index + 1, 0, dragGroup);
                                dropGroups = dropGroups.map((g, i) => {
                                    return { ...g, index: i, pcode: dropGroup.pcode }
                                });
                                modifyGroups = modifyGroups.concat(dragGroups, dropGroups);
                            }
                        }else { // 跨组
                            let dragGroups = group.filter(g => g.pcode === dragGroup.pcode).sort((a, b) => a.index - b.index);
                            let dropGroups = group.filter(g => g.pcode === dropGroup.pcode).sort((a, b) => a.index - b.index);
                            let dropChildrenGroups = group.filter(g => g.pcode === dropGroup.code).sort((a, b) => a.index - b.index);
                            
                            dragGroups.splice(dragGroup.index, 1);
                            dragGroups = dragGroups.map((g, i) => {
                                return { ...g, index: i }
                            });
                            if(dropPosition === -1) { // 目标前
                                console.log('before');
                                dropGroups.splice(dropGroup.index, 0, dragGroup);
                                dropGroups = dropGroups.map((g, i) => {
                                    return { ...g, index: i, pcode: dropGroup.pcode }
                                });
                                modifyGroups = modifyGroups.concat(dragGroups, dropGroups);
                            }else if(dropPosition === 0) { // 目标内
                                console.log('in');
                                dropChildrenGroups.push({
                                    ...dragGroup,
                                    index: dropChildrenGroups.length,
                                    pcode: dropGroup.code
                                });
                                modifyGroups = modifyGroups.concat(dragGroups, dropChildrenGroups);
                            }else if(dropPosition === 1) { // 目标后
                                console.log('after');
                                dropGroups.splice(dropGroup.index + 1, 0, dragGroup);
                                dropGroups = dropGroups.map((g, i) => {
                                    return { ...g, index: i, pcode: dropGroup.pcode }
                                });
                                modifyGroups = modifyGroups.concat(dragGroups, dropGroups);
                            }
                        }
                    }
                }else { // 不跨级
                    console.log('不跨级');
                    if(dragGroup.pcode === dropGroup.pcode) { // 不跨组
                        console.log('不跨组');
                        let dGroups = group.filter(g => g.pcode === dragGroup.pcode).sort((a, b) => a.index - b.index);
                        dGroups.splice(dragGroup.index, 1, {code: 'temp', index: dragGroup.index});
                        if(dropPosition === -1) { // 目标前
                            console.log('before');
                            dGroups.splice(dropGroup.index, 0, dragGroup);
                            dGroups = dGroups.filter(g => g.code !== 'temp').map((g, i) => {
                                return { ...g, index: i }
                            });
                            modifyGroups = modifyGroups.concat(dGroups);
                        }else if(dropPosition === 0) { // 目标内
                            console.log('in');
                            return;
                        }else if(dropPosition === 1) { // 目标后
                            console.log('after');
                            dGroups.splice(dropGroup.index + 1, 0, dragGroup);
                            dGroups = dGroups.filter(g => g.code !== 'temp').map((g, i) => {
                                return { ...g, index: i }
                            });
                            modifyGroups = modifyGroups.concat(dGroups);
                        }
                    }else { // 跨组
                        console.log('跨组');
                        let dragGroups = group.filter(g => g.pcode === dragGroup.pcode).sort((a, b) => a.index - b.index);
                        let dropGroups = group.filter(g => g.pcode === dropGroup.pcode).sort((a, b) => a.index - b.index);
                        
                        dragGroups.splice(dragGroup.index, 1);
                        dragGroups = dragGroups.map((g, i) => {
                            return { ...g, index: i }
                        });
                        for(let i = 0; i < dropGroups.length; i++) {
                            if(dropGroups[i].code === dropGroup.code) {
                                if(dropPosition === -1) { // 目标前
                                    console.log('before');
                                    dropGroups.splice(i, 0, dragGroup);
                                    dropGroups = dropGroups.map((g, i) => {
                                        return { ...g, index: i, pcode: dropGroup.pcode }
                                    });
                                    modifyGroups = modifyGroups.concat(dragGroups, dropGroups);
                                }else if(dropPosition === 0) { // 目标内
                                    console.log('in');
                                    return; // 不允许
                                }else if(dropPosition === 1) { // 目标后
                                    console.log('after');
                                    dropGroups.splice(i + 1, 0, dragGroup);
                                    dropGroups = dropGroups.map((g, i) => {
                                        return { ...g, index: i, pcode: dropGroup.pcode }
                                    });
                                    modifyGroups = modifyGroups.concat(dragGroups, dropGroups);
                                }
                                break;
                            }
                        }
                    }
                }
                console.log(dragGroup, dropGroup, modifyGroups);
                yield put({ type: 'remoteModifyGroups', groups: modifyGroups });
            }catch(e) {
                console.log(e);
                message.error('位置调整失败');
            }
        },
        /**
         * 为数据源设置所属分组
         */
        *remoteSetDataSourceGroup(action, { select, call, put }) {

            const { dataSource, group } = action;
            const dataSourceCode = dataSource.code;
            const groupCode = group.code;
            try {
                let body = { 
                    id: dataSourceCode,
                    groupId: groupCode
                }
                let res = yield call(service.fetch, {
                    url: URLS.GROUP_DATASOURCE_SET_GROUP,
                    body: body
                });
                console.log('设置数据源所属分组', body, res);
                if(!res.err && res.data.code > 0) {
                    yield put({ type: 'setDataSourceGroup', dataSourceCode, groupCode });
                }else {
                    message.error('设置分组失败: ' + (res.err || res.data.msg));
                }
            } catch(e) {
                console.log(e);
                message.error('设置分组失败');
            }
        },
        *transfer(action, { put, call, select }) {
            const { userCode, dataSourceCode } = action;
            const body = {
                userId: userCode,
                id: dataSourceCode
            };
            try {
                const res = yield call(service.fetch, {
                    url: URLS.DATASOURCE_TRANSFER,
                    body
                });
                console.log('数据源移交', body, res);
                if(!res.err && res.data.code > 0) {
                    const dataSource = yield select(state => state.present.dataSource);
                    const list = dataSource.list;
                    for(let i = 0; i < list.length; i++) {
                        if(list[i].code === dataSourceCode) {
                            list.splice(i, 1);
                            break;
                        }
                    }
                    yield put({ type: 'list', list });
                    message.success('移交成功');
                }else {
                    console.log(body, res.err || res.data.msg);
                    message.error('移交失败');
                }
            }catch(e) {
                console.log(body, e);
                message.error('移交失败');
            }
        }
    },
    subscriptions: {
        setup({ dispatch, history }) {
            return history.listen(({ pathname, query }) => {
            })
        }
    }
};