From aad8d2e96e7d77e72778c126a27a6115e306c6b0 Mon Sep 17 00:00:00 2001 From: ryx <2736755949@qq.com> Date: Thu, 29 Jan 2026 21:27:08 +0800 Subject: [PATCH] 2026.1.29 --- fapp/ciyon_ap/pages.json | 15 +- fapp/ciyon_ap/pages/lab/useradd.vue | 305 ++++++++++++ fapp/ciyon_ap/pages/lab/userlist.vue | 685 ++++++++++++++++++--------- fapp/ciyon_ap/util/ciy.js | 4 +- lab_user.sql | 22 +- web/ambap/common.php | 6 +- web/ambap/login.php | 25 +- web/ambap/member.php | 539 +++++++++++---------- web/ud/lab/lab.png | Bin 0 -> 7056 bytes zc_cata.sql | 13 +- 10 files changed, 1077 insertions(+), 537 deletions(-) create mode 100644 fapp/ciyon_ap/pages/lab/useradd.vue create mode 100644 web/ud/lab/lab.png diff --git a/fapp/ciyon_ap/pages.json b/fapp/ciyon_ap/pages.json index 46c8c72..915a667 100644 --- a/fapp/ciyon_ap/pages.json +++ b/fapp/ciyon_ap/pages.json @@ -412,13 +412,14 @@ ] }, { - "root": "pages/lab", - "pages": [ - { - "path": "userlist" - - - } + "root": "pages/lab", + "pages": [ + { + "path": "userlist" + }, + { + "path":"useradd" + } ] } ] diff --git a/fapp/ciyon_ap/pages/lab/useradd.vue b/fapp/ciyon_ap/pages/lab/useradd.vue new file mode 100644 index 0000000..a87faaf --- /dev/null +++ b/fapp/ciyon_ap/pages/lab/useradd.vue @@ -0,0 +1,305 @@ + + + + + 新增实验室成员 + 返回 + + + + + + + + 姓名 + + + + + + 头像 + + + 选择图片 + + + + + + 头衔 + + {{ getTitleText(form.usertitle) }} + + + + + + 状态 + + {{ statusMap[form.role] }} + + + + + + 学历 + + {{ educationMap[form.education] }} + + + + + + 编号 + + + + + + 性别 + + {{ sexMap[form.sex] }} + + + + + + 加入日期 + + {{ form.addtimesText || '请选择日期' }} + + + + + + 手机号 + + + + + + 邮箱 + + + + + + 初始密码 + + + + + + + + {{ isSubmitting ? '提交中...' : '提交成员信息' }} + + + + + + + + + \ No newline at end of file diff --git a/fapp/ciyon_ap/pages/lab/userlist.vue b/fapp/ciyon_ap/pages/lab/userlist.vue index f1d0860..a3feab4 100644 --- a/fapp/ciyon_ap/pages/lab/userlist.vue +++ b/fapp/ciyon_ap/pages/lab/userlist.vue @@ -1,105 +1,114 @@ - - - - + + + + + + - 搜索 - + 搜索 + + + 新增成员 - - 新增成员 - - - - - - 头像 - 姓名 - 手机号 - 头衔 - 状态 - 性别 - 学历 - 操作 - - - - - - - - - {{ item.name }} - {{ item.mobile }} - {{ getTitleText(item.usertitle) }} - - {{ getStatusText(item.stpstatus) }} - - {{ getSexText(item.sex) }} - {{ getEducationText(item.education) }} - - 编辑 - 删除 - - {{ item.stpstatus === 30 ? '设为历史' : '设为在册' }} - - - - - - - - 暂无成员数据 - - - - - + + 上一页 - {{ page }} / {{ Math.ceil(total / pageSize) }} - 下一页 - + v-for="(item, key) in statusMap" + :key="key" + class="status-btn mr2 flex-none rounded-full py1 px3 transition-all duration-300" + :class="activeStatus === key ? 'status-btn-active' : 'status-btn-default'" + @click="handleStatusChange(key)" + > + {{ item }} + + + + + + + + + 👤 + + 暂无当前状态的成员数据 + + + + + + + + + + + {{ member.name.substring(0, 1) }} + + + + + {{ member.name }} + {{ getTitleText(member.usertitle) }} + + + + {{ statusMap[member.role] }} + + + + + + + + + + + + 下拉加载更多... + + + \ No newline at end of file + + + \ No newline at end of file diff --git a/fapp/ciyon_ap/util/ciy.js b/fapp/ciyon_ap/util/ciy.js index f2b1a43..ed67133 100644 --- a/fapp/ciyon_ap/util/ciy.js +++ b/fapp/ciyon_ap/util/ciy.js @@ -2509,7 +2509,7 @@ export default { (1000 + Math.round(Math.random() * 8000)) + '.' + fext.toLowerCase(); if (opn.stor == '/') { var ufparam = {}; - ufparam.url = opn.action + "upload&pathfile=" + pathfile; + ufparam.url = opn.action + "upload?pathfile=" + pathfile; ufparam.header = header; if (opn.post) ufparam.formData = opn.post; @@ -2532,7 +2532,7 @@ export default { fn.success(jsonup.url, gf); } else { var [err, s3json] = await this.go(this.callfunc({ - func: opn.action + "s3&pathfile=" + pathfile + + func: opn.action + "s3?pathfile=" + pathfile + "&storselect=" + opn.stor })); if (err) diff --git a/lab_user.sql b/lab_user.sql index e6d2599..167f342 100644 --- a/lab_user.sql +++ b/lab_user.sql @@ -11,7 +11,7 @@ Target Server Version : 100510 File Encoding : 65001 - Date: 26/01/2026 15:46:45 + Date: 29/01/2026 17:03:51 */ SET NAMES utf8mb4; @@ -22,12 +22,13 @@ SET FOREIGN_KEY_CHECKS = 0; -- ---------------------------- DROP TABLE IF EXISTS `lab_user`; CREATE TABLE `lab_user` ( - `id` bigint(20) NOT NULL AUTO_INCREMENT, + `id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT '成员id', `laborgid` bigint(20) NOT NULL COMMENT '所属机构,DB,lab_orgbase', + `icon` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL DEFAULT '' COMMENT '头像,IMG1', `name` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '姓名', `usertitle` int(11) NOT NULL COMMENT '头衔,CATA,usertitle', `education` int(11) NOT NULL COMMENT '学历,CATA,education', - `sn` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '编号', + `sn` varchar(50) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL COMMENT '编号', `sex` int(11) NOT NULL COMMENT '性别,CATA,sex', `addtimes` bigint(20) NOT NULL COMMENT '加入日期,DATE,Y-m-d', `mobile` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '手机号,MSK,****', @@ -35,18 +36,29 @@ CREATE TABLE `lab_user` ( `password` varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT ',密码', `stpstatus` int(11) NOT NULL COMMENT '|状态|,CATA,stpstatus', `userlevel` int(11) NOT NULL COMMENT '|等级|,CATA,userlevel', - `totalpnt` bigint(20) NOT NULL COMMENT '总积分|,INT', + `upid` int(11) NOT NULL DEFAULT 0 COMMENT '分享人,DB,ep_user', `dvotecnt` bigint(20) NOT NULL COMMENT '互动贡献|,INT,次', `trytime` int(11) NOT NULL DEFAULT 0 COMMENT ',密码重试次数', `logintimes` bigint(20) NOT NULL COMMENT '登录时间,DATE', `sid` varchar(10) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL DEFAULT '' COMMENT ',授权码', `exptimes` bigint(20) NOT NULL COMMENT ',授权过期时间,DATE', `ip` varchar(40) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '#登录IP,IP', + `role` int(11) NOT NULL COMMENT '成员状态:负责人,科研秘书,在册成员,外部人员,历史人员', PRIMARY KEY (`id`) USING BTREE -) ENGINE = InnoDB AUTO_INCREMENT = 14 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_general_ci COMMENT = '实验室成员' ROW_FORMAT = Dynamic; +) ENGINE = InnoDB AUTO_INCREMENT = 25 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_general_ci COMMENT = '实验室成员' ROW_FORMAT = Dynamic; -- ---------------------------- -- Records of lab_user -- ---------------------------- +INSERT INTO `lab_user` VALUES (14, 1, '/lab/lab.png', '张三', 10, 70, 'LAB-2024-001', 20, 1700000000000, '13800138001', 'zhangsan@lab.com', 'd527d1bf5fe6a4361f230af48e36e1c4', 10, 30, 0, 120, 0, 1710000000000, '', 0, '192.168.1.101', 60); +INSERT INTO `lab_user` VALUES (15, 1, '/lab/lab.png', '李四', 50, 50, 'LAB-2024-002', 20, 1702000000000, '13900139002', 'lisi@lab.com', 'd527d1bf5fe6a4361f230af48e36e1c4', 10, 20, 0, 86, 11, 1769417475, '', 0, '192.168.1.102', 60); +INSERT INTO `lab_user` VALUES (16, 2, '/lab/lab.png', '王五', 80, 60, 'LAB-2024-003', 20, 1704000000000, '13700137003', 'wangwu@lab.com', 'd527d1bf5fe6a4361f230af48e36e1c4', 10, 10, 0, 45, 2, 1712000000000, '', 0, '192.168.1.103', 60); +INSERT INTO `lab_user` VALUES (17, 1, '/lab/lab.png', '赵六', 20, 60, 'LAB-2024-004', 10, 1706000000000, '13600136004', 'zhaoliu@lab.com', 'd527d1bf5fe6a4361f230af48e36e1c4', 10, 20, 0, 98, 0, 1713000000000, '', 0, '192.168.1.104', 60); +INSERT INTO `lab_user` VALUES (19, 0, '/lab/lab.png', ':3780', 0, 0, '', 90, 1769439652, '18248103780', '', 'd527d1bf5fe6a4361f230af48e36e1c4', 10, 10, 0, 0, 0, 1769671619, 'TM15jZmrBs', 1769675219, '127.0.0.1', 60); +INSERT INTO `lab_user` VALUES (20, 0, '/lab/lab.png', ':0022', 0, 0, '', 90, 1769445509, '13654880022', '', 'd527d1bf5fe6a4361f230af48e36e1c4', 10, 10, 0, 0, 0, 1769448199, 'p43i428v1j', 1769451799, '127.0.0.1', 60); +INSERT INTO `lab_user` VALUES (21, 0, '/lab/lab.png', ':0023', 0, 0, '', 90, 1769529209, '13654880023', '', 'd527d1bf5fe6a4361f230af48e36e1c4', 10, 10, 0, 0, 0, 1769529209, 'FuBzvhAHI5', 1769532809, '127.0.0.1', 60); +INSERT INTO `lab_user` VALUES (22, 0, '/lab/lab.png', ':3788', 0, 0, '', 90, 1769671931, '18248103788', '', 'd527d1bf5fe6a4361f230af48e36e1c4', 10, 10, 0, 0, 0, 1769672290, 'GjXvuqnEoM', 1769675890, '127.0.0.1', 60); +INSERT INTO `lab_user` VALUES (23, 0, '/lab/lab.png', ':3789', 0, 0, '', 90, 1769672770, '18248103789', '', 'd527d1bf5fe6a4361f230af48e36e1c4', 10, 10, 0, 0, 0, 1769674212, 'i49npHbGlL', 1769677812, '127.0.0.1', 60); +INSERT INTO `lab_user` VALUES (24, 0, '/lab/lab.png', ':0024', 0, 0, '', 90, 1769676173, '13654880024', '', 'd527d1bf5fe6a4361f230af48e36e1c4', 10, 10, 0, 0, 0, 1769676173, '1ZPWhJNtkd', 1769679773, '127.0.0.1', 60); SET FOREIGN_KEY_CHECKS = 1; diff --git a/web/ambap/common.php b/web/ambap/common.php index 131141d..1683d6b 100644 --- a/web/ambap/common.php +++ b/web/ambap/common.php @@ -42,7 +42,7 @@ function verifyuser($post = null) { $auth = json_decode(encrypt($ciyauth, 'D', $_token['salt']), true); if ($auth == null) return null; - $csql = new \ciy\sql('ap_user'); //弃用redis集群 + $csql = new \ciy\sql('lab_user'); //弃用redis集群 $csql->where('id', $auth['id']); $userrow = $db->getone($csql); if (!is_array($userrow)) @@ -58,7 +58,7 @@ function verifyuser($post = null) { if ($upid > 0) { $updata = array(); $updata['upid'] = $upid; - $csql = new \ciy\sql('ap_user'); + $csql = new \ciy\sql('lab_user'); $csql->where('id', $userrow['id']); $db->update($csql, $updata); } @@ -68,7 +68,7 @@ function verifyuser($post = null) { $exp = time() + $_token['swapsec']; $sid = randstr(10); $auth['_s'] = $sid; - if ($db->execute('update ap_user set exptimes=?,sid=? where id=?', array($exp, $sid, $auth['id'])) === false) + if ($db->execute('update lab_user set exptimes=?,sid=? where id=?', array($exp, $sid, $auth['id'])) === false) return null; $authstr = json_encode($auth, JSON_PARTIAL_OUTPUT_ON_ERROR); $enauth = encrypt($authstr, 'E', $_token['salt']); diff --git a/web/ambap/login.php b/web/ambap/login.php index 6d163e0..4e87d3b 100644 --- a/web/ambap/login.php +++ b/web/ambap/login.php @@ -134,6 +134,7 @@ class login { $rsuser['education'] = 0; $rsuser['sn'] = ''; $rsuser['sex'] = 90; + $rsuser['role']=60; $rsuser['stpstatus'] = 10; $rsuser['userlevel'] = 10; $rsuser['mobile'] = $user; @@ -388,7 +389,6 @@ class login { $ret['pnttrack'] = $db->get($csql); $ret['me'] = array(); $ret['me']['addtimes'] = $userrow['addtimes']; - $ret['me']['accounttimes'] = $userrow['accounttimes']; //$ret['me']['saasid_a'] = $userrow['saasid_a']; $ret['me']['id'] = $userrow['id']; $ret['me']['eid'] = enid($userrow['id']); @@ -397,31 +397,8 @@ class login { $ret['me']['mobile'] = $userrow['mobile']; $ret['me']['name'] = $userrow['name']; $ret['me']['userlevel'] = $userrow['userlevel']; - $ret['me']['mymoney'] = $userrow['mymoney']; - $ret['me']['mycashmoney'] = $userrow['mycashmoney']; - $ret['me']['myinvmoney'] = $userrow['myinvmoney']; - $ret['me']['mybondmoney'] = $userrow['mybondmoney']; - $ret['me']['mypnt'] = $userrow['mypnt']; - $ret['me']['certs'] = $userrow['certs']; $ret['me']['needpass'] = empty($userrow['password']); $ret['me']['cciy'] = ''; - $csql = new \ciy\sql('ap_usr_ext'); - $csql->where('id', $userrow['id']); - $extrow = $db->getone($csql); - if (is_array($extrow)) { - $ret['me']['truename'] = $extrow['truename']; - $ret['me']['email'] = $extrow['email']; - $ret['me']['wxno'] = $extrow['wxno']; - $ret['me']['idid'] = $extrow['idid']; - $ret['me']['cciy'] = $extrow['cciy'] . ''; - $ret['me']['cashtype'] = $extrow['cashtype']; - $ret['me']['bankno'] = $extrow['bankno']; - $ret['me']['bankname'] = $extrow['bankname']; - $ret['me']['bankaccount'] = $extrow['bankaccount']; - $ret['me']['bankcode'] = $extrow['bankcode']; - } else { - $ret['me']['truename'] = ''; - } return succjson($ret); } public static function json_logout() { diff --git a/web/ambap/member.php b/web/ambap/member.php index 8d80772..e4a051a 100644 --- a/web/ambap/member.php +++ b/web/ambap/member.php @@ -1,313 +1,342 @@ getint('page', 1); - $pageSize = $post->getint('pageSize', 15); - $offset = ($page - 1) * $pageSize; - - // 构建查询条件(通过 ciy\sql 的构造参数指定字段) - $csql = new \ciy\sql('lab_user', 'id, name, mobile, usertitle, stpstatus, sex, education, email, avatar, addtimes'); - $csql->limit($offset, $pageSize); // 分页:偏移量、每页条数 - $csql->order('addtimes DESC'); - // 核心修改:使用 db.php 的 get 方法($rowcount=-1 自动查总数) - $rowcount = -1; - $list = $db->get($csql, $rowcount); - - // 处理查询失败 + // 1. 初始化参数(解决未定义变量) + $page = $post->getint('page', 1); // 当前页 + $pagesize = $post->getint('pagesize', 20); // 每页条数 + $offset = ($page - 1) * $pagesize; // 偏移量 + $mobile = trim($post->get('mobile', '')); // 手机号筛选 + $name = trim($post->get('name', '')); // 姓名筛选 + $status = $post->getint('status', 0); // 状态筛选 + $role = $post->getint('role', 60); // 角色筛选 + + // 2. 构建SQL(修复:精简JOIN语句格式,避免语法错误) + $csql = new \ciy\sql("lab_user u + LEFT JOIN zc_cata s ON u.sex = s.codeid AND s.cbid = 10 + LEFT JOIN zc_cata st ON u.stpstatus = st.codeid AND st.cbid = 11 + LEFT JOIN zc_cata e ON u.education = e.codeid AND e.cbid = 102 + LEFT JOIN zc_cata ut ON u.usertitle = ut.codeid AND ut.cbid = 12001701 + LEFT JOIN zc_cata r ON u.role = r.codeid AND r.cbid = 12001703 + LEFT JOIN zc_cata rr ON u.userlevel=rr.codeid AND rr.cbid=12001704"); + + // 配置查询字段(含字典关联中文名称) + $csql->column("u.id, u.mobile, u.name, u.usertitle, u.education, u.sex, + u.role, u.userlevel, u.stpstatus, u.addtimes, u.logintimes, u.ip, + s.name as sex_name, st.name as stpstatus_name, e.name as education_name, + ut.name as usertitle_name, r.name as role_name, rr.name as userlevel_name"); + + // 3. 拼接筛选条件 + if (!empty($mobile)) { + $csql->where('u.mobile', $mobile); + } + if (!empty($name)) { + $csql->where('u.name', '%' . $name . '%', 'like'); + } + if ($status > 0) { + $csql->where('u.stpstatus', $status); + } + if ($role > 0) { + $csql->where('u.role', $role); + } + + // 4. 排序+分页(正确传参) + $csql->order('u.logintimes desc'); + $csql->limit($offset, $pagesize); + + // 5. 执行查询 + $list = $db->get($csql); if ($list === false) { - return self::err('获取列表失败:' . $db->error); + return errjson('查询成员列表失败: ' . $db->error); } - - // 格式化返回数据 - $retList = []; - foreach ($list as $item) { - $retList[] = [ - 'id' => intval($item['id']), - 'name' => $item['name'] ?? '', - 'mobile' => $item['mobile'] ?? '', - 'usertitle' => intval($item['usertitle']), - 'stpstatus' => intval($item['stpstatus']), - 'sex' => intval($item['sex']), - 'education' => intval($item['education'] ?? 50), - 'email' => $item['email'] ?? '', - 'avatar' => $item['avatar'] ?? '/static/avatar-default.png', - 'addtimes' => intval($item['addtimes']) - ]; - } - - echo json_encode([ - 'code' => 1, - 'list' => $retList, - 'total' => $rowcount, + + // 6. 查询总数(修复:移除limit方法,而非传0,0) + $countSql = clone $csql; + $countSql->column('count(DISTINCT u.id) as total'); + // 关键修复:删除limit(0,0),ciy\sql默认无limit + $total = $db->get1($countSql); + + // 7. 返回结果 + return succjson([ + 'list' => $list ?: [], + 'total' => $total ?: 0, 'page' => $page, - 'pageSize' => $pageSize - ], JSON_UNESCAPED_UNICODE); + 'pagesize' => $pagesize + ]); } - // 2. 新增成员(适配当前 db.php) - public static function json_add() { + /** + * 获取成员详情(含字典中文名称) + * @return array + */ + public static function json_get_detail() { global $db; $post = new \ciy\post(); + $id = $post->getint('id'); - // 获取表单数据 - $name = trim($post->get('name', '')); - $mobile = trim($post->get('mobile', '')); - $usertitle = $post->getint('usertitle', 10); - $stpstatus = $post->getint('stpstatus', 30); - $sex = $post->getint('sex', 90); - $education = $post->getint('education', 50); - $email = trim($post->get('email', '')); - $password = trim($post->get('password', '')); - - // 基础验证 - if (empty($name)) return self::err('请输入姓名'); - if (empty($mobile)) return self::err('请输入手机号'); - if (!preg_match('/^1[3-9]\d{9}$/', $mobile)) return self::err('手机号格式错误'); - if (empty($password)) return self::err('请设置密码'); - if (strlen($password) < 6) return self::err('密码长度不少于6位'); - - // 检查手机号是否已注册 - $csql = new \ciy\sql('lab_user', 'id'); - $csql->where('mobile', $mobile); - $exist = $db->getone($csql); - if (is_array($exist)) return self::err('该手机号已注册:' . $mobile); - - // 组装数据 - $data = [ - 'name' => $name, - 'mobile' => $mobile, - 'usertitle' => $usertitle, - 'stpstatus' => $stpstatus, - 'sex' => $sex, - 'education' => $education, - 'email' => $email, - 'password' => $password, - 'userlevel' => 10, - 'trytime' => 0, - 'logintimes' => self::tostamp(), - 'addtimes' => self::tostamp(), - 'ip' => self::getip(), - 'laborgid' => 1, - 'sn' => 'LAB-' . date('Ymd') . '-' . rand(1000, 9999), - 'totalpnt' => 0, - 'dvotecnt' => 0, - 'updatetime' => self::tostamp() - ]; - - // 插入数据 - $csql = new \ciy\sql('lab_user'); - $insertId = $db->insert($csql, $data); - if ($insertId === false) { - return self::err('新增失败:' . $db->error); + if ($id <= 0) { + return errjson('请传入有效的成员ID'); } - - echo json_encode([ - 'code' => 1, - 'msg' => '新增成功', - 'id' => $insertId - ], JSON_UNESCAPED_UNICODE); + + // 修复:精简JOIN语句格式 + $csql = new \ciy\sql("lab_user u + LEFT JOIN zc_cata s ON u.sex = s.codeid AND s.cbid = 10 + LEFT JOIN zc_cata st ON u.stpstatus = st.codeid AND st.cbid = 11 + LEFT JOIN zc_cata e ON u.education = e.codeid AND e.cbid = 102 + LEFT JOIN zc_cata ut ON u.usertitle = ut.codeid AND ut.cbid = 12001701 + LEFT JOIN zc_cata r ON u.role = r.codeid AND r.cbid = 12001703 + LEFT JOIN zc_cata rr ON u.userlevel=rr.codeid AND rr.cbid=12001704"); + + $csql->column("u.*, s.name as sex_name, st.name as stpstatus_name, + e.name as education_name, ut.name as usertitle_name, + r.name as role_name, rr.name as userlevel_name"); + $csql->where('u.id', $id); + + $detail = $db->getone($csql); + if ($detail === false) { + return errjson('查询成员详情失败: ' . $db->error); + } + if (!is_array($detail)) { + return errjson('该成员不存在'); + } + + // 补充扩展信息(单表直接传构造函数) + $extSql = new \ciy\sql('ap_usr_ext'); + $extSql->where('id', $id); + $extDetail = $db->getone($extSql); + if (is_array($extDetail)) { + $detail['appcid'] = $extDetail['appcid']; + } + + return succjson($detail); } - // 3. 编辑成员(适配当前 db.php) + /** + * 编辑成员信息 + * @return array + */ public static function json_edit() { global $db; $post = new \ciy\post(); + // 参数校验 $id = $post->getint('id'); $name = trim($post->get('name', '')); - $usertitle = $post->getint('usertitle', 10); - $stpstatus = $post->getint('stpstatus', 30); + $usertitle = $post->getint('usertitle', 0); + $education = $post->getint('education', 0); $sex = $post->getint('sex', 90); - $education = $post->getint('education', 50); - $email = trim($post->get('email', '')); - - // 参数验证 - if (empty($id)) return self::err('参数错误:缺少成员ID'); - if (empty($name)) return self::err('请输入姓名'); - + // 优化:role默认值改为0(避免无字典数据) + $role = $post->getint('role', 0); + $userlevel = $post->getint('userlevel', 10); + + if ($id <= 0) { + return errjson('请传入有效的成员ID'); + } + if (empty($name)) { + return errjson('请填写成员姓名'); + } + // 组装更新数据 - $data = [ + $updata = [ 'name' => $name, 'usertitle' => $usertitle, - 'stpstatus' => $stpstatus, - 'sex' => $sex, 'education' => $education, - 'email' => $email, - 'updatetime' => self::tostamp() + 'sex' => $sex, + 'role' => $role, + 'userlevel' => $userlevel ]; - - // 更新数据 + + // 单表操作:构造函数直接传表名 $csql = new \ciy\sql('lab_user'); $csql->where('id', $id); - $result = $db->update($csql, $data); - if ($result === false) { - return self::err('修改失败:' . $db->error); + $res = $db->update($csql, $updata); + + if ($res === false) { + savelog($db, 0, 'MEMBEREDIT', '编辑成员[' . $id . ']失败: ' . $db->error); + return errjson('编辑成员失败: ' . $db->error); } - - echo json_encode([ - 'code' => 1, - 'msg' => '修改成功' - ], JSON_UNESCAPED_UNICODE); + + savelog($db, $id, 'MEMBEREDIT', '编辑成员[' . $id . ']成功'); + return succjson(['msg' => '编辑成功']); } - // 4. 获取成员详情(适配当前 db.php) - public static function json_detail() { + /** + * 禁用/启用成员 + * @return array + */ + public static function json_change_status() { global $db; $post = new \ciy\post(); + $id = $post->getint('id'); - - if (empty($id)) return self::err('参数错误:缺少成员ID'); - - // 查询详情(通过 ciy\sql 构造参数指定字段) - $csql = new \ciy\sql('lab_user', 'id, name, mobile, usertitle, stpstatus, sex, education, email'); + $status = $post->getint('status'); + + if ($id <= 0) { + return errjson('请传入有效的成员ID'); + } + + $updata = ['stpstatus' => $status]; + $csql = new \ciy\sql('lab_user'); $csql->where('id', $id); - $item = $db->getone($csql); + $res = $db->update($csql, $updata); + + if ($res === false) { + $action = $status == 10 ? '启用' : '禁用'; + savelog($db, 0, 'MEMBERSTATUS', $action . '成员[' . $id . ']失败: ' . $db->error); + return errjson($action . '成员失败: ' . $db->error); + } + + $action = $status == 10 ? '启用' : '禁用'; + savelog($db, $id, 'MEMBERSTATUS', $action . '成员[' . $id . ']成功'); + return succjson(['msg' => $action . '成功']); + } - if (!is_array($item)) return self::err('成员不存在或已删除'); - - // 格式化返回数据 - $data = [ - 'id' => intval($item['id']), - 'name' => $item['name'] ?? '', - 'mobile' => $item['mobile'] ?? '', - 'usertitle' => intval($item['usertitle']), - 'stpstatus' => intval($item['stpstatus']), - 'sex' => intval($item['sex']), - 'education' => intval($item['education'] ?? 50), - 'email' => $item['email'] ?? '' + /** + * 逻辑删除成员(标记deletetimes) + * @return array + */ + public static function json_delete() { + global $db; + $post = new \ciy\post(); + + $id = $post->getint('id'); + if ($id <= 0) { + return errjson('请传入有效的成员ID'); + } + + // 逻辑删除:标记删除时间+禁用状态 + $updata = [ + 'stpstatus' => 99, // 99:已删除 + 'deletetimes' => tostamp() // 时间戳 ]; - - echo json_encode([ - 'code' => 1, - 'data' => $data - ], JSON_UNESCAPED_UNICODE); - } - - // 5. 删除成员(适配当前 db.php) - public static function json_del() { - global $db; - $post = new \ciy\post(); - $id = $post->getint('id'); - - if (empty($id)) return self::err('参数错误:缺少成员ID'); - - // 物理删除 + $csql = new \ciy\sql('lab_user'); $csql->where('id', $id); - $result = $db->delete($csql); - - if ($result === false) { - return self::err('删除失败:' . $db->error); + $res = $db->update($csql, $updata); + + if ($res === false) { + savelog($db, 0, 'MEMBERDELETE', '删除成员[' . $id . ']失败: ' . $db->error); + return errjson('删除成员失败: ' . $db->error); } - - echo json_encode([ - 'code' => 1, - 'msg' => '删除成功' - ], JSON_UNESCAPED_UNICODE); + + savelog($db, $id, 'MEMBERDELETE', '删除成员[' . $id . ']成功'); + return succjson(['msg' => '删除成功']); } - // 6. 审核成员(适配当前 db.php) - public static function json_audit() { + /** + * 重置成员密码(和登录逻辑一致) + * @return array + */ + public static function json_reset_pass() { global $db; + global $_token; // 确保全局_token包含salt $post = new \ciy\post(); + $id = $post->getint('id'); - $status = $post->getint('status'); - - if (empty($id)) return self::err('参数错误:缺少成员ID'); - if (!in_array($status, [10,20,30,40,50])) return self::err('无效的状态值'); - - $data = ['stpstatus' => $status]; + $newPass = trim($post->get('new_pass', '')); + + if ($id <= 0) { + return errjson('请传入有效的成员ID'); + } + if (empty($newPass)) { + return errjson('请填写新密码'); + } + + // 优化:校验$_token是否存在 + if (empty($_token) || empty($_token['salt'])) { + return errjson('密码加密配置异常,请联系管理员'); + } + + // 密码加密(和注册逻辑对齐) + $encryptPass = md5($newPass . $_token['salt']); + $updata = [ + 'password' => $encryptPass, + 'trytime' => 0 // 重置错误尝试次数 + ]; + $csql = new \ciy\sql('lab_user'); $csql->where('id', $id); - $result = $db->update($csql, $data); - if ($result === false) { - return self::err('审核失败:' . $db->error); + $res = $db->update($csql, $updata); + + if ($res === false) { + savelog($db, 0, 'MEMBERRESETPASS', '重置成员[' . $id . ']密码失败: ' . $db->error); + return errjson('重置密码失败: ' . $db->error); } - - echo json_encode([ - 'code' => 1, - 'msg' => '审核成功' - ], JSON_UNESCAPED_UNICODE); + + savelog($db, $id, 'MEMBERRESETPASS', '重置成员[' . $id . ']密码成功'); + return succjson(['msg' => '重置密码成功']); } - // 通用错误返回 - private static function err($msg) { - echo json_encode([ - 'code' => 0, - 'errmsg' => $msg - ], JSON_UNESCAPED_UNICODE); - exit; - } - - // 兼容tostamp函数 - private static function tostamp() { - return isset($GLOBALS['tostamp']) ? $GLOBALS['tostamp']() : time() * 1000; - } - - // 兼容getip函数 - private static function getip() { - if (isset($_SERVER['HTTP_X_REAL_IP'])) { - return $_SERVER['HTTP_X_REAL_IP']; - } elseif (isset($_SERVER['HTTP_X_FORWARDED_FOR'])) { - return $_SERVER['HTTP_X_FORWARDED_FOR']; - } else { - return $_SERVER['REMOTE_ADDR'] ?? '127.0.0.1'; + /** + * 获取字典表数据(用于前端下拉选项) + * @return array + */ + public static function json_get_cata() { + global $db; + $post = new \ciy\post(); + $cbid = $post->getint('cbid'); + + if ($cbid <= 0) { + return errjson('请传入有效的字典分类ID'); } + + $csql = new \ciy\sql('zc_cata'); + $csql->where('cbid', $cbid); + $csql->order('codeid asc'); + $list = $db->get($csql); + + if ($list === false) { + return errjson('查询字典失败: ' . $db->error); + } + + return succjson(['list' => $list ?: []]); } } +global $db; +$post = new \ciy\post(); +$action = trim($post->get('action', '')); +$result = []; -// 执行入口 -member::index(); -?> \ No newline at end of file +// 根据action调用对应方法 +switch ($action) { + case 'get_list': + $result = member::json_get_list(); + break; + case 'get_detail': + $result = member::json_get_detail(); + break; + case 'edit': + $result = member::json_edit(); + break; + case 'change_status': + $result = member::json_change_status(); + break; + case 'delete': + $result = member::json_delete(); + break; + case 'reset_pass': + $result = member::json_reset_pass(); + break; + case 'get_cata': + $result = member::json_get_cata(); + break; + default: + $result = errjson('无效的接口操作: ' . $action); +} + +// 输出JSON结果(前端才能接收数据) +header('Content-Type: application/json; charset=utf-8'); +echo json_encode($result, JSON_UNESCAPED_UNICODE); +exit; \ No newline at end of file diff --git a/web/ud/lab/lab.png b/web/ud/lab/lab.png new file mode 100644 index 0000000000000000000000000000000000000000..d42738527eabb6026a5e344cc50aaf8fd84e521a GIT binary patch literal 7056 zcmV;B8*k)^P)c2?rdQ=C;uvx_;IZgK8~K!u_}62BzzqeF-! z2ows1x>W^`qIRNwssyS8MkP=IGAf#Sp-MoA3XrM=RRR+dr~sJ|PRL9D_x=06OaJ`- z{ST(!zJGu063>}fCS<#nmY)PFK>Xx)Q=1A-MgQ>Q$7iPB-rwIoyuY`nra5$J*EDZT zP1C$|iRVl#!}7g!!0{z1dN0U(>4S^y-Y`=$yd@A3Al|$sL4b-$MI{)Zv=RhVbkVlY zOpOqK2*1xB)h|iWdqm!2A6yDphYmpG31#Z$DS-+QO92uP3JkR3(lby|2?mg&B4fAO zw(kH$o&eYu=|Fzz)mGyw;f5j%Q4-fbr{MK1UKL=;Ir` zV?Nyq-;*=}5?&61z@V}~X$~rmkI>5INJ^m4qp<&*<8A{CRe)d+I$&h%G0@A&Z4bjx zy@^IdMFWIZli^gs!04;Q*_+`0O+T~r<6;5AWlvbmlENu7UB~?!dQ`K*`IjmZAc(nN zxa^t#@H+OeZ69es9BXG)tvG-X92mjTC0kspn-F^#ke4b5QP$JE6&zM7zgP0Is+3#d zVmyePj0;gchp_tiK1XKN*cJ;H0T62s0n0m2oT3J!Z@bTyi$`P?0s zxX&6O()wZ9aw7wqBpWa;`y?3;#B{a*;Y~oS#JmNPQ^{m1Kyn=Yzni8mQwADXtY#gM zUZh73L^BmKS$Yr-CPITcDG#TG^dgV+$dK)U-Z>oUZBxn)AZqaHa&A1mE9$|<>;O_` zXcZ3)Bb1AIurVuuFh;JS)rd;R$i@mGm(gR8-U`jE08;vz{VGb8`Gbww0EDl(sorB1 zh-Cd>V>SSR_xODk^{9nycR%m%8}7Tr{I+eMS|PrP?R+jglfRDF zKJT%4-eoi=%mE;L(ln@gQsJpkNOwO!e*E&+r%&Jh^Xb!(jd0&3=KuH8r`P}9-%9{d z@lfU!Y3c1qAcNlq>B2Ml>v$zY-Eqe=>o7k;ifObWuscpNX@KzAtMRTmT{+U~QsHfD zQ~9WPP|zn@?TE^E&05nuqfH5l>kIQ|1i$1}h@%Mm$tKK78X#D`3h6xvjwf1OUtJ+s zF3JZ5_NAw*PcKL1W;?p;rg`KQbRJMXC`fV%v(g4g(}a4we}5fCq`KbfMYm$xu{IZaolWFE3xTh1! ziv(UoSw)7)0z|!>!Aocicf1H>SUIp4Nq!!33y?$x{VyTByoV5CjT?F*g%7<*3VbfX zW3mA8b>CRltl`y&hS7_J3bRt5sHY2%-R}QK#&E)g+uQKpaKZVx8ZyYH`&Q7;Z4h>7d`!w~B9w51!A zWC4PKa|*Grs`4*G{iwwPNdPiWb|ouWfCL)5N@hj^P1AV)oVfA7sXN1EyvxY~WFT~7 z35ANQjT=n7;OTTK+T$h*5LdlpTlJ=J?5MFGS?H-r$iR>>3fq5y)Guj)Y@@E&BM?(t}l z1Ixjxqzn+J8->9nR|#230O4(tt$)2DPfX;C3A{+&)Uo6%!W;2*V$$U$X`IppNYgy)Mj=)nfk8z(HO)b^ z?K4v&ME4l?UYws;eZ>9|)|NmyP+3_IdC@k~XFCJ~d14}8OsdhnI+lFxnuef0*aD?J zo&K%p6}3wiAbe$~?MOjUsK{2;sDK?XP`?9&35`9K^+bjI@#C{e1=}(N2I!vwYgc)1 z3zXL5B@TQCF<+-@$Kp0hCkqfNZfp_K%2EL>fiYxD0)@&vyx@Ayz7w$C_fyC!-daBQ1QAo)G1XkTT zTtbKUbBcg6f|Kl^;2_a+GHU-^^!A&cBNkuqMzbKf<;XB6(Z@{KyJP`E=ADwVY8HBileZ>+SERd6}#PzW9G5j=V`v zGA0*zE$4X@<}WVBY_h9MT`UhEXUUGn-eXFLLH;Hc@8icWTp&=7UkL8`KOcNkJSL+2 z15f#Q$}n7KW^|S;K$^LC z^U|754-_rtGv@_V0v4t9)G8rp@sDf>29}#jEJFYhOem-ICTs)k@*ah8Vja-C-6HTt zIj|w_;W-Y2wt0!^NY6>bz>}$j`qhI>3223D@}Hxol(fgw9!l`WxyjIa$}&(uD!e?l z_##lCKn%MqYFQSI#2e)>GY@-(x4fh0wB$Is;>miDDM=&bkd~WD3XnXYtUSklY?Iyu zmhLKq0iACy;OH7r3dDIymlbRulQ+r%Akofu7*YWoae*I9O8$h>1xVYDx@`>b1rQgI zz}ni1>mRM0c-vOHDi472e@HI;TwU}yS%EigNY#a>GhG=StC@PMUrrYw7NR3aq$jWg z$t&wwG@~u5Xn4OBWI%jr-iisS267hZ0;FlItujHv5Md|;-8ssIdtsUbuR5N(yd`-< zTTfFVRoEN0T@SajPZuClGMrFIuDT%XxkL3yfQ5VmzH7W@1}0>HE;u@dmGEyh_!~-H-BNZUc3b1<2Iz6Q-{9WlrVbyriGk9UHFBbj2t4 z9<;P!pa;DhJ~gzoZQfMuGA33NyCT@z(L{x&;3_|le%%-fAD&g{B>kM+ZyqC-u`D#-%GvA@REaHH(%nIz+inu4J9`!L%?X;4qA ztjLeb+mP3pa~=4vs$e3o1^QK?jh-Y6kdPB!DBO)AVo-y;vR{QTkHhf?{aK|MTm3@a zXuQdJ*^t@k^ZoSYw67)$5Y8XQL~ml9`*nAx)7SpFI_5K4-j;go$=#E|KgdoPfmpm9 zr{t>Sa@p~Dt;@;80q&)QyQehKPK-;*0))Z<5N<3#^CuLGmv0i4VuY60kBH<0kV0rf z5cQmvnEH?}TpwGC4$d1uYrJ{|zC`XTSnOlc070ms4O5h2v47@i%%bxLRt_&+kk%D- zwG3E1@-i9nfIdN}ZDS%+#~TfV326Id;Tg2x@0a0m$Qzraw`4K_$dde6wS@uFx$ZHG zJ4u^&*r_DiLQq8hXh_W`v_-m1mSNdu;@5v;OUoUN{+?h*KgTV5Al}f%mwvk@$1qSv z0AU|Y=xwn~(g4v}CWHyP`Gk?|r=F0dGMxAdpZ9n90yYAHM7d|8C1*mJu^$+*xNx~K zN$^h9^W_aPd$9E$Gy=lx<7BYRNXIXgG(c#XhE{(E%gw?2pcL6ggp%I$Bkp_9lP_Q+ z5YR@;J(GYXmk9;NHu7rYJ^FOGkih!=yuq;(Z}1#XCgA9dfRb%XP!8JHo&tQ%21`qD z;mo7~B4u?ucer|!Ae7kZErN5_TDIx%Mdjwtb{(q9Dg>|ea2E3yS#jbE%KISuJ5h$0 zI?qT0U(5lr!FFS+Rn2N98uIbX)L9 zW%ltLw#k4a9jUZG@9&L%PcDrLL&ph%6PJ#Z;l%YME+r2TN*T(+6__KB zCzAC`+Xy}?H@u_r7s@#<#LNOkw zh*Vy6J?f5qXQ+fWpU5NjcS!sp7Wa2D@8icWEN8=ryjNmVp;s1iHk$bNs%-W!3xH6% zQ~;^K6HobKg2|O07I#W)gNje3W6~)imDP#()+#m4pDrvB95g5{b+=e28-P%_RA7MQ zp|kSL8ze7)3}|J23S(mGZKVgL%xN%k0tW{;D}b;=1c|ir_xB8SFwV^VmE^?p*J(Y{ zNWex$0EGB^h-O4+;WXJbYfJ*LDyE(`d)a0W5KN}81~KLTsu)w~(D_Z% z-2A{x*Tzt`x-zNfWe*To!z+Mb5@{M+r#`mM{6q1LJjhVC&JAw3V)g*R%x$4 z1qn0`n;`@5VeDZIo`c&=zg!u~9w1!y9SUdXcoS?$C&zQs2|D|(lP&XeO4$R1gM~@w z@VDz`F*Ylgmu}v`G9rSx2Si7zrIlR-KwuSz0NLBb+G!1`JGVB^Utu*+_j70W#y48C z2!LoN>SCk!LsnH27!srVA7rwG`3L)11VD5Xby&a}W>EvKld()nn14_-MF50@Ih==J zwdRi+W>E#sNrhLYD_BL$KPZ_Z0K$&KWAH~+JiMeDW?e*qSg+FM000X)NklAG+ zm#_w8S;YKGmDSX?56<+adun=0$j4gl{o-lx0%Y;602zCOvL8@B6YGr6K`B8I5_7Q`2O> z?90C}pbShCmUeIEZKicoFIOx;=tVGix>Xsk|NaBbO>cZ#yG>|?&b*fDJJ7pjKJ}+bMO_`@mO1o>WlTGmep%+mT z_N(`2DPc*F$k0S(q_*q8VL9&*N+zjwH#on=1B4PKNU+YY4YhDx{yP;Xw>VB}BRJ>< zZNULqJWwV{bv6>S6(CBma;2tep4I7ax5wl*snsodJ%HnYju?kkC@TbHAY~!4{}^?! z0;DIV-Rbm|3ewB!9}*&w9NerTRJ9h^mdq#TmO9;=N-BJje+YJReUgjW>9^F;6(kBKypL%^EFG=!FW9!N3zFoS;%+2ABG$7jHtK z&}#QDE`3ZM=-HIlunVccEc;r)0YPZC3J{G@3_-%05-6vpd4qz!(1J5_i9}F#z)&8; z8W@VtV+Dtjgl1O(q7e$SI*?4vNm#5)RL)0QZ~*0i^b+Gvd><45<-rpeTy#mBs zR)Qd*;9>yspB8rcrt~@d?gT=NCPw*Bnb$DqOM9o zLXox#kVt|Zk|kiM$Q@{);1W0l4-?Mskf``fJicQ-6Y`%31SZlL(yr(6Bv2AS;z_Ym z&Q<~yAlVLW?N|s2RDgt#Vx^I-1d0I&9|Y_k08|hE@u^!T`7BiTOceI~nQFEJKGrcl zeT=^MWkK0=>4gtYQhsCgbIs2dAOr*lRi^iM`7mJj0AO=|cyNzFWy0=iEADUEsQ7%4 z@=6LqP&Qq9HEFmNE~9fp8V-r>5J_Gf%N-M-dD4NVBs4`*zTLx+Kn z6RewDIzQ6iw$B}4;At*i#)QCD%On910)k+W>HYoC{bqvRArK&j;}bN@BA97yhmClg z2jh>x_26TyDm@I7^fCYo4ZsC3l*d@bt>teLARQov-hqIC04aFv;%-prV1I)Es~S9H z3r5rKKMH+>&T*4~0q-&_18_D!k69fc1OqJ!y~7X?k-US^AhT`qWmI^+kZ%a1YavJ& z$bRaGFOYWw7&ZQjzWidYpNj*8fS_CN0I@*0G$(`6>$~0V_tA@n7uZ+BqWWUvxqDyQ z9D{N4i(fgCOBZe@LqhA;p zqJObuf2O;~?m8@6c%>{lKnM(a2?7G0Wrwj#X7id1GenDQ1f2O(-Y2>7pdNK|7#iN# zniLHnWS$;_9g5wFnDl+DGzK#GEWUBXN%b#ueUQ?SrjMb;008uFR z2}!m(0M?UXgl4XxkBbb9`D6Ht2C^I@rGMyNxGg9^#DZ2coCwS)A#D89tmL^=E5tXk z;0J&-QhM8dEZ7C_reb)Jpa8)jEon8q1!_sas&8%EezBzQT%2I!Z`}nwY>O{f;H!V&RjvQ+iS-TAk+j(cU+iE|UMx69ChSBh^H<=N z(_jFBdrN&?eRjamN2|#?-(Ac65yy$6eJ%vVt*G7f=N4@HQ_ zgF0H=2LlL*S%n}dpWMa}QcZHLc&8FG1OiCB!>&`?%2xncF`x>Qe|4Dc4l)j^hamxC zG)YW-WPB`ChzYW5`!R2(ZD~wl1cK^e5P*~r+g_BQZG9%W{?^U4eb;)Ijwf?qHCLSL zRS~9%CB$W*Y!D_ND`xS74 zY#U~Q-;xZN!0MjWJu5Ns2?dZ4mT`j3ZC!G)P^c5mh}efqK4Iaugm1tNWF1T&y#b=! zw*lK(6|s6iFoKMX!>kBxr!bJ)0Z4J~Td4>7Z5(FVlvU(sccx)hjJ9W)+du)A<#-+2 z-W~)*!-WnYme6Ko#gzpQX3;M4F$lAil7w&j!o+qDOby6Y4>Tts08-=tP?je5HDJMG zO^{~+YQi7;kz)#V!_W&L$~xvKU(-IBc+Y4PWCJT1t!+~QtyM16MBNJ@5v}7|a*QR0cU^=T)0h}*_G7|#E19y zmqj|N3A0LhFmX=4Atvh106}OGYjtL>-`l&cQBp9uRQP!tX6g9>OJ!~FqTUgXGe98f zr4#^7ZGO8_QsrH}2gkJ6eGj&D+on9ORPJhATzK#S$YKiM(y^uMz@uI!>o{K4yY@WB z;%zT2Xv_9|y@(S)l$Ek%HSgksfmr(fL*G&^-S)Nz)^jz_2_VZ_scp-@$DMqDaV_J) zFl(*0dotME;lOZN^XCK*v{L6E5W;YS;rPrn%wOajVb*GGFVaEhM!cp1t^o0B)VZtM zuSmHtt-&eVWm=={O}9CApUQ-3Yk*WYZX(uNW=j%a`02`zH9+9TmtCQ8?OCl?C7>kW zbHmUYAZRn6`3E{vxBMmGGf{T|Nd6M7Jw-Qx-wepRS7ss;CO1=ua0$vH9+{D*`N3KPe@Ho_f-b>o0q{I-?YCNKwKLttzPYK u9uoK;00030|J5F8Q2+n{21!IgR09AVo%2Q5{mAYB0000