作者 邓超

login

@@ -244,3 +244,34 @@ CREATE TABLE `system` ( @@ -244,3 +244,34 @@ CREATE TABLE `system` (
244 SET FOREIGN_KEY_CHECKS=1; 244 SET FOREIGN_KEY_CHECKS=1;
245 245
246 INSERT INTO `system` (`name`, `value`) VALUES ('roundcube-version', '2020122900'); 246 INSERT INTO `system` (`name`, `value`) VALUES ('roundcube-version', '2020122900');
  247 +
  248 +CREATE TABLE `email_server_address` (
  249 +`id` int(10) unsigned NOT NULL AUTO_INCREMENT,
  250 +`mail_suffix` varchar(20) NOT NULL DEFAULT '' COMMENT '邮件后缀',
  251 +`imap` varchar(50) NOT NULL DEFAULT '' COMMENT 'imap服务器地址',
  252 +`smtp` varchar(50) NOT NULL DEFAULT '' COMMENT 'stmp服务器地址',
  253 +`service_provider` varchar(50) NOT NULL DEFAULT '' COMMENT '服务商名称',
  254 +PRIMARY KEY (`id`),
  255 +KEY `mail_suffix` (`mail_suffix`)
  256 +) ENGINE=InnoDB AUTO_INCREMENT=4 DEFAULT CHARSET=utf8mb4 COMMENT='email服务器地址';
  257 +
  258 +CREATE TABLE `platform_users` (
  259 + `id` int(10) unsigned NOT NULL AUTO_INCREMENT,
  260 + `platform_id` int(10) unsigned NOT NULL DEFAULT '0' COMMENT ' platform 表id',
  261 + `user_id` int(10) unsigned NOT NULL DEFAULT '0' COMMENT 'user表id',
  262 + `platform_user_id` int(10) unsigned NOT NULL COMMENT '接入平台的用户id',
  263 + `created_at` datetime DEFAULT NULL COMMENT '创建时间',
  264 + PRIMARY KEY (`id`),
  265 + KEY `platform` (`platform_id`,`platform_user_id`,`user_id`) USING BTREE
  266 +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='接入平台,用户关系表';
  267 +
  268 +CREATE TABLE `platform` (
  269 + `id` int(10) unsigned NOT NULL AUTO_INCREMENT,
  270 + `name` varchar(20) NOT NULL DEFAULT '' COMMENT '那个平台',
  271 + `appid` int(1) unsigned NOT NULL DEFAULT '0' COMMENT 'appid',
  272 + `appkey` varchar(64) NOT NULL DEFAULT '' COMMENT 'key,来源验证使用',
  273 + `status` tinyint(1) unsigned NOT NULL DEFAULT '1' COMMENT '1,正常使用,0禁止使用',
  274 + `ip` varchar(64) NOT NULL DEFAULT '' COMMENT 'ipv6,ipv4,ip白名单',
  275 + PRIMARY KEY (`id`),
  276 + UNIQUE KEY `appid` (`appid`)
  277 +) ENGINE=InnoDB AUTO_INCREMENT=3 DEFAULT CHARSET=utf8mb4 COMMENT='平台';
1 <?php 1 <?php
2 /** 2 /**
3 - +-------------------------------------------------------------------------+  
4 - | Roundcube Webmail IMAP Client |  
5 - | Version 1.5.3 |  
6 - | |  
7 - | Copyright (C) The Roundcube Dev Team |  
8 - | |  
9 - | This program is free software: you can redistribute it and/or modify |  
10 - | it under the terms of the GNU General Public License (with exceptions |  
11 - | for skins & plugins) as published by the Free Software Foundation, |  
12 - | either version 3 of the License, or (at your option) any later version. |  
13 - | |  
14 - | This file forms part of the Roundcube Webmail Software for which the |  
15 - | following exception is added: Plugins and Skins which merely make |  
16 - | function calls to the Roundcube Webmail Software, and for that purpose |  
17 - | include it by reference shall not be considered modifications of |  
18 - | the software. |  
19 - | |  
20 - | If you wish to use this file in another project or create a modified |  
21 - | version that will not be part of the Roundcube Webmail Software, you |  
22 - | may remove the exception above and use this source code under the |  
23 - | original version of the license. |  
24 - | |  
25 - | This program is distributed in the hope that it will be useful, |  
26 - | but WITHOUT ANY WARRANTY; without even the implied warranty of |  
27 - | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |  
28 - | GNU General Public License for more details. |  
29 - | |  
30 - | You should have received a copy of the GNU General Public License |  
31 - | along with this program. If not, see http://www.gnu.org/licenses/. |  
32 - | |  
33 - +-------------------------------------------------------------------------+  
34 - | Author: Thomas Bruederli <roundcube@gmail.com> |  
35 - | Author: Aleksander Machniak <alec@alec.pl> |  
36 - +-------------------------------------------------------------------------+  
37 -*/ 3 ++-------------------------------------------------------------------------+
  4 +| Roundcube Webmail IMAP Client |
  5 +| Version 1.5.3 |
  6 +| |
  7 +| Copyright (C) The Roundcube Dev Team |
  8 +| |
  9 +| This program is free software: you can redistribute it and/or modify |
  10 +| it under the terms of the GNU General Public License (with exceptions |
  11 +| for skins & plugins) as published by the Free Software Foundation, |
  12 +| either version 3 of the License, or (at your option) any later version. |
  13 +| |
  14 +| This file forms part of the Roundcube Webmail Software for which the |
  15 +| following exception is added: Plugins and Skins which merely make |
  16 +| function calls to the Roundcube Webmail Software, and for that purpose |
  17 +| include it by reference shall not be considered modifications of |
  18 +| the software. |
  19 +| |
  20 +| If you wish to use this file in another project or create a modified |
  21 +| version that will not be part of the Roundcube Webmail Software, you |
  22 +| may remove the exception above and use this source code under the |
  23 +| original version of the license. |
  24 +| |
  25 +| This program is distributed in the hope that it will be useful, |
  26 +| but WITHOUT ANY WARRANTY; without even the implied warranty of |
  27 +| MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
  28 +| GNU General Public License for more details. |
  29 +| |
  30 +| You should have received a copy of the GNU General Public License |
  31 +| along with this program. If not, see http://www.gnu.org/licenses/. |
  32 +| |
  33 ++-------------------------------------------------------------------------+
  34 +| Author: Thomas Bruederli <roundcube@gmail.com> |
  35 +| Author: Aleksander Machniak <alec@alec.pl> |
  36 ++-------------------------------------------------------------------------+
  37 + */
38 38
39 // include environment 39 // include environment
40 require_once 'program/include/iniset.php'; 40 require_once 'program/include/iniset.php';
@@ -49,6 +49,44 @@ $RCMAIL->output->common_headers(!empty($_SESSION['user_id'])); @@ -49,6 +49,44 @@ $RCMAIL->output->common_headers(!empty($_SESSION['user_id']));
49 // turn on output buffering 49 // turn on output buffering
50 ob_start(); 50 ob_start();
51 51
  52 +// 测试链接
  53 +//?_platform=login&platform=2022072201&platform_user_id=1&sign=1
  54 +// TODO::测试链接
  55 +if(rcube_utils::get_input_value('_task', rcube_utils::INPUT_GET) == 'test'){
  56 + header("location:/?_platform=login&platform=2022072201&platform_user_id=1&sign=".(rcube_platform::create_token(1,2022072201,'BMeCgIi367f6lJ53dJI6dQ13u2NxLEqJuVaS8xgcXqw1pDdcjYa7MfWB2V6WWYjY')));
  57 + exit();
  58 +}
  59 +
  60 +// 平台登录
  61 +if(rcube_utils::get_input_value('_platform', rcube_utils::INPUT_GET) == 'login'){
  62 + // 平台用户id
  63 + $platform_user_id = rcube_utils::get_input_value('platform_user_id', rcube_utils::INPUT_GET);
  64 + $appid = rcube_utils::get_input_value('platform', rcube_utils::INPUT_GET);
  65 + $sign = rcube_utils::get_input_value('sign', rcube_utils::INPUT_GET);
  66 + // 验证加密签名
  67 + if(rcube_platform::check_token($platform_user_id,$appid,$sign)){
  68 + setcookie('platform_user_id',$platform_user_id);
  69 + setcookie('platform_appid',$appid);
  70 + setcookie('platform_id',(new rcube_platform())->getIdByAppId($appid));
  71 + //
  72 + }else{
  73 + setcookie('platform_user_id','0');
  74 + setcookie('platform_appid','0');
  75 + setcookie('platform_id','0');
  76 + }
  77 +}
  78 +// 是否验证过平台来源,当前访问回话没有验证来源
  79 +if(empty($_COOKIE['platform_user_id'])||empty($_COOKIE['platform_appid'])){
  80 + rcmail::raise_error(['code' => 403, 'message' => '你没有权限访问'], false, true);
  81 +//}else{
  82 + // 验证平台是否正常使用
  83 +// $platform = (new rcube_platform())->firstByAppId($_SESSION['platform_appid']);
  84 +// if($platform['status'] == rcube_platform::STATUS_DISABLED){
  85 +// rcmail::raise_error(['code' => 403, 'message' => '你没有权限访问'], false, true);
  86 +// }
  87 +}
  88 +
  89 +
52 // check if config files had errors 90 // check if config files had errors
53 if ($err_str = $RCMAIL->config->get_error()) { 91 if ($err_str = $RCMAIL->config->get_error()) {
54 rcmail::raise_error(['code' => 601, 'message' => $err_str], false, true); 92 rcmail::raise_error(['code' => 601, 'message' => $err_str], false, true);
@@ -120,9 +158,23 @@ if ($RCMAIL->task == 'login' && $RCMAIL->action == 'login') { @@ -120,9 +158,23 @@ if ($RCMAIL->task == 'login' && $RCMAIL->action == 'login') {
120 ]); 158 ]);
121 159
122 // Login 160 // Login
123 - if ($auth['valid'] && !$auth['abort']  
124 - && $RCMAIL->login($auth['user'], $auth['pass'], $auth['host'], $auth['cookiecheck'])  
125 - ) { 161 + $is_login = $auth['valid'] && !$auth['abort'] && $RCMAIL->login($auth['user'], $auth['pass'], $auth['host'], $auth['cookiecheck']);
  162 + if($is_login){
  163 + // 登录成功,创建绑定关系
  164 + $platform_user = (new rcube_platform_users())->create($_COOKIE['platform_id'],$RCMAIL->user->ID,$_COOKIE['platform_user_id']);
  165 + // 创建成功
  166 + if($platform_user){
  167 + // platform_user表的自增id
  168 + $_SESSION['table_platform_user_pk_id'] = $platform_user['id'];
  169 + // 当前选中操作的用户id
  170 + $_SESSION['selected_user_id'] = $RCMAIL->user->ID;
  171 + }else{
  172 + $RCMAIL->kill_session();
  173 + $is_login = false;
  174 + $auth['error'] = $RCMAIL->output->show_message('loginfailed', 'warning');
  175 + }
  176 + }
  177 + if ($is_login) {
126 // create new session ID, don't destroy the current session 178 // create new session ID, don't destroy the current session
127 // it was destroyed already by $RCMAIL->kill_session() above 179 // it was destroyed already by $RCMAIL->kill_session() above
128 $RCMAIL->session->remove('temp'); 180 $RCMAIL->session->remove('temp');
@@ -37,26 +37,27 @@ class help extends rcube_plugin @@ -37,26 +37,27 @@ class help extends rcube_plugin
37 37
38 function startup($args) 38 function startup($args)
39 { 39 {
40 - $rcmail = rcmail::get_instance();  
41 -  
42 - if (!$rcmail->output->framed) {  
43 - // add taskbar button  
44 - $this->add_button([  
45 - 'command' => 'help',  
46 - 'class' => 'button-help',  
47 - 'classsel' => 'button-help button-selected',  
48 - 'innerclass' => 'button-inner',  
49 - 'label' => 'help.help',  
50 - 'type' => 'link',  
51 - ], 'taskbar'  
52 - );  
53 -  
54 - $this->include_script('help.js');  
55 - $rcmail->output->set_env('help_open_extwin', $rcmail->config->get('help_open_extwin', false), true);  
56 - }  
57 -  
58 - // add style for taskbar button (must be here) and Help UI  
59 - $this->include_stylesheet($this->local_skin_path() . '/help.css'); 40 + // TODO::帮助按钮
  41 +// $rcmail = rcmail::get_instance();
  42 +//
  43 +// if (!$rcmail->output->framed) {
  44 +// // add taskbar button
  45 +// $this->add_button([
  46 +// 'command' => 'help',
  47 +// 'class' => 'button-help',
  48 +// 'classsel' => 'button-help button-selected',
  49 +// 'innerclass' => 'button-inner',
  50 +// 'label' => 'help.help',
  51 +// 'type' => 'link',
  52 +// ], 'taskbar'
  53 +// );
  54 +//
  55 +// $this->include_script('help.js');
  56 +// $rcmail->output->set_env('help_open_extwin', $rcmail->config->get('help_open_extwin', false), true);
  57 +// }
  58 +//
  59 +// // add style for taskbar button (must be here) and Help UI
  60 +// $this->include_stylesheet($this->local_skin_path() . '/help.css');
60 } 61 }
61 62
62 function action() 63 function action()
@@ -49,6 +49,7 @@ class rcmail_action_utils_error extends rcmail_action @@ -49,6 +49,7 @@ class rcmail_action_utils_error extends rcmail_action
49 49
50 $error_title = $rcmail->gettext('errrequestcheckfailed'); 50 $error_title = $rcmail->gettext('errrequestcheckfailed');
51 $error_text = nl2br($rcmail->gettext('errcsrfprotectionexplain')) . '<p>' . $add . '</p>'; 51 $error_text = nl2br($rcmail->gettext('errcsrfprotectionexplain')) . '<p>' . $add . '</p>';
  52 + $error_text .= nl2br($ERROR_MESSAGE);
52 } 53 }
53 // failed request (wrong step in URL) 54 // failed request (wrong step in URL)
54 else if ($ERROR_CODE == 404) { 55 else if ($ERROR_CODE == 404) {
@@ -113,6 +113,19 @@ class rcmail extends rcube @@ -113,6 +113,19 @@ class rcmail extends rcube
113 // Remember default skin, before it's replaced by user prefs 113 // Remember default skin, before it's replaced by user prefs
114 $this->default_skin = $this->config->get('skin'); 114 $this->default_skin = $this->config->get('skin');
115 115
  116 +
  117 + // 当前登录平台关系的用户id platform_users表的自增id
  118 + // 查询当前用户
  119 +// $platform_users = (new rcube_platform_users($this->get_dbh()))->firstById(($_SESSION['table_platform_users_id']??0));
  120 +// if($platform_users){
  121 +//
  122 +// }
  123 +
  124 + // 当前平台登录用户所选中的user_id;并设置为当前管理的邮箱用户
  125 + if(isset($_SESSION['selected_user_id']) && $_SESSION['selected_user_id']){
  126 + $_SESSION['user_id'] = $_SESSION['selected_user_id'];
  127 + }
  128 +
116 // create user object 129 // create user object
117 $this->set_user(new rcube_user(isset($_SESSION['user_id']) ? $_SESSION['user_id'] : null)); 130 $this->set_user(new rcube_user(isset($_SESSION['user_id']) ? $_SESSION['user_id'] : null));
118 131
@@ -418,6 +418,26 @@ class rcube_config @@ -418,6 +418,26 @@ class rcube_config
418 } 418 }
419 $result = (string) $result; 419 $result = (string) $result;
420 } 420 }
  421 + // 2022-07-22 邮箱服务器
  422 + else if($name == 'default_host' || $name == 'smtp_server'){
  423 +
  424 + if(!$result){
  425 + $result = [];
  426 + $rows = rcube_email_server_address::all($rcube->get_dbh());
  427 +
  428 + foreach ($rows as $row){
  429 + $result['imaps'][$row['imap']] = $row['name'];
  430 +
  431 + $result['stmps'][parse_url($row['imap'])['host']] = $row['smtp'];
  432 + }
  433 +
  434 + $this->set('default_host',$result['imaps']??[]);
  435 + $this->set('smtp_server',$result['stmps']??[]);
  436 +
  437 + $result = $name == 'default_host' ? ($result['imaps']??[]) : ($result['stmps']??[]);
  438 + }
  439 +
  440 + }
421 441
422 $plugin = $rcube->plugins->exec_hook('config_get', [ 442 $plugin = $rcube->plugins->exec_hook('config_get', [
423 'name' => $name, 443 'name' => $name,
  1 +<?php
  2 +
  3 +
  4 +/**
  5 + * 邮件服务商,通过邮件后缀来自动确定要请求的服务商
  6 + * @author:dc
  7 + * @time 2022/7/22 14:10
  8 + * Class rcube_email_server_address
  9 + */
  10 +class rcube_email_server_address{
  11 +
  12 +// /**
  13 +// * @var int
  14 +// */
  15 +// public $id = 0;
  16 +//
  17 +// /**
  18 +// * 邮箱后缀
  19 +// * qq.com
  20 +// * @var string
  21 +// */
  22 +// public $mail_suffix;
  23 +//
  24 +// /**
  25 +// * ssl://imap.qq.com
  26 +// * @var string
  27 +// */
  28 +// public $imap;
  29 +//
  30 +// /**
  31 +// * smtp.qq.com
  32 +// * @var string
  33 +// */
  34 +// public $smtp;
  35 +//
  36 +// /**
  37 +// * 服务商名称
  38 +// * @var string
  39 +// */
  40 +// public $name;
  41 +//
  42 +//
  43 +// private $rc;
  44 +//
  45 +// private $db;
  46 +//
  47 +// public static $rows;
  48 +//
  49 + /**
  50 + * 表
  51 + * @var string
  52 + */
  53 +// public $table = 'email_server_address';
  54 +
  55 +
  56 + /**
  57 + * Object constructor
  58 + *
  59 + * @param int $db
  60 + */
  61 +// function __construct($db = null)
  62 +// {
  63 +//
  64 +// if(!$db){
  65 +// $db = rcube::get_instance()->get_dbh();
  66 +// }
  67 +// // 查询数据
  68 +// $result = $db->query("select * from ". $db->table_name($this->table,true) );
  69 +//
  70 +// // 获取列表
  71 +// $rows = $result->fetchAll(PDO::FETCH_ASSOC);
  72 +//
  73 +// foreach ($rows as $row){
  74 +// static::$rows[$row['mail_suffix']] = [
  75 +// 'name' => $row['service_provider'],
  76 +// 'smtp' => $row['smtp'],
  77 +// 'imap' => $row['imap'],
  78 +// ];
  79 +// }
  80 +//
  81 +// $rows = null;
  82 +//
  83 +// }
  84 +
  85 +
  86 + public static function all($db = null)
  87 + {
  88 + if(!$db){
  89 + $db = rcube::get_instance()->get_dbh();
  90 + }
  91 + // 查询数据
  92 + $result = $db->query("select * from ". $db->table_name('email_server_address',true) );
  93 +
  94 + // 获取列表
  95 + $rows = [];
  96 +
  97 + foreach ($result->fetchAll(PDO::FETCH_ASSOC) as $row){
  98 + $rows[$row['mail_suffix']] = [
  99 + 'name' => $row['service_provider'],
  100 + 'smtp' => $row['smtp'],
  101 + 'imap' => $row['imap'],
  102 + ];
  103 + }
  104 +
  105 + return $rows;
  106 + }
  107 +
  108 +
  109 +
  110 +
  111 +
  112 +
  113 +
  114 +}
  1 +<?php
  2 +
  3 +
  4 +/**
  5 + * 接入平台
  6 + * @author:dc
  7 + * @time 2022/7/22 14:10
  8 + * Class rcube_email_server_address
  9 + */
  10 +class rcube_platform {
  11 +
  12 + const STATUS_ACTIVE = 1;
  13 + const STATUS_DISABLED = 0;
  14 +
  15 + private $db;
  16 +
  17 + /**
  18 + * 表
  19 + * @var string
  20 + */
  21 + public $table;
  22 +
  23 +
  24 + /**
  25 + * rcube_platform constructor.
  26 + * @param null $db
  27 + */
  28 + public function __construct($db = null)
  29 + {
  30 +
  31 + $this->db = $db ? $db : rcube::get_instance()->get_dbh();
  32 +
  33 + $this->table = $this->db->table_name('platform',true);
  34 + }
  35 +
  36 +
  37 + public function lists(){
  38 + // 查询数据
  39 + $result = $this->db->query("select * from ". $this->table);
  40 +
  41 + return $result->fetchAll(PDO::FETCH_ASSOC);
  42 + }
  43 +
  44 + /**
  45 + * 查询一条数据
  46 + * @param $id
  47 + * @return array|false
  48 + * @author:dc
  49 + * @time 2022/7/23 14:50
  50 + */
  51 + public function firstById($id)
  52 + {
  53 + // 查询数据
  54 + $result = $this->db->query("select * from ". $this->table ." where `id` = ? limit 1",$id);
  55 +
  56 + return $this->db->fetch_assoc($result);
  57 + }
  58 +
  59 + /**
  60 + * 查询一条数据
  61 + * @param $appid
  62 + * @return array|false
  63 + * @author:dc
  64 + * @time 2022/7/23 14:50
  65 + */
  66 + public function firstByAppId($appid)
  67 + {
  68 + // 查询数据
  69 + $result = $this->db->query("select * from ". $this->table ." where `appid` = ? limit 1",$appid);
  70 +
  71 + return $this->db->fetch_assoc($result);
  72 + }
  73 +
  74 + /**
  75 + * 根据appid获取id
  76 + * @param $appid
  77 + * @return int|mixed
  78 + * @author:dc
  79 + * @time 2022/7/23 15:14
  80 + */
  81 + public function getIdByAppId($appid){
  82 + // 查询数据
  83 + $result = $this->db->query("select `id` from ". $this->table ." where `appid` = ? limit 1",$appid);
  84 +
  85 + $row = $this->db->fetch_assoc($result);
  86 + if($row){
  87 + return $row['id'];
  88 + }
  89 +
  90 + return 0;
  91 + }
  92 +
  93 +
  94 + /**
  95 + * 创建验证规则
  96 + * @param $user_id
  97 + * @param $appid
  98 + * @param $appkey
  99 + * @return string
  100 + * @author:dc
  101 + * @time 2022/7/23 9:56
  102 + */
  103 + public static function create_token($user_id,$appid,$appkey)
  104 + {
  105 + // 有效时间一分钟
  106 + $sign = md5("ui={$user_id}&ai={$appid}&ak={$appkey}&t=".date('ymdhi'));
  107 +
  108 + return strtoupper($sign);
  109 + }
  110 +
  111 + /**
  112 + * 验证token规则
  113 + * @param $user_id
  114 + * @param $appid
  115 + * @param $sign
  116 + * @return bool
  117 + * @author:dc
  118 + * @time 2022/7/23 10:00
  119 + */
  120 + public static function check_token($user_id,$appid,$sign):bool {
  121 + if($sign){
  122 + $row = (new static())->firstByAppId($appid);
  123 + if($row){
  124 + return self::create_token($user_id,$appid,$row['appkey']) === $sign;
  125 + }
  126 + }
  127 + return false;
  128 + }
  129 +
  130 +
  131 +
  132 +
  133 +
  134 +}
  1 +<?php
  2 +
  3 +
  4 +/**
  5 + * 接入平台的用户
  6 + * @author:dc
  7 + * @time 2022/7/22 14:10
  8 + * Class rcube_platform_users
  9 + */
  10 +class rcube_platform_users{
  11 +
  12 + private $db;
  13 +
  14 + /**
  15 + * 表
  16 + * @var string
  17 + */
  18 + public $table;
  19 +
  20 + /**
  21 + * rcube_platform constructor.
  22 + * @param null $db
  23 + */
  24 + public function __construct($db = null)
  25 + {
  26 +
  27 + $this->db = $db ? $db : rcube::get_instance()->get_dbh();
  28 +
  29 + $this->table = $this->db->table_name('platform_users',true);
  30 + }
  31 +
  32 +
  33 + public function firstByPlatformUserId($platform_user_id)
  34 + {
  35 + // 查询数据
  36 + $result = $this->db->query("select * from ". $this->table ." where `platform_user_id` = ?",$platform_user_id);
  37 +
  38 + return $this->db->fetch_assoc($result);
  39 + }
  40 +
  41 +
  42 + public function firstById($id){
  43 + // 查询数据
  44 + $result = $this->db->query("select * from ". $this->table ." where `id` = ?",$id);
  45 +
  46 + return $this->db->fetch_assoc($result);
  47 + }
  48 +
  49 +
  50 + /**
  51 + * 创建用户,平台用户
  52 + * @param $platform_id
  53 + * @param $user_id
  54 + * @param $platform_user_id
  55 + * @author:dc
  56 + * @time 2022/7/23 14:21
  57 + */
  58 + public function create($platform_id,$user_id,$platform_user_id){
  59 + // 存在,就直接返回
  60 + $result = $this->db->query("select `id`,`platform_id`,`user_id`,`platform_user_id` from {$this->table} where `platform_id` = ? and `user_id` = ? and `platform_user_id` = ? limit 1",$platform_id,$user_id,$platform_user_id);
  61 + $row = $this->db->fetch_assoc($result);
  62 + if($row){
  63 + return $row;
  64 + }
  65 + // 使用参数绑定一样要按照?所排列的字段来,不然会混乱
  66 + // 不存在,则新增
  67 + $insert = $this->db->query("insert into {$this->table} set `platform_id` = ? , `user_id` = ? , `platform_user_id` = ? , `created_at` = ?",$platform_id,$user_id,$platform_user_id,date('Y-m-d H:i:s'));
  68 +
  69 + if ($insert && $this->db->affected_rows($insert) && ($id = $this->db->insert_id('platform_users'))) {
  70 + return $this->firstById($id);
  71 + }else{
  72 + return false;
  73 + }
  74 +
  75 + }
  76 +
  77 +
  78 +
  79 +
  80 +
  81 +
  82 +
  83 +}
  1 +plugins
  2 +skins
@@ -33,8 +33,7 @@ @@ -33,8 +33,7 @@
33 <roundcube:add_label name="lightmode" /> 33 <roundcube:add_label name="lightmode" />
34 <roundcube:button name="theme" label="darkmode" type="link" innerClass="inner" class="theme dark" /> 34 <roundcube:button name="theme" label="darkmode" type="link" innerClass="inner" class="theme dark" />
35 <roundcube:endif /> 35 <roundcube:endif />
36 - <roundcube:button name="about" label="about" type="link"  
37 - class="about" innerClass="inner" onclick="UI.about_dialog(this)" /> 36 +<!-- <roundcube:button name="about" label="about" type="link" class="about" innerClass="inner" onclick="UI.about_dialog(this)" />-->
38 <roundcube:button command="logout" label="logout" type="link" 37 <roundcube:button command="logout" label="logout" type="link"
39 class="logout" innerClass="inner" /> 38 class="logout" innerClass="inner" />
40 </span> 39 </span>
  1 +linux 服务器
  2 +public_html目录下没有skins和plugins两个目录的软链接请在 public_html目录下面执行以下命令
  3 +ln -s ../skins skins
  4 +ln -s ../plugins plugins
  5 +
  6 +如不进行软链接,则无法访问静态文件