const app = getApp(); const nodeSetting = function (node) { node.label = node.name return node; }; const edgeSetting = function (edge) { return edge; } //调试用 // const prefix = 'http://192.168.1.197:15001/newCourt/race/v2/api' const prefix = '' Page({ data: { frameStyle: { useTop: true, name: '添加赛程', leftArrow: true, useBar: false }, match_id: '', group_id: '', project_id: '', loadChart: false, winData: {}, loseData: {}, schList: [], playerList: [], canvasWidth: 375, canvasHeight: 600, pixelRatio: 2, edgeSetting, nodeSetting, tabs: { active: 'a', menu: [ { title: '比赛流程', active: 'a' }, { title: '败者组流程', active: 'b' }, { title: '赛事赛程', active: 'c' }, ], }, show: false, selectNode: {}, dialog: { title: '添加信息', show: false, type: '1' }, form: {}, // 场地 addressList: [], // 裁判列表 refereeList: [], // 状态列表 statusList: [], }, // 返回 back: function () { wx.navigateBack({ delta: 1 }) }, // 修改 toEdit: function (e) { const that = this; const { item } = e.currentTarget.dataset; if (item._id) { that.setData({ form: item }) that.setData({ dialog: { title: '添加信息', show: true, type: '1' } }) } }, // 场地 addressChange: async function (e) { const that = this; let data = that.data.addressList[e.detail.value]; if (data) { that.setData({ 'form.address_id': data.id, 'form.address_id_name': data.name }); } }, // 裁判 refereeChange: async function (e) { const that = this; let data = that.data.refereeList[e.detail.value]; if (data) { that.setData({ 'form.referee_id': data.id, 'form.referee_id_name': data.name }); } }, // 选择时间 datetimeChange: function (e) { const that = this; that.setData({ [`form.${e.detail.name}`]: e.detail.datetime }); }, // 选择状态 statusChange: function (e) { const that = this; let data = that.data.statusList[e.detail.value]; if (data) { that.setData({ 'form.status': data.value, 'form.zhStatus': data.label }); } }, //保存(单条) onSubmit: async function (e) { const that = this; let form = that.data.form; let player = that.data.schList.find(i => i.id == form.id) form = { ...form, player_one: player.player_one, player_two: player.player_two } let arr; if (form.id) { arr = await app.$post(`${prefix}/eliminate/${form.id}`, form, 'race'); if (arr.errcode == 0) { let data = arr?.data; let ri = this.data.schList.findIndex(f => f._id === form._id) if (ri >= 0) { const list = this.data.schList this.setStatus(data); list[ri] = data; this.setData({ schList: list }) } } } if (arr.errcode == '0') { wx.showToast({ title: `维护信息完成`, icon: 'success', duration: 2000 }); that.toClose(); } else wx.showToast({ title: `${arr.errmsg}`, icon: 'error', duration: 2000 }) }, // 关闭弹框 toClose: function () { const that = this; that.setData({ form: {} }) that.setData({ dialog: { title: '查询条件', show: false, type: '1' } }) }, /** * 生命周期函数--监听页面加载 */ onLoad: async function (options) { const that = this that.setData({ match_id: options.match_id, group_id: options.group_id, project_id: options.project_id }) await this.search(); await this.searchUser(); that.searchLevel(); }, /** * 查询函数 */ search: async function () { const that = this; const match_id = that.data.match_id; const group_id = that.data.group_id; const project_id = that.data.project_id; let arr; arr = await app.$get(`${prefix}/eliminate/graphData`, { match_id, group_id, project_id }, 'race'); if (arr.errcode == '0') { const { winData, loseData } = that.groupData(arr.data); const schList = that.schData(arr.data) that.setData({ winData, loseData, schList }) } arr = await app.$get(`${prefix}/eliminate/playerList`, { match_id, group_id, project_id }, 'race'); if (arr.errcode == '0' && arr.data.length > 0) { that.setData({ playerList: arr.data }) } }, // 查询赛事赛程 searchUser: async function () { const that = this; const match_id = that.data.match_id; const group_id = that.data.group_id; const project_id = that.data.project_id; const playerList = that.data.playerList; let arr; arr = await app.$get(`${prefix}/eliminate`, { match_id: match_id, group_id: group_id, project_id: project_id }, 'race'); if (arr.errcode == '0' && arr.total > 0) { for (const val of arr.data) { this.setNodeInfo(val) // 状态 this.setStatus(val); } that.setData({ schList: arr.data }); this.setTopPlayerName(); } }, searchLevel: function (e) { const that = this; let nodes = that.data.winData.nodes; nodes = nodes.filter(f => !f.id.includes('l')); let mls = nodes.map(i => i.level); let marr = []; for (const i of mls) { if (!marr.includes(i)) marr.push(i) } const group = marr.map(i => { const list = nodes.filter(f => f.level == i) return list; }) const schList = that.data.schList; for (const i of nodes) { const { level, id } = i; const r1 = group.find(f => f[0].level == level) let J1 = r1.length, J2 = J1 / 2; const r2 = schList.find(f => f.player_one_node == id) if (!r2) continue; r2.J1 = J1, r2.J2 = J2; } // let levels = {}; // for (const val of nodes) { // let level = val.level; // levels[level]; // if (levels[level]) { // levels[level].push(val); // } else { // let dui = [val]; // levels[level] = dui; // } // } // for (const val of nodes) { // let level = val.level; // let node = schList.find((i) => i.player_one_node == val.id); // let J1 = levels[level].length; // let J2 = levels[level].length / 2; // if (node) node.J1 = J1, node.J2 = J2; // } that.setData({ schList: schList }) }, /** * 同步图与赛程的人名 * @param {Object} data 赛程数据 */ setNodeInfo(data) { const { player_one, player_one_node, player_one_name, player_two, player_two_node, player_two_name } = data const setNode = (node_id, name) => { let data = this.data.winData; let r = data.nodes.find(f => f.id === node_id) if (r) { const ri = data.nodes.findIndex(f => f.id === node_id) r.name = name; data.nodes[ri] = r; this.setData({ winData: data }) return; } data = this.data.loseData; r = data.nodes.find(f => f.id === node_id) if (r) { const ri = data.nodes.findIndex(f => f.id === node_id) r.name = name; data.nodes[ri] = r; this.setData({ loseData: data }) return; } } if (player_one && player_one_node) setNode(player_one_node, player_one_name) if (player_two && player_two_node) setNode(player_two_node, player_two_name) }, /** * 设置状态中文 * @param {Object} data 赛程数据 */ setStatus(data) { let status = this.data.statusList.find(i => i.value == data.status) if (status) data.zhStatus = status.label; }, /** * 给所有顶点去找到选手 */ setTopPlayerName() { const func = type => { const { nodes, edges } = this.data[`${type}Data`]; // 顶点:是其他的target且不是任何节点的source const tops = nodes.filter(f => { const { id } = f; const r = edges.find(f => f.source === id) if (!r) return true }) if (tops.length <= 0) return; for (const t of tops) { const { id } = t; const es = edges.filter(f => f.target === id) const ns = nodes.filter(f => es.find(ef => ef.source === f.id)) const headNodeId = ns[0]?.id; const lastNodeId = ns[ns.length - 1]?.id const r = this.data.schList.find(f => (f.player_one_node === headNodeId && f.player_two_node === lastNodeId) || (f.player_one_node === lastNodeId && f.player_two_node === headNodeId)) if (!r) continue; const { player_one_score, player_one_name, player_two_score, player_two_name, status } = r // 未结束不查 if (status !== '2') continue; if (player_one_score > player_two_score) t.name = player_one_name else t.name = player_two_name const ri = nodes.findIndex(f => f.id === t.id) nodes[ri] = t; } this.setData({ [`${type}Data.nodes`]: nodes }) } func('win') func('lose') }, /** * 选中选手的处理 * @param {Object} selected 选中的选手数据 */ selectPlayer({ detail: selected }) { let node = this.data.selectNode; const { _id: player_id, name } = selected node = { ...node, player_id, name } let targetData; let type; if (node.mark && !node.mark.includes('w')) { // 需要进入胜者节点中进行查找 targetData = this.data.loseData.nodes type = 'lose' } else { targetData = this.data.winData.nodes type = 'win' } const i = targetData.findIndex(f => f.id === node.id) if (i < 0) { console.warn('未在合理的范围内找到更改的节点') return false } targetData[i] = node; this.setData({ [`${type}Data.nodes`]: targetData }) // 修改赛程部分 // 找到该节点的数据 const schList = this.data.schList; const sch = schList.find(f => f.player_one_node === node.id || f.player_two_node === node.id) if (!sch) { console.warn('没找到该节点所在的赛程') return } if (sch.player_one_node === node.id) { sch.player_one = node.player_id; sch.player_one_name = node.name; } else { sch.player_two = node.player_id; sch.player_two_name = node.name; } // const schIndex = schList.findIndex(f => f.player_one_node === node.id || f.player_two_node === node.id) // schList.splice(schIndex, 1, sch) // this.setData({ schList }) this.setData({ form: sch }) this.onSubmit(); }, /** * 选择节点并存储在selectNode变量中 * @param {Object} node 节点数据 */ nodeSelect({ detail: node }) { this.setData({ show: true, selectNode: node }) }, /** * 给流程图数据分组 * @param {Array} data 流程图数据 */ groupData(data) { const { nodes, edges } = data; // 按胜/败进行分组,显示在2个选项卡中 const winNodes = nodes.filter(f => !f.mark || f.mark.includes('w')) const winEdges = this.getNodesEdges(winNodes, edges); const loseNodes = nodes.filter(f => f.mark && !f.mark.includes('w')) const loseEdges = this.getNodesEdges(loseNodes, edges); return { winData: { nodes: winNodes, edges: winEdges }, loseData: { nodes: loseNodes, edges: loseEdges } } }, /** * 获取该图中的赛程列表 * @param {Object} data 流程图数据 */ schData(data) { const { edges } = data; let stop = false; const schList = []; let dupAll = JSON.parse(JSON.stringify(edges)) while (!stop) { const dup = JSON.parse(JSON.stringify(dupAll)) // 取出第一个关系 const head = dup[0] // 删除第一个关系 dup.shift(); // 查看是否有与第一个关系指向一个目标的地方 const r = dup.find(f => f.target === head.target) if (r) { // 有,则将这俩关系组为一个比赛,然后在dup中删除 const sch = { player_one_node: head.source, player_two_node: r.source } schList.push(sch) const ri = dup.find(f => f.target === head.target) dup.splice(ri, 1) } dupAll = dup; if (dupAll.length <= 0) stop = true } return schList; }, /** * 找到这些节点的边关系 * @param {Array} list 节点数据 * @param {Array} edges 所有的辺数据 */ getNodesEdges(list, edges) { const fedges = []; for (let i = 0; i < list.length; i += 2) { const n1 = list[i]; const n2 = list[i + 1] const n1id = n1.id; const n2id = n2.id if (!n1id || !n2id) continue; const n1e = edges.find(f => f.source === n1id) const n2e = edges.find(f => f.source === n2id) if (!n1e || !n2e) continue; const n1et = n1e.target; const n2et = n2e.target; if (n1et === n2et) fedges.push(n1e, n2e) } return fedges; }, tabsChange: function (e) { const that = this; let { active } = e.detail; that.setData({ 'tabs.active': active }); }, /** * 生命周期函数--监听页面显示 */ onShow: function () { this.setData({ loadChart: true }) const that = this; // 监听用户是否登录 that.watchLogin(); }, // 监听用户是否登录 watchLogin: async function () { const that = this; wx.getStorage({ key: 'raceuser', success: async res => { // 场地 let arr; arr = await app.$get(`${prefix}/matchAddress`, { belong_id: res.data._id, is_use: '0' }, 'race'); if (arr.errcode == '0') { that.setData({ addressList: arr.data }) } // 裁判 arr = await app.$get(`${prefix}/user`, { parent_id: res.data._id, type: '2' }, 'race') if (arr.errcode == '0') { for (const val of arr.data) { val.name = val.user_id.name } that.setData({ refereeList: arr.data }) } // 状态 arr = await app.$get(`/dict`, { code: 'schedule_status' }); if (arr.errcode == '0' && arr.total > 0) that.setData({ statusList: arr.data[0].list }); }, fail: async res => { wx.redirectTo({ url: '/pages/index/index' }) } }) }, })