极域教师端预览学生界面学生机按IP重排

Posted sjg20010414

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了极域教师端预览学生界面学生机按IP重排相关的知识,希望对你有一定的参考价值。

极域教师端,表格视图中可以按机器名或者IP地址进行排序,而学生桌面预览处通常是按第一次登录上来的顺序排列的,这个看起来不太方便。另外,我通常喜欢噢易保护系统在刚装好重启进入修改IP地址的时候,让所有学生机连接一遍教师机,这样干活快一点,但这有一个毛病,就是学生母机如果最先开启并登录,导致之后第一个登录的学生机器名显示不正确,而如果学生母机后来开启,那么它的机器名不正确——极域本身的逻辑是要求所有学生机都修改完毕IP地址,重启一遍进入,再去开启教师机,这样显示的机器名才会按顺序。

事实上,第一次登录上的班级信息,极域把它写入了配置文件,配置文件位置在软件配置中可以指定(我一般默认)。修改这个配置文件,就可以修改任何学生机的机器名,也可以移动它的位置。我的任务是按IP地址来命名机器名,同时按IP顺序摆放位置,所以,写了以下php脚本来完成任务:

<?php

const DEBUG = 0;

$path = 'C:/Users/Public/Documents';
$filenames = scandir($path);
$dirnames = array_values(array_filter($filenames, function ($name) 
    return substr($name, 0,  6) === '极域';
));
if (count($dirnames) === 0) exit('未找到 C:/Users/Public/Documents 下极域相关目录'.PHP_EOL);
$dirname = $dirnames[count($dirnames)-1];
$path .= '/'.$dirname.'/zime/Class Data';
is_dir($path) || exit($path.' 不是目录'.PHP_EOL); 

$filenames = scandir($path);
$clsnames = array_values(array_filter($filenames, function ($name) 
    return substr($name, -4,  4) === '.cls';
));
$cnt = count($clsnames);
if ($cnt === 0)  exit('No cls file found!!'.PHP_EOL);
$clsname = $clsnames[0];
foreach ($clsnames as $k => $v) 
    echo "[$k]  $v".PHP_EOL;

echo 'Please select cls file, input the number [ENTER = 0]:';
$selectedKey = intval(fread(STDIN, 10));
if ($selectedKey >= 0 && $selectedKey < $cnt)  $clsname = $clsnames[$selectedKey];

$fileName = $path.'/'.$clsname;
echo 'Please input the prefix for machine name (i.e. JF517-):';
INPUT_PREFIX:
$prefix = trim(fread(STDIN, 10));
if (empty($prefix)) 
	echo 'Prefix should not be empty!'.PHP_EOL. 'Prefix: ';
	goto INPUT_PREFIX;


//libxml_disable_entity_loader(true);  // 禁止引用外部实体
$xmlObj = simplexml_load_file($fileName, 'SimpleXMLElement', LIBXML_NOCDATA);
$json = json_encode($xmlObj);
$a = json_decode($json, true);
//var_dump($a['students']['student']);

usort($a['students']['student'], function ($a, $b) 
    $address1 = $a['address']['@attributes']['IP'];
    $address2 = $b['address']['@attributes']['IP'];
    $n1 = intval(explode('.', $address1)[3]);
    $n2 = intval(explode('.', $address2)[3]);
    return $n1 > $n2;
);
//var_dump($a['students']['student']);

$positions = [];
foreach ($a['students']['student'] as $i => $student) 
    $attrs = $student['posThumb']['@attributes'];
    $positions[$i] = ['x' => $attrs['x'], 'y' => $attrs['y']];


usort($positions, function ($a, $b) 
    if ($a['y'] == $b['y']) return $a['x'] > $b['x'];
    else return $a['y'] > $b['y'];
);

//foreach ($positions as $i => $pos)
//    echo $i."\\tx=".$pos['x']."\\ty=".$pos['y'].PHP_EOL;

$indent1 = '    ';
$indent2 = '        ';
$indent3 = '            ';
$result = '';
foreach ($a['students']['student'] as $i => $student) 
    $addressAttributes = $student['address']['@attributes'];
    $n = explode('.', $addressAttributes['IP'])[3];
    $result .= $indent2.'<student>'.PHP_EOL;
    $result .= $indent3.'<name>'.$prefix.
        str_pad($n, 2, '0', STR_PAD_LEFT).
        '</name>'.PHP_EOL;
    $result .= $indent3.'<address';
    foreach ($addressAttributes as $k => $v)
        $result .= ' '.$k.'="'.$v.'"';
    $result .= ' />'.PHP_EOL;
    $result .= $indent3.'<posThumb';
