123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345 |
- const app = getApp()
- Page({
- query: {},
- data: {
- view: 'graph',
- frameStyle: { useTop: true, name: '赛程管理', leftArrow: true, useBar: false },
- canvasWidth: 375,
- canvasHeight: 600,
- pixelRatio: 1,
- forceMini: false,
- // 数据
- data: undefined,
- riseList: [],
- arrangeList: [],
- raceList: [],
- groundList: [],
- refereeList: [],
- arrangeData: {},
- // picker
- show: false,
- personList: [],
- selectNode: undefined
- },
- // 计算晋级图
- computedTreeData() {
- const getWinnerNumList = this.data.riseList; // 将每个小组取多少人收到1个纯数字的数组中
- const getWinnerNum = getWinnerNumList.reduce((p, n) => p + n, 0); // 小组赛选取人数: 应该是该比赛项目的 各组选取人数加和
- let level = 1;
- let loop = true;
- while (loop) {
- const needUserNum = 2 ** (level - 1);
- // 相等,说明已经计算出结果
- if (needUserNum === getWinnerNum) loop = false;
- // 小于,说明还可以继续往后计算
- else if (needUserNum < getWinnerNum) level++;
- else {
- // 大于,说明不符合淘汰赛安排,需要手动定位
- loop = false;
- level = NaN
- }
- }
- if (!level) {
- console.log('不继续,返回了,编不了数据')
- return;
- }
- const levelList = [];
- // 1:16;2:8;3:4;4:2
- for (let i = 0; i < level - 1; i++) {
- const t = level - i - 1;
- // 计算:该层的位置数量
- const number = 2 ** t;
- const arr = [];
- for (let j = 1; j <= number; j++) {
- const obj = { id: `${i}-${j}`, num: `${i}-${j}`, pos: [i, j] }
- arr.push(obj);
- }
- levelList.push(arr)
- }
- // 进行数据组合,从最少的入手,依次取回,然后将取出来的数据删除掉
- let getLevelIndex = levelList.length - 1;
- const data = this.resetData(levelList, getLevelIndex)
- let obj = { id: `${levelList.length}`, num: `${levelList.length}`, children: data }
- return obj;
- },
- resetData(dataList, index = 0) {
- const thisLevelList = dataList[index]
- // 取出2条数据
- const p1 = thisLevelList[0]
- const p2 = thisLevelList[1]
- // 删除取出的2条数据
- dataList[index].shift()
- dataList[index].shift()
- if (index - 1 < 0) return [p1, p2]
- const p1c = this.resetData(dataList, index - 1)
- const p2c = this.resetData(dataList, index - 1)
- p1.children = p1c
- p2.children = p2c;
- return [p1, p2]
- },
- // 点击节点事件
- nodeTap(e) {
- const node = e.detail;
- if (!node) return;
- this.setData({ selectNode: node })
- this.toOpen();
- },
- // 获取最基础的那一层节点数据
- getFirstLevelNodes(node) {
- if (!node.children) return node;
- const res = [];
- const nodes = node.children;
- for (const node of nodes) {
- if (node?.children) {
- let list = this.getFirstLevelNodes(node);
- res.push(list);
- } else {
- res.push(node)
- }
- }
- return res.flat();
- },
- // 选择人员的处理
- selectChange(changeNode, selectNode) {
- const obj = { player_name: changeNode.label, player_id: changeNode.value, node_id: selectNode.id, label: 'player_name', pos: selectNode.pos }
- const arrangeList = this.data.arrangeList;
- const i = arrangeList.findIndex(f => f.player_id === obj.player_id && f.pos && obj.pos && f.pos[0] === obj.pos[0])
- if (i >= 0) arrangeList.splice(i, 1)
- arrangeList.push(obj)
- this.setData({ arrangeList })
- // 并非使用数据重组的方式,将选择的数据放入创建晋级图的数据中心,而是使用一维数组,以节点id对应的方式进行数据更新,更为灵活
- // 接下来需要生成比赛信息的数据
- this.getRaceList();
- },
- // 设置比赛数据
- getRaceList() {
- const arrangeList = this.data.arrangeList;
- arrangeList.sort((a, b) => {
- if (!a.pos) return b - a
- else if (!b.pos) return a - b
- else {
- // 根据 晋级节点位置,小组内节点位置进行排序
- const a1 = a.pos[0]
- const b1 = b.pos[0]
- if (a1 - b1 !== 0) return a1 - b1
- else {
- const a2 = a.pos[1]
- const b2 = b.pos[1]
- return a2 - b2
- }
- }
- })
- const raceList = [];
- for (let i = 0; i < arrangeList.length; i += 2) {
- const d1 = arrangeList[i]
- const d2 = arrangeList[i + 1]
- // 前后缺项,没法比赛
- if (!(d1 && d2)) continue;
- const { pos: d1pos } = d1
- const { pos: d2pos } = d2;
- // 前后两项的层级不一样,不能形成比赛
- if (d1pos[0] !== d2pos[0]) continue
- // 前后两项层级一样,但是不是连续的数字,例如:1-1与1-3,不能进行比赛,必须是 前+1=后
- if (d1pos[1] + 1 !== d2pos[1]) continue
- const { player_id: player_one, player_name: player_name_one, node_id: node_id_one } = d1
- const { player_id: player_two, player_name: player_name_two, node_id: node_id_two } = d2
- raceList.push({ player_one, player_name_one, node_id_one, player_two, player_name_two, node_id_two })
- }
- // 因为是数组,所以需要将model特殊处理下,按照一定规则处理可以正常赋值
- for (let i = 0; i < raceList.length; i++) {
- const d = raceList[i];
- d.groundModelName = `ground_id-${i}`;
- d.refereeModelName = `referee_id-${i}`;
- d.timeModelName = `match_time-${i}`;
- }
- const oRaceList = this.data.raceList;
- for (const race of raceList) {
- const { node_id_one, node_id_two } = race;
- const r = oRaceList.find(f => f.node_id_one === node_id_one && f.node_id_two === node_id_two)
- if (r) {
- const ri = oRaceList.findIndex(f => f.node_id_one === node_id_one && f.node_id_two === node_id_two)
- const { groundModelName, refereeModelName, timeModelName } = race
- r = { ...r, groundModelName, refereeModelName, timeModelName }
- oRaceList.splice(ri, 1, r)
- } else {
- oRaceList.push(race)
- }
- }
- this.setData({ raceList: oRaceList })
- },
- async onLoad(options) {
- console.log(options);
- const { match_id, grouping_id, project_id } = options
- this.query = { match_id, grouping_id, project_id }
- await this.getTeams()
- // 设置初始的晋级图
- const data = this.computedTreeData();
- this.setData({ data })
- // 请求 小组赛的 胜者列表
- await this.searchWinnerList();
- await this.search();
- await this.searchOthers()
- },
- // 查询已安排的数据
- async search() {
- let res = await app.$get(`/newCourt/api/eliminatArrange/getOne`, this.query)
- if (app.$checkRes(res)) {
- if (res.data) { const { arrange } = res.data; this.setData({ arrangeData: res.data, arrangeList: arrange }) }
- }
- res = await app.$get(`/newCourt/api/eliminateRace`, this.query)
- if (app.$checkRes(res)) {
- this.setData({
- raceList: res.data
- })
- }
- // 数据本地化处理下
- this.getRaceList();
- },
- // 获取该项目的小组,形成晋级图
- async getTeams() {
- const res = await app.$get(`/newCourt/api/raceTeam`, this.query)
- if (app.$checkRes(res)) {
- const { data } = res
- const riseList = data.map(i => i.rise)
- this.setData({ riseList })
- }
- },
- // 获取小组赛胜者名单
- async searchWinnerList() {
- const res = await app.$post(`/newCourt/api/race/getWinnerList`, this.query)
- if (app.$checkRes(res)) {
- const { data } = res;
- const arr = [];
- for (const i of data) {
- const { personList, name } = i;
- for (const person of personList) {
- // person.player_name += `(${name})`;
- const obj = { label: person.player_name, value: person.player_id }
- arr.push(obj)
- }
- }
- this.setData({
- personList: arr
- })
- }
- },
- /**自动排列最底层,挨个放 */
- toAutoInitData() {
- const personList = this.data.personList;
- const data = this.data.data
- const getBaseList = data => {
- if (!data.children) return data;
- const arr = [];
- for (const d of data.children) {
- const r = getBaseList(d)
- arr.push(r);
- }
- return arr.flat();
- }
- const firstList = getBaseList(data);
- for (let i = 0; i < firstList.length; i++) {
- const f = firstList[i];
- const p = personList[i];
- this.selectChange(p, f);
- }
- },
- /**查询选项的数据 */
- async searchOthers() {
- let res;
- res = await app.$get(`/newCourt/api/ground`)
- if (app.$checkRes(res)) {
- this.setData({ groundList: res.data })
- }
- res = await app.$get(`/newCourt/api/user`, { type: '1' })
- if (app.$checkRes(res)) {
- this.setData({ refereeList: res.data })
- }
- },
- turnView(e) {
- const view = e?.target?.dataset?.view || 'graph';
- this.setData({ view })
- },
- //picker
- onChange(event) {
- const obj = event?.detail?.value;
- this.selectChange(obj, this.data.selectNode);
- this.toClose();
- },
- toOpen() {
- this.setData({ show: true })
- },
- toClose() {
- this.setData({ show: false, selectNode: undefined })
- },
- toSelected(event) {
- const data = event?.detail;
- const { value, model } = data;
- if (!model) return;
- const arr = model.split('-')
- const modelName = arr[0]
- const index = arr[1]
- const raceList = this.data.raceList;
- raceList[index][modelName] = value;
- this.setData({ raceList })
- },
- // 跳转菜单
- back(e) {
- wx.navigateBack({
- delta: 1,
- })
- },
- async toSubmit() {
- // 生成的比赛信息
- let raceList = this.data.raceList;
- // 安排信息
- let arrangeList = this.data.arrangeList;
- // arrangeList:需要将match_id,grouping_id,project_id 也放入,确定是这个项目的淘汰赛
- let arrange = this.data.arrangeData;
- if (!arrange._id) {
- arrange = { arrange: arrangeList, ...this.query }
- }
- // raceList:淘汰赛的比赛赛程
- raceList = raceList.map(i => {
- const { groundModelName, refereeModelName, timeModelName, ...others } = i
- return { ...others, ...this.query }
- })
- // 创建安排
- let res
- if (arrange._id) {
- res = await app.$post(`/newCourt/api/eliminatArrange/${arrange._id}`, arrange)
- if (app.$checkRes(res)) {
- console.log('淘汰赛安排创建成功')
- }
- } else {
- res = await app.$post(`/newCourt/api/eliminatArrange`, arrange)
- if (app.$checkRes(res)) {
- console.log('淘汰赛安排创建成功')
- }
- }
- res = await app.$post('/newCourt/api/eliminateRace/saveAll', raceList)
- wx.showToast({
- title: '保存成功',
- })
- }
- });
|