//    foreach ($student['posThumb']['@attributes'] as $k => $v)
//        $result .= ' '.$k.'="'.$v.'"';
    $result .= ' x="'.$positions[$i]['x'].'" y="'.$positions[$i]['y'].'"';
    $result .= ' />'.PHP_EOL;
    $result .= $indent3.'<group';
    foreach ($student['group']['@attributes'] as $k => $v)
        $result .= ' '.$k.'="'.$v.'"';
    $result .= ' />'.PHP_EOL;
    $result .= $indent3.'<signIn';
    foreach ($student['signIn']['@attributes'] as $k => $v)
        $result .= ' '.$k.'="'.$v.'"';
    $result .= ' />'.PHP_EOL;
    $result .= $indent3.'<platform';
    foreach ($student['platform']['@attributes'] as $k => $v)
        $result .= ' '.$k.'="'.$v.'"';
    $result .= ' />'.PHP_EOL;
    $result .= $indent2.'</student>'.PHP_EOL;


$result = '<?xml version="1.0" encoding="utf-8" standalone="yes" ?>'.PHP_EOL.
    '<classmodel version="2.0" name="班级 1">'.PHP_EOL.
    $indent1.'<students>'.PHP_EOL.$result.
    $indent1.'</students>'.PHP_EOL;
$result .= $indent1.'<groups>'.PHP_EOL;
$result .= $indent2.'<group';
foreach ($a['groups']['group']['@attributes'] as $k => $v)
    $result .= ' '.$k.'="'.$v.'"';
$result .= ' />'.PHP_EOL;
$result .= $indent1.'</groups>'.PHP_EOL;
$result .= $indent1.'<signInInfos signInStrategy="0" signInSeqId="0" />'.PHP_EOL;
$result .= '</classmodel>'.PHP_EOL.PHP_EOL;

if (DEBUG)
	echo $result;
else 
	$cmd = 'del "'.$path.'/*.old"';
	$cmd = str_replace('/', '\\\\', $cmd);
	echo $cmd.PHP_EOL;
	system($cmd);  // delete .old file
	$cmd = 'rename "'.$fileName.'" "'.$clsname.'.old"';
	$cmd = str_replace('/', '\\\\', $cmd);
	echo $cmd.PHP_EOL;
	system($cmd);   // rename current to .old 
	file_put_contents($fileName, $result);  // write new data to .cls
	echo 'write new data to '.$fileName.' OK'.PHP_EOL;



//$xmlObj->asXML('/home/sjg/Downloads/newclass.cls');

上述脚本主要逻辑:

  • 查找 C:/Users/Public/Documents 下带有“极域”字样的目录,如果有多个,选择最后一个(多个的原因是装过旧版软件),在目录 C:/Users/Public/Documents/极域..../zime/Class Data  下(其中zime和教师账户名有关)找到所有 .cls 班级文件供选择;
  • 选定班级文件后,设定机器名前缀,我通常使用 JF+房间号+-,如 JF517-
  • 从所选班级文件(是xml文件)中读取数据转换为数组,将数组中学生机器部分进行自定义排序,排序规则为IP地址尾号
  • 读取数组中所有学生机显示位置的信息,把这个位置信息记录到数组并进行自定义排序,按 y 值大的大,y值相同的 x 值大的大
  • 用修改好的班级文件数组来生成新的xml文件,同时,每个位置依次用位置数组中的值

对于xml文件的生成,我采用了直接字符串拼接(没有用simplexml或dom操作之类),主要是因为班级文件比较简单,用拼合反而更容易。

配合这个php脚本处理写了个bat

@echo off
path=%path%;C:\\wamp64\\bin\\php\\php7.4.9
cmd  /c  php  jiyu.php
pause

rem  C:\\Users\\Public\\Documents\\极域课堂管理系统软件V6.0 2016 豪华版\\zime\\Class Data\\班级 1.cls

说实话,这个功能按理应该是极域自己提供的,例如提供一个编辑表格功能

以上是关于极域教师端预览学生界面学生机按IP重排的主要内容,如果未能解决你的问题,请参考以下文章

极域教师端预览学生界面学生机按IP重排

win7下使用极域电子教室,在屏幕广播时出现学生全部黑屏,如何解决?

极域电子教室如何设置自动锁屏

惠普课堂管理系统极域教室学生端不能打开word文档等应用软件,提示出现一个电脑一把锁?

如何防止学生脱离极域电子教室的控制

如何破解教师机对学生机的键盘锁定 黑屏