diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..9880042 --- /dev/null +++ b/.gitignore @@ -0,0 +1,7 @@ +.arts/* +.codeartsdoer/* +uahpet/cat/* +uahpet/report-data/* +uahpet/report-data_bak/*.idea/ +logs/ +cache/ \ No newline at end of file diff --git a/.htaccess b/.htaccess new file mode 100644 index 0000000..6c63ed4 --- /dev/null +++ b/.htaccess @@ -0,0 +1,6 @@ + + Require all denied + + + Deny from all + \ No newline at end of file diff --git a/.idea/.gitignore b/.idea/.gitignore new file mode 100644 index 0000000..13566b8 --- /dev/null +++ b/.idea/.gitignore @@ -0,0 +1,8 @@ +# Default ignored files +/shelf/ +/workspace.xml +# Editor-based HTTP Client requests +/httpRequests/ +# Datasource local storage ignored files +/dataSources/ +/dataSources.local.xml diff --git a/.idea/application.iml b/.idea/application.iml new file mode 100644 index 0000000..c956989 --- /dev/null +++ b/.idea/application.iml @@ -0,0 +1,8 @@ + + + + + + + + \ No newline at end of file diff --git a/.idea/modules.xml b/.idea/modules.xml new file mode 100644 index 0000000..7a9616c --- /dev/null +++ b/.idea/modules.xml @@ -0,0 +1,8 @@ + + + + + + + + \ No newline at end of file diff --git a/.idea/php.xml b/.idea/php.xml new file mode 100644 index 0000000..f324872 --- /dev/null +++ b/.idea/php.xml @@ -0,0 +1,19 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/.idea/vcs.xml b/.idea/vcs.xml new file mode 100644 index 0000000..d586662 --- /dev/null +++ b/.idea/vcs.xml @@ -0,0 +1,8 @@ + + + + + + + + \ No newline at end of file diff --git a/.merkle-snapshot.json b/.merkle-snapshot.json new file mode 100644 index 0000000..5e3a539 --- /dev/null +++ b/.merkle-snapshot.json @@ -0,0 +1 @@ +{"rootHash":"f06c940aa695edb4d76ca57838784edade0b517c6d6d6bc4a14caf20fab19275","timestamp":1789371873112,"fileCount":5,"files":[{"path":"uahpet\\report-data_bak\\Feline\\convert.bak.py","hash":"1d470c56718115a869ce9d330ff997f525858d6ee87d0c55fdc4005b9ab627cc","size":2958,"modified":1789371596769.8796},{"path":"uahpet\\report-data_bak\\Feline\\convert.py","hash":"f47c56a14584481f2c06cdca9bdb088a431e571c8b0cf9696be5ab32e82c9125","size":3448,"modified":1789371596769.8796},{"path":"uahpet\\report-data\\Feline\\convert.bak.py","hash":"1d470c56718115a869ce9d330ff997f525858d6ee87d0c55fdc4005b9ab627cc","size":2958,"modified":1789371588699.2039},{"path":"uahpet\\report-data\\Feline\\convert.py","hash":"f47c56a14584481f2c06cdca9bdb088a431e571c8b0cf9696be5ab32e82c9125","size":3448,"modified":1789371588699.2039},{"path":"uahpet\\report-data\\Feline\\convert.sh","hash":"ee842dea3a9be975cba4cc500eba27a01e9d33d12db7ef2100ec516c35a2c4a7","size":420,"modified":1789371588699.2039}]} \ No newline at end of file diff --git a/config/autoload.php b/config/autoload.php new file mode 100644 index 0000000..49f4aff --- /dev/null +++ b/config/autoload.php @@ -0,0 +1,138 @@ + 'ua'); +*/ +//$autoload['libraries'] = array(); +// 'session' 启用 $_SESSION功能 +$autoload['libraries'] = array('Permission'); + + +/* +| ------------------------------------------------------------------- +| Auto-load Drivers +| ------------------------------------------------------------------- +| These classes are located in system/libraries/ or in your +| application/libraries/ directory, but are also placed inside their +| own subdirectory and they extend the CI_Driver_Library class. They +| offer multiple interchangeable driver options. +| +| Prototype: +| +| $autoload['drivers'] = array('cache'); +| +| You can also supply an alternative property name to be assigned in +| the controller: +| +| $autoload['drivers'] = array('cache' => 'cch'); +| +*/ +$autoload['drivers'] = array(); + +/* +| ------------------------------------------------------------------- +| Auto-load Helper Files +| ------------------------------------------------------------------- +| Prototype: +| +| $autoload['helper'] = array('url', 'file'); +*/ +$autoload['helper'] = array('url'); + +/* +| ------------------------------------------------------------------- +| Auto-load Config files +| ------------------------------------------------------------------- +| Prototype: +| +| $autoload['config'] = array('config1', 'config2'); +| +| NOTE: This item is intended for use ONLY if you have created custom +| config files. Otherwise, leave it blank. +| +*/ +$autoload['config'] = array(); + +/* +| ------------------------------------------------------------------- +| Auto-load Language files +| ------------------------------------------------------------------- +| Prototype: +| +| $autoload['language'] = array('lang1', 'lang2'); +| +| NOTE: Do not include the "_lang" part of your file. For example +| "codeigniter_lang.php" would be referenced as array('codeigniter'); +| +*/ +$autoload['language'] = array(); + +/* +| ------------------------------------------------------------------- +| Auto-load Models +| ------------------------------------------------------------------- +| Prototype: +| +| $autoload['model'] = array('first_model', 'second_model'); +| +| You can also supply an alternative model name to be assigned +| in the controller: +| +| $autoload['model'] = array('first_model' => 'first'); +*/ +$autoload['model'] = array(); diff --git a/config/config.php b/config/config.php new file mode 100644 index 0000000..b25f399 --- /dev/null +++ b/config/config.php @@ -0,0 +1,609 @@ +]+$/i +| +| DO NOT CHANGE THIS UNLESS YOU FULLY UNDERSTAND THE REPERCUSSIONS!! +| +*/ +$config['permitted_uri_chars'] = 'a-z 0-9~%.:_\-'; + +/* +|-------------------------------------------------------------------------- +| Enable Query Strings +|-------------------------------------------------------------------------- +| +| By default CodeIgniter uses search-engine friendly segment based URLs: +| example.com/who/what/where/ +| +| You can optionally enable standard query string based URLs: +| example.com?who=me&what=something&where=here +| +| Options are: TRUE or FALSE (boolean) +| +| The other items let you set the query string 'words' that will +| invoke your controllers and its functions: +| example.com/index.php?c=controller&m=function +| +| Please note that some of the helpers won't work as expected when +| this feature is enabled, since CodeIgniter is designed primarily to +| use segment based URLs. +| +*/ +$config['enable_query_strings'] = FALSE; +$config['controller_trigger'] = 'c'; +$config['function_trigger'] = 'm'; +$config['directory_trigger'] = 'd'; + +/* +|-------------------------------------------------------------------------- +| Allow $_GET array +|-------------------------------------------------------------------------- +| +| By default CodeIgniter enables access to the $_GET array. If for some +| reason you would like to disable it, set 'allow_get_array' to FALSE. +| +| WARNING: This feature is DEPRECATED and currently available only +| for backwards compatibility purposes! +| +*/ +$config['allow_get_array'] = TRUE; + +/* +|-------------------------------------------------------------------------- +| Error Logging Threshold +|-------------------------------------------------------------------------- +| +| You can enable error logging by setting a threshold over zero. The +| threshold determines what gets logged. Threshold options are: +| +| 0 = Disables logging, Error logging TURNED OFF +| 1 = Error Messages (including PHP errors) +| 2 = Debug Messages +| 3 = Informational Messages +| 4 = All Messages +| +| You can also pass an array with threshold levels to show individual error types +| +| array(2) = Debug Messages, without Error Messages +| +| For a live site you'll usually only enable Errors (1) to be logged otherwise +| your log files will fill up very fast. +| +*/ +$config['log_threshold'] = 1; + +/* +|-------------------------------------------------------------------------- +| Error Logging Directory Path +|-------------------------------------------------------------------------- +| +| Leave this BLANK unless you would like to set something other than the default +| application/logs/ directory. Use a full server path with trailing slash. +| +*/ +$config['log_path'] = ''; + +/* +|-------------------------------------------------------------------------- +| Log File Extension +|-------------------------------------------------------------------------- +| +| The default filename extension for log files. The default 'php' allows for +| protecting the log files via basic scripting, when they are to be stored +| under a publicly accessible directory. +| +| Note: Leaving it blank will default to 'php'. +| +*/ +$config['log_file_extension'] = ''; + +/* +|-------------------------------------------------------------------------- +| Log File Permissions +|-------------------------------------------------------------------------- +| +| The file system permissions to be applied on newly created log files. +| +| IMPORTANT: This MUST be an integer (no quotes) and you MUST use octal +| integer notation (i.e. 0700, 0644, etc.) +*/ +$config['log_file_permissions'] = 0644; + +/* +|-------------------------------------------------------------------------- +| Date Format for Logs +|-------------------------------------------------------------------------- +| +| Each item that is logged has an associated date. You can use PHP date +| codes to set your own date formatting +| +*/ +$config['log_date_format'] = 'Y-m-d H:i:s'; + +/* +|-------------------------------------------------------------------------- +| Error Views Directory Path +|-------------------------------------------------------------------------- +| +| Leave this BLANK unless you would like to set something other than the default +| application/views/errors/ directory. Use a full server path with trailing slash. +| +*/ +$config['error_views_path'] = ''; + +/* +|-------------------------------------------------------------------------- +| Cache Directory Path +|-------------------------------------------------------------------------- +| +| Leave this BLANK unless you would like to set something other than the default +| application/cache/ directory. Use a full server path with trailing slash. +| +*/ +$config['cache_path'] = ''; + +/* +|-------------------------------------------------------------------------- +| Cache Include Query String +|-------------------------------------------------------------------------- +| +| Whether to take the URL query string into consideration when generating +| output cache files. Valid options are: +| +| FALSE = Disabled +| TRUE = Enabled, take all query parameters into account. +| Please be aware that this may result in numerous cache +| files generated for the same page over and over again. +| array('q') = Enabled, but only take into account the specified list +| of query parameters. +| +*/ +$config['cache_query_string'] = FALSE; + +/* +|-------------------------------------------------------------------------- +| Encryption Key +|-------------------------------------------------------------------------- +| +| If you use the Encryption class, you must set an encryption key. +| See the user guide for more info. +| +| https://codeigniter.com/user_guide/libraries/encryption.html +| +*/ +$config['encryption_key'] = ''; + +/* +|-------------------------------------------------------------------------- +| Session Variables +|-------------------------------------------------------------------------- +| +| 'sess_driver' +| +| The storage driver to use: files, database, redis, memcached +| +| 'sess_cookie_name' +| +| The session cookie name, must contain only [0-9a-z_-] characters +| +| 'sess_expiration' +| +| The number of SECONDS you want the session to last. +| Setting to 0 (zero) means expire when the browser is closed. +| +| 'sess_save_path' +| +| The location to save sessions to, driver dependent. +| +| For the 'files' driver, it's a path to a writable directory. +| WARNING: Only absolute paths are supported! +| +| For the 'database' driver, it's a table name. +| Please read up the manual for the format with other session drivers. +| +| IMPORTANT: You are REQUIRED to set a valid save path! +| +| 'sess_match_ip' +| +| Whether to match the user's IP address when reading the session data. +| +| WARNING: If you're using the database driver, don't forget to update +| your session table's PRIMARY KEY when changing this setting. +| +| 'sess_time_to_update' +| +| How many seconds between CI regenerating the session ID. +| +| 'sess_regenerate_destroy' +| +| Whether to destroy session data associated with the old session ID +| when auto-regenerating the session ID. When set to FALSE, the data +| will be later deleted by the garbage collector. +| +| Other session cookie settings are shared with the rest of the application, +| except for 'cookie_prefix' and 'cookie_httponly', which are ignored here. +| +*/ +$config['sess_driver'] = 'files'; +$config['sess_cookie_name'] = 'ci_session'; +$config['sess_expiration'] = 7200; +$config['sess_save_path'] = NULL; +$config['sess_match_ip'] = FALSE; +$config['sess_time_to_update'] = 300; +$config['sess_regenerate_destroy'] = FALSE; + +/* +|-------------------------------------------------------------------------- +| Cookie Related Variables +|-------------------------------------------------------------------------- +| +| 'cookie_prefix' = Set a cookie name prefix if you need to avoid collisions +| 'cookie_domain' = Set to .your-domain.com for site-wide cookies +| 'cookie_path' = Typically will be a forward slash +| 'cookie_secure' = Cookie will only be set if a secure HTTPS connection exists. +| 'cookie_httponly' = Cookie will only be accessible via HTTP(S) (no javascript) +| +| Note: These settings (with the exception of 'cookie_prefix' and +| 'cookie_httponly') will also affect sessions. +| +*/ +$config['cookie_prefix'] = ''; +$config['cookie_domain'] = ''; +$config['cookie_path'] = '/'; +$config['cookie_secure'] = FALSE; +$config['cookie_httponly'] = FALSE; + +/* +|-------------------------------------------------------------------------- +| Standardize newlines +|-------------------------------------------------------------------------- +| +| Determines whether to standardize newline characters in input data, +| meaning to replace \r\n, \r, \n occurrences with the PHP_EOL value. +| +| WARNING: This feature is DEPRECATED and currently available only +| for backwards compatibility purposes! +| +*/ +$config['standardize_newlines'] = FALSE; + +/* +|-------------------------------------------------------------------------- +| Global XSS Filtering +|-------------------------------------------------------------------------- +| +| Determines whether the XSS filter is always active when GET, POST or +| COOKIE data is encountered +| +| WARNING: This feature is DEPRECATED and currently available only +| for backwards compatibility purposes! +| +*/ +$config['global_xss_filtering'] = FALSE; + +/* +|-------------------------------------------------------------------------- +| Cross Site Request Forgery +|-------------------------------------------------------------------------- +| Enables a CSRF cookie token to be set. When set to TRUE, token will be +| checked on a submitted form. If you are accepting user data, it is strongly +| recommended CSRF protection be enabled. +| +| 'csrf_token_name' = The token name +| 'csrf_cookie_name' = The cookie name +| 'csrf_expire' = The number in seconds the token should expire. +| 'csrf_regenerate' = Regenerate token on every submission +| 'csrf_exclude_uris' = Array of URIs which ignore CSRF checks +*/ +$config['csrf_protection'] = FALSE; +$config['csrf_token_name'] = 'csrf_test_name'; +$config['csrf_cookie_name'] = 'csrf_cookie_name'; +$config['csrf_expire'] = 7200; +$config['csrf_regenerate'] = TRUE; +$config['csrf_exclude_uris'] = array(); + +/* +|-------------------------------------------------------------------------- +| Output Compression +|-------------------------------------------------------------------------- +| +| Enables Gzip output compression for faster page loads. When enabled, +| the output class will test whether your server supports Gzip. +| Even if it does, however, not all browsers support compression +| so enable only if you are reasonably sure your visitors can handle it. +| +| Only used if zlib.output_compression is turned off in your php.ini. +| Please do not use it together with httpd-level output compression. +| +| VERY IMPORTANT: If you are getting a blank page when compression is enabled it +| means you are prematurely outputting something to your browser. It could +| even be a line of whitespace at the end of one of your scripts. For +| compression to work, nothing can be sent before the output buffer is called +| by the output class. Do not 'echo' any values with compression enabled. +| +*/ +$config['compress_output'] = FALSE; + +/* +|-------------------------------------------------------------------------- +| Master Time Reference +|-------------------------------------------------------------------------- +| +| Options are 'local' or any PHP supported timezone. This preference tells +| the system whether to use your server's local time as the master 'now' +| reference, or convert it to the configured one timezone. See the 'date +| helper' page of the user guide for information regarding date handling. +| +*/ +$config['time_reference'] = 'local'; + +/* +|-------------------------------------------------------------------------- +| Rewrite PHP Short Tags +|-------------------------------------------------------------------------- +| +| If your PHP installation does not have short tag support enabled CI +| can rewrite the tags on-the-fly, enabling you to utilize that syntax +| in your view files. Options are TRUE or FALSE (boolean) +| +| Note: You need to have eval() enabled for this to work. +| +*/ +$config['rewrite_short_tags'] = FALSE; + +/* +|-------------------------------------------------------------------------- +| Reverse Proxy IPs +|-------------------------------------------------------------------------- +| +| If your server is behind a reverse proxy, you must whitelist the proxy +| IP addresses from which CodeIgniter should trust headers such as +| HTTP_X_FORWARDED_FOR and HTTP_CLIENT_IP in order to properly identify +| the visitor's IP address. +| +| You can use both an array or a comma-separated list of proxy addresses, +| as well as specifying whole subnets. Here are a few examples: +| +| Comma-separated: '10.0.1.200,192.168.5.0/24' +| Array: array('10.0.1.200', '192.168.5.0/24') +*/ +$config['proxy_ips'] = ''; + +// JWT 自定义配置 +$config['jwt_key'] = 'pocoyo'; +$config['jwt_access_token_exp'] = 7200; // 单位秒 +$config['jwt_refresh_token_exp'] = 604800; // 单位秒 +$config['jwt_refresh_count'] = 7; // 调用refresh_token接口超过此次数时, 会重置刷新token过期时间 + +$config['jwt_api_prefix'] = 'api/v2'; + +// 白名单里的uri不认证 +$config['jwt_white_list'] = [ + '/sys/user/login', + '/sys/user/logout', + '/sys/user/refreshtoken', // 刷新token接口需要在控制器内作权限验证,比较特殊 + // 下面接口uri 可以在菜单权限里面添加,再分配给对应角色即可, 方便/安全? + // 如果不想在前端菜单里添加,也可以直接在后端在控制器里单独做token验证,不用做权限认证 + // 参考/sys/user/refreshtoken + '/sys/user/info', + '/sys/user/list', + '/sys/user/getroleoptions', + '/sys/role/allroles', + '/sys/role/allmenus', + '/sys/role/rolemenu', + '/sys/role/rolerole', + '/sys/menu/treeoptions' +]; + +// 自定义jwt token 过期或异常返回值,根据前端需要可以分开 +// SignatureInvalidException 签名不正确 +// BeforeValidException签名在某个时间点之后才能用 +// ExpiredException token过期 +// Exception 其他错误 +$config['jwt_token_expired'] = ["code" => 50014, "message" => "Token 过期了oo"]; +$config['jwt_token_exception'] = ['code' => 50008, 'message' => "非法的token"]; + +/* +|-------------------------------------------------------------------------- +| 微信公众号配置 +|-------------------------------------------------------------------------- +*/ +//精准宠爱 +//define('WEIXIN_APPID','wx2527f37a99f36591'); +//define('WEIXIN_APPSECERT','1fa0a4f1866a270fccbc3b5c9bccf2ab'); +//深知生物 +//define('WEIXIN_APPID','wx5d49b7f2f3f0b364'); +//define('WEIXIN_APPSECERT','f4980e8e790986aa9b04445b56111276'); + +//有哈公众号 +$config['weixin_uah'] = [ + 'AppId'=>'wx68a9516b40596f7c', + 'AppSecert'=>'617bb0abbe9988198a4be7e79f6ec877', + 'Token'=>'rpR69GDeKO5Ap37aojeEieTv6CXdn6zR', + 'EncodingAESKey'=>'tgmB5BG6EdVxudQkI9tuCQrPhjDvb50nMCsgCHBtD2J', + //微信支付 + 'mch_id'=>'1575062461',//微信支付商户号 + 'pay_api_key'=>'6410724d88504fac0e2e0ac49f40da4e',//微信支付密钥 + 'pay_api_key_v3'=>'9a99c6046a960c1d572b4c198532a132',//微信支付密钥v3 + 'pay_cert_path'=>APPPATH.'cert/apiclient_cert.pem',//证书 + 'pay_key_path'=>APPPATH.'cert/apiclient_key.pem',//证书密钥 +]; + +//有哈小程序后端服务token +$config['uah_server_token'] = '0d5b7617-890f-ff07-1e57-a3e4ab91ca39'; + +/* +|-------------------------------------------------------------------------- +| 中通快递配置 https://zop.zto.com/consoleBoard/home +|-------------------------------------------------------------------------- +*/ +$config['zto'] = [ + 'id'=>'70720bf074944864923a13debd69b50a', + 'key'=>'aace38d17062', + 'host'=>'http://japi.zto.cn/' +]; + +/* +|-------------------------------------------------------------------------- +| 顺风快递配置 https://qiao.sf-express.com/pages/developDoc/index.html?level2=194867 +|-------------------------------------------------------------------------- +*/ +$config['sf-express'] = [ + 'clientCode'=>'YHKJ_HQJYM', + 'checkword'=>'HSJPtAvNanJlUHaK4y6nr5ldjiw8C8Te', + 'custid'=>'7550176107',//月结卡号:测试卡号7551234567 +]; diff --git a/config/constants.php b/config/constants.php new file mode 100644 index 0000000..18d3b4b --- /dev/null +++ b/config/constants.php @@ -0,0 +1,85 @@ +db->last_query() and profiling of DB queries. +| When you run a query, with this setting set to TRUE (default), +| CodeIgniter will store the SQL statement for debugging purposes. +| However, this may cause high memory usage, especially if you run +| a lot of SQL queries ... disable this to avoid that problem. +| +| The $active_group variable lets you choose which connection group to +| make active. By default there is only one group (the 'default' group). +| +| The $query_builder variables lets you determine whether or not to load +| the query builder class. +*/ +$active_group = 'default'; +$query_builder = TRUE; + +$db['default'] = array( + 'dsn' => '', + 'hostname' => 'localhost', + 'username' => 'dna', + 'password' => 'wSFH4T47VAHpSpfS', + 'database' => 'dna', + 'dbdriver' => 'mysqli', + 'dbprefix' => '', + 'pconnect' => FALSE, + 'db_debug' => (ENVIRONMENT !== 'production'), + 'cache_on' => FALSE, + 'cachedir' => '', + 'char_set' => 'utf8', + 'dbcollat' => 'utf8_general_ci', + 'swap_pre' => '', + 'encrypt' => FALSE, + 'compress' => FALSE, + 'stricton' => FALSE, + 'failover' => array(), + 'save_queries' => TRUE +); diff --git a/config/development/config.php b/config/development/config.php new file mode 100644 index 0000000..e4023b1 --- /dev/null +++ b/config/development/config.php @@ -0,0 +1,13 @@ +'kfpttestCode', + 'key'=>'kfpttestkey==', + 'host'=>'http://58.40.16.122:8080/' + //'host'=>'http://58.40.16.120:9001/' +]; diff --git a/config/doctypes.php b/config/doctypes.php new file mode 100644 index 0000000..59a7991 --- /dev/null +++ b/config/doctypes.php @@ -0,0 +1,24 @@ + '', + 'xhtml1-strict' => '', + 'xhtml1-trans' => '', + 'xhtml1-frame' => '', + 'xhtml-basic11' => '', + 'html5' => '', + 'html4-strict' => '', + 'html4-trans' => '', + 'html4-frame' => '', + 'mathml1' => '', + 'mathml2' => '', + 'svg10' => '', + 'svg11' => '', + 'svg11-basic' => '', + 'svg11-tiny' => '', + 'xhtml-math-svg-xh' => '', + 'xhtml-math-svg-sh' => '', + 'xhtml-rdfa-1' => '', + 'xhtml-rdfa-2' => '' +); diff --git a/config/foreign_chars.php b/config/foreign_chars.php new file mode 100644 index 0000000..995f483 --- /dev/null +++ b/config/foreign_chars.php @@ -0,0 +1,103 @@ + 'ae', + '/ö|œ/' => 'oe', + '/ü/' => 'ue', + '/Ä/' => 'Ae', + '/Ü/' => 'Ue', + '/Ö/' => 'Oe', + '/À|Á|Â|Ã|Ä|Å|Ǻ|Ā|Ă|Ą|Ǎ|Α|Ά|Ả|Ạ|Ầ|Ẫ|Ẩ|Ậ|Ằ|Ắ|Ẵ|Ẳ|Ặ|А/' => 'A', + '/à|á|â|ã|å|ǻ|ā|ă|ą|ǎ|ª|α|ά|ả|ạ|ầ|ấ|ẫ|ẩ|ậ|ằ|ắ|ẵ|ẳ|ặ|а/' => 'a', + '/Б/' => 'B', + '/б/' => 'b', + '/Ç|Ć|Ĉ|Ċ|Č/' => 'C', + '/ç|ć|ĉ|ċ|č/' => 'c', + '/Д/' => 'D', + '/д/' => 'd', + '/Ð|Ď|Đ|Δ/' => 'Dj', + '/ð|ď|đ|δ/' => 'dj', + '/È|É|Ê|Ë|Ē|Ĕ|Ė|Ę|Ě|Ε|Έ|Ẽ|Ẻ|Ẹ|Ề|Ế|Ễ|Ể|Ệ|Е|Э/' => 'E', + '/è|é|ê|ë|ē|ĕ|ė|ę|ě|έ|ε|ẽ|ẻ|ẹ|ề|ế|ễ|ể|ệ|е|э/' => 'e', + '/Ф/' => 'F', + '/ф/' => 'f', + '/Ĝ|Ğ|Ġ|Ģ|Γ|Г|Ґ/' => 'G', + '/ĝ|ğ|ġ|ģ|γ|г|ґ/' => 'g', + '/Ĥ|Ħ/' => 'H', + '/ĥ|ħ/' => 'h', + '/Ì|Í|Î|Ï|Ĩ|Ī|Ĭ|Ǐ|Į|İ|Η|Ή|Ί|Ι|Ϊ|Ỉ|Ị|И|Ы/' => 'I', + '/ì|í|î|ï|ĩ|ī|ĭ|ǐ|į|ı|η|ή|ί|ι|ϊ|ỉ|ị|и|ы|ї/' => 'i', + '/Ĵ/' => 'J', + '/ĵ/' => 'j', + '/Ķ|Κ|К/' => 'K', + '/ķ|κ|к/' => 'k', + '/Ĺ|Ļ|Ľ|Ŀ|Ł|Λ|Л/' => 'L', + '/ĺ|ļ|ľ|ŀ|ł|λ|л/' => 'l', + '/М/' => 'M', + '/м/' => 'm', + '/Ñ|Ń|Ņ|Ň|Ν|Н/' => 'N', + '/ñ|ń|ņ|ň|ʼn|ν|н/' => 'n', + '/Ò|Ó|Ô|Õ|Ō|Ŏ|Ǒ|Ő|Ơ|Ø|Ǿ|Ο|Ό|Ω|Ώ|Ỏ|Ọ|Ồ|Ố|Ỗ|Ổ|Ộ|Ờ|Ớ|Ỡ|Ở|Ợ|О/' => 'O', + '/ò|ó|ô|õ|ō|ŏ|ǒ|ő|ơ|ø|ǿ|º|ο|ό|ω|ώ|ỏ|ọ|ồ|ố|ỗ|ổ|ộ|ờ|ớ|ỡ|ở|ợ|о/' => 'o', + '/П/' => 'P', + '/п/' => 'p', + '/Ŕ|Ŗ|Ř|Ρ|Р/' => 'R', + '/ŕ|ŗ|ř|ρ|р/' => 'r', + '/Ś|Ŝ|Ş|Ș|Š|Σ|С/' => 'S', + '/ś|ŝ|ş|ș|š|ſ|σ|ς|с/' => 's', + '/Ț|Ţ|Ť|Ŧ|τ|Т/' => 'T', + '/ț|ţ|ť|ŧ|т/' => 't', + '/Þ|þ/' => 'th', + '/Ù|Ú|Û|Ũ|Ū|Ŭ|Ů|Ű|Ų|Ư|Ǔ|Ǖ|Ǘ|Ǚ|Ǜ|Ũ|Ủ|Ụ|Ừ|Ứ|Ữ|Ử|Ự|У/' => 'U', + '/ù|ú|û|ũ|ū|ŭ|ů|ű|ų|ư|ǔ|ǖ|ǘ|ǚ|ǜ|υ|ύ|ϋ|ủ|ụ|ừ|ứ|ữ|ử|ự|у/' => 'u', + '/Ƴ|Ɏ|Ỵ|Ẏ|Ӳ|Ӯ|Ў|Ý|Ÿ|Ŷ|Υ|Ύ|Ϋ|Ỳ|Ỹ|Ỷ|Ỵ|Й/' => 'Y', + '/ẙ|ʏ|ƴ|ɏ|ỵ|ẏ|ӳ|ӯ|ў|ý|ÿ|ŷ|ỳ|ỹ|ỷ|ỵ|й/' => 'y', + '/В/' => 'V', + '/в/' => 'v', + '/Ŵ/' => 'W', + '/ŵ/' => 'w', + '/Ź|Ż|Ž|Ζ|З/' => 'Z', + '/ź|ż|ž|ζ|з/' => 'z', + '/Æ|Ǽ/' => 'AE', + '/ß/' => 'ss', + '/IJ/' => 'IJ', + '/ij/' => 'ij', + '/Œ/' => 'OE', + '/ƒ/' => 'f', + '/ξ/' => 'ks', + '/π/' => 'p', + '/β/' => 'v', + '/μ/' => 'm', + '/ψ/' => 'ps', + '/Ё/' => 'Yo', + '/ё/' => 'yo', + '/Є/' => 'Ye', + '/є/' => 'ye', + '/Ї/' => 'Yi', + '/Ж/' => 'Zh', + '/ж/' => 'zh', + '/Х/' => 'Kh', + '/х/' => 'kh', + '/Ц/' => 'Ts', + '/ц/' => 'ts', + '/Ч/' => 'Ch', + '/ч/' => 'ch', + '/Ш/' => 'Sh', + '/ш/' => 'sh', + '/Щ/' => 'Shch', + '/щ/' => 'shch', + '/Ъ|ъ|Ь|ь/' => '', + '/Ю/' => 'Yu', + '/ю/' => 'yu', + '/Я/' => 'Ya', + '/я/' => 'ya' +); diff --git a/config/hooks.php b/config/hooks.php new file mode 100644 index 0000000..282ba1f --- /dev/null +++ b/config/hooks.php @@ -0,0 +1,20 @@ + 'ManageAuth', //类名 + 'function' => 'auth', //执行的方法 + 'filename' => 'ManageAuth.php', //文件名 + 'filepath' => 'hooks' //文件路径,默认是application/hooks +); diff --git a/config/index.html b/config/index.html new file mode 100644 index 0000000..b702fbc --- /dev/null +++ b/config/index.html @@ -0,0 +1,11 @@ + + + + 403 Forbidden + + + +

Directory access is forbidden.

+ + + diff --git a/config/memcached.php b/config/memcached.php new file mode 100644 index 0000000..5c23b39 --- /dev/null +++ b/config/memcached.php @@ -0,0 +1,19 @@ + array( + 'hostname' => '127.0.0.1', + 'port' => '11211', + 'weight' => '1', + ), +); diff --git a/config/migration.php b/config/migration.php new file mode 100644 index 0000000..4b585a6 --- /dev/null +++ b/config/migration.php @@ -0,0 +1,84 @@ +migration->current() this is the version that schema will +| be upgraded / downgraded to. +| +*/ +$config['migration_version'] = 0; + +/* +|-------------------------------------------------------------------------- +| Migrations Path +|-------------------------------------------------------------------------- +| +| Path to your migrations folder. +| Typically, it will be within your application path. +| Also, writing permission is required within the migrations path. +| +*/ +$config['migration_path'] = APPPATH.'migrations/'; diff --git a/config/mimes.php b/config/mimes.php new file mode 100644 index 0000000..0ec9db0 --- /dev/null +++ b/config/mimes.php @@ -0,0 +1,184 @@ + array('application/mac-binhex40', 'application/mac-binhex', 'application/x-binhex40', 'application/x-mac-binhex40'), + 'cpt' => 'application/mac-compactpro', + 'csv' => array('text/x-comma-separated-values', 'text/comma-separated-values', 'application/octet-stream', 'application/vnd.ms-excel', 'application/x-csv', 'text/x-csv', 'text/csv', 'application/csv', 'application/excel', 'application/vnd.msexcel', 'text/plain'), + 'bin' => array('application/macbinary', 'application/mac-binary', 'application/octet-stream', 'application/x-binary', 'application/x-macbinary'), + 'dms' => 'application/octet-stream', + 'lha' => 'application/octet-stream', + 'lzh' => 'application/octet-stream', + 'exe' => array('application/octet-stream', 'application/x-msdownload'), + 'class' => 'application/octet-stream', + 'psd' => array('application/x-photoshop', 'image/vnd.adobe.photoshop'), + 'so' => 'application/octet-stream', + 'sea' => 'application/octet-stream', + 'dll' => 'application/octet-stream', + 'oda' => 'application/oda', + 'pdf' => array('application/pdf', 'application/force-download', 'application/x-download', 'binary/octet-stream'), + 'ai' => array('application/pdf', 'application/postscript'), + 'eps' => 'application/postscript', + 'ps' => 'application/postscript', + 'smi' => 'application/smil', + 'smil' => 'application/smil', + 'mif' => 'application/vnd.mif', + 'xls' => array('application/vnd.ms-excel', 'application/msexcel', 'application/x-msexcel', 'application/x-ms-excel', 'application/x-excel', 'application/x-dos_ms_excel', 'application/xls', 'application/x-xls', 'application/excel', 'application/download', 'application/vnd.ms-office', 'application/msword'), + 'ppt' => array('application/powerpoint', 'application/vnd.ms-powerpoint', 'application/vnd.ms-office', 'application/msword'), + 'pptx' => array('application/vnd.openxmlformats-officedocument.presentationml.presentation', 'application/x-zip', 'application/zip'), + 'wbxml' => 'application/wbxml', + 'wmlc' => 'application/wmlc', + 'dcr' => 'application/x-director', + 'dir' => 'application/x-director', + 'dxr' => 'application/x-director', + 'dvi' => 'application/x-dvi', + 'gtar' => 'application/x-gtar', + 'gz' => 'application/x-gzip', + 'gzip' => 'application/x-gzip', + 'php' => array('application/x-httpd-php', 'application/php', 'application/x-php', 'text/php', 'text/x-php', 'application/x-httpd-php-source'), + 'php4' => 'application/x-httpd-php', + 'php3' => 'application/x-httpd-php', + 'phtml' => 'application/x-httpd-php', + 'phps' => 'application/x-httpd-php-source', + 'js' => array('application/x-javascript', 'text/plain'), + 'swf' => 'application/x-shockwave-flash', + 'sit' => 'application/x-stuffit', + 'tar' => 'application/x-tar', + 'tgz' => array('application/x-tar', 'application/x-gzip-compressed'), + 'z' => 'application/x-compress', + 'xhtml' => 'application/xhtml+xml', + 'xht' => 'application/xhtml+xml', + 'zip' => array('application/x-zip', 'application/zip', 'application/x-zip-compressed', 'application/s-compressed', 'multipart/x-zip'), + 'rar' => array('application/x-rar', 'application/rar', 'application/x-rar-compressed'), + 'mid' => 'audio/midi', + 'midi' => 'audio/midi', + 'mpga' => 'audio/mpeg', + 'mp2' => 'audio/mpeg', + 'mp3' => array('audio/mpeg', 'audio/mpg', 'audio/mpeg3', 'audio/mp3'), + 'aif' => array('audio/x-aiff', 'audio/aiff'), + 'aiff' => array('audio/x-aiff', 'audio/aiff'), + 'aifc' => 'audio/x-aiff', + 'ram' => 'audio/x-pn-realaudio', + 'rm' => 'audio/x-pn-realaudio', + 'rpm' => 'audio/x-pn-realaudio-plugin', + 'ra' => 'audio/x-realaudio', + 'rv' => 'video/vnd.rn-realvideo', + 'wav' => array('audio/x-wav', 'audio/wave', 'audio/wav'), + 'bmp' => array('image/bmp', 'image/x-bmp', 'image/x-bitmap', 'image/x-xbitmap', 'image/x-win-bitmap', 'image/x-windows-bmp', 'image/ms-bmp', 'image/x-ms-bmp', 'application/bmp', 'application/x-bmp', 'application/x-win-bitmap'), + 'gif' => 'image/gif', + 'jpeg' => array('image/jpeg', 'image/pjpeg'), + 'jpg' => array('image/jpeg', 'image/pjpeg'), + 'jpe' => array('image/jpeg', 'image/pjpeg'), + 'jp2' => array('image/jp2', 'video/mj2', 'image/jpx', 'image/jpm'), + 'j2k' => array('image/jp2', 'video/mj2', 'image/jpx', 'image/jpm'), + 'jpf' => array('image/jp2', 'video/mj2', 'image/jpx', 'image/jpm'), + 'jpg2' => array('image/jp2', 'video/mj2', 'image/jpx', 'image/jpm'), + 'jpx' => array('image/jp2', 'video/mj2', 'image/jpx', 'image/jpm'), + 'jpm' => array('image/jp2', 'video/mj2', 'image/jpx', 'image/jpm'), + 'mj2' => array('image/jp2', 'video/mj2', 'image/jpx', 'image/jpm'), + 'mjp2' => array('image/jp2', 'video/mj2', 'image/jpx', 'image/jpm'), + 'png' => array('image/png', 'image/x-png'), + 'tiff' => 'image/tiff', + 'tif' => 'image/tiff', + 'css' => array('text/css', 'text/plain'), + 'html' => array('text/html', 'text/plain'), + 'htm' => array('text/html', 'text/plain'), + 'shtml' => array('text/html', 'text/plain'), + 'txt' => 'text/plain', + 'text' => 'text/plain', + 'log' => array('text/plain', 'text/x-log'), + 'rtx' => 'text/richtext', + 'rtf' => 'text/rtf', + 'xml' => array('application/xml', 'text/xml', 'text/plain'), + 'xsl' => array('application/xml', 'text/xsl', 'text/xml'), + 'mpeg' => 'video/mpeg', + 'mpg' => 'video/mpeg', + 'mpe' => 'video/mpeg', + 'qt' => 'video/quicktime', + 'mov' => 'video/quicktime', + 'avi' => array('video/x-msvideo', 'video/msvideo', 'video/avi', 'application/x-troff-msvideo'), + 'movie' => 'video/x-sgi-movie', + 'doc' => array('application/msword', 'application/vnd.ms-office'), + 'docx' => array('application/vnd.openxmlformats-officedocument.wordprocessingml.document', 'application/zip', 'application/msword', 'application/x-zip'), + 'dot' => array('application/msword', 'application/vnd.ms-office'), + 'dotx' => array('application/vnd.openxmlformats-officedocument.wordprocessingml.document', 'application/zip', 'application/msword'), + 'xlsx' => array('application/vnd.openxmlformats-officedocument.spreadsheetml.sheet', 'application/zip', 'application/vnd.ms-excel', 'application/msword', 'application/x-zip'), + 'word' => array('application/msword', 'application/octet-stream'), + 'xl' => 'application/excel', + 'eml' => 'message/rfc822', + 'json' => array('application/json', 'text/json'), + 'pem' => array('application/x-x509-user-cert', 'application/x-pem-file', 'application/octet-stream'), + 'p10' => array('application/x-pkcs10', 'application/pkcs10'), + 'p12' => 'application/x-pkcs12', + 'p7a' => 'application/x-pkcs7-signature', + 'p7c' => array('application/pkcs7-mime', 'application/x-pkcs7-mime'), + 'p7m' => array('application/pkcs7-mime', 'application/x-pkcs7-mime'), + 'p7r' => 'application/x-pkcs7-certreqresp', + 'p7s' => 'application/pkcs7-signature', + 'crt' => array('application/x-x509-ca-cert', 'application/x-x509-user-cert', 'application/pkix-cert'), + 'crl' => array('application/pkix-crl', 'application/pkcs-crl'), + 'der' => 'application/x-x509-ca-cert', + 'kdb' => 'application/octet-stream', + 'pgp' => 'application/pgp', + 'gpg' => 'application/gpg-keys', + 'sst' => 'application/octet-stream', + 'csr' => 'application/octet-stream', + 'rsa' => 'application/x-pkcs7', + 'cer' => array('application/pkix-cert', 'application/x-x509-ca-cert'), + '3g2' => 'video/3gpp2', + '3gp' => array('video/3gp', 'video/3gpp'), + 'mp4' => 'video/mp4', + 'm4a' => 'audio/x-m4a', + 'f4v' => array('video/mp4', 'video/x-f4v'), + 'flv' => 'video/x-flv', + 'webm' => 'video/webm', + 'aac' => 'audio/x-acc', + 'm4u' => 'application/vnd.mpegurl', + 'm3u' => 'text/plain', + 'xspf' => 'application/xspf+xml', + 'vlc' => 'application/videolan', + 'wmv' => array('video/x-ms-wmv', 'video/x-ms-asf'), + 'au' => 'audio/x-au', + 'ac3' => 'audio/ac3', + 'flac' => 'audio/x-flac', + 'ogg' => array('audio/ogg', 'video/ogg', 'application/ogg'), + 'kmz' => array('application/vnd.google-earth.kmz', 'application/zip', 'application/x-zip'), + 'kml' => array('application/vnd.google-earth.kml+xml', 'application/xml', 'text/xml'), + 'ics' => 'text/calendar', + 'ical' => 'text/calendar', + 'zsh' => 'text/x-scriptzsh', + '7z' => array('application/x-7z-compressed', 'application/x-compressed', 'application/x-zip-compressed', 'application/zip', 'multipart/x-zip'), + '7zip' => array('application/x-7z-compressed', 'application/x-compressed', 'application/x-zip-compressed', 'application/zip', 'multipart/x-zip'), + 'cdr' => array('application/cdr', 'application/coreldraw', 'application/x-cdr', 'application/x-coreldraw', 'image/cdr', 'image/x-cdr', 'zz-application/zz-winassoc-cdr'), + 'wma' => array('audio/x-ms-wma', 'video/x-ms-asf'), + 'jar' => array('application/java-archive', 'application/x-java-application', 'application/x-jar', 'application/x-compressed'), + 'svg' => array('image/svg+xml', 'application/xml', 'text/xml'), + 'vcf' => 'text/x-vcard', + 'srt' => array('text/srt', 'text/plain'), + 'vtt' => array('text/vtt', 'text/plain'), + 'ico' => array('image/x-icon', 'image/x-ico', 'image/vnd.microsoft.icon'), + 'odc' => 'application/vnd.oasis.opendocument.chart', + 'otc' => 'application/vnd.oasis.opendocument.chart-template', + 'odf' => 'application/vnd.oasis.opendocument.formula', + 'otf' => 'application/vnd.oasis.opendocument.formula-template', + 'odg' => 'application/vnd.oasis.opendocument.graphics', + 'otg' => 'application/vnd.oasis.opendocument.graphics-template', + 'odi' => 'application/vnd.oasis.opendocument.image', + 'oti' => 'application/vnd.oasis.opendocument.image-template', + 'odp' => 'application/vnd.oasis.opendocument.presentation', + 'otp' => 'application/vnd.oasis.opendocument.presentation-template', + 'ods' => 'application/vnd.oasis.opendocument.spreadsheet', + 'ots' => 'application/vnd.oasis.opendocument.spreadsheet-template', + 'odt' => 'application/vnd.oasis.opendocument.text', + 'odm' => 'application/vnd.oasis.opendocument.text-master', + 'ott' => 'application/vnd.oasis.opendocument.text-template', + 'oth' => 'application/vnd.oasis.opendocument.text-web' +); diff --git a/config/profiler.php b/config/profiler.php new file mode 100644 index 0000000..3db22e3 --- /dev/null +++ b/config/profiler.php @@ -0,0 +1,14 @@ +function($username, $password) +| In other cases override the function _perform_library_auth in your controller +| +| For digest authentication the library function should return already a stored +| md5(username:restrealm:password) for that username +| +| e.g: md5('admin:REST API:1234') = '1e957ebc35631ab22d5bd6526bd14ea2' +| +*/ +$config['auth_library_class'] = ''; +$config['auth_library_function'] = ''; + +/* +|-------------------------------------------------------------------------- +| Override auth types for specific class/method +|-------------------------------------------------------------------------- +| +| Set specific authentication types for methods within a class (controller) +| +| Set as many config entries as needed. Any methods not set will use the default 'rest_auth' config value. +| +| e.g: +| +| $config['auth_override_class_method']['deals']['view'] = 'none'; +| $config['auth_override_class_method']['deals']['insert'] = 'digest'; +| $config['auth_override_class_method']['accounts']['user'] = 'basic'; +| $config['auth_override_class_method']['dashboard']['*'] = 'none|digest|basic'; +| +| Here 'deals', 'accounts' and 'dashboard' are controller names, 'view', 'insert' and 'user' are methods within. An asterisk may also be used to specify an authentication method for an entire classes methods. Ex: $config['auth_override_class_method']['dashboard']['*'] = 'basic'; (NOTE: leave off the '_get' or '_post' from the end of the method name) +| Acceptable values are; 'none', 'digest' and 'basic'. +| +*/ +// $config['auth_override_class_method']['deals']['view'] = 'none'; +// $config['auth_override_class_method']['deals']['insert'] = 'digest'; +// $config['auth_override_class_method']['accounts']['user'] = 'basic'; +// $config['auth_override_class_method']['dashboard']['*'] = 'basic'; + +// ---Uncomment list line for the wildard unit test +// $config['auth_override_class_method']['wildcard_test_cases']['*'] = 'basic'; + +/* +|-------------------------------------------------------------------------- +| Override auth types for specific 'class/method/HTTP method' +|-------------------------------------------------------------------------- +| +| example: +| +| $config['auth_override_class_method_http']['deals']['view']['get'] = 'none'; +| $config['auth_override_class_method_http']['deals']['insert']['post'] = 'none'; +| $config['auth_override_class_method_http']['deals']['*']['options'] = 'none'; +*/ + +// ---Uncomment list line for the wildard unit test +// $config['auth_override_class_method_http']['wildcard_test_cases']['*']['options'] = 'basic'; + +// ����Class User ��� verifycode �� get ���� auth ����Ϊ none�� *����ΪСд user* +// ��֤��ͼƬ�� '1234']; + +/* +|-------------------------------------------------------------------------- +| Global IP White-listing +|-------------------------------------------------------------------------- +| +| Limit connections to your REST server to White-listed IP addresses +| +| Usage: +| 1. Set to TRUE and select an auth option for extreme security (client's IP +| address must be in white-list and they must also log in) +| 2. Set to TRUE with auth set to FALSE to allow White-listed IPs access with no login +| 3. Set to FALSE but set 'auth_override_class_method' to 'white-list' to +| restrict certain methods to IPs in your white-list +| +*/ +$config['rest_ip_whitelist_enabled'] = false; + +/* +|-------------------------------------------------------------------------- +| REST Handle Exceptions +|-------------------------------------------------------------------------- +| +| Handle exceptions caused by the controller +| +*/ +$config['rest_handle_exceptions'] = true; + +/* +|-------------------------------------------------------------------------- +| REST IP White-list +|-------------------------------------------------------------------------- +| +| Limit connections to your REST server with a comma separated +| list of IP addresses +| +| e.g: '123.456.789.0, 987.654.32.1' +| +| 127.0.0.1 and 0.0.0.0 are allowed by default +| +*/ +$config['rest_ip_whitelist'] = ''; + +/* +|-------------------------------------------------------------------------- +| Global IP Blacklisting +|-------------------------------------------------------------------------- +| +| Prevent connections to the REST server from blacklisted IP addresses +| +| Usage: +| 1. Set to TRUE and add any IP address to 'rest_ip_blacklist' +| +*/ +$config['rest_ip_blacklist_enabled'] = false; + +/* +|-------------------------------------------------------------------------- +| REST IP Blacklist +|-------------------------------------------------------------------------- +| +| Prevent connections from the following IP addresses +| +| e.g: '123.456.789.0, 987.654.32.1' +| +*/ +$config['rest_ip_blacklist'] = ''; + +/* +|-------------------------------------------------------------------------- +| REST Database Group +|-------------------------------------------------------------------------- +| +| Connect to a database group for keys, logging, etc. It will only connect +| if you have any of these features enabled +| +*/ +$config['rest_database_group'] = 'default'; + +/* +|-------------------------------------------------------------------------- +| REST API Keys Table Name +|-------------------------------------------------------------------------- +| +| The table name in your database that stores API keys +| +*/ +$config['rest_keys_table'] = 'keys'; + +/* +|-------------------------------------------------------------------------- +| REST Enable Keys +|-------------------------------------------------------------------------- +| +| When set to TRUE, the REST API will look for a column name called 'key'. +| If no key is provided, the request will result in an error. To override the +| column name see 'rest_key_column' +| +| Default table schema: +| CREATE TABLE `keys` ( +| `id` INT(11) NOT NULL AUTO_INCREMENT, +| `user_id` INT(11) NOT NULL, +| `key` VARCHAR(40) NOT NULL, +| `level` INT(2) NOT NULL, +| `ignore_limits` TINYINT(1) NOT NULL DEFAULT '0', +| `is_private_key` TINYINT(1) NOT NULL DEFAULT '0', +| `ip_addresses` TEXT NULL DEFAULT NULL, +| `date_created` INT(11) NOT NULL, +| PRIMARY KEY (`id`) +| ) ENGINE=InnoDB DEFAULT CHARSET=utf8; +| +*/ +$config['rest_enable_keys'] = false; + +/* +|-------------------------------------------------------------------------- +| REST Table Key Column Name +|-------------------------------------------------------------------------- +| +| If not using the default table schema in 'rest_enable_keys', specify the +| column name to match e.g. my_key +| +*/ +$config['rest_key_column'] = 'key'; + +/* +|-------------------------------------------------------------------------- +| REST API Limits method +|-------------------------------------------------------------------------- +| +| Specify the method used to limit the API calls +| +| Available methods are : +| $config['rest_limits_method'] = 'IP_ADDRESS'; // Put a limit per ip address +| $config['rest_limits_method'] = 'API_KEY'; // Put a limit per api key +| $config['rest_limits_method'] = 'METHOD_NAME'; // Put a limit on method calls +| $config['rest_limits_method'] = 'ROUTED_URL'; // Put a limit on the routed URL +| +*/ +$config['rest_limits_method'] = 'ROUTED_URL'; + +/* +|-------------------------------------------------------------------------- +| REST Key Length +|-------------------------------------------------------------------------- +| +| Length of the created keys. Check your default database schema on the +| maximum length allowed +| +| Note: The maximum length is 40 +| +*/ +$config['rest_key_length'] = 40; + +/* +|-------------------------------------------------------------------------- +| REST API Key Variable +|-------------------------------------------------------------------------- +| +| Custom header to specify the API key + +| Note: Custom headers with the X- prefix are deprecated as of +| 2012/06/12. See RFC 6648 specification for more details +| +*/ +$config['rest_key_name'] = 'X-API-KEY'; + +/* +|-------------------------------------------------------------------------- +| REST Enable Logging +|-------------------------------------------------------------------------- +| +| When set to TRUE, the REST API will log actions based on the column names 'key', 'date', +| 'time' and 'ip_address'. This is a general rule that can be overridden in the +| $this->method array for each controller +| +| Default table schema: +| CREATE TABLE `logs` ( +| `id` INT(11) NOT NULL AUTO_INCREMENT, +| `uri` VARCHAR(255) NOT NULL, +| `method` VARCHAR(6) NOT NULL, +| `params` TEXT DEFAULT NULL, +| `api_key` VARCHAR(40) NOT NULL, +| `ip_address` VARCHAR(45) NOT NULL, +| `time` INT(11) NOT NULL, +| `rtime` FLOAT DEFAULT NULL, +| `authorized` VARCHAR(1) NOT NULL, +| `response_code` smallint(3) DEFAULT '0', +| PRIMARY KEY (`id`) +| ) ENGINE=InnoDB DEFAULT CHARSET=utf8; +| +*/ +$config['rest_enable_logging'] = false; + +/* +|-------------------------------------------------------------------------- +| REST API Logs Table Name +|-------------------------------------------------------------------------- +| +| If not using the default table schema in 'rest_enable_logging', specify the +| table name to match e.g. my_logs +| +*/ +$config['rest_logs_table'] = 'logs'; + +/* +|-------------------------------------------------------------------------- +| REST Method Access Control +|-------------------------------------------------------------------------- +| When set to TRUE, the REST API will check the access table to see if +| the API key can access that controller. 'rest_enable_keys' must be enabled +| to use this +| +| Default table schema: +| CREATE TABLE `access` ( +| `id` INT(11) unsigned NOT NULL AUTO_INCREMENT, +| `key` VARCHAR(40) NOT NULL DEFAULT '', +| `all_access` TINYINT(1) NOT NULL DEFAULT '0', +| `controller` VARCHAR(50) NOT NULL DEFAULT '', +| `date_created` DATETIME DEFAULT NULL, +| `date_modified` TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, +| PRIMARY KEY (`id`) +| ) ENGINE=InnoDB DEFAULT CHARSET=utf8; +| +*/ +$config['rest_enable_access'] = false; + +/* +|-------------------------------------------------------------------------- +| REST API Access Table Name +|-------------------------------------------------------------------------- +| +| If not using the default table schema in 'rest_enable_access', specify the +| table name to match e.g. my_access +| +*/ +$config['rest_access_table'] = 'access'; + +/* +|-------------------------------------------------------------------------- +| REST API Param Log Format +|-------------------------------------------------------------------------- +| +| When set to TRUE, the REST API log parameters will be stored in the database as JSON +| Set to FALSE to log as serialized PHP +| +*/ +$config['rest_logs_json_params'] = false; + +/* +|-------------------------------------------------------------------------- +| REST Enable Limits +|-------------------------------------------------------------------------- +| +| When set to TRUE, the REST API will count the number of uses of each method +| by an API key each hour. This is a general rule that can be overridden in the +| $this->method array in each controller +| +| Default table schema: +| CREATE TABLE `limits` ( +| `id` INT(11) NOT NULL AUTO_INCREMENT, +| `uri` VARCHAR(255) NOT NULL, +| `count` INT(10) NOT NULL, +| `hour_started` INT(11) NOT NULL, +| `api_key` VARCHAR(40) NOT NULL, +| PRIMARY KEY (`id`) +| ) ENGINE=InnoDB DEFAULT CHARSET=utf8; +| +| To specify the limits within the controller's __construct() method, add per-method +| limits with: +| +| $this->methods['METHOD_NAME']['limit'] = [NUM_REQUESTS_PER_HOUR]; +| +| See application/controllers/api/example.php for examples +*/ +$config['rest_enable_limits'] = false; + +/* +|-------------------------------------------------------------------------- +| REST API Limits Table Name +|-------------------------------------------------------------------------- +| +| If not using the default table schema in 'rest_enable_limits', specify the +| table name to match e.g. my_limits +| +*/ +$config['rest_limits_table'] = 'limits'; + +/* +|-------------------------------------------------------------------------- +| REST Ignore HTTP Accept +|-------------------------------------------------------------------------- +| +| Set to TRUE to ignore the HTTP Accept and speed up each request a little. +| Only do this if you are using the $this->rest_format or /format/xml in URLs +| +*/ +$config['rest_ignore_http_accept'] = false; + +/* +|-------------------------------------------------------------------------- +| REST AJAX Only +|-------------------------------------------------------------------------- +| +| Set to TRUE to allow AJAX requests only. Set to FALSE to accept HTTP requests +| +| Note: If set to TRUE and the request is not AJAX, a 505 response with the +| error message 'Only AJAX requests are accepted.' will be returned. +| +| Hint: This is good for production environments +| +*/ +$config['rest_ajax_only'] = false; + +/* +|-------------------------------------------------------------------------- +| REST Language File +|-------------------------------------------------------------------------- +| +| Language file to load from the language directory +| +*/ +$config['rest_language'] = 'simplified-chinese'; + +/* +|-------------------------------------------------------------------------- +| CORS Check +|-------------------------------------------------------------------------- +| +| Set to TRUE to enable Cross-Origin Resource Sharing (CORS). Useful if you +| are hosting your API on a different domain from the application that +| will access it through a browser +| +*/ +//$config['check_cors'] = false; +$config['check_cors'] = true; + +/* +|-------------------------------------------------------------------------- +| CORS Allowable Headers +|-------------------------------------------------------------------------- +| +| If using CORS checks, set the allowable headers here +| +*/ +$config['allowed_cors_headers'] = [ + 'Origin', + 'X-Requested-With', + 'Content-Type', + 'Accept', + 'Access-Control-Request-Method', + 'X-API-KEY', + 'X-Token', + 'cache-control' +]; + +/* +|-------------------------------------------------------------------------- +| CORS Allowable Methods +|-------------------------------------------------------------------------- +| +| If using CORS checks, you can set the methods you want to be allowed +| +*/ +$config['allowed_cors_methods'] = [ + 'GET', + 'POST', + 'OPTIONS', + 'PUT', + 'PATCH', + 'DELETE', +]; + +/* +|-------------------------------------------------------------------------- +| CORS Allow Any Domain +|-------------------------------------------------------------------------- +| +| Set to TRUE to enable Cross-Origin Resource Sharing (CORS) from any +| source domain +| +*/ +//$config['allow_any_cors_domain'] = false; +$config['allow_any_cors_domain'] = false; + +/* +|-------------------------------------------------------------------------- +| CORS Allowable Domains +|-------------------------------------------------------------------------- +| +| Used if $config['check_cors'] is set to TRUE and $config['allow_any_cors_domain'] +| is set to FALSE. Set all the allowable domains within the array +| +| e.g. $config['allowed_origins'] = ['http://www.example.com', 'https://spa.example.com'] +| +*/ +$config['allowed_cors_origins'] = [ + 'user'=>'https://user.uahpet.com', + 'dna'=>'https://dna.uahpet.com', + 'report'=>'https://report.uahpet.com', + 'user_dev'=>'http://192.168.0.100:8080', + 'dna_dev'=>'http://localhost:9527', + 'report_dev'=>'http://192.168.0.107:8080', + 'report_dev_2'=>'http://192.168.0.105:8080', + 'report_dev_3'=>'http://192.168.88.101:8080', + 'report_dev_4'=>'http://192.168.0.104:8080', + 'report_dev_5'=>'http://192.168.0.109:8080', +]; + +/* +|-------------------------------------------------------------------------- +| CORS Forced Headers +|-------------------------------------------------------------------------- +| +| If using CORS checks, always include the headers and values specified here +| in the OPTIONS client preflight. +| Example: +| $config['forced_cors_headers'] = [ +| 'Access-Control-Allow-Credentials' => 'true' +| ]; +| +| Added because of how Sencha Ext JS framework requires the header +| Access-Control-Allow-Credentials to be set to true to allow the use of +| credentials in the REST Proxy. +| See documentation here: +| http://docs.sencha.com/extjs/6.5.2/classic/Ext.data.proxy.Rest.html#cfg-withCredentials +| +*/ +$config['forced_cors_headers'] = []; diff --git a/config/routes.php b/config/routes.php new file mode 100644 index 0000000..f06f858 --- /dev/null +++ b/config/routes.php @@ -0,0 +1,71 @@ + my_controller/index +| my-controller/my-method -> my_controller/my_method +*/ +$route['default_controller'] = 'welcome'; +$route['404_override'] = ''; +$route['translate_uri_dashes'] = FALSE; + + +//// http://localhost/restful/trunk/index.php/api/books_articles/index/2/22 +///* +//| ------------------------------------------------------------------------- +//| Sample REST API Routes +//| ------------------------------------------------------------------------- +//*/ +// 重新定义路由规则了 可选 根据控制器中获取的参数 将不规则的路由 重新定义成规则的路由 +//$route['api/example/users/(:num)'] = 'api/example/users/id/$1'; // Example 4 , api/example/users/3 转换成 api/example/users/id/3 形式 +//$route['api/example/users/(:num)(\.)([a-zA-Z0-9_-]+)(.*)'] = 'api/example/users/id/$1/format/$3$4'; // Example 8 + +// qiaokun test restful api +//$route['api/([a-z0-9]+)/(\d+)'] = "api/$1/index/$2"; +//$route['api/([a-z0-9]+)/(\d+)/([a-z0-9]+)'] = "api/$1_$3/index/$2"; +//$route['api/([a-z0-9]+)/(\d+)/([a-z0-9]+)/(\d+)'] = "api/$1_$3/index/$2/$4"; +//$route['api/([a-z0-9]+)/(\d+)'] = "api/$1/index/$2"; \ No newline at end of file diff --git a/config/smileys.php b/config/smileys.php new file mode 100644 index 0000000..abf9a89 --- /dev/null +++ b/config/smileys.php @@ -0,0 +1,64 @@ + array('grin.gif', '19', '19', 'grin'), + ':lol:' => array('lol.gif', '19', '19', 'LOL'), + ':cheese:' => array('cheese.gif', '19', '19', 'cheese'), + ':)' => array('smile.gif', '19', '19', 'smile'), + ';-)' => array('wink.gif', '19', '19', 'wink'), + ';)' => array('wink.gif', '19', '19', 'wink'), + ':smirk:' => array('smirk.gif', '19', '19', 'smirk'), + ':roll:' => array('rolleyes.gif', '19', '19', 'rolleyes'), + ':-S' => array('confused.gif', '19', '19', 'confused'), + ':wow:' => array('surprise.gif', '19', '19', 'surprised'), + ':bug:' => array('bigsurprise.gif', '19', '19', 'big surprise'), + ':-P' => array('tongue_laugh.gif', '19', '19', 'tongue laugh'), + '%-P' => array('tongue_rolleye.gif', '19', '19', 'tongue rolleye'), + ';-P' => array('tongue_wink.gif', '19', '19', 'tongue wink'), + ':P' => array('raspberry.gif', '19', '19', 'raspberry'), + ':blank:' => array('blank.gif', '19', '19', 'blank stare'), + ':long:' => array('longface.gif', '19', '19', 'long face'), + ':ohh:' => array('ohh.gif', '19', '19', 'ohh'), + ':grrr:' => array('grrr.gif', '19', '19', 'grrr'), + ':gulp:' => array('gulp.gif', '19', '19', 'gulp'), + '8-/' => array('ohoh.gif', '19', '19', 'oh oh'), + ':down:' => array('downer.gif', '19', '19', 'downer'), + ':red:' => array('embarrassed.gif', '19', '19', 'red face'), + ':sick:' => array('sick.gif', '19', '19', 'sick'), + ':shut:' => array('shuteye.gif', '19', '19', 'shut eye'), + ':-/' => array('hmm.gif', '19', '19', 'hmmm'), + '>:(' => array('mad.gif', '19', '19', 'mad'), + ':mad:' => array('mad.gif', '19', '19', 'mad'), + '>:-(' => array('angry.gif', '19', '19', 'angry'), + ':angry:' => array('angry.gif', '19', '19', 'angry'), + ':zip:' => array('zip.gif', '19', '19', 'zipper'), + ':kiss:' => array('kiss.gif', '19', '19', 'kiss'), + ':ahhh:' => array('shock.gif', '19', '19', 'shock'), + ':coolsmile:' => array('shade_smile.gif', '19', '19', 'cool smile'), + ':coolsmirk:' => array('shade_smirk.gif', '19', '19', 'cool smirk'), + ':coolgrin:' => array('shade_grin.gif', '19', '19', 'cool grin'), + ':coolhmm:' => array('shade_hmm.gif', '19', '19', 'cool hmm'), + ':coolmad:' => array('shade_mad.gif', '19', '19', 'cool mad'), + ':coolcheese:' => array('shade_cheese.gif', '19', '19', 'cool cheese'), + ':vampire:' => array('vampire.gif', '19', '19', 'vampire'), + ':snake:' => array('snake.gif', '19', '19', 'snake'), + ':exclaim:' => array('exclaim.gif', '19', '19', 'exclaim'), + ':question:' => array('question.gif', '19', '19', 'question') + +); diff --git a/config/user_agents.php b/config/user_agents.php new file mode 100644 index 0000000..ad0b0fd --- /dev/null +++ b/config/user_agents.php @@ -0,0 +1,215 @@ + 'Windows 10', + 'windows nt 6.3' => 'Windows 8.1', + 'windows nt 6.2' => 'Windows 8', + 'windows nt 6.1' => 'Windows 7', + 'windows nt 6.0' => 'Windows Vista', + 'windows nt 5.2' => 'Windows 2003', + 'windows nt 5.1' => 'Windows XP', + 'windows nt 5.0' => 'Windows 2000', + 'windows nt 4.0' => 'Windows NT 4.0', + 'winnt4.0' => 'Windows NT 4.0', + 'winnt 4.0' => 'Windows NT', + 'winnt' => 'Windows NT', + 'windows 98' => 'Windows 98', + 'win98' => 'Windows 98', + 'windows 95' => 'Windows 95', + 'win95' => 'Windows 95', + 'windows phone' => 'Windows Phone', + 'windows' => 'Unknown Windows OS', + 'android' => 'Android', + 'blackberry' => 'BlackBerry', + 'iphone' => 'iOS', + 'ipad' => 'iOS', + 'ipod' => 'iOS', + 'os x' => 'Mac OS X', + 'ppc mac' => 'Power PC Mac', + 'freebsd' => 'FreeBSD', + 'ppc' => 'Macintosh', + 'linux' => 'Linux', + 'debian' => 'Debian', + 'sunos' => 'Sun Solaris', + 'beos' => 'BeOS', + 'apachebench' => 'ApacheBench', + 'aix' => 'AIX', + 'irix' => 'Irix', + 'osf' => 'DEC OSF', + 'hp-ux' => 'HP-UX', + 'netbsd' => 'NetBSD', + 'bsdi' => 'BSDi', + 'openbsd' => 'OpenBSD', + 'gnu' => 'GNU/Linux', + 'unix' => 'Unknown Unix OS', + 'symbian' => 'Symbian OS' +); + + +// The order of this array should NOT be changed. Many browsers return +// multiple browser types so we want to identify the sub-type first. +$browsers = array( + 'OPR' => 'Opera', + 'Flock' => 'Flock', + 'Edge' => 'Edge', + 'Chrome' => 'Chrome', + // Opera 10+ always reports Opera/9.80 and appends Version/ to the user agent string + 'Opera.*?Version' => 'Opera', + 'Opera' => 'Opera', + 'MSIE' => 'Internet Explorer', + 'Internet Explorer' => 'Internet Explorer', + 'Trident.* rv' => 'Internet Explorer', + 'Shiira' => 'Shiira', + 'Firefox' => 'Firefox', + 'Chimera' => 'Chimera', + 'Phoenix' => 'Phoenix', + 'Firebird' => 'Firebird', + 'Camino' => 'Camino', + 'Netscape' => 'Netscape', + 'OmniWeb' => 'OmniWeb', + 'Safari' => 'Safari', + 'Mozilla' => 'Mozilla', + 'Konqueror' => 'Konqueror', + 'icab' => 'iCab', + 'Lynx' => 'Lynx', + 'Links' => 'Links', + 'hotjava' => 'HotJava', + 'amaya' => 'Amaya', + 'IBrowse' => 'IBrowse', + 'Maxthon' => 'Maxthon', + 'Ubuntu' => 'Ubuntu Web Browser' +); + +$mobiles = array( + // legacy array, old values commented out + 'mobileexplorer' => 'Mobile Explorer', +// 'openwave' => 'Open Wave', +// 'opera mini' => 'Opera Mini', +// 'operamini' => 'Opera Mini', +// 'elaine' => 'Palm', + 'palmsource' => 'Palm', +// 'digital paths' => 'Palm', +// 'avantgo' => 'Avantgo', +// 'xiino' => 'Xiino', + 'palmscape' => 'Palmscape', +// 'nokia' => 'Nokia', +// 'ericsson' => 'Ericsson', +// 'blackberry' => 'BlackBerry', +// 'motorola' => 'Motorola' + + // Phones and Manufacturers + 'motorola' => 'Motorola', + 'nokia' => 'Nokia', + 'nexus' => 'Nexus', + 'palm' => 'Palm', + 'iphone' => 'Apple iPhone', + 'ipad' => 'iPad', + 'ipod' => 'Apple iPod Touch', + 'sony' => 'Sony Ericsson', + 'ericsson' => 'Sony Ericsson', + 'blackberry' => 'BlackBerry', + 'cocoon' => 'O2 Cocoon', + 'blazer' => 'Treo', + 'lg' => 'LG', + 'amoi' => 'Amoi', + 'xda' => 'XDA', + 'mda' => 'MDA', + 'vario' => 'Vario', + 'htc' => 'HTC', + 'samsung' => 'Samsung', + 'sharp' => 'Sharp', + 'sie-' => 'Siemens', + 'alcatel' => 'Alcatel', + 'benq' => 'BenQ', + 'ipaq' => 'HP iPaq', + 'mot-' => 'Motorola', + 'playstation portable' => 'PlayStation Portable', + 'playstation 3' => 'PlayStation 3', + 'playstation vita' => 'PlayStation Vita', + 'hiptop' => 'Danger Hiptop', + 'nec-' => 'NEC', + 'panasonic' => 'Panasonic', + 'philips' => 'Philips', + 'sagem' => 'Sagem', + 'sanyo' => 'Sanyo', + 'spv' => 'SPV', + 'zte' => 'ZTE', + 'sendo' => 'Sendo', + 'nintendo dsi' => 'Nintendo DSi', + 'nintendo ds' => 'Nintendo DS', + 'nintendo 3ds' => 'Nintendo 3DS', + 'wii' => 'Nintendo Wii', + 'open web' => 'Open Web', + 'openweb' => 'OpenWeb', + + // Operating Systems + 'android' => 'Android', + 'symbian' => 'Symbian', + 'SymbianOS' => 'SymbianOS', + 'elaine' => 'Palm', + 'series60' => 'Symbian S60', + 'windows ce' => 'Windows CE', + + // Browsers + 'obigo' => 'Obigo', + 'netfront' => 'Netfront Browser', + 'openwave' => 'Openwave Browser', + 'mobilexplorer' => 'Mobile Explorer', + 'operamini' => 'Opera Mini', + 'opera mini' => 'Opera Mini', + 'opera mobi' => 'Opera Mobile', + 'fennec' => 'Firefox Mobile', + + // Other + 'digital paths' => 'Digital Paths', + 'avantgo' => 'AvantGo', + 'xiino' => 'Xiino', + 'novarra' => 'Novarra Transcoder', + 'vodafone' => 'Vodafone', + 'docomo' => 'NTT DoCoMo', + 'o2' => 'O2', + + // Fallback + 'mobile' => 'Generic Mobile', + 'wireless' => 'Generic Mobile', + 'j2me' => 'Generic Mobile', + 'midp' => 'Generic Mobile', + 'cldc' => 'Generic Mobile', + 'up.link' => 'Generic Mobile', + 'up.browser' => 'Generic Mobile', + 'smartphone' => 'Generic Mobile', + 'cellphone' => 'Generic Mobile' +); + +// There are hundreds of bots but these are the most common. +$robots = array( + 'googlebot' => 'Googlebot', + 'msnbot' => 'MSNBot', + 'baiduspider' => 'Baiduspider', + 'bingbot' => 'Bing', + 'slurp' => 'Inktomi Slurp', + 'yahoo' => 'Yahoo', + 'ask jeeves' => 'Ask Jeeves', + 'fastcrawler' => 'FastCrawler', + 'infoseek' => 'InfoSeek Robot 1.0', + 'lycos' => 'Lycos', + 'yandex' => 'YandexBot', + 'mediapartners-google' => 'MediaPartners Google', + 'CRAZYWEBCRAWLER' => 'Crazy Webcrawler', + 'adsbot-google' => 'AdsBot Google', + 'feedfetcher-google' => 'Feedfetcher Google', + 'curious george' => 'Curious George', + 'ia_archiver' => 'Alexa Crawler', + 'MJ12bot' => 'Majestic-12', + 'Uptimebot' => 'Uptimebot' +); diff --git a/controllers/Cert.php b/controllers/Cert.php new file mode 100644 index 0000000..9ee5e71 --- /dev/null +++ b/controllers/Cert.php @@ -0,0 +1,303 @@ +load->model('wx_token'); + } + + /** + * 验证查看权限 + * 用户/手机号主人/超管可以看 + **/ + protected function _check_auth($device_id){ + //未登录验证 + if(in_array($device_id,$_SESSION[self::SESSION_KEY])){ + return true; + } + //超级管理员可以查看任意证书 + $isLoggedIn = $this->session->userdata ( 'isAdminLoggedIn' ); + if (isset ( $isLoggedIn ) || $isLoggedIn == TRUE) { + return true; + } + //已登录查看自己的验证码 + if(!empty($_SESSION['users_id'])){ + $this->load->model('model_UsersInfo'); + //检查信息是否能对应 + $row = $this->model_UsersInfo->get( + $device_id, + 'device_id' + ); + if(!empty($row) && $row['users_id'] == $_SESSION['users_id']){ + return true; + } + } + return false; + } + + protected function _set_auth($device_id){ + //未登录验证 + $_SESSION[self::SESSION_KEY][] = $device_id; + } + + // 验证短信验证码是否有效 + public function send_sms_code(){ + $this->load->model('sms_code'); + $this->sms_code->test(); + $mobile = $_POST['mobile']; + + $data = [ + 'ret' => 1, + 'msg' => '' + ]; + + if(empty($mobile)){ + $data['msg'] = '信息不完整'; + } + $this->load->model('sms_code'); + if($this->sms_code->send( + $mobile, + rand(0,9) + )){ + $data['msg'] = '验证码错误或已过期,请重新获取'; + } + + } + + // 验证短信验证码是否有效 + public function check_sms_code(){ + + $mobile = $_POST['mobile']; + $device_id = $_POST['device_id']; + $code = $_POST['code']; + + $data = [ + 'ret' => 1, + 'msg' => '' + ]; + + if(empty($mobile) or empty($device_id) or empty($code)){ + $data['msg'] = '信息不完整'; + } + + + //检查设备号对应情况,没有填手机号则报错 + $this->load->model('Model_UsersInfo'); + //检查信息是否能对应 + $row = $this->model_UsersInfo->get( + $mobile, + 'users_tel' + ); + if(empty($row) or $row['device_id']!==$device_id){ + $data['msg'] = '手机号或序列号错误'; + } + + //检查验证码 + $this->load->model('sms_code'); + if($this->sms_code->check( + $mobile, + $code + )){ + $data['msg'] = '验证码错误或已过期,请重新获取'; + } + echo json_encode($data,JSON_UNESCAPED_UNICODE); + } + + + + /** + * 激活查询 + */ + public function query() + { + $mobile = isset($_REQUEST['mobile']) ? $_REQUEST['mobile'] : 0; + $device_id = isset($_REQUEST['device_id']) ? $_REQUEST['device_id'] : 0; + $data = [ + 'info' => [], + 'warning' => '' + ]; + if($mobile and $device_id){ + //检查信息是否能对应 + $row = $this->model_UsersInfo->get( + $mobile, + 'users_tel' + ); + if(empty($row) or $row['device_id']!==$device_id){ + $data['warning'] = '手机号或序列号错误'; + }else{ + $data['info'] = $row; + } + } + $data['type'] = 'info'; + $this->load->view('cert/index', $data); + } + + /** + * 证书查询 + */ + public function index() + { + $this->load->model('model_UsersInfo'); + $device_id = isset($_REQUEST['device_id']) ? $_REQUEST['device_id'] : 0; + $data = [ + 'info' => [], + 'warning' => '' + ]; + if($device_id){ + //检查信息是否能对应 + $row = $this->model_UsersInfo->get( + $device_id, + 'device_id' + ); + if(empty($row)){ + $data['warning'] = '序列号错误'; + }else{ + header('Location:/cert/id/'.trim($device_id)); + $data['info'] = $row; + } + } + $data['type'] = 'cert'; + $this->load->view('cert/index', $data); + } + + /** + * 激活信息 + */ + public function info($id) + { + + if(empty($id)){ + return $this->notify(); + } + + $this->load->model('Model_UsersInfo'); + $this->load->model('report_model'); + //报告文件 + $file = $this->report_model->report_file_path(trim($id)); + $reportJson = []; + if(file_exists($file)){ + $a=filemtime($file); + $data['time'] = date("Y.m.d",$a); + //return $this->notify(); + $reportJson = file_get_contents($file); + $reportJson = json_decode($reportJson,true); + } + + //补充图片,物种 + $info = $this->Model_UsersInfo->get_by_device_id($id); + if(!$info){ + return $this->notify(); + } + $data = array( + 'owner'=>'' + ); + + $data['device_id'] = $id; + //$data['name'] = $reportJson['header']['宠物名']; + //$data['wolf'] = isset($reportJson['进阶项目研究']['body']['狼性']['body'])?$reportJson['进阶项目研究']['body']['狼性']['body']:'未知'; + if(!empty($reportJson)){ + $data['mixed'] = isset($reportJson['血统分析']['body']['品系纯度'])?$reportJson['血统分析']['body']['品系纯度']:[]; + } + //主人信息 + $data['owner'] = $info['users_name']; + $data['name'] = $info['pet_name']; + $data['time'] = date("Y.m.d",$info['createtime']); + //预置血统信息优先 + $data['mixed'] = ['未知'=>'']; + if(!empty($info['lineage'])){ + $data['mixed'] = []; + $lineage = explode(';',$info['lineage']); + foreach ($lineage as $val) { + $val = explode(':',$val); + if(count($val)<2){ + continue; + } + $data['mixed'][$val[0]] = $val[1]; + } + } + $this->load->view('user/includes/header', NULL); + $this->load->view('user/includes/nav', NULL); + $this->load->view('cert/id', $data); + $this->load->view('user/includes/footer', NULL); + } + + /** + * 证书 + */ + public function id($id) + { + + if(empty($id)){ + return $this->notify(); + } + + $this->load->model('Model_UsersInfo'); + $this->load->model('report_model'); + //报告文件 + $file = $this->report_model->report_file_path(trim($id)); + $reportJson = []; + if(file_exists($file)){ + $a=filemtime($file); + $data['time'] = date("Y.m.d",$a); + //return $this->notify(); + $reportJson = file_get_contents($file); + $reportJson = json_decode($reportJson,true); + } + + //补充图片,物种 + $info = $this->Model_UsersInfo->get_by_device_id($id); + if(!$info){ + return $this->notify(); + } + $data = array( + 'owner'=>'' + ); + + $data['device_id'] = $id; + //$data['name'] = $reportJson['header']['宠物名']; + //$data['wolf'] = isset($reportJson['进阶项目研究']['body']['狼性']['body'])?$reportJson['进阶项目研究']['body']['狼性']['body']:'未知'; + if(!empty($reportJson)){ + $data['mixed'] = isset($reportJson['血统分析']['body']['品系纯度'])?$reportJson['血统分析']['body']['品系纯度']:[]; + } + //主人信息 + $data['owner'] = $info['users_name']; + $data['name'] = $info['pet_name']; + $data['time'] = date("Y.m.d",$info['createtime']); + //预置血统信息优先 + $data['mixed'] = ['未知'=>'']; + if(!empty($info['lineage'])){ + $data['mixed'] = []; + $lineage = explode(';',$info['lineage']); + foreach ($lineage as $val) { + $val = explode(':',$val); + if(count($val)<2){ + continue; + } + $data['mixed'][$val[0]] = $val[1]; + } + } + $data['test_date'] = $info['test_date']; + $data['birthday'] = $info['pet_birthday']; + $this->load->view('user/includes/header', NULL); + $this->load->view('user/includes/nav', NULL); + $this->load->view('cert/id', $data); + $this->load->view('user/includes/footer', NULL); + } + + protected function notify(){ + $this->load->view('user/includes/header', NULL); + $this->load->view('user/includes/nav', NULL); + $this->load->view('cert/notify', []); + $this->load->view('user/includes/footer', NULL); + } + + +} diff --git a/controllers/Rest_server.php b/controllers/Rest_server.php new file mode 100644 index 0000000..5d44f92 --- /dev/null +++ b/controllers/Rest_server.php @@ -0,0 +1,13 @@ +load->helper('url'); + + $this->load->view('rest_server'); + } +} diff --git a/controllers/Test.php b/controllers/Test.php new file mode 100644 index 0000000..ef99098 --- /dev/null +++ b/controllers/Test.php @@ -0,0 +1,76 @@ +load->library('session'); + $this->load->model('customer_model'); + } + + // 中通快递查询 + public function zto() + { + $this->load->model('zto_model'); + //$ret_search = $this->zto_model->commonOrderSearchbycode('200310051678942109','29'); + //$ret_search = $this->zto_model->commonOrderSearchbycode('200311000100544107','27'); + //$ret_search = $this->zto_model->commonOrderSearchbycode('200311000276939109','49'); + //print_r($ret_search); + /* + if($ship_order){ + $track = $this->zto_model->traceInterfaceNewTraces($ship_order['order_code']); + }*/ + $track = $this->zto_model->traceInterfaceNewTraces(73127201209703); + print_r($track); + } + + // 中通 + public function zto_query() + { + $this->load->model('zto_model'); + $this->zto_model->commonOrderSearchbycode('200210000005196104','1'); + } + + // 测试顺丰 + public function sf() + { + $this->load->model('sf_express_model'); + $data = [ + 'trade_id'=>'2020041903', + 'province'=>'上海市', + 'city'=>'上海市', + 'district'=>'嘉定区', + 'name'=>'测试', + 'tel'=>'15815725225', + 'address'=>'黄浦江晓东楼房', + ]; + $ret = $this->sf_express_model->shipSample($data); + print_r($ret);die; + //$this->sf_express_model->test(); + } + + // 测试顺丰 + public function sf2() + { + $this->load->model('sf_express_model'); + $data = [ + 'user_id'=>'1', + 'trade_id'=>'2020041903', + 'province'=>'上海市', + 'city'=>'上海市', + 'district'=>'嘉定区', + 'name'=>'测试', + 'tel'=>'15815725225', + 'address'=>'黄浦江晓东楼房', + ]; + $this->sf_express_model->test($data); + } + +} diff --git a/controllers/Weixin.php b/controllers/Weixin.php new file mode 100644 index 0000000..9811ccd --- /dev/null +++ b/controllers/Weixin.php @@ -0,0 +1,143 @@ +load->library('session'); + $this->load->model('customer_model'); + } + + protected function getApp(){ + $conf = $this->config->item('weixin_uah'); + $config = [ + 'app_id' => $conf['AppId'], + 'secret' => $conf['AppSecert'], + 'token' => $conf['Token'], + 'aes_key' => $conf['EncodingAESKey'], + 'response_type' => 'array', + ]; + return new OfficialAccount($config); + } + + // 发起授权页 + public function index() + { + $to_url = $this->input->get('url'); + if(empty($to_url)){ + die('Url is empty.'); + } + //支持静默授权 + $scope = !empty($this->input->get('is_base'))?'snsapi_base':'snsapi_userinfo'; + + //如已登录,则不跳转 + if(!empty($this->session->{Customer_model::SESSION_KEY})){ + Header("HTTP/1.1 303 See Other"); + Header("Location: $to_url"); + die; + } + + //未登录,则跳转授权,处理会员数据之后再进行一次跳转 + $callback_url = base_url().strtolower(__CLASS__).'/callback'; + $callback_url.='?url='.urlencode($to_url); + $app = $this->getApp(); + $response = $app->oauth->scopes([$scope])->redirect($callback_url); + $response->send(); + } + + //授权回调页 + public function callback() + { + $to_url = $this->input->get('url'); + $app = $this->getApp(); + try{ + $user = $app->oauth->user(); + }catch (Exception $e){ + die('Error:'.$e->getMessage()); + } + if(!$user){ + die('User info empty.'); + } + if($user->original['scope'] == 'snsapi_base') { + $this->session->{Customer_model::SESSION_KEY_WX_OPEN_ID} = $user->original['openid']; + }else{ + $ret = $this->customer_model->weixin_users($user->original); + if(!$ret){ + die('Database connect failed.'); + } + $this->session->{Customer_model::SESSION_KEY} = $ret; + } + Header("HTTP/1.1 303 See Other"); + Header("Location: $to_url"); + } + + // 直接设置session user id,在微信外登录 + public function test() + { + $this->session->{Customer_model::SESSION_KEY} = 1; + die('dfdf'); + //$this->session->{Customer_model::SESSION_KEY_WX_OPEN_ID} = 'ddd'; + //echo $this->session->{Customer_model::SESSION_KEY_WX_OPEN_ID};die; + } + + public function test2() + { + unset($this->session->{Customer_model::SESSION_KEY}); + //$this->session->{Customer_model::SESSION_KEY} = 26; +// $this->session->{Customer_model::SESSION_KEY} = 'aadd'; +// if(!empty($this->session->{Customer_model::SESSION_KEY})){ +// die('222'); +// } + } + public function test_get() + { + var_dump($this->session->{Customer_model::SESSION_KEY}); + } + + //判断是介入还是用户 只有第一次介入的时候才会返回echostr + public function check_sign(){ + //这个echostr呢 只有说验证的时候才会echo 如果是验证过之后这个echostr是不存在的字段了 + $echoStr = $_GET["echostr"]; + if ($this->checkSignature()) { + echo $echoStr; + //如果你不知道是否验证成功 你可以先echo echostr 然后再写一个东西 + exit; + } + } + + //验证微信开发者模式接入是否成功 + private function checkSignature(){ + //signature 是微信传过来的 类似于签名的东西 + $signature = $_GET["signature"]; + //微信发过来的东西 + $timestamp = $_GET["timestamp"]; + //微信传过来的值 什么用我不知道... + $nonce = $_GET["nonce"]; + //定义你在微信公众号开发者模式里面定义的token + $token = $this->Token; + //三个变量 按照字典排序 形成一个数组 + $tmpArr = array( + $token, + $timestamp, + $nonce + ); + // use SORT_STRING rule + sort($tmpArr, SORT_STRING); + $tmpStr = implode($tmpArr); + //哈希加密 在laravel里面是Hash:: + $tmpStr = sha1($tmpStr); + //按照微信的套路 给你一个signature没用是不可能的 这里就用得上了 + if ($tmpStr == $signature) { + return true; //一定要返回 不要echo 负责微信拿不到返回值导致不通过 + } else { + return false; + } + }// checkSignature end +} diff --git a/controllers/Welcome.php b/controllers/Welcome.php new file mode 100644 index 0000000..e322673 --- /dev/null +++ b/controllers/Welcome.php @@ -0,0 +1,25 @@ + + * @see https://codeigniter.com/user_guide/general/urls.html + */ + public function index() + { + $this->load->view('welcome_message'); + } +} diff --git a/controllers/api/Example.php b/controllers/api/Example.php new file mode 100644 index 0000000..8b6c648 --- /dev/null +++ b/controllers/api/Example.php @@ -0,0 +1,330 @@ +methods['users_get']['limit'] = 500; // 500 requests per hour per user/key + $this->methods['users_post']['limit'] = 100; // 100 requests per hour per user/key + $this->methods['users_delete']['limit'] = 50; // 50 requests per hour per user/key + } + + + public function users_get() + { +// var_dump($this->input->server('REQUEST_METHOD')); + +// var_dump($this->get('id')); // 参数带id +// var_dump($this->get('blah')); // http://www.cirest.com:8889/api/example/users/id/2/di/3 可以传多个参数 +// +// //通过query获取 url 传参 测试失败? +// var_dump($this->query('id')); +// var_dump($this->query('blah')); +// var_dump($this->query()); + + // Users from a data store e.g. database + $users = [ + ['id' => 1, 'name' => 'John', 'email' => 'john@example.com', 'fact' => 'Loves coding'], + ['id' => 2, 'name' => 'Jim', 'email' => 'jim@example.com', 'fact' => 'Developed on CodeIgniter'], + ['id' => 3, 'name' => 'Jane', 'email' => 'jane@example.com', 'fact' => 'Lives in the USA', ['hobbies' => ['guitar', 'cycling']]], + ]; + + $id = $this->get('id'); + + // If the id parameter doesn't exist return all the users + + if ($id === NULL) + { + // Check if the users data store contains users (in case the database result returns NULL) + if ($users) + { + // Set the response and exit + $this->response($users, RestController::HTTP_OK); // OK (200) being the HTTP response code + } + else + { + // Set the response and exit + $this->response([ + 'status' => FALSE, + 'message' => 'No users were found' + ], RestController::HTTP_NOT_FOUND); // NOT_FOUND (404) being the HTTP response code + } + } + + // Find and return a single record for a particular user. + + $id = (int) $id; + + // Validate the id. + if ($id <= 0) + { + // Invalid id, set the response and exit. + $this->response(NULL, RestController::HTTP_BAD_REQUEST); // BAD_REQUEST (400) being the HTTP response code + } + + // Get the user from the array, using the id as key for retrieval. + // Usually a model is to be used for this. + + $user = NULL; + + if (!empty($users)) + { + foreach ($users as $key => $value) + { + if (isset($value['id']) && $value['id'] === $id) + { + $user = $value; + } + } + } + + if (!empty($user)) + { + $this->set_response($user, RestController::HTTP_OK); // OK (200) being the HTTP response code + } + else + { + $this->set_response([ + 'status' => FALSE, + 'message' => 'User could not be found' + ], RestController::HTTP_NOT_FOUND); // NOT_FOUND (404) being the HTTP response code + } + } + + public function users_post() + { + // $this->some_model->update_user( ... ); + $message = [ + 'id' => 100, // Automatically generated by the model + 'name' => $this->post('name'), + 'email' => $this->post('email'), + 'message' => 'Added a resource' + ]; + + $this->set_response($message, RestController::HTTP_CREATED); // CREATED (201) being the HTTP response code + } + + public function users_delete() + { + + // $this->>delete获取不到参数 + // 可以使用 url 传参数方式获取 使用 $this->get('id')来接收 + // DELETE http://www.cirest.com:8889/api/example/users/2 使用中路由重写了 成/users/id/2 + // DELETE http://www.cirest.com:8889/api/example/users/id/2 + var_dump($this->get('id')); // 参数带id + var_dump($this->get('blah')); // http://www.cirest.com:8889/api/example/users/id/2/blah/3 可以传多个参数 + + $id = (int) $this->get('id'); + var_dump($id); + + // Validate the id. + if ($id <= 0) + { + // Set the response and exit + $this->response(NULL, RestController::HTTP_BAD_REQUEST); // BAD_REQUEST (400) being the HTTP response code + } + + // $this->some_model->delete_something($id); + $message = [ + 'id' => $id, + 'message' => 'Deleted the resource' + ]; + + $this->set_response($message, RestController::HTTP_NO_CONTENT); // NO_CONTENT (204) being the HTTP response code + } + + // 签发Token + public function issue_get() + { + $key = '344'; //key + $time = time(); //当前时间 + $token = [ + 'iss' => 'http://www.helloweba.net', //签发者 可选 + 'aud' => 'http://www.helloweba.net', //接收该JWT的一方,可选 + 'iat' => $time, //签发时间 + 'nbf' => $time, //(Not Before):某个时间点后才能访问,比如设置time+30,表示当前时间30秒后才能使用 + 'exp' => $time + 7200, //过期时间,这里设置2个小时 + 'data' => [ //自定义信息,不要定义敏感信息 + 'userid' => 1, + 'username' => '李小龙' + ] + ]; + + $jsonList = [ + 'access_token' => JWT::encode($token, $key), + ]; + + $this->set_response($jsonList, RestController::HTTP_CREATED); + } + + public function verification_post() + { + + $key = '344'; //key要和签发的时候一样 + + $jwt = $this->post('access_token'); //签发的Token + try { + JWT::$leeway = 60;//当前时间减去60,把时间留点余地 + $decoded = JWT::decode($jwt, $key, ['HS256']); //HS256方式,这里要和签发的时候对应 + $arr = (array)$decoded; + print_r($arr); + } catch (\Firebase\JWT\SignatureInvalidException $e) { //签名不正确 + echo $e->getMessage(); + } catch (\Firebase\JWT\BeforeValidException $e) { // 签名在某个时间点之后才能用 + echo $e->getMessage(); + } catch (\Firebase\JWT\ExpiredException $e) { // token过期 + echo $e->getMessage(); + } catch (Exception $e) { //其他错误 + echo $e->getMessage(); + } + //Firebase定义了多个 throw new,我们可以捕获多个catch来定义问题,catch加入自己的业务,比如token过期可以用当前Token刷新一个新Token + + } + + // 七牛 上传图片测试 + public function qiniu_get() + { + $cfg = [ + 'access' => 'K5w2Fe4XowpU6kuklgLlAhGkXWt111WVssI1R0ff', + 'secret' => 'i9QhgiUvdO5AgpPnQkPXO6n9wA9jILLeaskqP0Iz', + 'bucket' => 'pocoyo_bucket', + 'domain' => 'http://pub8vjaao.bkt.clouddn.com' + ]; + + $auth = new Auth($cfg['access'], $cfg['secret']); + // 创建一个过期时间为1小时的临时上传令牌 + $token = $auth->uploadToken($cfg['bucket'], null, 3600); + + // 中文名需要转换编码? + $filePath = iconv('UTF-8', 'GBK', APPPATH . 'controllers\api\QQ图片20160922141622.png'); + + $uploadMgr = new UploadManager(); + list($ret, $err) = $uploadMgr->putFile($token, null, $filePath); + if($err !== null) { + $this->err = $err; + var_dump($err); + } else { + echo $cfg['domain'] . '/' . $ret['key']; + } + } + + // Chevereto 图床免费版本地址:https://github.com/Chevereto/Chevereto-Free + // https://chevereto.com/docs/api-v1 + // 上传图片测试 + public function chevereto_post() + { + // 1. 上传本地文件时应使用 $fields post base64_encode方法 + // Always use POST when uploading local files. Url encoding may alter the base64 source + // due to encoded characters or just by URL request length limit due to GET request. + // base64编码 会导致过长 url request + // var_dump($_FILES); 参考 uploadimg 可以做一些前置校验处理 // 前置判断 if (empty($_FILES) === false) + $key = '5486424e4dfb6b87453dd4bb25c0dcb0'; + $url = 'http://172.17.1.110/chevereto/api/1/upload'; + + // What do we send to chevereto api? + $fields = array( + 'key' => urlencode($key), + // The image encoded in base64 + 'source' => base64_encode(file_get_contents($_FILES["file"]['tmp_name'])), + // format: txt / json txt 只返回图片地址或错误信息 eg.Duplicated upload 较为简洁 + 'format' => urlencode('json') + ); + + //open connection + $ch = curl_init(); + + //set the url, number of POST vars, POST data + curl_setopt($ch, CURLOPT_URL, $url); + curl_setopt($ch, CURLOPT_POST, sizeof($fields)); + curl_setopt($ch, CURLOPT_HEADER, false); + curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); + curl_setopt($ch, CURLOPT_TIMEOUT, 240); + curl_setopt($ch, CURLOPT_POSTFIELDS, $fields); + curl_setopt($ch, CURLOPT_HTTPHEADER, array('Expect: ')); + + //execute post + $result = curl_exec($ch); + //释放curl句柄 + curl_close($ch); + echo $result; + //close connection + + // 2. 上传远程图片地址可使用 _get source=urlencode{source} 方法即可 + +// $key = '6a55c7f9fa13813c2da613dc7b5b920b'; +// // 设定远程图片地址 +// $source = 'https://img3.doubanio.com/view/group_topic/large/public/p67032015.jpg'; +// // format: txt / json txt 只返回图片地址或错误信息 eg.Duplicated upload 较为简洁 +// $url = 'http://172.17.1.110:8888/api/1/upload/?key={key}&source={source}&format=txt'; +// $url = str_replace(array('{key}','{source}'),array($key,urlencode($source)),$url); +// +// //初始化 +// $ch = curl_init(); +// //设置选项,包括URL +// curl_setopt($ch, CURLOPT_URL, $url); +// curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); +// curl_setopt($ch, CURLOPT_HEADER, 0); +// //执行并获取HTML文档内容 +// $output = curl_exec($ch); +// //释放curl句柄 +// curl_close($ch); +// echo $output; + + +// 失败 +// { +// "status_txt": "Bad Request", +// "error": { +// "context": "Exception", +// "code": 102, +// "message": "Duplicated upload" +// }, +// "status_code": 400 +// } +// 成功 +// { +// "status_txt": "OK", +// "image": { +// "image": { +// "size": "89163", +// "url": "http://172.17.1.110:8888/images/2019/07/09/p67032015.jpg", +// "extension": "jpg", +// "mime": "image/jpeg", +// "name": "p67032015", +// "filename": "p67032015.jpg" +// }, +// }, +// "success": { +// "code": 200, +// "message": "image uploaded" +// }, +// "status_code": 200 +// } + + } + +} diff --git a/controllers/api/Key.php b/controllers/api/Key.php new file mode 100644 index 0000000..5629cab --- /dev/null +++ b/controllers/api/Key.php @@ -0,0 +1,256 @@ + ['level' => 10, 'limit' => 10], + 'index_delete' => ['level' => 10], + 'level_post' => ['level' => 10], + 'regenerate_post' => ['level' => 10], + ]; + + /** + * Insert a key into the database + * + * @access public + * @return void + */ + public function index_put() + { + // Build a new key + $key = $this->_generate_key(); + + // If no key level provided, provide a generic key + $level = $this->put('level') ? $this->put('level') : 1; + $ignore_limits = ctype_digit($this->put('ignore_limits')) ? (int)$this->put('ignore_limits') : 1; + + // Insert the new key + if ($this->_insert_key($key, ['level' => $level, 'ignore_limits' => $ignore_limits])) { + $this->response([ + 'status' => TRUE, + 'key' => $key + ], RestController::HTTP_CREATED); // CREATED (201) being the HTTP response code + } else { + $this->response([ + 'status' => FALSE, + 'message' => 'Could not save the key' + ], RestController::HTTP_INTERNAL_SERVER_ERROR); // INTERNAL_SERVER_ERROR (500) being the HTTP response code + } + } + + /** + * Remove a key from the database to stop it working + * + * @access public + * @return void + */ + public function index_delete($key) + { + // $this->>delete获取不到参数 + // 可以使用 url 传参数方式获取 + // DELETE http://www.cirest.com:8889/api/key/8ww0sgk0sogs0ocg4gsw0gwsosk8wwcwoks044ws +// $key = $this->delete('key'); +// $key='oocwo8cs88g4c8w8c08ow00ss844cc4osko0s0ks'; + + // Does this key exist? + if (!$this->_key_exists($key)) { + // It doesn't appear the key exists + $this->response([ + 'status' => FALSE, + 'message' => 'Invalid API key' + ], RestController::HTTP_BAD_REQUEST); // BAD_REQUEST (400) being the HTTP response code + } + + // Destroy it + $this->_delete_key($key); + + // Respond that the key was destroyed + $this->response([ + 'status' => TRUE, + 'message' => 'API key was deleted' + ], RestController::HTTP_NO_CONTENT); // NO_CONTENT (204) being the HTTP response code + } + + /** + * Change the level + * + * @access public + * @return void + */ + public function level_post() + { + $key = $this->post('key'); + $new_level = $this->post('level'); + + // Does this key exist? + if (!$this->_key_exists($key)) { + // It doesn't appear the key exists + $this->response([ + 'status' => FALSE, + 'message' => 'Invalid API key' + ], RestController::HTTP_BAD_REQUEST); // BAD_REQUEST (400) being the HTTP response code + } + + // Update the key level + if ($this->_update_key($key, ['level' => $new_level])) { + $this->response([ + 'status' => TRUE, + 'message' => 'API key was updated' + ], RestController::HTTP_OK); // OK (200) being the HTTP response code + } else { + $this->response([ + 'status' => FALSE, + 'message' => 'Could not update the key level' + ], RestController::HTTP_INTERNAL_SERVER_ERROR); // INTERNAL_SERVER_ERROR (500) being the HTTP response code + } + } + + /** + * Suspend a key + * 挂起api key 则key 的level 设置为0 + * @access public + * @return void + */ + public function suspend_post() + { + $key = $this->post('key'); + + // Does this key exist? + if (!$this->_key_exists($key)) { + // It doesn't appear the key exists + $this->response([ + 'status' => FALSE, + 'message' => 'Invalid API key' + ], RestController::HTTP_BAD_REQUEST); // BAD_REQUEST (400) being the HTTP response code + } + + // Update the key level + if ($this->_update_key($key, ['level' => 0])) { + $this->response([ + 'status' => TRUE, + 'message' => 'Key was suspended' + ], RestController::HTTP_OK); // OK (200) being the HTTP response code + } else { + $this->response([ + 'status' => FALSE, + 'message' => 'Could not suspend the user' + ], RestController::HTTP_INTERNAL_SERVER_ERROR); // INTERNAL_SERVER_ERROR (500) being the HTTP response code + } + } + + /** + * Regenerate a key + * 将 key level 设置为0 (禁用),数据库里生成一条新的key记录并且延用原来level,ignore_limits + * @access public + * @return void + */ + public function regenerate_post() + { + $old_key = $this->post('key'); + $key_details = $this->_get_key($old_key); + + // Does this key exist? + if (!$key_details) { + // It doesn't appear the key exists + $this->response([ + 'status' => FALSE, + 'message' => 'Invalid API key' + ], RestController::HTTP_BAD_REQUEST); // BAD_REQUEST (400) being the HTTP response code + } + + // Build a new key + $new_key = $this->_generate_key(); + + // Insert the new key + if ($this->_insert_key($new_key, ['level' => $key_details->level, 'ignore_limits' => $key_details->ignore_limits])) { + // Suspend old key + $this->_update_key($old_key, ['level' => 0]); + + $this->response([ + 'status' => TRUE, + 'key' => $new_key + ], RestController::HTTP_CREATED); // CREATED (201) being the HTTP response code + } else { + $this->response([ + 'status' => FALSE, + 'message' => 'Could not save the key' + ], RestController::HTTP_INTERNAL_SERVER_ERROR); // INTERNAL_SERVER_ERROR (500) being the HTTP response code + } + } + + /* Helper Methods */ + + private function _generate_key() + { + do { + // Generate a random salt + $salt = base_convert(bin2hex($this->security->get_random_bytes(64)), 16, 36); + + // If an error occurred, then fall back to the previous method + if ($salt === FALSE) { + $salt = hash('sha256', time() . mt_rand()); + } + + $new_key = substr($salt, 0, config_item('rest_key_length')); + } while ($this->_key_exists($new_key)); + + return $new_key; + } + + /* Private Data Methods */ + + private function _get_key($key) + { + return $this->rest->db + ->where(config_item('rest_key_column'), $key) + ->get(config_item('rest_keys_table')) + ->row(); + } + + private function _key_exists($key) + { + return $this->rest->db + ->where(config_item('rest_key_column'), $key) + ->count_all_results(config_item('rest_keys_table')) > 0; + } + + private function _insert_key($key, $data) + { + $data[config_item('rest_key_column')] = $key; + $data['date_created'] = function_exists('now') ? now() : time(); + + return $this->rest->db + ->set($data) + ->insert(config_item('rest_keys_table')); + } + + private function _update_key($key, $data) + { + return $this->rest->db + ->where(config_item('rest_key_column'), $key) + ->update(config_item('rest_keys_table'), $data); + } + + private function _delete_key($key) + { + return $this->rest->db + ->where(config_item('rest_key_column'), $key) + ->delete(config_item('rest_keys_table')); + } + +} diff --git a/controllers/api/report/Index.php b/controllers/api/report/Index.php new file mode 100644 index 0000000..21f6031 --- /dev/null +++ b/controllers/api/report/Index.php @@ -0,0 +1,402 @@ +load->model('sample_model'); + $this->load->model('report_model'); + } + + public function index_get() + { + if(empty($_GET['id'])){ + $this->setError('请求错误'); + } + $id = trim($_GET['id']); + $id = $this->getDeviceId($id); + //报告文件 + $ret = $this->report_model->get_result($id,$this->_is_test); + if(empty($ret)){ + $this->setError('报告未生成'); + die; + } + + $this->setSuccess($ret); + } + + //获取犬类疾病的列表,需要挂钩报告编号,以便显示锁定与解锁的疾病 + protected function disease_list($need_category,$need_detail) + { + /* + * 从库中读取 + $params = []; + //区分单基因/多基因 + if(!empty($_GET['gene_type'])){ + $params['gene_type'] = $_GET['gene_type']; + } + + $this->load->model('disease_model'); + $list = $this->disease_model->listing($params, 0,50000,'base.*'); + */ + + /* + * 从素材分类 + $material = $this->report_model->get_material(); + $info = []; + $list = array_merge($material['犬类单基因疾病'],$material['犬类复杂疾病']); + //类别描述删除多余字符 + $searchStrOne = explode('|','类遗传疾病|类疾病|系统遗传病|遗传病|遗传疾病|疾病'); + $searchStrTwo = explode('|','类|系统类|系统'); + foreach ($list as $key=>$val) { + if(empty($val['所属类别'])){ + $name = '其他'; + }else{ + //删除多余的描述 + $name = str_replace($searchStrOne,'',$val['所属类别']); + $name = str_replace($searchStrTwo,'',$name); + } + $info[$name][] = [ + 'name'=>$key, + 'lock'=>$lock && !in_array($key,$lockDisease) + ]; + } + */ + + if(empty($_GET['id'])){ + $this->setError('请求错误'); + } + + $id = trim($_GET['id']); + $id = $this->getDeviceId($id); + + //样品及套餐信息 + $this->load->model('sample_model'); + $this->load->model('package_model'); + $sample = $this->sample_model->get($id,'device_id'); + if(empty($sample)){ + $this->setError('样品不存在'); + die; + } + //报告文件 + $json = $this->report_model->get_report_json($id,$sample['pet_species']); + + //套餐设置成1,上线后删除 + //$sample['package_id'] = 1; + $package = $this->package_model->get($sample['package_id']); + if(!$package){ + return []; + } + $gene_type = !empty($_GET['gene_type'])?$_GET['gene_type']:0; + return $this->report_model->get_disease_list($gene_type,$sample,$json,$package,$need_category,$need_detail); + } + + //疾病列表 + public function disease_list_get(){ + $ret = $this->disease_list(!empty($_GET['need_category']),false); + if(!empty($_GET['need_category'])){ + //需要分类的疾病是单基因疾病,将解锁的放前面 + foreach ($ret as $category_name => $list) { + $lock = []; + $unlock = []; + foreach ($list as $key=>$val) { + if($val['lock']){ + $lock[] = $val; + }else{ + $unlock[] = $val; + } + } + $ret[$category_name] = array_merge($unlock,$lock); + } + } + $this->setSuccess($ret); + } + + //疾病列表 + public function disease_get() + { + /* + $this->load->model('disease_model'); + $row = $this->disease_model->get($_GET['disease_name'],'base.name'); + */ + if(empty($_GET['disease_name'])){ + $this->setError('请求错误'); + } + $ret = []; + $material = $this->disease_list(false,true); + foreach ($material as $item) { + if($item['name'] == $_GET['disease_name']){ + $ret = $item; + break; + } + } + //根据基因类型,做低风险描述调整,未检测出时没有描述 + if(!$ret['risk']){ + $ret['risk_desc'] = $ret['gene_type'] == 1?'未检测到致病突变':'低发病风险'; + } + $this->setSuccess($ret); + } + + //证书图片信息 + public function cert_health_list_get() + { + //疾病描述 + $this->load->model('Cat_disease_desc_model'); + + $disease = []; + $material = $this->disease_list(false,true); + foreach ($material as $item) { + $description = $this->Cat_disease_desc_model->breeding_single_detail($item['name']); + if(empty($description)){ + continue; + } + //风险等级 + $risk_tag = 'N/N'; + if($item['risk']){ + $risk_tag = $item['risk_level'] == 1?'N/F':'F/F'; + } + $disease[] = [ + //疾病名称 + 'name'=>$item['name'], + //疾病N/N + 'risk_tag'=>$risk_tag, + //结果说明 + 'risk_desc'=>$description['检测结果'][$risk_tag], + //检测手段 + 'method'=>$description['检测手段'], + //基因型 + 'gene_type'=>$description['基因型'], + //N/N + 'NN'=>$description['结果说明']['N/N'], + 'NF'=>$description['结果说明']['N/F'], + 'FF'=>$description['结果说明']['F/F'], + ]; + } + $this->success($disease); + } + + //证书图片单张 + public function cert_health_get() + { + + if(empty($_GET['name'])){ + $this->setError('请求错误'); + } + $disease = []; + $material = $this->disease_list(false,true); + foreach ($material as $item) { + if($item['name'] == $_GET['name']){ + $disease = $item; + break; + } + } + //根据基因类型,做低风险描述调整,未检测出时没有描述 + if(!$disease['risk']){ + $disease['risk_desc'] = $disease['gene_type'] == 1?'未检测到致病突变':'低发病风险'; + } + + + //样本信息 + $id = trim($_GET['id']); + $id = $this->getDeviceId($id); + + //样品及套餐信息 + $this->load->model('sample_model'); + $this->load->model('package_model'); + $sample = $this->sample_model->get($id,'device_id'); + if(empty($sample)){ + $this->setError('样品不存在'); + die; + } + + //疾病描述 + $this->load->model('Cat_disease_desc_model'); + $description = $this->Cat_disease_desc_model->breeding_single_detail($_GET['name']); + if(empty($description)){ + die('empty'); + } + + + //证书文件如果有就直接输出 + $this->load->library('uploads'); + $id = strtoupper($id); + $upload_path = $this->uploads->get_upload_path(); + $cert_img_path = $upload_path.Uploads::DIR_PER_CERT_IMG.DIRECTORY_SEPARATOR.$id.DIRECTORY_SEPARATOR; + $cert_file_name = $cert_img_path.$_GET['name'].'.jpg'; + if(file_exists($cert_file_name)){ + //声明需要创建的图层的图片格式 + header("Content-Type:image/jpg"); + echo file_get_contents($cert_file_name); + die(); + } + + //风险等级 + $risk_tag = 'N/N'; + if($disease['risk']){ + $risk_tag = $disease['risk_level'] == 1?'N/F':'F/F'; + } + + //图片 + header("Content-type: image/png"); + $file = APPPATH."uahpet/cert_template/health.png";//图片跟路径 + $font = APPPATH."uahpet/font/SourceHanSansCN-Regular.otf"; + $font_bold = APPPATH."uahpet/font/SourceHanSansCN-Bold.otf"; + $img = imagecreatefrompng($file); + $blue = imagecolorallocate($img, 17, 182, 179); + $black = imagecolorallocate($img, 62, 62, 62); + + //名字 + $sting = $sample['pet_name']; + imagettftext($img, 15, 0, 288, 705, $black, $font, $sting); + + //养育人 + $sting = $sample['name']; + imagettftext($img, 15, 0, 600, 705, $black, $font, $sting); + + //测试日期 + $sting = date('Y-m-d',$sample['create_time']); + imagettftext($img, 15, 0, 970, 705, $black, $font, $sting); + + //疾病名称 + $sting = $_GET['name']; + imagettftext($img, 27, 0, 186, 965, $blue, $font_bold, $sting); + + //疾病N/N + $sting = $risk_tag; + imagettftext($img, 27, 0, 638, 965, $blue, $font_bold, $sting); + + //结果说明 + $sting = $description['检测结果'][$risk_tag] ; + imagettftext($img, 15, 0, 736, 960, $black, $font, $sting); + + /* 证书左侧段落 */ + + //检测手段 + $sting = '检测手段:'.$description['检测手段']; + imagettftext($img, 13, 0, 188, 1030, $black, $font, $sting); + + //检测手段解释 + $sting = '基 因 型:'; + imagettftext($img, 13, 0, 188, 1061, $black, $font, $sting); + + //检测手段解释 + $sting_arr = explode("\n",$description['基因型']); + //右侧,处理换行 + foreach ($sting_arr as $key=>$val) { + imagettftext($img, 13, 0, 188+85, 1061+$key*25, $black, $font, $val); + } + + /* 证书右侧段落 */ + + //N/N + $sting = 'N/N:'.$description['结果说明']['N/N']; + imagettftext($img, 13, 0, 644, 1030, $black, $font, $sting); + + //N/F + //标题 + $sting_arr = $this->cutImgString($description['结果说明']['N/F'],26); + $sting = 'N/F:'; + imagettftext($img, 13, 0, 644, 1061, $black, $font, $sting); + //右侧,处理换行 + foreach ($sting_arr as $key=>$val) { + imagettftext($img, 13, 0, 644+45, 1061+$key*25, $black, $font, $val); + } + + //F/F + $sting = 'F/F:'.$description['结果说明']['F/F']; + imagettftext($img, 13, 0, 644, 1093+(count($sting_arr)-1)*16, $black, $font, $sting); + + imagejpeg($img,$cert_file_name,75); + imagedestroy($img); + + echo file_get_contents($cert_file_name); + exit; + } + + public function cert_health_down_post() + { + //接口禁用 + die(''); + $data = $this->json_input(); + if(empty($data) || empty($data['id'])){ + $this->setError('请求错误'); + } + + //样本序列号 + $device_id = trim($data['id']); + $device_id = $this->getDeviceId($device_id); + + //接收血统证书,血统证书很难在服务器端生成 + $base64_cert_lineage = trim($data['cert_lineage']); + + $this->load->library('uploads'); + $this->load->library('MakeZip'); + + //报告id + $device_id = strtoupper($device_id); + + //图片 + $pet_img = $this->uploads->save_cert_img_base64( + $base64_cert_lineage, + $device_id, + '健康证书' + ); + + if(!$pet_img){ + $this->error('健康证书输出失败'); + } + + //压缩 + $path = (Uploads::DIR).DIRECTORY_SEPARATOR; + $sourceDir = $path.(Uploads::DIR_PER_CERT_IMG).DIRECTORY_SEPARATOR.$device_id.DIRECTORY_SEPARATOR; + $targetFile = $path.(Uploads::DIR_PER_CERT_ZIP).DIRECTORY_SEPARATOR.uniqid().'.zip'; + $res = $this->makezip->zip(FCPATH.$sourceDir,FCPATH.$targetFile); + if(!$res){ + throw new Exception('压缩失败'); + } + $this->success(['file'=>base_url().$targetFile]); + exit; + } + + private function setError($err,$code = 0){ + echo json_encode(['code'=>$code,'msg'=>$err]); + die; + } + private function setSuccess($data){ + echo json_encode(['code'=>1,'msg'=>'','data'=>$data]); + die; + } + + protected function getDeviceId($deviceID){ + //是否预置了测试参数 + $this->_is_test = substr($deviceID,-strlen(self::TEST_SUFFIX)) == self::TEST_SUFFIX; + if($this->_is_test){ + return substr($deviceID,0,-strlen(self::TEST_SUFFIX)); + } + return $deviceID; + } + + //字数太长要折行,统计折行的行数 + protected function cutImgString($str,$len){ + if(mb_strlen($str)<$len){ + return [$str]; + } + $str_len = mb_strlen($str); + $count = ceil($str_len/$len); + $result = []; + for($x = 0; $x <= $count; $x++){ + $result[] =mb_substr($str,$len*$x,$len); + } + return $result; + } +} diff --git a/controllers/api/user/Active.php b/controllers/api/user/Active.php new file mode 100644 index 0000000..426720b --- /dev/null +++ b/controllers/api/user/Active.php @@ -0,0 +1,739 @@ +load->library('session'); + $this->load->model('series_number_model'); + $this->load->model('package_model'); + $this->load->model('sample_model'); + $this->load->model('customer_model'); + $this->checkUser(); + } + + public function ticket_get() + { + $conf = $this->config->item('weixin_uah'); + $config = [ + 'app_id' => $conf['AppId'], + 'secret' => $conf['AppSecert'], + 'token' => $conf['Token'], + 'aes_key' => $conf['EncodingAESKey'], + 'response_type' => 'array', + ]; + $app = new OfficialAccount($config); + $url = $this->input->get('url'); + if(!empty($url)){ + $app->js->setUrl($url); + }else + if(!empty($_SERVER['HTTP_REFERER'])){ + $app->js->setUrl($_SERVER['HTTP_REFERER']); + } + $config = $app->js->config(array('updateAppMessageShareData', 'updateTimelineShareData', 'scanQRCode'), $debug = false, $beta = false, $json = true); + $this->success(['config'=>json_decode($config)]); + } + + public function check_number_post() + { + $config = array( + array( + 'field' => 'device_id', + 'label' => '序列号', + 'rules' => 'trim|required|min_length[3]|max_length[20]' + ), + ); + $data = $this->json_validation($config); + $series = $this->series_number_model->get($data['device_id'],'device_id'); + if(!$series){ + $this->error('请联系【店铺】在线客服绑定序列号'); + } + $sample = $this->sample_model->get($series['id'],'series_id'); + if($sample){ + $this->error('序列号已使用'); + } + + $package = $this->package_model->get($series['package_ori']); + if(!$package){ + $this->error('序列号不可用,套餐信息不存在'); + } + + $content = empty($package['content'])?[]:json_decode($package['content'],true); + //获取所有疾病的名称 + if(!empty($content)){ + $disease_ids = []; + foreach ($content as $item) { + $disease_ids = array_merge($disease_ids,$item['disease_id']); + } + $this->load->model('disease_model'); + $disease_list = $this->disease_model->get($disease_ids,'base.id',true); + $disease_map = []; + foreach ($disease_list as $val) { + $disease_map[$val['id']] = $val; + } + //疾病详情存到信息中 + foreach ($content as $key=>$val) { + $val['disease_list'] = []; + foreach ($val['disease_id'] as $v) { + if(!isset($disease_map[$v])){ + continue; + } + $val['disease_list'][] = $disease_map[$v]; + } + $content[$key] = $val; + } + } + $package['content'] = $content; + $this->success(['package'=>$package]); + + } + + //新建样本 + public function create_post() + { + $config = array( + array( + 'field' => 'device_id', + 'label' => '序列号', + 'rules' => 'trim|required|min_length[4]|max_length[20]', + 'errors' => array( + 'required' => '请提供以下信息:%s.', + 'min_length' => '%s长度不足:%s.', + 'max_length' => '%s长度不能超过:%s.', + ), + ), + array( + 'field' => 'name', + 'label' => '用户姓名', + 'rules' => 'trim|required|min_length[1]|max_length[20]', + 'errors' => array( + 'required' => '请提供以下信息:%s.', + ), + ), + array( + 'field' => 'tel', + 'label' => '手机', + 'rules' => 'required', + 'errors' => array( + 'required' => '请提供以下信息:%s.', + ), + ), + array( + 'field' => 'pet_name', + 'label' => '宠物名称', + 'rules' => 'required', + 'errors' => array( + 'required' => '请提供以下信息:%s.', + ), + ), + array( + 'field' => 'pet_sex', + 'label' => '宠物性别', + 'rules' => 'required', + 'errors' => array( + 'required' => '请提供以下信息:%s.', + ), + ), + array( + 'field' => 'pet_birthday', + 'label' => '宠物生日', + 'rules' => 'required', + 'errors' => array( + 'required' => '请提供以下信息:%s.', + ), + ), + //繁育:芯片号 + array( + 'field' => 'chip_number', + 'label' => '芯片号', + 'rules' => 'trim', + 'errors' => array( + 'required' => '请提供以下信息:%s.', + ), + ), + //繁育:是否种猫 + array( + 'field' => 'is_breeding', + 'label' => '是否种猫', + 'rules' => 'trim', + 'errors' => array( + 'required' => '请提供以下信息:%s.', + ), + ), + //繁育:血统认证机构 + array( + 'field' => 'lineage_cert_body', + 'label' => '血统认证机构', + 'rules' => 'trim', + 'errors' => array( + 'required' => '请提供以下信息:%s.', + ), + ) + ); + $data = $this->json_validation($config); + $series = $this->series_number_model->get($data['device_id'],'device_id'); + if(!$series){ + $this->error('序列号不存在'); + } + $sample = $this->sample_model->get($series['id'],'series_id'); + if($sample){ + $this->error('序列号已使用'); + } + $package = $this->package_model->get($series['package_ori']); + if(!$package){ + $this->error('套餐不存在'); + } + + //过滤字段 + $fields = array_column($config,'field'); + $entity = []; + foreach ($data as $key=>$val) { + if(in_array($key,$fields)){ + $entity[$key] = $val; + } + } + unset($entity['device_id']); + + //套餐是否要求选择疾病 + $package['content'] = empty($package['content'])?[]:json_decode($package['content'],true); + //选择的疾病处理 + if(!empty($package['content'])){ + if(!isset($data['package_custom'])){ + $this->error('请选择套餐选项'); + } + //选择的选项是否允许选择 + if(!isset($package['content'][$data['package_custom']])){ + $this->error('您选择的套餐选项已失效'); + } + + $package_custom = $package['content'][$data['package_custom']]; + //获取疾病的名称,保存起来,以免id变化 + $this->load->model('disease_model'); + $tmp = $this->disease_model->get($package_custom['disease_id'],'base.id',true); + $entity['package_custom'] = json_encode([ + 'id'=>$data['package_custom'], + 'name'=>$package_custom['name'], + 'disease_id'=>$package_custom['disease_id'], + 'disease_name'=>array_column($tmp,'name') + ],JSON_UNESCAPED_UNICODE); + }else{ + $entity['package_custom'] = ''; + } + //用户id + $entity['user_id'] = $this->_user_id; + //从device_id读取序列号ID + $entity['series_id'] = $series['id']; + //套餐 + $entity['package_id'] = $series['package_ori']; + //套餐的猫狗写进样品,防止套餐变更造成影响 + $entity['pet_species'] = $package['species']; + //头像处理 + if(!empty($data['file']['content'])){ + $imgBase64 = $data['file']['content']; + + if(!empty($data['file']['ext'])){ + //对于java接口,需要兼容前端的格式 + $imgBase64 = 'data:image/'.trim($data['file']['ext']).';base64,'.$imgBase64; + } + + $this->load->library('uploads'); + //存原图 + $pet_img = $this->uploads->save_pet_img_base64( + $imgBase64, + $data['device_id'] + ); + if($pet_img){ + $entity['pet_img'] = $pet_img; + } + } + + //绝育情况,如果没有传入则按“否”处理 + if(empty($entity['is_sterilized'])){ + $entity['is_sterilized'] = 0; + } + + //处理宠物性别与绝育情况合并的情况(非繁育用户) + switch ($entity['pet_sex']){ + case 1: + $entity['pet_sex'] = 1; + break; + case 2: + $entity['pet_sex'] = 2; + break; + case 3: + $entity['pet_sex'] = 1; + $entity['is_sterilized'] = 1; + break; + case 4: + $entity['pet_sex'] = 2; + $entity['is_sterilized'] = 1; + break; + default: + $entity['pet_sex'] = 1; + } + + //步骤置为初始步骤 + $entity['step'] = Sample_model::STEP_BIND; + //发送微信通知 + $this->load->model('weixin_message_model'); + $user = $this->customer_model->get($this->_user_id); + $conf = $this->config->item('allowed_cors_origins'); + try{ + //如果没关注,会抛出错误,忽略 + $this->weixin_message_model->send( + $user['openid'], + Weixin_message_model::TEMPLATE_ACTIVE, + base_url().'weixin/?url='.urlencode($conf['user'].'/ship'), + [ + 'first'=>'激活成功,如您还没选择回寄,请点击回寄', + 'keyword1'=>$data['device_id'], + 'keyword2'=>$package['name'], + 'remark'=>'', + ] + ); + }catch (Exception $e){ + } + + //如果证书有多个,用逗号组合 + if(is_array($entity['lineage_cert_body'])){ + $entity['lineage_cert_body'] = implode(',',$entity['lineage_cert_body']); + } + + $ret = $this->sample_model->add($entity); + /* + //保存一条样品流程处理信息 + $this->load->model('sample_processing_model'); + $this->sample_processing_model->add([ + 'sample_id'=>$ret, + 'step'=>$entity['step'] + ]); + //保存一条样品套餐升级信息 + $this->load->model('sample_upgrade_model'); + $this->sample_upgrade_model->add([ + 'sample_id'=>$ret, + 'package_id'=>$entity['package_id'], + 'package_custom'=>$entity['package_custom'] + ]); + */ + if($ret){ + //激活了繁育套餐的客户,用户信息修改 + //if(!empty($package['is_breed'])){} + $this->success(); + }else{ + $this->error('提交失败'); + } + } + + //获取需回寄的样品 + public function ship_get() + { + $ret = $this->sample_model->get($this->_user_id,'user_id',true); + //只展示需回寄样品 + $un_ship = []; + foreach ($ret as $key=>$item) { + if($item['step'] < Sample_model::STEP_SENT){ + $un_ship[] = $ret[$key]; + } + } + $first = []; + //取第一个样品的信息 + if(!empty($un_ship)){ + $first = $un_ship[0]; + }elseif(!empty($ret)){ + $first = $ret[0]; + } + $this->success(['sample'=>$un_ship,'info'=>$first]); + } + + //样品回寄 + public function ship_post() + { + $config = array( + array( + 'field' => 'device_id[]', + 'label' => '样品', + 'rules' => 'trim|required|min_length[2]|max_length[20]', + 'errors' => array( + 'required' => '请提供以下信息:%s.', + ), + ), + array( + 'field' => 'name', + 'label' => '姓名', + 'rules' => 'trim|required|min_length[2]|max_length[20]', + 'errors' => array( + 'required' => '请提供以下信息:%s.', + ), + ), + array( + 'field' => 'tel', + 'label' => '手机号', + 'rules' => 'required' + ), + array( + 'field' => 'address', + 'label' => '地址', + 'rules' => 'required' + ), + array( + 'field' => 'province', + 'label' => '省', + 'rules' => 'required' + ), + array( + 'field' => 'city', + 'label' => '市', + 'rules' => 'required' + ), + array( + 'field' => 'district', + 'label' => '区', + 'rules' => 'required' + ) + ); + $receiver_address = array( + 'cat' => array( + 'd_province' => '广东省', + 'd_city' => '深圳市', + 'd_county' => '大鹏新区', + 'd_company' => '有哈科技', + 'd_contact' => '有哈收样组(侯佩彤)', + 'd_tel' => '13723470168', + 'd_address' => '大鹏街道鹏飞路7号中国农科院中国农业科学院深圳农业基因组研究所', + ), + 'dog' => array( + 'd_province' => '广东省', + 'd_city' => '深圳市', + 'd_county' => '大鹏新区', + 'd_company' => '有哈科技', + 'd_contact' => '有哈收样组(侯佩彤)', + 'd_tel' => '13723470168', + 'd_address' => '大鹏街道鹏飞路7号中国农科院中国农业科学院深圳农业基因组研究所', + ) + ); + $data = $this->json_validation($config); + $sample_ids = []; + $dog_cat = [false, false]; + $samples = array( + 'cat' => [], + 'cat_device_ids' =>[], + 'dog' => [], + 'dog_device_ids' =>[], + ); + foreach ($data['device_id'] as $device_id) { + $sample = $this->sample_model->get($device_id,'device_id'); + if($sample['user_id'] != $this->_user_id){ + $this->error('该样品不在您名下'); + } + if ($sample['pet_species'] == 1){ + $dog_cat[0] = true; + $samples['dog'][] = $sample['id']; + $samples['dog_device_ids'][] = $device_id; + }else if ($sample['pet_species'] == 2){ + $dog_cat[1] = true; + $samples['cat'][] = $sample['id']; + $samples['cat_device_ids'][] = $device_id; + } + $sample_ids[] = $sample['id']; + } + //创建订单 + $data['user_id'] = $this->_user_id; + $this->load->model('sf_express_model'); + if ($dog_cat[0] && $dog_cat[1]){ + // $this->error("ship -> dog: $dog_cat[0], cat: $dog_cat[1]"); + $data['d_province'] = $receiver_address['dog']['d_province']; + $data['d_city'] = $receiver_address['dog']['d_city']; + $data['d_county'] = $receiver_address['dog']['d_county']; + $data['d_company'] = $receiver_address['dog']['d_company']; + $data['d_contact'] = $receiver_address['dog']['d_contact']; + $data['d_tel'] = $receiver_address['dog']['d_tel']; + $data['d_address'] = $receiver_address['dog']['d_address']; + $data['trade_id'] = $samples['dog'][0]; + $ret = $this->sf_express_model->shipSample($data); + //$ret = [true]; + error_log("shipSample dog: $ret[0] $ret[1]"); + if($ret[0]){ + //快递id写到样品中 + $this->sample_model->update(['ship_order_id'=>$ret[1],'step'=>Sample_model::STEP_SENT],'id in ('.implode(',',$samples['dog']).')'); + try{ + //发送微信通知 + $this->load->model('weixin_message_model'); + $user = $this->customer_model->get($this->_user_id); + //如果没关系,会抛出错误,忽略 + $this->weixin_message_model->send( + $user['openid'], + Weixin_message_model::TEMPLATE_SENT, + null, + [ + 'first'=>'尊敬的用户:我们已为您分配了快递员,请保持手机畅通,快递员会尽快与您联系。', + 'keyword1'=>implode(',',$samples['dog_device_ids']), + //'keyword2'=>'上门取货后获取', + 'keyword2'=>$ret[1], + 'keyword3'=>'预估两小时内', + //'remark'=>'物流信息只能在中通官网查看,请保管好回寄单号方便日后物流查询。', + 'remark'=>'我们已为您呼叫了顺丰速运,请耐心等待。物流信息可在“顺丰速运”公众号查看。', + ] + ); + }catch (Exception $e){ + } + }else{ + if (strpos($ret[1], '您的预约超出今日营业时间') !== false){ + $this->error('快递营业时间:8-18点,现已超出今日营业时间,请于明日8点后进行预约取件。'); + }else{ + $this->error('快递未能使用,请添加微信号“uap_pet”咨询客服,错误信息:'.$ret[1]); + + } + } + sleep(1); + $data['d_province'] = $receiver_address['cat']['d_province']; + $data['d_city'] = $receiver_address['cat']['d_city']; + $data['d_county'] = $receiver_address['cat']['d_county']; + $data['d_company'] = $receiver_address['cat']['d_company']; + $data['d_contact'] = $receiver_address['cat']['d_contact']; + $data['d_tel'] = $receiver_address['cat']['d_tel']; + $data['d_address'] = $receiver_address['cat']['d_address']; + $data['trade_id'] = $samples['cat'][0]; + $ret = $this->sf_express_model->shipSample($data); + //$ret = [true]; + error_log("shipSample cat: $ret[0] $ret[1]"); + if($ret[0]){ + //快递id写到样品中 + $this->sample_model->update(['ship_order_id'=>$ret[1],'step'=>Sample_model::STEP_SENT],'id in ('.implode(',',$samples['dog']).')'); + try{ + //发送微信通知 + $this->load->model('weixin_message_model'); + $user = $this->customer_model->get($this->_user_id); + //如果没关系,会抛出错误,忽略 + $this->weixin_message_model->send( + $user['openid'], + Weixin_message_model::TEMPLATE_SENT, + null, + [ + 'first'=>'尊敬的用户:我们已为您分配了快递员,请保持手机畅通,快递员会尽快与您联系。', + 'keyword1'=>implode(',',$samples['cat_device_ids']), + //'keyword2'=>'上门取货后获取', + 'keyword2'=>$ret[1], + 'keyword3'=>'预估两小时内', + //'remark'=>'物流信息只能在中通官网查看,请保管好回寄单号方便日后物流查询。', + 'remark'=>'我们已为您呼叫了顺丰速运,请耐心等待。物流信息可在“顺丰速运”公众号查看。', + ] + ); + }catch (Exception $e){ + } + $this->success(); + }else{ + if (strpos($ret[1], '您的预约超出今日营业时间') !== false){ + $this->error('快递营业时间:8-18点,现已超出今日营业时间,请于明日8点后进行预约取件。'); + }else{ + $this->error('快递未能使用,请添加微信号“uap_pet”咨询客服,错误信息:'.$ret[1]); + + } + } + }else if ($dog_cat[1] || $dog_cat[0]){ + $data['trade_id'] = $data['device_id'][0]; + if ($dog_cat[0]){ + $data['d_province'] = $receiver_address['dog']['d_province']; + $data['d_city'] = $receiver_address['dog']['d_city']; + $data['d_county'] = $receiver_address['dog']['d_county']; + $data['d_company'] = $receiver_address['dog']['d_company']; + $data['d_contact'] = $receiver_address['dog']['d_contact']; + $data['d_tel'] = $receiver_address['dog']['d_tel']; + $data['d_address'] = $receiver_address['dog']['d_address']; + }else{ + $data['d_province'] = $receiver_address['cat']['d_province']; + $data['d_city'] = $receiver_address['cat']['d_city']; + $data['d_county'] = $receiver_address['cat']['d_county']; + $data['d_company'] = $receiver_address['cat']['d_company']; + $data['d_contact'] = $receiver_address['cat']['d_contact']; + $data['d_tel'] = $receiver_address['cat']['d_tel']; + $data['d_address'] = $receiver_address['cat']['d_address']; + } + $ret = $this->sf_express_model->shipSample($data); + //$ret = [true]; + if($ret[0]){ + //快递id写到样品中 + $this->sample_model->update(['ship_order_id'=>$ret[1],'step'=>Sample_model::STEP_SENT],'id in ('.implode(',',$sample_ids).')'); + try{ + //发送微信通知 + $this->load->model('weixin_message_model'); + $user = $this->customer_model->get($this->_user_id); + //如果没关系,会抛出错误,忽略 + $this->weixin_message_model->send( + $user['openid'], + Weixin_message_model::TEMPLATE_SENT, + null, + [ + 'first'=>'尊敬的用户:我们已为您分配了快递员,请保持手机畅通,快递员会尽快与您联系。', + 'keyword1'=>implode(',',$data['device_id']), + //'keyword2'=>'上门取货后获取', + 'keyword2'=>$ret[1], + 'keyword3'=>'预估两小时内', + //'remark'=>'物流信息只能在中通官网查看,请保管好回寄单号方便日后物流查询。', + 'remark'=>'我们已为您呼叫了顺丰速运,请耐心等待。物流信息可在“顺丰速运”公众号查看。', + ] + ); + }catch (Exception $e){ + } + $this->success(); + }else{ + if (strpos($ret[1], '您的预约超出今日营业时间') !== false){ + $this->error('快递营业时间:8-18点,现已超出今日营业时间,请于明日8点后进行预约取件。'); + }else{ + $this->error('快递未能使用,请添加微信号“uap_pet”咨询客服,错误信息:'.$ret[1]); + + } + } + } + /* + if($data['name'] == '有哈'){ + $this->load->model('sf_express_model'); + $ret = $this->sf_express_model->shipSample($data); + }else{ + $this->load->model('zto_model'); + $ret = $this->zto_model->shipSample($data); + }*/ + } + + //进度查询:样品列表 + public function list_get() + { + $ret = $this->sample_model->get($this->_user_id,'user_id',true); + $list = []; + if($ret)foreach ($ret as $item) { + //废弃的样品不呈现 + if($item['step'] == Sample_model::STEP_DISCARD){ + continue; + } + $item['step_fail'] = $item['step'] == Sample_model::STEP_UNQUALIFIED; + $list[] = $item; + } + $this->success($list); + } + + //进度查询:样品进度详情 + public function detail_get() + { + $config = array( + array( + 'field' => 'id', + 'label' => '样品ID', + 'rules' => 'trim|required|min_length[4]|max_length[20]' + ) + ); + $this->load->library('form_validation'); + $data = $this->input->get(); + $this->form_validation->set_data($data); + $this->form_validation->set_rules($config); + if ($this->form_validation->run() === FALSE) + { + $this->error('参数错误',$this->form_validation->error_array()); + } + $sample = $this->sample_model->get(trim($data['id']),'device_id'); + if($sample['user_id'] != $this->_user_id){ + $this->error('您没有权限查看该样品'); + } + if($sample['step'] == Sample_model::STEP_DISCARD){ + $this->error('该样品已作废'); + } + //获取摘要版的进度 + $steps = $this->sample_model->step_summary; + //当前进度 + $sample['step_desc'] = $steps[$sample['step']]; + //成功与失败状态不能同时存在 + $sample['step_fail'] = $sample['step'] == Sample_model::STEP_UNQUALIFIED; + if($sample['step_fail']){ + //隐藏成功项目 + unset($steps[Sample_model::STEP_DNA_EXTRACTED]); + }else{ + //隐藏失败项目 + unset($steps[Sample_model::STEP_UNQUALIFIED]); + } + //删除重复的进度 + $steps = array_keys(array_flip($steps)); + //当前在哪一个步骤 + $sample['step_active'] = array_search($sample['step_desc'],$steps); + $sample['step_active_fail'] = $sample['step_fail'] ? $sample['step_active'] : -1; + + //状态描述改成小描述 + $sample['step_desc'] = $this->sample_model->step[$sample['step']]; + //获取物流信息 + $track = []; + $this->load->model('zto_model'); + $ship_order = false; + //$ship_order = $this->zto_model->get(trim($sample['id']),'sample_id'); + if($ship_order){ + $track = $this->zto_model->traceInterfaceNewTraces($ship_order['order_code']); + } + $this->success([ + 'sample'=>$sample, + 'ship_order'=>$ship_order, + //步骤需要提醒 + 'error_step'=>Sample_model::STEP_UNQUALIFIED, + 'track'=>$track, + 'steps'=>$steps, + ]); + } + + //升级样品:获取可升级的套餐 + public function upgrade_post() + { + $config = array( + array( + 'field' => 'id', + 'label' => '样品ID', + 'rules' => 'trim|required|min_length[4]|max_length[20]' + ) + ); + $data = $this->json_validation($config); + $sample = $this->sample_model->get(trim($data['id']),'device_id'); + /* + if($sample['user_id'] != $this->_user_id){ + $this->error('您没有权限查看该样品'); + }*/ + //查询可升级套餐,即同物种的更高价格的套餐 + $packages = $this->package_model->get(trim($sample['pet_species']),'species',true); + $cur_package = null; + $up_packages = []; + foreach ($packages as $package) { + if($package['id'] == $sample['package_id']){ + $cur_package = $package; + }else{ + //只输出特定信息给用户前端 + $up_packages[] = [ + 'id'=>$package['id'], + 'name'=>$package['name'], + 'description'=>$package['description'], + 'price'=>$package['price'] + ]; + } + } + if(is_null($cur_package)){ + $this->error('样品原套餐信息丢失,暂不可升级'); + } + //过滤比当前套餐价格低的套餐 + foreach ($up_packages as $key=> $package) { + if($package['price'] <= $cur_package['price']){ + unset($up_packages[$key]); + continue; + } + //输出升级差价 + $up_packages[$key]['balance'] = round($package['price'] - $cur_package['price'],2); + } + if(empty($up_packages)){ + $this->success(); + } + //按照价格从低到高排序 + array_multisort(array_column($up_packages,'price'),SORT_DESC,$up_packages); + $this->success(['packages'=>$up_packages]); + } + + public function test_get(){ + $this->load->library('uploads'); + echo $this->uploads->get_upload_path(); + } + +} diff --git a/controllers/api/user/Active.php.20240424 b/controllers/api/user/Active.php.20240424 new file mode 100644 index 0000000..75b76eb --- /dev/null +++ b/controllers/api/user/Active.php.20240424 @@ -0,0 +1,590 @@ +load->library('session'); + $this->load->model('series_number_model'); + $this->load->model('package_model'); + $this->load->model('sample_model'); + $this->load->model('customer_model'); + $this->checkUser(); + } + + public function ticket_get() + { + $conf = $this->config->item('weixin_uah'); + $config = [ + 'app_id' => $conf['AppId'], + 'secret' => $conf['AppSecert'], + 'token' => $conf['Token'], + 'aes_key' => $conf['EncodingAESKey'], + 'response_type' => 'array', + ]; + $app = new OfficialAccount($config); + $url = $this->input->get('url'); + if(!empty($url)){ + $app->js->setUrl($url); + }else + if(!empty($_SERVER['HTTP_REFERER'])){ + $app->js->setUrl($_SERVER['HTTP_REFERER']); + } + $config = $app->js->config(array('updateAppMessageShareData', 'updateTimelineShareData', 'scanQRCode'), $debug = false, $beta = false, $json = true); + $this->success(['config'=>json_decode($config)]); + } + + public function check_number_post() + { + $config = array( + array( + 'field' => 'device_id', + 'label' => '序列号', + 'rules' => 'trim|required|min_length[3]|max_length[20]' + ), + ); + $data = $this->json_validation($config); + $series = $this->series_number_model->get($data['device_id'],'device_id'); + if(!$series){ + $this->error('序列号不存在'); + } + $sample = $this->sample_model->get($series['id'],'series_id'); + if($sample){ + $this->error('序列号已使用'); + } + + $package = $this->package_model->get($series['package_ori']); + if(!$package){ + $this->error('序列号不可用,套餐信息不存在'); + } + + $content = empty($package['content'])?[]:json_decode($package['content'],true); + //获取所有疾病的名称 + if(!empty($content)){ + $disease_ids = []; + foreach ($content as $item) { + $disease_ids = array_merge($disease_ids,$item['disease_id']); + } + $this->load->model('disease_model'); + $disease_list = $this->disease_model->get($disease_ids,'base.id',true); + $disease_map = []; + foreach ($disease_list as $val) { + $disease_map[$val['id']] = $val; + } + //疾病详情存到信息中 + foreach ($content as $key=>$val) { + $val['disease_list'] = []; + foreach ($val['disease_id'] as $v) { + if(!isset($disease_map[$v])){ + continue; + } + $val['disease_list'][] = $disease_map[$v]; + } + $content[$key] = $val; + } + } + $package['content'] = $content; + $this->success(['package'=>$package]); + + } + + //新建样本 + public function create_post() + { + $config = array( + array( + 'field' => 'device_id', + 'label' => '序列号', + 'rules' => 'trim|required|min_length[4]|max_length[20]', + 'errors' => array( + 'required' => '请提供以下信息:%s.', + 'min_length' => '%s长度不足:%s.', + 'max_length' => '%s长度不能超过:%s.', + ), + ), + array( + 'field' => 'name', + 'label' => '用户姓名', + 'rules' => 'trim|required|min_length[1]|max_length[20]', + 'errors' => array( + 'required' => '请提供以下信息:%s.', + ), + ), + array( + 'field' => 'tel', + 'label' => '手机', + 'rules' => 'required', + 'errors' => array( + 'required' => '请提供以下信息:%s.', + ), + ), + array( + 'field' => 'pet_name', + 'label' => '宠物名称', + 'rules' => 'required', + 'errors' => array( + 'required' => '请提供以下信息:%s.', + ), + ), + array( + 'field' => 'pet_sex', + 'label' => '宠物性别', + 'rules' => 'required', + 'errors' => array( + 'required' => '请提供以下信息:%s.', + ), + ), + array( + 'field' => 'pet_birthday', + 'label' => '宠物生日', + 'rules' => 'required', + 'errors' => array( + 'required' => '请提供以下信息:%s.', + ), + ), + //繁育:芯片号 + array( + 'field' => 'chip_number', + 'label' => '芯片号', + 'rules' => 'trim', + 'errors' => array( + 'required' => '请提供以下信息:%s.', + ), + ), + //繁育:是否种猫 + array( + 'field' => 'is_breeding', + 'label' => '是否种猫', + 'rules' => 'trim', + 'errors' => array( + 'required' => '请提供以下信息:%s.', + ), + ), + //繁育:血统认证机构 + array( + 'field' => 'lineage_cert_body', + 'label' => '血统认证机构', + 'rules' => 'trim', + 'errors' => array( + 'required' => '请提供以下信息:%s.', + ), + ) + ); + $data = $this->json_validation($config); + $series = $this->series_number_model->get($data['device_id'],'device_id'); + if(!$series){ + $this->error('序列号不存在'); + } + $sample = $this->sample_model->get($series['id'],'series_id'); + if($sample){ + $this->error('序列号已使用'); + } + $package = $this->package_model->get($series['package_ori']); + if(!$package){ + $this->error('套餐不存在'); + } + + //过滤字段 + $fields = array_column($config,'field'); + $entity = []; + foreach ($data as $key=>$val) { + if(in_array($key,$fields)){ + $entity[$key] = $val; + } + } + unset($entity['device_id']); + + //套餐是否要求选择疾病 + $package['content'] = empty($package['content'])?[]:json_decode($package['content'],true); + //选择的疾病处理 + if(!empty($package['content'])){ + if(!isset($data['package_custom'])){ + $this->error('请选择套餐选项'); + } + //选择的选项是否允许选择 + if(!isset($package['content'][$data['package_custom']])){ + $this->error('您选择的套餐选项已失效'); + } + + $package_custom = $package['content'][$data['package_custom']]; + //获取疾病的名称,保存起来,以免id变化 + $this->load->model('disease_model'); + $tmp = $this->disease_model->get($package_custom['disease_id'],'base.id',true); + $entity['package_custom'] = json_encode([ + 'id'=>$data['package_custom'], + 'name'=>$package_custom['name'], + 'disease_id'=>$package_custom['disease_id'], + 'disease_name'=>array_column($tmp,'name') + ],JSON_UNESCAPED_UNICODE); + }else{ + $entity['package_custom'] = ''; + } + //用户id + $entity['user_id'] = $this->_user_id; + //从device_id读取序列号ID + $entity['series_id'] = $series['id']; + //套餐 + $entity['package_id'] = $series['package_ori']; + //套餐的猫狗写进样品,防止套餐变更造成影响 + $entity['pet_species'] = $package['species']; + //头像处理 + if(!empty($data['file']['content'])){ + $imgBase64 = $data['file']['content']; + + if(!empty($data['file']['ext'])){ + //对于java接口,需要兼容前端的格式 + $imgBase64 = 'data:image/'.trim($data['file']['ext']).';base64,'.$imgBase64; + } + + $this->load->library('uploads'); + //存原图 + $pet_img = $this->uploads->save_pet_img_base64( + $imgBase64, + $data['device_id'] + ); + if($pet_img){ + $entity['pet_img'] = $pet_img; + } + } + + //绝育情况,如果没有传入则按“否”处理 + if(empty($entity['is_sterilized'])){ + $entity['is_sterilized'] = 0; + } + + //处理宠物性别与绝育情况合并的情况(非繁育用户) + switch ($entity['pet_sex']){ + case 1: + $entity['pet_sex'] = 1; + break; + case 2: + $entity['pet_sex'] = 2; + break; + case 3: + $entity['pet_sex'] = 1; + $entity['is_sterilized'] = 1; + break; + case 4: + $entity['pet_sex'] = 2; + $entity['is_sterilized'] = 1; + break; + default: + $entity['pet_sex'] = 1; + } + + //步骤置为初始步骤 + $entity['step'] = Sample_model::STEP_BIND; + //发送微信通知 + $this->load->model('weixin_message_model'); + $user = $this->customer_model->get($this->_user_id); + $conf = $this->config->item('allowed_cors_origins'); + try{ + //如果没关注,会抛出错误,忽略 + $this->weixin_message_model->send( + $user['openid'], + Weixin_message_model::TEMPLATE_ACTIVE, + base_url().'weixin/?url='.urlencode($conf['user'].'/ship'), + [ + 'first'=>'激活成功,如您还没选择回寄,请点击回寄', + 'keyword1'=>$data['device_id'], + 'keyword2'=>$package['name'], + 'remark'=>'', + ] + ); + }catch (Exception $e){ + } + + //如果证书有多个,用逗号组合 + if(is_array($entity['lineage_cert_body'])){ + $entity['lineage_cert_body'] = implode(',',$entity['lineage_cert_body']); + } + + $ret = $this->sample_model->add($entity); + /* + //保存一条样品流程处理信息 + $this->load->model('sample_processing_model'); + $this->sample_processing_model->add([ + 'sample_id'=>$ret, + 'step'=>$entity['step'] + ]); + //保存一条样品套餐升级信息 + $this->load->model('sample_upgrade_model'); + $this->sample_upgrade_model->add([ + 'sample_id'=>$ret, + 'package_id'=>$entity['package_id'], + 'package_custom'=>$entity['package_custom'] + ]); + */ + if($ret){ + //激活了繁育套餐的客户,用户信息修改 + //if(!empty($package['is_breed'])){} + $this->success(); + }else{ + $this->error('提交失败'); + } + } + + //获取需回寄的样品 + public function ship_get() + { + $ret = $this->sample_model->get($this->_user_id,'user_id',true); + //只展示需回寄样品 + $un_ship = []; + foreach ($ret as $key=>$item) { + if($item['step'] < Sample_model::STEP_SENT){ + $un_ship[] = $ret[$key]; + } + } + $first = []; + //取第一个样品的信息 + if(!empty($un_ship)){ + $first = $un_ship[0]; + }elseif(!empty($ret)){ + $first = $ret[0]; + } + $this->success(['sample'=>$un_ship,'info'=>$first]); + } + + //样品回寄 + public function ship_post() + { + $config = array( + array( + 'field' => 'device_id[]', + 'label' => '样品', + 'rules' => 'trim|required|min_length[2]|max_length[20]', + 'errors' => array( + 'required' => '请提供以下信息:%s.', + ), + ), + array( + 'field' => 'name', + 'label' => '姓名', + 'rules' => 'trim|required|min_length[2]|max_length[20]', + 'errors' => array( + 'required' => '请提供以下信息:%s.', + ), + ), + array( + 'field' => 'tel', + 'label' => '手机号', + 'rules' => 'required' + ), + array( + 'field' => 'address', + 'label' => '地址', + 'rules' => 'required' + ), + array( + 'field' => 'province', + 'label' => '省', + 'rules' => 'required' + ), + array( + 'field' => 'city', + 'label' => '市', + 'rules' => 'required' + ), + array( + 'field' => 'district', + 'label' => '区', + 'rules' => 'required' + ) + ); + $data = $this->json_validation($config); + $sample_ids = []; + foreach ($data['device_id'] as $device_id) { + $sample = $this->sample_model->get($device_id,'device_id'); + if($sample['user_id'] != $this->_user_id){ + $this->error('该样品不在您名下'); + } + $sample_ids[] = $sample['id']; + } + + //创建订单 + $data['user_id'] = $this->_user_id; + $data['trade_id'] = $data['device_id'][0]; + /* + if($data['name'] == '有哈'){ + $this->load->model('sf_express_model'); + $ret = $this->sf_express_model->shipSample($data); + }else{ + $this->load->model('zto_model'); + $ret = $this->zto_model->shipSample($data); + }*/ + $this->load->model('sf_express_model'); + $ret = $this->sf_express_model->shipSample($data); + //$ret = [true]; + if($ret[0]){ + //快递id写到样品中 + $this->sample_model->update(['ship_order_id'=>$ret[1],'step'=>Sample_model::STEP_SENT],'id in ('.implode(',',$sample_ids).')'); + try{ + //发送微信通知 + $this->load->model('weixin_message_model'); + $user = $this->customer_model->get($this->_user_id); + //如果没关系,会抛出错误,忽略 + $this->weixin_message_model->send( + $user['openid'], + Weixin_message_model::TEMPLATE_SENT, + null, + [ + 'first'=>'尊敬的用户:我们已为您分配了快递员,请保持手机畅通,快递员会尽快与您联系。', + 'keyword1'=>implode(',',$data['device_id']), + //'keyword2'=>'上门取货后获取', + 'keyword2'=>$ret[1], + 'keyword3'=>'预估两小时内', + //'remark'=>'物流信息只能在中通官网查看,请保管好回寄单号方便日后物流查询。', + 'remark'=>'我们已为您呼叫了顺丰速运,请耐心等待。物流信息可在“顺丰速运”公众号查看。', + ] + ); + }catch (Exception $e){ + } + $this->success(); + }else{ + $this->error('快递未能使用,请添加微信号“uap_pet”咨询客服,错误信息:'.$ret[1]); + } + } + + //进度查询:样品列表 + public function list_get() + { + $ret = $this->sample_model->get($this->_user_id,'user_id',true); + $list = []; + if($ret)foreach ($ret as $item) { + //废弃的样品不呈现 + if($item['step'] == Sample_model::STEP_DISCARD){ + continue; + } + $item['step_fail'] = $item['step'] == Sample_model::STEP_UNQUALIFIED; + $list[] = $item; + } + $this->success($list); + } + + //进度查询:样品进度详情 + public function detail_get() + { + $config = array( + array( + 'field' => 'id', + 'label' => '样品ID', + 'rules' => 'trim|required|min_length[4]|max_length[20]' + ) + ); + $this->load->library('form_validation'); + $data = $this->input->get(); + $this->form_validation->set_data($data); + $this->form_validation->set_rules($config); + if ($this->form_validation->run() === FALSE) + { + $this->error('参数错误',$this->form_validation->error_array()); + } + $sample = $this->sample_model->get(trim($data['id']),'device_id'); + if($sample['user_id'] != $this->_user_id){ + $this->error('您没有权限查看该样品'); + } + if($sample['step'] == Sample_model::STEP_DISCARD){ + $this->error('该样品已作废'); + } + //获取摘要版的进度 + $steps = $this->sample_model->step_summary; + //当前进度 + $sample['step_desc'] = $steps[$sample['step']]; + //成功与失败状态不能同时存在 + $sample['step_fail'] = $sample['step'] == Sample_model::STEP_UNQUALIFIED; + if($sample['step_fail']){ + //隐藏成功项目 + unset($steps[Sample_model::STEP_DNA_EXTRACTED]); + }else{ + //隐藏失败项目 + unset($steps[Sample_model::STEP_UNQUALIFIED]); + } + //删除重复的进度 + $steps = array_keys(array_flip($steps)); + //当前在哪一个步骤 + $sample['step_active'] = array_search($sample['step_desc'],$steps); + $sample['step_active_fail'] = $sample['step_fail'] ? $sample['step_active'] : -1; + + //状态描述改成小描述 + $sample['step_desc'] = $this->sample_model->step[$sample['step']]; + //获取物流信息 + $track = []; + $this->load->model('zto_model'); + $ship_order = false; + //$ship_order = $this->zto_model->get(trim($sample['id']),'sample_id'); + if($ship_order){ + $track = $this->zto_model->traceInterfaceNewTraces($ship_order['order_code']); + } + $this->success([ + 'sample'=>$sample, + 'ship_order'=>$ship_order, + //步骤需要提醒 + 'error_step'=>Sample_model::STEP_UNQUALIFIED, + 'track'=>$track, + 'steps'=>$steps, + ]); + } + + //升级样品:获取可升级的套餐 + public function upgrade_post() + { + $config = array( + array( + 'field' => 'id', + 'label' => '样品ID', + 'rules' => 'trim|required|min_length[4]|max_length[20]' + ) + ); + $data = $this->json_validation($config); + $sample = $this->sample_model->get(trim($data['id']),'device_id'); + /* + if($sample['user_id'] != $this->_user_id){ + $this->error('您没有权限查看该样品'); + }*/ + //查询可升级套餐,即同物种的更高价格的套餐 + $packages = $this->package_model->get(trim($sample['pet_species']),'species',true); + $cur_package = null; + $up_packages = []; + foreach ($packages as $package) { + if($package['id'] == $sample['package_id']){ + $cur_package = $package; + }else{ + //只输出特定信息给用户前端 + $up_packages[] = [ + 'id'=>$package['id'], + 'name'=>$package['name'], + 'description'=>$package['description'], + 'price'=>$package['price'] + ]; + } + } + if(is_null($cur_package)){ + $this->error('样品原套餐信息丢失,暂不可升级'); + } + //过滤比当前套餐价格低的套餐 + foreach ($up_packages as $key=> $package) { + if($package['price'] <= $cur_package['price']){ + unset($up_packages[$key]); + continue; + } + //输出升级差价 + $up_packages[$key]['balance'] = round($package['price'] - $cur_package['price'],2); + } + if(empty($up_packages)){ + $this->success(); + } + //按照价格从低到高排序 + array_multisort(array_column($up_packages,'price'),SORT_DESC,$up_packages); + $this->success(['packages'=>$up_packages]); + } + + public function test_get(){ + $this->load->library('uploads'); + echo $this->uploads->get_upload_path(); + } + +} diff --git a/controllers/api/user/Active.php.20240514 b/controllers/api/user/Active.php.20240514 new file mode 100644 index 0000000..ecab924 --- /dev/null +++ b/controllers/api/user/Active.php.20240514 @@ -0,0 +1,724 @@ +load->library('session'); + $this->load->model('series_number_model'); + $this->load->model('package_model'); + $this->load->model('sample_model'); + $this->load->model('customer_model'); + $this->checkUser(); + } + + public function ticket_get() + { + $conf = $this->config->item('weixin_uah'); + $config = [ + 'app_id' => $conf['AppId'], + 'secret' => $conf['AppSecert'], + 'token' => $conf['Token'], + 'aes_key' => $conf['EncodingAESKey'], + 'response_type' => 'array', + ]; + $app = new OfficialAccount($config); + $url = $this->input->get('url'); + if(!empty($url)){ + $app->js->setUrl($url); + }else + if(!empty($_SERVER['HTTP_REFERER'])){ + $app->js->setUrl($_SERVER['HTTP_REFERER']); + } + $config = $app->js->config(array('updateAppMessageShareData', 'updateTimelineShareData', 'scanQRCode'), $debug = false, $beta = false, $json = true); + $this->success(['config'=>json_decode($config)]); + } + + public function check_number_post() + { + $config = array( + array( + 'field' => 'device_id', + 'label' => '序列号', + 'rules' => 'trim|required|min_length[3]|max_length[20]' + ), + ); + $data = $this->json_validation($config); + $series = $this->series_number_model->get($data['device_id'],'device_id'); + if(!$series){ + $this->error('序列号不存在'); + } + $sample = $this->sample_model->get($series['id'],'series_id'); + if($sample){ + $this->error('序列号已使用'); + } + + $package = $this->package_model->get($series['package_ori']); + if(!$package){ + $this->error('序列号不可用,套餐信息不存在'); + } + + $content = empty($package['content'])?[]:json_decode($package['content'],true); + //获取所有疾病的名称 + if(!empty($content)){ + $disease_ids = []; + foreach ($content as $item) { + $disease_ids = array_merge($disease_ids,$item['disease_id']); + } + $this->load->model('disease_model'); + $disease_list = $this->disease_model->get($disease_ids,'base.id',true); + $disease_map = []; + foreach ($disease_list as $val) { + $disease_map[$val['id']] = $val; + } + //疾病详情存到信息中 + foreach ($content as $key=>$val) { + $val['disease_list'] = []; + foreach ($val['disease_id'] as $v) { + if(!isset($disease_map[$v])){ + continue; + } + $val['disease_list'][] = $disease_map[$v]; + } + $content[$key] = $val; + } + } + $package['content'] = $content; + $this->success(['package'=>$package]); + + } + + //新建样本 + public function create_post() + { + $config = array( + array( + 'field' => 'device_id', + 'label' => '序列号', + 'rules' => 'trim|required|min_length[4]|max_length[20]', + 'errors' => array( + 'required' => '请提供以下信息:%s.', + 'min_length' => '%s长度不足:%s.', + 'max_length' => '%s长度不能超过:%s.', + ), + ), + array( + 'field' => 'name', + 'label' => '用户姓名', + 'rules' => 'trim|required|min_length[1]|max_length[20]', + 'errors' => array( + 'required' => '请提供以下信息:%s.', + ), + ), + array( + 'field' => 'tel', + 'label' => '手机', + 'rules' => 'required', + 'errors' => array( + 'required' => '请提供以下信息:%s.', + ), + ), + array( + 'field' => 'pet_name', + 'label' => '宠物名称', + 'rules' => 'required', + 'errors' => array( + 'required' => '请提供以下信息:%s.', + ), + ), + array( + 'field' => 'pet_sex', + 'label' => '宠物性别', + 'rules' => 'required', + 'errors' => array( + 'required' => '请提供以下信息:%s.', + ), + ), + array( + 'field' => 'pet_birthday', + 'label' => '宠物生日', + 'rules' => 'required', + 'errors' => array( + 'required' => '请提供以下信息:%s.', + ), + ), + //繁育:芯片号 + array( + 'field' => 'chip_number', + 'label' => '芯片号', + 'rules' => 'trim', + 'errors' => array( + 'required' => '请提供以下信息:%s.', + ), + ), + //繁育:是否种猫 + array( + 'field' => 'is_breeding', + 'label' => '是否种猫', + 'rules' => 'trim', + 'errors' => array( + 'required' => '请提供以下信息:%s.', + ), + ), + //繁育:血统认证机构 + array( + 'field' => 'lineage_cert_body', + 'label' => '血统认证机构', + 'rules' => 'trim', + 'errors' => array( + 'required' => '请提供以下信息:%s.', + ), + ) + ); + $data = $this->json_validation($config); + $series = $this->series_number_model->get($data['device_id'],'device_id'); + if(!$series){ + $this->error('序列号不存在'); + } + $sample = $this->sample_model->get($series['id'],'series_id'); + if($sample){ + $this->error('序列号已使用'); + } + $package = $this->package_model->get($series['package_ori']); + if(!$package){ + $this->error('套餐不存在'); + } + + //过滤字段 + $fields = array_column($config,'field'); + $entity = []; + foreach ($data as $key=>$val) { + if(in_array($key,$fields)){ + $entity[$key] = $val; + } + } + unset($entity['device_id']); + + //套餐是否要求选择疾病 + $package['content'] = empty($package['content'])?[]:json_decode($package['content'],true); + //选择的疾病处理 + if(!empty($package['content'])){ + if(!isset($data['package_custom'])){ + $this->error('请选择套餐选项'); + } + //选择的选项是否允许选择 + if(!isset($package['content'][$data['package_custom']])){ + $this->error('您选择的套餐选项已失效'); + } + + $package_custom = $package['content'][$data['package_custom']]; + //获取疾病的名称,保存起来,以免id变化 + $this->load->model('disease_model'); + $tmp = $this->disease_model->get($package_custom['disease_id'],'base.id',true); + $entity['package_custom'] = json_encode([ + 'id'=>$data['package_custom'], + 'name'=>$package_custom['name'], + 'disease_id'=>$package_custom['disease_id'], + 'disease_name'=>array_column($tmp,'name') + ],JSON_UNESCAPED_UNICODE); + }else{ + $entity['package_custom'] = ''; + } + //用户id + $entity['user_id'] = $this->_user_id; + //从device_id读取序列号ID + $entity['series_id'] = $series['id']; + //套餐 + $entity['package_id'] = $series['package_ori']; + //套餐的猫狗写进样品,防止套餐变更造成影响 + $entity['pet_species'] = $package['species']; + //头像处理 + if(!empty($data['file']['content'])){ + $imgBase64 = $data['file']['content']; + + if(!empty($data['file']['ext'])){ + //对于java接口,需要兼容前端的格式 + $imgBase64 = 'data:image/'.trim($data['file']['ext']).';base64,'.$imgBase64; + } + + $this->load->library('uploads'); + //存原图 + $pet_img = $this->uploads->save_pet_img_base64( + $imgBase64, + $data['device_id'] + ); + if($pet_img){ + $entity['pet_img'] = $pet_img; + } + } + + //绝育情况,如果没有传入则按“否”处理 + if(empty($entity['is_sterilized'])){ + $entity['is_sterilized'] = 0; + } + + //处理宠物性别与绝育情况合并的情况(非繁育用户) + switch ($entity['pet_sex']){ + case 1: + $entity['pet_sex'] = 1; + break; + case 2: + $entity['pet_sex'] = 2; + break; + case 3: + $entity['pet_sex'] = 1; + $entity['is_sterilized'] = 1; + break; + case 4: + $entity['pet_sex'] = 2; + $entity['is_sterilized'] = 1; + break; + default: + $entity['pet_sex'] = 1; + } + + //步骤置为初始步骤 + $entity['step'] = Sample_model::STEP_BIND; + //发送微信通知 + $this->load->model('weixin_message_model'); + $user = $this->customer_model->get($this->_user_id); + $conf = $this->config->item('allowed_cors_origins'); + try{ + //如果没关注,会抛出错误,忽略 + $this->weixin_message_model->send( + $user['openid'], + Weixin_message_model::TEMPLATE_ACTIVE, + base_url().'weixin/?url='.urlencode($conf['user'].'/ship'), + [ + 'first'=>'激活成功,如您还没选择回寄,请点击回寄', + 'keyword1'=>$data['device_id'], + 'keyword2'=>$package['name'], + 'remark'=>'', + ] + ); + }catch (Exception $e){ + } + + //如果证书有多个,用逗号组合 + if(is_array($entity['lineage_cert_body'])){ + $entity['lineage_cert_body'] = implode(',',$entity['lineage_cert_body']); + } + + $ret = $this->sample_model->add($entity); + /* + //保存一条样品流程处理信息 + $this->load->model('sample_processing_model'); + $this->sample_processing_model->add([ + 'sample_id'=>$ret, + 'step'=>$entity['step'] + ]); + //保存一条样品套餐升级信息 + $this->load->model('sample_upgrade_model'); + $this->sample_upgrade_model->add([ + 'sample_id'=>$ret, + 'package_id'=>$entity['package_id'], + 'package_custom'=>$entity['package_custom'] + ]); + */ + if($ret){ + //激活了繁育套餐的客户,用户信息修改 + //if(!empty($package['is_breed'])){} + $this->success(); + }else{ + $this->error('提交失败'); + } + } + + //获取需回寄的样品 + public function ship_get() + { + $ret = $this->sample_model->get($this->_user_id,'user_id',true); + //只展示需回寄样品 + $un_ship = []; + foreach ($ret as $key=>$item) { + if($item['step'] < Sample_model::STEP_SENT){ + $un_ship[] = $ret[$key]; + } + } + $first = []; + //取第一个样品的信息 + if(!empty($un_ship)){ + $first = $un_ship[0]; + }elseif(!empty($ret)){ + $first = $ret[0]; + } + $this->success(['sample'=>$un_ship,'info'=>$first]); + } + + //样品回寄 + public function ship_post() + { + $config = array( + array( + 'field' => 'device_id[]', + 'label' => '样品', + 'rules' => 'trim|required|min_length[2]|max_length[20]', + 'errors' => array( + 'required' => '请提供以下信息:%s.', + ), + ), + array( + 'field' => 'name', + 'label' => '姓名', + 'rules' => 'trim|required|min_length[2]|max_length[20]', + 'errors' => array( + 'required' => '请提供以下信息:%s.', + ), + ), + array( + 'field' => 'tel', + 'label' => '手机号', + 'rules' => 'required' + ), + array( + 'field' => 'address', + 'label' => '地址', + 'rules' => 'required' + ), + array( + 'field' => 'province', + 'label' => '省', + 'rules' => 'required' + ), + array( + 'field' => 'city', + 'label' => '市', + 'rules' => 'required' + ), + array( + 'field' => 'district', + 'label' => '区', + 'rules' => 'required' + ) + ); + $receiver_address = array( + 'cat' => array( + 'd_province' => '广东省', + 'd_city' => '深圳市', + 'd_county' => '龙岗区', + 'd_company' => '有哈科技', + 'd_contact' => '有哈收样组(猫)王先生', + 'd_tel' => '17596551135', + 'd_address' => '大鹏新区布新路97号农科院基因组所A栋', + ), + 'dog' => array( + 'd_province' => '江苏省', + 'd_city' => '南京市', + 'd_county' => '浦口区', + 'd_company' => '有哈科技', + 'd_contact' => '有哈收样组(犬)', + 'd_tel' => '17751784617', + 'd_address' => '行知路8号南京农创中心方舟实验室C栋南楼3层', + ) + ); + $data = $this->json_validation($config); + $sample_ids = []; + $dog_cat = [false, false]; + $samples = array( + 'cat' => [], + 'cat_device_ids' =>[], + 'dog' => [], + 'dog_device_ids' =>[], + ); + foreach ($data['device_id'] as $device_id) { + $sample = $this->sample_model->get($device_id,'device_id'); + if($sample['user_id'] != $this->_user_id){ + $this->error('该样品不在您名下'); + } + if ($sample['pet_species'] == 1){ + $dog_cat[0] = true; + $samples['dog'][] = $sample['id']; + $samples['dog_device_ids'][] = $device_id; + }else if ($sample['pet_species'] == 2){ + $dog_cat[1] = true; + $samples['cat'][] = $sample['id']; + $samples['cat_device_ids'][] = $device_id; + } + $sample_ids[] = $sample['id']; + } + //创建订单 + $data['user_id'] = $this->_user_id; + $this->load->model('sf_express_model'); + if ($dog_cat[0] && $dog_cat[1]){ + // $this->error("ship -> dog: $dog_cat[0], cat: $dog_cat[1]"); + $data['d_province'] = $receiver_address['dog']['d_province']; + $data['d_city'] = $receiver_address['dog']['d_city']; + $data['d_county'] = $receiver_address['dog']['d_county']; + $data['d_company'] = $receiver_address['dog']['d_company']; + $data['d_contact'] = $receiver_address['dog']['d_contact']; + $data['d_tel'] = $receiver_address['dog']['d_tel']; + $data['d_address'] = $receiver_address['dog']['d_address']; + $data['trade_id'] = $samples['dog'][0]; + $ret = $this->sf_express_model->shipSample($data); + //$ret = [true]; + error_log("shipSample dog: $ret[0] $ret[1]"); + if($ret[0]){ + //快递id写到样品中 + $this->sample_model->update(['ship_order_id'=>$ret[1],'step'=>Sample_model::STEP_SENT],'id in ('.implode(',',$samples['dog']).')'); + try{ + //发送微信通知 + $this->load->model('weixin_message_model'); + $user = $this->customer_model->get($this->_user_id); + //如果没关系,会抛出错误,忽略 + $this->weixin_message_model->send( + $user['openid'], + Weixin_message_model::TEMPLATE_SENT, + null, + [ + 'first'=>'尊敬的用户:我们已为您分配了快递员,请保持手机畅通,快递员会尽快与您联系。', + 'keyword1'=>implode(',',$samples['dog_device_ids']), + //'keyword2'=>'上门取货后获取', + 'keyword2'=>$ret[1], + 'keyword3'=>'预估两小时内', + //'remark'=>'物流信息只能在中通官网查看,请保管好回寄单号方便日后物流查询。', + 'remark'=>'我们已为您呼叫了顺丰速运,请耐心等待。物流信息可在“顺丰速运”公众号查看。', + ] + ); + }catch (Exception $e){ + } + }else{ + $this->error('快递未能使用,请添加微信号“uap_pet”咨询客服,错误信息:'.$ret[1]); + } + sleep(1); + $data['d_province'] = $receiver_address['cat']['d_province']; + $data['d_city'] = $receiver_address['cat']['d_city']; + $data['d_county'] = $receiver_address['cat']['d_county']; + $data['d_company'] = $receiver_address['cat']['d_company']; + $data['d_contact'] = $receiver_address['cat']['d_contact']; + $data['d_tel'] = $receiver_address['cat']['d_tel']; + $data['d_address'] = $receiver_address['cat']['d_address']; + $data['trade_id'] = $samples['cat'][0]; + $ret = $this->sf_express_model->shipSample($data); + //$ret = [true]; + error_log("shipSample cat: $ret[0] $ret[1]"); + if($ret[0]){ + //快递id写到样品中 + $this->sample_model->update(['ship_order_id'=>$ret[1],'step'=>Sample_model::STEP_SENT],'id in ('.implode(',',$samples['dog']).')'); + try{ + //发送微信通知 + $this->load->model('weixin_message_model'); + $user = $this->customer_model->get($this->_user_id); + //如果没关系,会抛出错误,忽略 + $this->weixin_message_model->send( + $user['openid'], + Weixin_message_model::TEMPLATE_SENT, + null, + [ + 'first'=>'尊敬的用户:我们已为您分配了快递员,请保持手机畅通,快递员会尽快与您联系。', + 'keyword1'=>implode(',',$samples['cat_device_ids']), + //'keyword2'=>'上门取货后获取', + 'keyword2'=>$ret[1], + 'keyword3'=>'预估两小时内', + //'remark'=>'物流信息只能在中通官网查看,请保管好回寄单号方便日后物流查询。', + 'remark'=>'我们已为您呼叫了顺丰速运,请耐心等待。物流信息可在“顺丰速运”公众号查看。', + ] + ); + }catch (Exception $e){ + } + $this->success(); + }else{ + $this->error('快递未能使用,请添加微信号“uap_pet”咨询客服,错误信息:'.$ret[1]); + } + }else if ($dog_cat[1] || $dog_cat[0]){ + $data['trade_id'] = $data['device_id'][0]; + if ($dog_cat[0]){ + $data['d_province'] = $receiver_address['dog']['d_province']; + $data['d_city'] = $receiver_address['dog']['d_city']; + $data['d_county'] = $receiver_address['dog']['d_county']; + $data['d_company'] = $receiver_address['dog']['d_company']; + $data['d_contact'] = $receiver_address['dog']['d_contact']; + $data['d_tel'] = $receiver_address['dog']['d_tel']; + $data['d_address'] = $receiver_address['dog']['d_address']; + }else{ + $data['d_province'] = $receiver_address['cat']['d_province']; + $data['d_city'] = $receiver_address['cat']['d_city']; + $data['d_county'] = $receiver_address['cat']['d_county']; + $data['d_company'] = $receiver_address['cat']['d_company']; + $data['d_contact'] = $receiver_address['cat']['d_contact']; + $data['d_tel'] = $receiver_address['cat']['d_tel']; + $data['d_address'] = $receiver_address['cat']['d_address']; + } + $ret = $this->sf_express_model->shipSample($data); + //$ret = [true]; + if($ret[0]){ + //快递id写到样品中 + $this->sample_model->update(['ship_order_id'=>$ret[1],'step'=>Sample_model::STEP_SENT],'id in ('.implode(',',$sample_ids).')'); + try{ + //发送微信通知 + $this->load->model('weixin_message_model'); + $user = $this->customer_model->get($this->_user_id); + //如果没关系,会抛出错误,忽略 + $this->weixin_message_model->send( + $user['openid'], + Weixin_message_model::TEMPLATE_SENT, + null, + [ + 'first'=>'尊敬的用户:我们已为您分配了快递员,请保持手机畅通,快递员会尽快与您联系。', + 'keyword1'=>implode(',',$data['device_id']), + //'keyword2'=>'上门取货后获取', + 'keyword2'=>$ret[1], + 'keyword3'=>'预估两小时内', + //'remark'=>'物流信息只能在中通官网查看,请保管好回寄单号方便日后物流查询。', + 'remark'=>'我们已为您呼叫了顺丰速运,请耐心等待。物流信息可在“顺丰速运”公众号查看。', + ] + ); + }catch (Exception $e){ + } + $this->success(); + }else{ + $this->error('快递未能使用,请添加微信号“uap_pet”咨询客服,错误信息:'.$ret[1]); + } + } + /* + if($data['name'] == '有哈'){ + $this->load->model('sf_express_model'); + $ret = $this->sf_express_model->shipSample($data); + }else{ + $this->load->model('zto_model'); + $ret = $this->zto_model->shipSample($data); + }*/ + } + + //进度查询:样品列表 + public function list_get() + { + $ret = $this->sample_model->get($this->_user_id,'user_id',true); + $list = []; + if($ret)foreach ($ret as $item) { + //废弃的样品不呈现 + if($item['step'] == Sample_model::STEP_DISCARD){ + continue; + } + $item['step_fail'] = $item['step'] == Sample_model::STEP_UNQUALIFIED; + $list[] = $item; + } + $this->success($list); + } + + //进度查询:样品进度详情 + public function detail_get() + { + $config = array( + array( + 'field' => 'id', + 'label' => '样品ID', + 'rules' => 'trim|required|min_length[4]|max_length[20]' + ) + ); + $this->load->library('form_validation'); + $data = $this->input->get(); + $this->form_validation->set_data($data); + $this->form_validation->set_rules($config); + if ($this->form_validation->run() === FALSE) + { + $this->error('参数错误',$this->form_validation->error_array()); + } + $sample = $this->sample_model->get(trim($data['id']),'device_id'); + if($sample['user_id'] != $this->_user_id){ + $this->error('您没有权限查看该样品'); + } + if($sample['step'] == Sample_model::STEP_DISCARD){ + $this->error('该样品已作废'); + } + //获取摘要版的进度 + $steps = $this->sample_model->step_summary; + //当前进度 + $sample['step_desc'] = $steps[$sample['step']]; + //成功与失败状态不能同时存在 + $sample['step_fail'] = $sample['step'] == Sample_model::STEP_UNQUALIFIED; + if($sample['step_fail']){ + //隐藏成功项目 + unset($steps[Sample_model::STEP_DNA_EXTRACTED]); + }else{ + //隐藏失败项目 + unset($steps[Sample_model::STEP_UNQUALIFIED]); + } + //删除重复的进度 + $steps = array_keys(array_flip($steps)); + //当前在哪一个步骤 + $sample['step_active'] = array_search($sample['step_desc'],$steps); + $sample['step_active_fail'] = $sample['step_fail'] ? $sample['step_active'] : -1; + + //状态描述改成小描述 + $sample['step_desc'] = $this->sample_model->step[$sample['step']]; + //获取物流信息 + $track = []; + $this->load->model('zto_model'); + $ship_order = false; + //$ship_order = $this->zto_model->get(trim($sample['id']),'sample_id'); + if($ship_order){ + $track = $this->zto_model->traceInterfaceNewTraces($ship_order['order_code']); + } + $this->success([ + 'sample'=>$sample, + 'ship_order'=>$ship_order, + //步骤需要提醒 + 'error_step'=>Sample_model::STEP_UNQUALIFIED, + 'track'=>$track, + 'steps'=>$steps, + ]); + } + + //升级样品:获取可升级的套餐 + public function upgrade_post() + { + $config = array( + array( + 'field' => 'id', + 'label' => '样品ID', + 'rules' => 'trim|required|min_length[4]|max_length[20]' + ) + ); + $data = $this->json_validation($config); + $sample = $this->sample_model->get(trim($data['id']),'device_id'); + /* + if($sample['user_id'] != $this->_user_id){ + $this->error('您没有权限查看该样品'); + }*/ + //查询可升级套餐,即同物种的更高价格的套餐 + $packages = $this->package_model->get(trim($sample['pet_species']),'species',true); + $cur_package = null; + $up_packages = []; + foreach ($packages as $package) { + if($package['id'] == $sample['package_id']){ + $cur_package = $package; + }else{ + //只输出特定信息给用户前端 + $up_packages[] = [ + 'id'=>$package['id'], + 'name'=>$package['name'], + 'description'=>$package['description'], + 'price'=>$package['price'] + ]; + } + } + if(is_null($cur_package)){ + $this->error('样品原套餐信息丢失,暂不可升级'); + } + //过滤比当前套餐价格低的套餐 + foreach ($up_packages as $key=> $package) { + if($package['price'] <= $cur_package['price']){ + unset($up_packages[$key]); + continue; + } + //输出升级差价 + $up_packages[$key]['balance'] = round($package['price'] - $cur_package['price'],2); + } + if(empty($up_packages)){ + $this->success(); + } + //按照价格从低到高排序 + array_multisort(array_column($up_packages,'price'),SORT_DESC,$up_packages); + $this->success(['packages'=>$up_packages]); + } + + public function test_get(){ + $this->load->library('uploads'); + echo $this->uploads->get_upload_path(); + } + +} diff --git a/controllers/api/user/Active.php.20250102 b/controllers/api/user/Active.php.20250102 new file mode 100644 index 0000000..536f3a8 --- /dev/null +++ b/controllers/api/user/Active.php.20250102 @@ -0,0 +1,739 @@ +load->library('session'); + $this->load->model('series_number_model'); + $this->load->model('package_model'); + $this->load->model('sample_model'); + $this->load->model('customer_model'); + $this->checkUser(); + } + + public function ticket_get() + { + $conf = $this->config->item('weixin_uah'); + $config = [ + 'app_id' => $conf['AppId'], + 'secret' => $conf['AppSecert'], + 'token' => $conf['Token'], + 'aes_key' => $conf['EncodingAESKey'], + 'response_type' => 'array', + ]; + $app = new OfficialAccount($config); + $url = $this->input->get('url'); + if(!empty($url)){ + $app->js->setUrl($url); + }else + if(!empty($_SERVER['HTTP_REFERER'])){ + $app->js->setUrl($_SERVER['HTTP_REFERER']); + } + $config = $app->js->config(array('updateAppMessageShareData', 'updateTimelineShareData', 'scanQRCode'), $debug = false, $beta = false, $json = true); + $this->success(['config'=>json_decode($config)]); + } + + public function check_number_post() + { + $config = array( + array( + 'field' => 'device_id', + 'label' => '序列号', + 'rules' => 'trim|required|min_length[3]|max_length[20]' + ), + ); + $data = $this->json_validation($config); + $series = $this->series_number_model->get($data['device_id'],'device_id'); + if(!$series){ + $this->error('请联系【店铺】在线客服绑定序列号'); + } + $sample = $this->sample_model->get($series['id'],'series_id'); + if($sample){ + $this->error('序列号已使用'); + } + + $package = $this->package_model->get($series['package_ori']); + if(!$package){ + $this->error('序列号不可用,套餐信息不存在'); + } + + $content = empty($package['content'])?[]:json_decode($package['content'],true); + //获取所有疾病的名称 + if(!empty($content)){ + $disease_ids = []; + foreach ($content as $item) { + $disease_ids = array_merge($disease_ids,$item['disease_id']); + } + $this->load->model('disease_model'); + $disease_list = $this->disease_model->get($disease_ids,'base.id',true); + $disease_map = []; + foreach ($disease_list as $val) { + $disease_map[$val['id']] = $val; + } + //疾病详情存到信息中 + foreach ($content as $key=>$val) { + $val['disease_list'] = []; + foreach ($val['disease_id'] as $v) { + if(!isset($disease_map[$v])){ + continue; + } + $val['disease_list'][] = $disease_map[$v]; + } + $content[$key] = $val; + } + } + $package['content'] = $content; + $this->success(['package'=>$package]); + + } + + //新建样本 + public function create_post() + { + $config = array( + array( + 'field' => 'device_id', + 'label' => '序列号', + 'rules' => 'trim|required|min_length[4]|max_length[20]', + 'errors' => array( + 'required' => '请提供以下信息:%s.', + 'min_length' => '%s长度不足:%s.', + 'max_length' => '%s长度不能超过:%s.', + ), + ), + array( + 'field' => 'name', + 'label' => '用户姓名', + 'rules' => 'trim|required|min_length[1]|max_length[20]', + 'errors' => array( + 'required' => '请提供以下信息:%s.', + ), + ), + array( + 'field' => 'tel', + 'label' => '手机', + 'rules' => 'required', + 'errors' => array( + 'required' => '请提供以下信息:%s.', + ), + ), + array( + 'field' => 'pet_name', + 'label' => '宠物名称', + 'rules' => 'required', + 'errors' => array( + 'required' => '请提供以下信息:%s.', + ), + ), + array( + 'field' => 'pet_sex', + 'label' => '宠物性别', + 'rules' => 'required', + 'errors' => array( + 'required' => '请提供以下信息:%s.', + ), + ), + array( + 'field' => 'pet_birthday', + 'label' => '宠物生日', + 'rules' => 'required', + 'errors' => array( + 'required' => '请提供以下信息:%s.', + ), + ), + //繁育:芯片号 + array( + 'field' => 'chip_number', + 'label' => '芯片号', + 'rules' => 'trim', + 'errors' => array( + 'required' => '请提供以下信息:%s.', + ), + ), + //繁育:是否种猫 + array( + 'field' => 'is_breeding', + 'label' => '是否种猫', + 'rules' => 'trim', + 'errors' => array( + 'required' => '请提供以下信息:%s.', + ), + ), + //繁育:血统认证机构 + array( + 'field' => 'lineage_cert_body', + 'label' => '血统认证机构', + 'rules' => 'trim', + 'errors' => array( + 'required' => '请提供以下信息:%s.', + ), + ) + ); + $data = $this->json_validation($config); + $series = $this->series_number_model->get($data['device_id'],'device_id'); + if(!$series){ + $this->error('序列号不存在'); + } + $sample = $this->sample_model->get($series['id'],'series_id'); + if($sample){ + $this->error('序列号已使用'); + } + $package = $this->package_model->get($series['package_ori']); + if(!$package){ + $this->error('套餐不存在'); + } + + //过滤字段 + $fields = array_column($config,'field'); + $entity = []; + foreach ($data as $key=>$val) { + if(in_array($key,$fields)){ + $entity[$key] = $val; + } + } + unset($entity['device_id']); + + //套餐是否要求选择疾病 + $package['content'] = empty($package['content'])?[]:json_decode($package['content'],true); + //选择的疾病处理 + if(!empty($package['content'])){ + if(!isset($data['package_custom'])){ + $this->error('请选择套餐选项'); + } + //选择的选项是否允许选择 + if(!isset($package['content'][$data['package_custom']])){ + $this->error('您选择的套餐选项已失效'); + } + + $package_custom = $package['content'][$data['package_custom']]; + //获取疾病的名称,保存起来,以免id变化 + $this->load->model('disease_model'); + $tmp = $this->disease_model->get($package_custom['disease_id'],'base.id',true); + $entity['package_custom'] = json_encode([ + 'id'=>$data['package_custom'], + 'name'=>$package_custom['name'], + 'disease_id'=>$package_custom['disease_id'], + 'disease_name'=>array_column($tmp,'name') + ],JSON_UNESCAPED_UNICODE); + }else{ + $entity['package_custom'] = ''; + } + //用户id + $entity['user_id'] = $this->_user_id; + //从device_id读取序列号ID + $entity['series_id'] = $series['id']; + //套餐 + $entity['package_id'] = $series['package_ori']; + //套餐的猫狗写进样品,防止套餐变更造成影响 + $entity['pet_species'] = $package['species']; + //头像处理 + if(!empty($data['file']['content'])){ + $imgBase64 = $data['file']['content']; + + if(!empty($data['file']['ext'])){ + //对于java接口,需要兼容前端的格式 + $imgBase64 = 'data:image/'.trim($data['file']['ext']).';base64,'.$imgBase64; + } + + $this->load->library('uploads'); + //存原图 + $pet_img = $this->uploads->save_pet_img_base64( + $imgBase64, + $data['device_id'] + ); + if($pet_img){ + $entity['pet_img'] = $pet_img; + } + } + + //绝育情况,如果没有传入则按“否”处理 + if(empty($entity['is_sterilized'])){ + $entity['is_sterilized'] = 0; + } + + //处理宠物性别与绝育情况合并的情况(非繁育用户) + switch ($entity['pet_sex']){ + case 1: + $entity['pet_sex'] = 1; + break; + case 2: + $entity['pet_sex'] = 2; + break; + case 3: + $entity['pet_sex'] = 1; + $entity['is_sterilized'] = 1; + break; + case 4: + $entity['pet_sex'] = 2; + $entity['is_sterilized'] = 1; + break; + default: + $entity['pet_sex'] = 1; + } + + //步骤置为初始步骤 + $entity['step'] = Sample_model::STEP_BIND; + //发送微信通知 + $this->load->model('weixin_message_model'); + $user = $this->customer_model->get($this->_user_id); + $conf = $this->config->item('allowed_cors_origins'); + try{ + //如果没关注,会抛出错误,忽略 + $this->weixin_message_model->send( + $user['openid'], + Weixin_message_model::TEMPLATE_ACTIVE, + base_url().'weixin/?url='.urlencode($conf['user'].'/ship'), + [ + 'first'=>'激活成功,如您还没选择回寄,请点击回寄', + 'keyword1'=>$data['device_id'], + 'keyword2'=>$package['name'], + 'remark'=>'', + ] + ); + }catch (Exception $e){ + } + + //如果证书有多个,用逗号组合 + if(is_array($entity['lineage_cert_body'])){ + $entity['lineage_cert_body'] = implode(',',$entity['lineage_cert_body']); + } + + $ret = $this->sample_model->add($entity); + /* + //保存一条样品流程处理信息 + $this->load->model('sample_processing_model'); + $this->sample_processing_model->add([ + 'sample_id'=>$ret, + 'step'=>$entity['step'] + ]); + //保存一条样品套餐升级信息 + $this->load->model('sample_upgrade_model'); + $this->sample_upgrade_model->add([ + 'sample_id'=>$ret, + 'package_id'=>$entity['package_id'], + 'package_custom'=>$entity['package_custom'] + ]); + */ + if($ret){ + //激活了繁育套餐的客户,用户信息修改 + //if(!empty($package['is_breed'])){} + $this->success(); + }else{ + $this->error('提交失败'); + } + } + + //获取需回寄的样品 + public function ship_get() + { + $ret = $this->sample_model->get($this->_user_id,'user_id',true); + //只展示需回寄样品 + $un_ship = []; + foreach ($ret as $key=>$item) { + if($item['step'] < Sample_model::STEP_SENT){ + $un_ship[] = $ret[$key]; + } + } + $first = []; + //取第一个样品的信息 + if(!empty($un_ship)){ + $first = $un_ship[0]; + }elseif(!empty($ret)){ + $first = $ret[0]; + } + $this->success(['sample'=>$un_ship,'info'=>$first]); + } + + //样品回寄 + public function ship_post() + { + $config = array( + array( + 'field' => 'device_id[]', + 'label' => '样品', + 'rules' => 'trim|required|min_length[2]|max_length[20]', + 'errors' => array( + 'required' => '请提供以下信息:%s.', + ), + ), + array( + 'field' => 'name', + 'label' => '姓名', + 'rules' => 'trim|required|min_length[2]|max_length[20]', + 'errors' => array( + 'required' => '请提供以下信息:%s.', + ), + ), + array( + 'field' => 'tel', + 'label' => '手机号', + 'rules' => 'required' + ), + array( + 'field' => 'address', + 'label' => '地址', + 'rules' => 'required' + ), + array( + 'field' => 'province', + 'label' => '省', + 'rules' => 'required' + ), + array( + 'field' => 'city', + 'label' => '市', + 'rules' => 'required' + ), + array( + 'field' => 'district', + 'label' => '区', + 'rules' => 'required' + ) + ); + $receiver_address = array( + 'cat' => array( + 'd_province' => '江苏省', + 'd_city' => '南京市', + 'd_county' => '浦口区', + 'd_company' => '有哈科技', + 'd_contact' => '有哈收样组', + 'd_tel' => '17751784617', + 'd_address' => '行知路8号南京农创中心方舟实验室C栋南楼3层', + ), + 'dog' => array( + 'd_province' => '江苏省', + 'd_city' => '南京市', + 'd_county' => '浦口区', + 'd_company' => '有哈科技', + 'd_contact' => '有哈收样组', + 'd_tel' => '17751784617', + 'd_address' => '行知路8号南京农创中心方舟实验室C栋南楼3层', + ) + ); + $data = $this->json_validation($config); + $sample_ids = []; + $dog_cat = [false, false]; + $samples = array( + 'cat' => [], + 'cat_device_ids' =>[], + 'dog' => [], + 'dog_device_ids' =>[], + ); + foreach ($data['device_id'] as $device_id) { + $sample = $this->sample_model->get($device_id,'device_id'); + if($sample['user_id'] != $this->_user_id){ + $this->error('该样品不在您名下'); + } + if ($sample['pet_species'] == 1){ + $dog_cat[0] = true; + $samples['dog'][] = $sample['id']; + $samples['dog_device_ids'][] = $device_id; + }else if ($sample['pet_species'] == 2){ + $dog_cat[1] = true; + $samples['cat'][] = $sample['id']; + $samples['cat_device_ids'][] = $device_id; + } + $sample_ids[] = $sample['id']; + } + //创建订单 + $data['user_id'] = $this->_user_id; + $this->load->model('sf_express_model'); + if ($dog_cat[0] && $dog_cat[1]){ + // $this->error("ship -> dog: $dog_cat[0], cat: $dog_cat[1]"); + $data['d_province'] = $receiver_address['dog']['d_province']; + $data['d_city'] = $receiver_address['dog']['d_city']; + $data['d_county'] = $receiver_address['dog']['d_county']; + $data['d_company'] = $receiver_address['dog']['d_company']; + $data['d_contact'] = $receiver_address['dog']['d_contact']; + $data['d_tel'] = $receiver_address['dog']['d_tel']; + $data['d_address'] = $receiver_address['dog']['d_address']; + $data['trade_id'] = $samples['dog'][0]; + $ret = $this->sf_express_model->shipSample($data); + //$ret = [true]; + error_log("shipSample dog: $ret[0] $ret[1]"); + if($ret[0]){ + //快递id写到样品中 + $this->sample_model->update(['ship_order_id'=>$ret[1],'step'=>Sample_model::STEP_SENT],'id in ('.implode(',',$samples['dog']).')'); + try{ + //发送微信通知 + $this->load->model('weixin_message_model'); + $user = $this->customer_model->get($this->_user_id); + //如果没关系,会抛出错误,忽略 + $this->weixin_message_model->send( + $user['openid'], + Weixin_message_model::TEMPLATE_SENT, + null, + [ + 'first'=>'尊敬的用户:我们已为您分配了快递员,请保持手机畅通,快递员会尽快与您联系。', + 'keyword1'=>implode(',',$samples['dog_device_ids']), + //'keyword2'=>'上门取货后获取', + 'keyword2'=>$ret[1], + 'keyword3'=>'预估两小时内', + //'remark'=>'物流信息只能在中通官网查看,请保管好回寄单号方便日后物流查询。', + 'remark'=>'我们已为您呼叫了顺丰速运,请耐心等待。物流信息可在“顺丰速运”公众号查看。', + ] + ); + }catch (Exception $e){ + } + }else{ + if (strpos($ret[1], '您的预约超出今日营业时间') !== false){ + $this->error('快递营业时间:8-18点,现已超出今日营业时间,请于明日8点后进行预约取件。'); + }else{ + $this->error('快递未能使用,请添加微信号“uap_pet”咨询客服,错误信息:'.$ret[1]); + + } + } + sleep(1); + $data['d_province'] = $receiver_address['cat']['d_province']; + $data['d_city'] = $receiver_address['cat']['d_city']; + $data['d_county'] = $receiver_address['cat']['d_county']; + $data['d_company'] = $receiver_address['cat']['d_company']; + $data['d_contact'] = $receiver_address['cat']['d_contact']; + $data['d_tel'] = $receiver_address['cat']['d_tel']; + $data['d_address'] = $receiver_address['cat']['d_address']; + $data['trade_id'] = $samples['cat'][0]; + $ret = $this->sf_express_model->shipSample($data); + //$ret = [true]; + error_log("shipSample cat: $ret[0] $ret[1]"); + if($ret[0]){ + //快递id写到样品中 + $this->sample_model->update(['ship_order_id'=>$ret[1],'step'=>Sample_model::STEP_SENT],'id in ('.implode(',',$samples['dog']).')'); + try{ + //发送微信通知 + $this->load->model('weixin_message_model'); + $user = $this->customer_model->get($this->_user_id); + //如果没关系,会抛出错误,忽略 + $this->weixin_message_model->send( + $user['openid'], + Weixin_message_model::TEMPLATE_SENT, + null, + [ + 'first'=>'尊敬的用户:我们已为您分配了快递员,请保持手机畅通,快递员会尽快与您联系。', + 'keyword1'=>implode(',',$samples['cat_device_ids']), + //'keyword2'=>'上门取货后获取', + 'keyword2'=>$ret[1], + 'keyword3'=>'预估两小时内', + //'remark'=>'物流信息只能在中通官网查看,请保管好回寄单号方便日后物流查询。', + 'remark'=>'我们已为您呼叫了顺丰速运,请耐心等待。物流信息可在“顺丰速运”公众号查看。', + ] + ); + }catch (Exception $e){ + } + $this->success(); + }else{ + if (strpos($ret[1], '您的预约超出今日营业时间') !== false){ + $this->error('快递营业时间:8-18点,现已超出今日营业时间,请于明日8点后进行预约取件。'); + }else{ + $this->error('快递未能使用,请添加微信号“uap_pet”咨询客服,错误信息:'.$ret[1]); + + } + } + }else if ($dog_cat[1] || $dog_cat[0]){ + $data['trade_id'] = $data['device_id'][0]; + if ($dog_cat[0]){ + $data['d_province'] = $receiver_address['dog']['d_province']; + $data['d_city'] = $receiver_address['dog']['d_city']; + $data['d_county'] = $receiver_address['dog']['d_county']; + $data['d_company'] = $receiver_address['dog']['d_company']; + $data['d_contact'] = $receiver_address['dog']['d_contact']; + $data['d_tel'] = $receiver_address['dog']['d_tel']; + $data['d_address'] = $receiver_address['dog']['d_address']; + }else{ + $data['d_province'] = $receiver_address['cat']['d_province']; + $data['d_city'] = $receiver_address['cat']['d_city']; + $data['d_county'] = $receiver_address['cat']['d_county']; + $data['d_company'] = $receiver_address['cat']['d_company']; + $data['d_contact'] = $receiver_address['cat']['d_contact']; + $data['d_tel'] = $receiver_address['cat']['d_tel']; + $data['d_address'] = $receiver_address['cat']['d_address']; + } + $ret = $this->sf_express_model->shipSample($data); + //$ret = [true]; + if($ret[0]){ + //快递id写到样品中 + $this->sample_model->update(['ship_order_id'=>$ret[1],'step'=>Sample_model::STEP_SENT],'id in ('.implode(',',$sample_ids).')'); + try{ + //发送微信通知 + $this->load->model('weixin_message_model'); + $user = $this->customer_model->get($this->_user_id); + //如果没关系,会抛出错误,忽略 + $this->weixin_message_model->send( + $user['openid'], + Weixin_message_model::TEMPLATE_SENT, + null, + [ + 'first'=>'尊敬的用户:我们已为您分配了快递员,请保持手机畅通,快递员会尽快与您联系。', + 'keyword1'=>implode(',',$data['device_id']), + //'keyword2'=>'上门取货后获取', + 'keyword2'=>$ret[1], + 'keyword3'=>'预估两小时内', + //'remark'=>'物流信息只能在中通官网查看,请保管好回寄单号方便日后物流查询。', + 'remark'=>'我们已为您呼叫了顺丰速运,请耐心等待。物流信息可在“顺丰速运”公众号查看。', + ] + ); + }catch (Exception $e){ + } + $this->success(); + }else{ + if (strpos($ret[1], '您的预约超出今日营业时间') !== false){ + $this->error('快递营业时间:8-18点,现已超出今日营业时间,请于明日8点后进行预约取件。'); + }else{ + $this->error('快递未能使用,请添加微信号“uap_pet”咨询客服,错误信息:'.$ret[1]); + + } + } + } + /* + if($data['name'] == '有哈'){ + $this->load->model('sf_express_model'); + $ret = $this->sf_express_model->shipSample($data); + }else{ + $this->load->model('zto_model'); + $ret = $this->zto_model->shipSample($data); + }*/ + } + + //进度查询:样品列表 + public function list_get() + { + $ret = $this->sample_model->get($this->_user_id,'user_id',true); + $list = []; + if($ret)foreach ($ret as $item) { + //废弃的样品不呈现 + if($item['step'] == Sample_model::STEP_DISCARD){ + continue; + } + $item['step_fail'] = $item['step'] == Sample_model::STEP_UNQUALIFIED; + $list[] = $item; + } + $this->success($list); + } + + //进度查询:样品进度详情 + public function detail_get() + { + $config = array( + array( + 'field' => 'id', + 'label' => '样品ID', + 'rules' => 'trim|required|min_length[4]|max_length[20]' + ) + ); + $this->load->library('form_validation'); + $data = $this->input->get(); + $this->form_validation->set_data($data); + $this->form_validation->set_rules($config); + if ($this->form_validation->run() === FALSE) + { + $this->error('参数错误',$this->form_validation->error_array()); + } + $sample = $this->sample_model->get(trim($data['id']),'device_id'); + if($sample['user_id'] != $this->_user_id){ + $this->error('您没有权限查看该样品'); + } + if($sample['step'] == Sample_model::STEP_DISCARD){ + $this->error('该样品已作废'); + } + //获取摘要版的进度 + $steps = $this->sample_model->step_summary; + //当前进度 + $sample['step_desc'] = $steps[$sample['step']]; + //成功与失败状态不能同时存在 + $sample['step_fail'] = $sample['step'] == Sample_model::STEP_UNQUALIFIED; + if($sample['step_fail']){ + //隐藏成功项目 + unset($steps[Sample_model::STEP_DNA_EXTRACTED]); + }else{ + //隐藏失败项目 + unset($steps[Sample_model::STEP_UNQUALIFIED]); + } + //删除重复的进度 + $steps = array_keys(array_flip($steps)); + //当前在哪一个步骤 + $sample['step_active'] = array_search($sample['step_desc'],$steps); + $sample['step_active_fail'] = $sample['step_fail'] ? $sample['step_active'] : -1; + + //状态描述改成小描述 + $sample['step_desc'] = $this->sample_model->step[$sample['step']]; + //获取物流信息 + $track = []; + $this->load->model('zto_model'); + $ship_order = false; + //$ship_order = $this->zto_model->get(trim($sample['id']),'sample_id'); + if($ship_order){ + $track = $this->zto_model->traceInterfaceNewTraces($ship_order['order_code']); + } + $this->success([ + 'sample'=>$sample, + 'ship_order'=>$ship_order, + //步骤需要提醒 + 'error_step'=>Sample_model::STEP_UNQUALIFIED, + 'track'=>$track, + 'steps'=>$steps, + ]); + } + + //升级样品:获取可升级的套餐 + public function upgrade_post() + { + $config = array( + array( + 'field' => 'id', + 'label' => '样品ID', + 'rules' => 'trim|required|min_length[4]|max_length[20]' + ) + ); + $data = $this->json_validation($config); + $sample = $this->sample_model->get(trim($data['id']),'device_id'); + /* + if($sample['user_id'] != $this->_user_id){ + $this->error('您没有权限查看该样品'); + }*/ + //查询可升级套餐,即同物种的更高价格的套餐 + $packages = $this->package_model->get(trim($sample['pet_species']),'species',true); + $cur_package = null; + $up_packages = []; + foreach ($packages as $package) { + if($package['id'] == $sample['package_id']){ + $cur_package = $package; + }else{ + //只输出特定信息给用户前端 + $up_packages[] = [ + 'id'=>$package['id'], + 'name'=>$package['name'], + 'description'=>$package['description'], + 'price'=>$package['price'] + ]; + } + } + if(is_null($cur_package)){ + $this->error('样品原套餐信息丢失,暂不可升级'); + } + //过滤比当前套餐价格低的套餐 + foreach ($up_packages as $key=> $package) { + if($package['price'] <= $cur_package['price']){ + unset($up_packages[$key]); + continue; + } + //输出升级差价 + $up_packages[$key]['balance'] = round($package['price'] - $cur_package['price'],2); + } + if(empty($up_packages)){ + $this->success(); + } + //按照价格从低到高排序 + array_multisort(array_column($up_packages,'price'),SORT_DESC,$up_packages); + $this->success(['packages'=>$up_packages]); + } + + public function test_get(){ + $this->load->library('uploads'); + echo $this->uploads->get_upload_path(); + } + +} diff --git a/controllers/api/user/Breeding.php b/controllers/api/user/Breeding.php new file mode 100644 index 0000000..e00da82 --- /dev/null +++ b/controllers/api/user/Breeding.php @@ -0,0 +1,229 @@ +load->library('session'); + $this->load->model('customer_model'); + //$this->session->{Customer_model::SESSION_KEY} = 1; + $this->checkUser(); + } + + //获取繁育人信息 + public function info_get(){ + $row = $this->customer_model->get($this->_user_id); + //统计数量 + $this->load->model('sample_model'); + $this->load->model('breeding_plan_model'); + $row['total_sample'] = $this->sample_model->getUserTotal($this->_user_id); + $row['total_breeding_plan'] = $this->breeding_plan_model->getUserTotal($this->_user_id); + $this->success($row); + } + + //获取种猫/犬 + public function candidate_post(){ + $this->load->model('sample_model'); + $this->load->model('report_model'); + $data = $this->json_input(); + $ids = []; + if(!empty($data['tree']) && is_array($data['tree'])){ + $ids = $this->_getTreeSampleIds($data['tree']); + } + $pet_sex = empty($data['pet_sex'])?0:(int)$data['pet_sex']; + $pet_species = empty($data['pet_species'])?0:(int)$data['pet_species']; + + $list = $this->sample_model->getBreeding($this->_user_id,$ids,$pet_species,$pet_sex,100); + $ret = []; + foreach ($list as $val) { + $reportJson = $this->report_model->get_report_json($val['device_id'],$val['pet_species']); + $ret[] = $this->_getCandidateItem($val,$reportJson); + } + $this->success($ret); + } + + //繁育计划保存 + public function plan_save_post() + { + $data = $this->json_input(); + if(empty($data['tree'])){ + $this->error('参数不完整'); + } + $tree = $data['tree']; + //保存孩子的样本id + $children_ids = []; + foreach ($tree['children'] as $item) { + if(!empty($item['id'])){ + $children_ids[] = $item['id']; + } + } + //雌性 + $female_id = !empty($tree['female']['self']['id'])?(int)$tree['female']['self']['id']:0; + $female_father_id = !empty($tree['female']['father']['id'])?(int)$tree['female']['father']['id']:0; + $female_mother_id = !empty($tree['female']['mother']['id'])?(int)$tree['female']['mother']['id']:0; + + //雄性 + $male_id = !empty($tree['male']['self']['id'])?(int)$tree['male']['self']['id']:0; + $male_father_id = !empty($tree['male']['father']['id'])?(int)$tree['male']['father']['id']:0; + $male_mother_id = !empty($tree['male']['mother']['id'])?(int)$tree['male']['mother']['id']:0; + + if(empty($female_id) || empty($male_id)){ + $this->error('关系不完整'); + } + $this->load->model('breeding_plan_model'); + $entity = [ + 'children_ids' => implode(',',$children_ids), + 'user_id' => $this->_user_id, + 'female_id' => $female_id, + 'female_father_id' => $female_father_id, + 'female_mother_id' => $female_mother_id, + 'male_id' => $male_id, + 'male_father_id' => $male_father_id, + 'male_mother_id' => $male_mother_id, + ]; + if(empty($data['id'])){ + $this->breeding_plan_model->add($entity); + }else{ + $this->breeding_plan_model->update($entity,[ + 'id'=>$data['id'] + ]); + } + $this->success('保存成功'); + } + + + //繁育计划列表 + public function list_get() + { + $this->load->model('breeding_plan_model'); + $ret = $this->breeding_plan_model->get($this->_user_id,'user_id',true); + $list = []; + if($ret){ + //获取所有相关样品 + $sample_ids = []; + foreach ($ret as $item) { + $sample_ids[] = $item['male_id']; + $sample_ids[] = $item['female_id']; + } + + $this->load->model('sample_model'); + //根据id获取样本信息 + $samples = $this->sample_model->getByUserIds($sample_ids); + $sample_map = []; + foreach ($samples as $item) { + $this->sample_model->format($item); + $sample_map[$item['id']] = $item; + } + + //格式化信息 + foreach ($ret as $item) { + $male = [ + 'name'=>$sample_map[$item['male_id']]['pet_name'], + 'pet_img'=>$sample_map[$item['male_id']]['pet_img'], + 'device_id'=>$sample_map[$item['male_id']]['device_id'], + ]; + $female = [ + 'name'=>$sample_map[$item['female_id']]['pet_name'], + 'pet_img'=>$sample_map[$item['female_id']]['pet_img'], + 'device_id'=>$sample_map[$item['female_id']]['device_id'], + ]; + $tmp = [ + 'id'=>$item['id'], + 'male'=>$male, + 'female'=>$female, + ]; + $list[] = $tmp; + } + } + + $this->success($list); + } + + //繁育计划列表 + public function detail_get() + { + $id = $this->input->get('id'); + if(empty($id)){ + $this->error('参数错误'); + } + $this->load->model('breeding_plan_model'); + $plan = $this->breeding_plan_model->get($id); + if(!$plan){ + $this->error('计划不存在'); + } + $tree = [ + 'male'=>[ + 'father'=>$this->_getNode($plan['male_father_id']), + 'mother'=>$this->_getNode($plan['male_mother_id']), + 'self'=>$this->_getNode($plan['male_id']), + ], + 'female'=>[ + 'father'=>$this->_getNode($plan['female_father_id']), + 'mother'=>$this->_getNode($plan['female_mother_id']), + 'self'=>$this->_getNode($plan['female_id']), + ], + 'children'=>[] + ]; + if(!empty($plan['children_ids'])){ + $plan['children_ids'] = explode(',',$plan['children_ids']); + foreach ($plan['children_ids'] as $val) { + $tree['children'][] = $this->_getNode($val); + } + } + //如果没有children,补一个 + if(empty($tree['children'])){ + $tree['children'][] = [ + 'id'=>0, + 'pet_name'=>'', + 'pet_img'=>'', + ]; + } + + $this->success($tree); + } + + + //繁育计划节点 + protected function _getNode($sample_id) + { + $this->load->model('sample_model'); + $sample = $this->sample_model->get($sample_id); + if(!$sample){ + return [ + 'id'=>0 + ]; + } + return $sample; + } + + //繁育计划候选列表项目 + protected function _getCandidateItem($sample,$reportJson) + { + $lineage = !empty($reportJson['血统分析']['body']['品系纯度'])?$reportJson['血统分析']['body']['品系纯度']:[]; + $lineage = implode(',',array_keys($lineage)); + + $item = [ + 'id'=>$sample['id'], + 'pet_name'=>$sample['pet_name'], + 'pet_img'=>$sample['pet_img'], + 'pet_sex'=>$sample['pet_sex'], + 'lineage'=>$lineage, + ]; + return $item; + } + + //繁育计划树的所有id + protected function _getTreeSampleIds($tree) + { + $ids = []; + foreach ($tree as $key=>$val) { + foreach ($val as $v) { + $ids[] = $v['id']; + } + } + return array_filter(array_unique($ids)); + } +} diff --git a/controllers/api/user/Sync.php b/controllers/api/user/Sync.php new file mode 100644 index 0000000..03968a4 --- /dev/null +++ b/controllers/api/user/Sync.php @@ -0,0 +1,87 @@ +load->model('series_number_model'); + $this->load->model('package_model'); + $this->load->model('sample_model'); + $this->load->model('customer_model'); + } + + /** + * 服务端请求创建用户 + * 绕过了前端授权 + */ + public function user_post() + { + $ret = $this->serverSign(); + if(!$ret){ + $this->error('您的签名错误'); + } + $config = array( + array( + 'field' => 'openid', + 'label' => 'OPENID', + 'rules' => 'trim|required|min_length[3]|max_length[50]' + ), + array( + 'field' => 'unionid', + 'label' => 'UNIONID', + 'rules' => 'trim|required|min_length[3]|max_length[50]' + ), + array( + 'field' => 'nickname', + 'label' => 'nickname', + 'rules' => 'trim|required|min_length[1]|max_length[50]' + ), + array( + 'field' => 'sex', + 'label' => 'sex', + 'rules' => 'trim|min_length[1]|max_length[2]' + ), + array( + 'field' => 'language', + 'label' => 'language', + 'rules' => 'trim|min_length[1]|max_length[50]' + ), + array( + 'field' => 'city', + 'label' => 'city', + 'rules' => 'trim|min_length[1]|max_length[50]' + ), + array( + 'field' => 'province', + 'label' => 'province', + 'rules' => 'trim|min_length[0]|max_length[50]' + ), + array( + 'field' => 'country', + 'label' => 'country', + 'rules' => 'trim|min_length[0]|max_length[50]' + ), + array( + 'field' => 'headimgurl', + 'label' => 'headimgurl', + 'rules' => 'trim|required|min_length[3]|max_length[1000]' + ), + ); + $data = $this->json_validation($config); + $data['is_server'] = 1; + $ret = $this->customer_model->weixin_users($data); + if($ret){ + $this->success('成功'); + }else{ + $this->error('创建失败'); + } + } + +} diff --git a/controllers/api/user/Upgrade.bak.php b/controllers/api/user/Upgrade.bak.php new file mode 100644 index 0000000..6c26b17 --- /dev/null +++ b/controllers/api/user/Upgrade.bak.php @@ -0,0 +1,159 @@ +config->item('weixin_uah'); + $config = [ + 'app_id' => $conf['AppId'], + 'secret' => $conf['AppSecert'], + 'token' => $conf['Token'], + 'aes_key' => $conf['EncodingAESKey'], + 'response_type' => 'array', + 'payment'=>[ + // 必要配置 + 'app_id' => $conf['AppId'], + 'mch_id' => $conf['mch_id'], + 'key' => $conf['pay_api_key'], // API 密钥 + + // 如需使用敏感接口(如退款、发送红包等)需要配置 + 'cert_path' => $conf['pay_cert_path'], // 绝对路径 + 'key_path' => $conf['pay_key_path'], // 绝对路径 + + 'notify_url' => '默认的订单回调地址', // 下单时单独设置来覆盖它 + + //'sandbox_mode' => (ENVIRONMENT !== 'production'), // 设置为 false 或注释则关闭沙箱模式 + ] + ]; + return new OfficialAccount($config); + } + + //创建升级订单 + public function order_post() + { + $config = array( + array( + 'field' => 'id', + 'label' => 'ID', + 'rules' => 'trim|required|min_length[4]|max_length[20]' + ), + array( + 'field' => 'package_id', + 'label' => 'ID', + 'rules' => 'trim|required|min_length[1]|max_length[20]' + ) + ); + $data = $this->json_validation($config); + $this->load->model('sample_model'); + $sample = $this->sample_model->get($data['id'],'device_id'); + if(empty($sample)){ + $this->error('样品不存在'); + } + if($sample['package_id'] == $data['package_id']){ + $this->error('升级信息不正确'); + } + $this->load->model('package_model'); + $to_package = $this->package_model->get($data['package_id'],'id'); + $from_package = $this->package_model->get($sample['package_id'],'id'); + if(empty($to_package) || empty($from_package)){ + $this->error('套餐信息不存在'); + } + $total = $to_package['price'] - $from_package['price']; + //生成订单 + //同样订单升级方案只能创建一个订单 + $order_id = null; + $this->load->model('sample_upgrade_order_model'); + $order_list = $this->sample_upgrade_order_model->get($sample['id'],'base.sample_id',true); + foreach ($order_list as $value) { + if($value['package_before'] == $from_package['id'] && + $value['package_after'] == $to_package['id'] + ){ + if($value['paid_time'] > 0){ + $this->error('您的订单已支付'); + } + $order_id = $value['id']; + } + } + if(is_null($order_id)){ + $order_id = $this->sample_upgrade_order_model->add([ + 'sample_id'=>$sample['id'], + 'grand_total'=>$total, + 'package_before'=>$from_package['id'], + 'package_after'=>$to_package['id'], + 'grand_total'=>$total, + ]); + } + if(!$order_id){ + $this->error('订单创建失败'); + } + //获取用户的openid + $this->load->model('customer_model'); + $customer = $this->customer_model->get($sample['user_id'],'id'); + + $attributes = [ + 'body' => '有哈检测套餐升级', + 'out_trade_no' => 'testadsfdsffadsf', + //'total_fee' => (ENVIRONMENT !== 'production'?101:$total*100),//沙箱环境固定为1.01,正式环境固定为分 + 'total_fee' => $total*100,//单位:分 + //'spbill_create_ip' => '', // 可选,如不传该参数,SDK 将会自动获取相应 IP 地址 + 'notify_url' => base_url().'api/user/'.strtolower(__CLASS__).'/callback', // 支付结果通知网址,如果不设置则会使用配置里的默认地址 + 'trade_type' => 'JSAPI', // 请对应换成你的支付方式对应的值类型 + 'openid' => $customer['openid'], + ]; + $order = new WxPayOrder($attributes); + //print_r($attributes);die; + $app = $this->getApp(); + $result = $app->payment->prepare($order); + if ($result->return_code == 'SUCCESS' && $result->result_code == 'SUCCESS'){ + $prepayId = $result->prepay_id; + $json = $app->payment->configForPayment($prepayId,false); // 返回 json 字符串,如果想返回数组,传第二个参数 + $this->success($json); + } + //print_r($result);die; + log_message('error', json_encode($data).''.json_encode($result)); + $this->error('下单失败,请联系客服'); + } + + public function callback_get() + { + log_message('error',json_encode($_GET)); + log_message('error',json_encode($_POST)); + log_message('error',json_encode(file_get_contents('php://input'))); + $app = $this->getApp(); + $this->$app->payment->handleNotify(function($notify, $successful){ + // 使用通知里的 "微信支付订单号" 或者 "商户订单号" 去自己的数据库找到订单 + $this->load->model('sample_upgrade_order_model'); + $order = $this->sample_upgrade_order_model->get($notify->out_trade_no); + if (!$order) { // 如果订单不存在 + return 'Order not exist.'; // 告诉微信,我已经处理完了,订单没找到,别再通知我了 + } + // 如果订单存在 + // 检查订单是否已经更新过支付状态 + if ($order['paid_time']) { // 假设订单字段“支付时间”不为空代表已经支付 + return true; // 已经支付成功了就不再更新了 + } + $data = []; + // 用户是否支付成功 + if ($successful) { + // 不是已经支付状态则修改为已经支付状态 + $data['paid_time'] = time(); // 更新支付时间为当前时间 + $data['pay_status'] = 1; + } else { // 用户支付失败 + $data['pay_status'] = 2; + } + $this->sample_upgrade_order_model->update($data,[ + 'id'=>$notify->out_trade_no + ]); + return true; // 返回处理完成 + }); + } + +} diff --git a/controllers/api/user/Upgrade.php b/controllers/api/user/Upgrade.php new file mode 100644 index 0000000..a406442 --- /dev/null +++ b/controllers/api/user/Upgrade.php @@ -0,0 +1,213 @@ +load->library('session'); + } + + protected function getApp(){ + $conf = $this->config->item('weixin_uah'); + $config = [ + 'app_id' => $conf['AppId'], + 'secret' => $conf['AppSecert'], + 'token' => $conf['Token'], + 'aes_key' => $conf['EncodingAESKey'], + 'response_type' => 'array', + 'payment'=>[ + // 必要配置 + 'app_id' => $conf['AppId'], + 'mch_id' => $conf['mch_id'], + 'key' => $conf['pay_api_key'], // API 密钥 + + // 如需使用敏感接口(如退款、发送红包等)需要配置 + 'cert_path' => $conf['pay_cert_path'], // 绝对路径 + 'key_path' => $conf['pay_key_path'], // 绝对路径 + + 'notify_url' => '默认的订单回调地址', // 下单时单独设置来覆盖它 + + //'sandbox_mode' => (ENVIRONMENT !== 'production'), // 设置为 false 或注释则关闭沙箱模式 + ] + ]; + return new OfficialAccount($config); + } + + //创建升级订单 + public function order_post() + { + $config = array( + array( + 'field' => 'id', + 'label' => '样本编号', + 'rules' => 'trim|required|min_length[4]|max_length[20]', + 'errors' => array( + 'required' => '请提供以下信息:%s.', + ), + ) + ); + $data = $this->json_validation($config); + //样本信息 + $this->load->model('sample_model'); + $sample = $this->sample_model->get($data['id'],'device_id'); + if(!$sample){ + $this->error('样本不存在'); + } + //序列号信息 + $this->load->model('series_number_model'); + $series = $this->series_number_model->get($data['id'],'device_id'); + if(empty($series)){ + $this->error('序列号信息不存在'); + } + //如果样本中没有记录套餐,则根据序列号绑定的套餐做升级 + $package_ori = !empty($sample['package_id'])?$sample['package_id']:$series['package_ori']; + //套餐信息 + $this->load->model('package_model'); + $from_package = $this->package_model->get($package_ori); + if(empty($from_package['package_up'])){ + $this->error('您的套餐已经升级到最高套餐'); + } + $to_package = $this->package_model->get($from_package['package_up']); + if(empty($to_package)){ + $this->error('套餐信息不存在'); + } + $total = round($to_package['price'] - $from_package['price'],2); + if($total <= 0){ + $this->error('升级后套餐价格比当前套餐价格低'); + } + + //用户信息处理,获取用户的openid + $this->load->model('customer_model'); + if(!empty($this->session->{Customer_model::SESSION_KEY})){ + //如已登录,获取用户的open + $customer = $this->customer_model->get( + $this->session->{Customer_model::SESSION_KEY}, + 'id' + ); + //用户可能会被删除 + if($customer){ + $open_id = $customer['openid']; + } + } + if(empty($open_id) && !empty($this->session->{Customer_model::SESSION_KEY_WX_OPEN_ID})){ + $open_id = $this->session->{Customer_model::SESSION_KEY_WX_OPEN_ID}; + } + if(empty($open_id)){ + $this->success(['need_open_id'=>true]); + } + + + //生成订单,订单不能重复,每次都重新创建 + $this->load->model('sample_upgrade_order_model'); + /* + //同样订单升级方案只能创建一个订单 + $order_id = null; + $order_list = $this->sample_upgrade_order_model->get($sample['id'],'base.sample_id',true); + foreach ($order_list as $value) { + if($value['package_before'] == $from_package['id'] && + $value['package_after'] == $to_package['id'] + ){ + if($value['paid_time'] > 0){ + $this->error('您的订单已支付'); + } + //如果金额不一致,需要做金额修改 + if($total!=$value['grand_total']){ + $this->sample_upgrade_order_model->update([ + 'grand_total'=>$total, + ],[ + 'id'=>$value['id'] + ]); + } + $order_id = $value['id']; + break; + } + } + if(is_null($order_id)){ + }*/ + $order_id = $this->sample_upgrade_order_model->add([ + 'sample_id'=>$sample['id'], + 'package_before'=>$from_package['id'], + 'package_after'=>$to_package['id'], + 'grand_total'=>$total, + ]); + if(!$order_id){ + $this->error('订单创建失败'); + } + + $attributes = [ + 'body' => '有哈检测套餐升级', + 'out_trade_no' => $order_id, + //'total_fee' => (ENVIRONMENT !== 'production'?101:$total*100),//沙箱环境固定为1.01,正式环境固定为分 + 'total_fee' => round($total*100),//单位:分 + //'spbill_create_ip' => '', // 可选,如不传该参数,SDK 将会自动获取相应 IP 地址 + 'notify_url' => base_url().'api/user/'.strtolower(__CLASS__).'/callback', // 支付结果通知网址,如果不设置则会使用配置里的默认地址 + 'trade_type' => 'JSAPI', // 请对应换成你的支付方式对应的值类型 + 'openid' => $open_id, + ]; + //echo base_url().'api/user/'.strtolower(__CLASS__).'/callback';die; + $order = new WxPayOrder($attributes); + //print_r($attributes);die; + $app = $this->getApp(); + $result = $app->payment->prepare($order); + if ($result->return_code == 'SUCCESS' && $result->result_code == 'SUCCESS'){ + $prepayId = $result->prepay_id; + $json = $app->payment->configForPayment($prepayId,false); // 返回 json 字符串,如果想返回数组,传第二个参数 + $this->success($json); + } + //print_r($result);die; + log_message('error', json_encode($data).''.json_encode($result)); + $this->error('下单失败,请联系客服'); + } + + public function callback_post() + { + log_message('error',json_encode($_GET)); + log_message('error',json_encode($_POST)); + log_message('error',file_get_contents('php://input')); + $app = $this->getApp(); + $app->payment->handleNotify(function($notify, $successful){ + // 使用通知里的 "微信支付订单号" 或者 "商户订单号" 去自己的数据库找到订单 + $this->load->model('sample_upgrade_order_model'); + $order = $this->sample_upgrade_order_model->get($notify->out_trade_no); + if (!$order) { // 如果订单不存在 + return 'Order not exist.'; // 告诉微信,我已经处理完了,订单没找到,别再通知我了 + } + // 如果订单存在 + // 检查订单是否已经更新过支付状态 + if ($order['paid_time']) { // 假设订单字段“支付时间”不为空代表已经支付 + return true; // 已经支付成功了就不再更新了 + } + $data = []; + + // 用户是否支付成功 + if(!$successful){ + $data['pay_status'] = 2; + $this->sample_upgrade_order_model->update($data,[ + 'id'=>$notify->out_trade_no + ]); + return true; + } + $this->load->model('sample_model'); + $this->sample_model->update([ + 'package_id'=>$order['package_after'] + ],[ + 'id'=>$order['sample_id'] + ]); + + // 不是已经支付状态则修改为已经支付状态 + $data['paid_time'] = time(); // 更新支付时间为当前时间 + $data['pay_status'] = 1; + $this->sample_upgrade_order_model->update($data,[ + 'id'=>$notify->out_trade_no + ]); + //样本更改套餐 + + + return true; // 返回处理完成 + }); + } +} diff --git a/controllers/api/v1/Table.php b/controllers/api/v1/Table.php new file mode 100644 index 0000000..cd27d17 --- /dev/null +++ b/controllers/api/v1/Table.php @@ -0,0 +1,121 @@ +load->model('Api_model'); +// $this->load->model('Record_model'); +// $this->load->model('Dept_model', 'Dept'); +// $this->config->load('config', true); + } + + public function index() + { + $this->load->view('login_view'); + } + + public function testapi() + { + echo "test api ok..."; + } + + public function phpinfo() + { + phpinfo(); + } + + public function testdb() + { + $this->load->database(); + $query = $this->db->query("show tables"); + var_dump($query); + var_dump($query->result()); + var_dump($query->row_array()); +// 有结果表明数据库连接正常 reslut() 与 row_array 结果有时不太一样 +// 一般加载到时model里面使用。 + } + + + function list_get() + { + + $items = [ + ["id" => 1, + "title" => "www", + "status" => "draft", + "author" => "qiaokun", + "display_time" => "", + "pageviews" => 300 + ], + ["id" => 3, + "title" => "bbb", + "status" => "bbbb", + "author" => "乔锟", + "display_time" => "", + "pageviews" => 300 + ], + ]; + + $message = [ + "code" => 20000, + "data" => [ + "items" => $items + ] + ]; + + $this->set_response($message, REST_Controller::HTTP_OK); + + } + + function goods_get() + { + + $items = array( + array('id' => 1, 'title' => 'iphone 7 ', 'price' => 399, 'num' => 1), + array('id' => 2, 'title' => 'hdcms 7 ', 'price' => 2000, 'num' => 2), + array('id' => 3, 'title' => 'aaaas 7 ', 'price' => 2000, 'num' => 2), + array('id' => 4, 'title' => 'iphone 7 ', 'price' => 399, 'num' => 1), + array('id' => 5, 'title' => 'hdcms 7 ', 'price' => 2000, 'num' => 2), + array('id' => 6, 'title' => 'aaaas 7 ', 'price' => 2000, 'num' => 2), + array('id' => 7, 'title' => 'iphone 7 ', 'price' => 399, 'num' => 1), + array('id' => 8, 'title' => 'hdcms 7 ', 'price' => 2000, 'num' => 2), + array('id' => 9, 'title' => 'aaaas 7 ', 'price' => 2000, 'num' => 2), + array('id' => 10, 'title' => 'iphone 7 ', 'price' => 399, 'num' => 1), + array('id' => 11, 'title' => 'hdcms 7 ', 'price' => 2000, 'num' => 2), + array('id' => 31, 'title' => 'aaaas 7 ', 'price' => 2000, 'num' => 2), + array('id' => 13, 'title' => 'iphone 7 ', 'price' => 399, 'num' => 1), + array('id' => 24, 'title' => 'hdcms 7 ', 'price' => 2000, 'num' => 2), + array('id' => 35, 'title' => 'aaaas 7 ', 'price' => 2000, 'num' => 2), + array('id' => 19, 'title' => 'iphone 7 ', 'price' => 399, 'num' => 1), + array('id' => 22, 'title' => 'hdcms 7 ', 'price' => 2000, 'num' => 2), + array('id' => 33, 'title' => 'aaaas 7 ', 'price' => 2000, 'num' => 2), + ); + + $message = [ + "code" => 20000, + "data" => [ + "items" => $items + ] + ]; + + $this->set_response($message, REST_Controller::HTTP_OK); + + } + +} + +/* End of file welcome.php */ +/* Location: ./application/controllers/welcome.php */ \ No newline at end of file diff --git a/controllers/api/v1/Uploadimg.php b/controllers/api/v1/Uploadimg.php new file mode 100644 index 0000000..42bdfc2 --- /dev/null +++ b/controllers/api/v1/Uploadimg.php @@ -0,0 +1,325 @@ +load->model('Api_model'); + } + + + public function testapi_get() + { + echo "test api ok..."; + + echo APPPATH . "\n"; + echo SELF . "\n"; + echo BASEPATH . "\n"; + echo FCPATH . "\n"; + echo SYSDIR . "\n"; + var_dump($this->config->item('rest_language')); + var_dump($this->config->item('language')); + + var_dump($this->config); + } + + public function upload_post() + { + $uploadDir = FCPATH . 'uploads/'; + $id = 'T' . $this->POST('identify'); + $php_path = dirname(__FILE__) . '/';//dirname($_SERVER['DOCUMENT_ROOT']); dirname(__FILE__) +// $php_url = "";//dirname($_SERVER['HTTP_HOST']) . '/';//PHP_SELF + $php_url = $_SERVER['HTTP_HOST'] . '/'; //PHP_SELF + + $save_path = $uploadDir; + //文件保存目录URL + $save_url = $php_url . 'uploads/'; + // nginx服务器端修改绝对路径 + //$save_url = "http://172.30.3.11/static/home/kindeditor/attached/"; + + // var_dump($save_path); + // var_dump($save_url); + // string(46) "D:\Q\code\vue\CodeIgniter-3.1.10\uploads\imgs\" + // string(28) "www.cirest.com:8889/uploads/" + + + //定义允许上传的文件扩展名 + $ext_arr = array( + 'image' => array('gif', 'jpg', 'jpeg', 'png', 'bmp'), + 'flash' => array('swf', 'flv'), + 'media' => array('swf', 'flv', 'mp3', 'wav', 'wma', 'wmv', 'mid', 'avi', 'mpg', 'asf', 'rm', 'rmvb'), + 'file' => array('doc', 'docx', 'xls', 'xlsx', 'ppt', 'htm', 'html', 'txt', 'zip', 'rar', 'gz', 'bz2'), + ); + //最大文件大小 10M 默认是1M + $max_size = 10000000; + + $save_path = realpath($save_path) . '/'; + $save_path = str_replace('\\', '/', $save_path); + +//PHP上传失败 + if (!empty($_FILES['file']['error'])) { + switch ($_FILES['file']['error']) { + case '1': + $error = '超过php.ini允许的大小。'; + break; + case '2': + $error = '超过表单允许的大小。'; + break; + case '3': + $error = '图片只有部分被上传。'; + break; + case '4': + $error = '请选择图片。'; + break; + case '6': + $error = '找不到临时目录。'; + break; + case '7': + $error = '写文件到硬盘出错。'; + break; + case '8': + $error = 'File upload stopped by extension。'; + break; + case '999': + default: + $error = '未知错误。'; + } + $this->alert($error); + } + +//有上传文件时 + if (empty($_FILES) === false) { + //原文件名 + $file_name = $_FILES['file']['name']; + //服务器上临时文件名 + $tmp_name = $_FILES['file']['tmp_name']; + //文件大小 + $file_size = $_FILES['file']['size']; + //检查文件名 + if (!$file_name) { + $this->alert("请选择文件。"); + } + //检查目录 + if (@is_dir($save_path) === false) { + $this->alert("上传目录不存在。"); + } + //检查目录写权限 + if (@is_writable($save_path) === false) { + $this->alert("上传目录没有写权限。"); + } + //检查是否已上传 + if (@is_uploaded_file($tmp_name) === false) { + $this->alert("上传失败。"); + } + //检查文件大小 + if ($file_size > $max_size) { + $this->alert("上传文件大小超过限制(<10M)。"); + } + //检查目录名 + $dir_name = empty($_GET['dir']) ? 'image' : trim($_GET['dir']); + if (empty($ext_arr[$dir_name])) { + $this->alert("目录名不正确。"); + } + //获得文件扩展名 + $temp_arr = explode(".", $file_name); + $file_ext = array_pop($temp_arr); + $file_ext = trim($file_ext); + $file_ext = strtolower($file_ext); + + //检查扩展名 + if (!in_array($file_ext, $ext_arr[$dir_name])) { + $this->alert("上传文件扩展名是不允许的扩展名。\n只允许" . implode(",", $ext_arr[$dir_name]) . "格式。"); + + } + + /* + * 以 T+身份证号作为临时目录 , 以身份证作为正式目录 + */ + $identify = empty($id) ? '' : trim($id); + + if ($identify == '') { + echo "Invalid session identify."; + exit; + } + //创建文件夹 + if ($dir_name !== '') { + $save_path .= $dir_name . "/" . $identify . "/"; + $save_url .= $dir_name . "/" . $identify . "/"; + if (!file_exists($save_path)) { + mkdir($save_path, 0777, true); // true 允许创建多级目录 + } + } + $ymd = date("Ym"); + $save_path .= $ymd . "/"; + $save_url .= $ymd . "/"; + if (!file_exists($save_path)) { + mkdir($save_path); + } + //新文件名 + $new_file_name = date("YmdHis") . '_' . rand(10000, 99999) . '.' . $file_ext; + //移动文件 + $file_path = $save_path . $new_file_name; + if (move_uploaded_file($tmp_name, $file_path) === false) { + $this->alert("上传文件失败。"); + } + @chmod($file_path, 0644); + $file_url = $save_url . $new_file_name; + + header('Content-type: text/html; charset=UTF-8'); + // Insert file information in the database + // $insert = $db->query("INSERT INTO files (file_name, uploaded_on) VALUES ('".$fileName."', NOW())"); + $link = "http://" . $file_url; + // http://www.cirest.com:8889/uploads/image/T410000000000000000/201902/20190228071354_96833.png + $message = [ + "code" => 20000, + "error" => 0, + "message" => "上传成功", + "link" => $link, + "filepath" => preg_replace('/^http.*uploads/', '/uploads', $link) + ]; + + echo json_encode($message); + // $this->set_response($message, REST_Controller::HTTP_OK); + // alert里面使用时 exit() 产生的是空,或字符串,使用原生的json_encode返回统一的字符串,在客户端在统一处理成对象 + } + } + + public function delimg_post() + { + $php_path = dirname(__FILE__) . '/';//dirname($_SERVER['DOCUMENT_ROOT']); dirname(__FILE__) + + //文件保存目录路径 + $save_path = $php_path . '../../../../'; + + $save_path = realpath($save_path) . '/'; + $save_path = str_replace('\\', '/', $save_path); + // var_dump($save_path); + // "D:/Q/code/vue/CodeIgniter-3.1.10/" + + $DelFileName = $this->POST('filename'); + $DelFileType = $this->POST('isdir'); + + $FilePath = $save_path . $DelFileName; + + // var_dump($FilePath);return; + + if ($DelFileType == 'F') { + if (!is_file($FilePath)) { + $message = [ + "code" => 20000, + "data" => "文件不存在 - " . $DelFileName, + "message" => "文件不存在 - " . $DelFileName + ]; + + echo json_encode($message); + + } else { + + if (!unlink($FilePath)) { + $message = [ + "code" => 20000, + "data" => "Error deleting " . $FilePath, + "message" => "Error deleting " . $FilePath + ]; + echo json_encode($message); + + } else { + // 必须返回code 由于前端vue封装的 request 请求,返回数据对code进行判断 + $message = [ + "code" => 20000, + "data" => '服务器删除成功!', + "message" => '服务器删除成功!' + ]; + echo json_encode($message); + } + } + exit; + } + + if ($DelFileType == 'D') { + if (!@rmdir($FilePath)) { + echo "文件夹 " . $FilePath . " 不为空,不能删除!"; + } else { + echo "succeed"; + } + exit; + } + } + + private function alert($msg) + { + header('Content-type: text/html; charset=UTF-8'); + $message = [ + "code" => 20000, + "error" => 1, + "message" => $msg + ]; + echo json_encode($message); + exit(); + // var_dump($message); + // $this->set_response($message, REST_Controller::HTTP_OK); + // die(); + } + + + public function onsubmit_post() + { + $identify = $this->POST('identify'); + $phone = $this->POST('phone'); + $idinfo = $this->POST('idinfo'); + $bankinfo = $this->POST('bankinfo'); +// $data = [ +// 'identify' => $identify, +// 'phone' => $phone, +// 'idinfo' => $idinfo, +// 'check' => '待审核' +// ]; + + // 写入数据库表 身份证号,手机号,证件照,文件路径等 + $where = [ + 'identify' => $identify, + 'phone' => $phone, + ]; + + $data = [ + 'idinfo' => $idinfo, + 'bankinfo' => $bankinfo, + 'check' => '待审核' + ]; + + $result = $this->Api_model->saveEdit('upload_tbl', $data, $where); + + if ($result) { + $message = [ + "code" => 20000, + "message" => '写入数据库表成功,请请待审核通知!', + "data" => array_merge($where, $data) + ]; + $this->set_response($message, REST_Controller::HTTP_OK); + } else { + $message = [ + "code" => 20000, + "message" => '写入数据库表失败!', + "data" => array_merge($where, $data) + ]; + $this->set_response($message, REST_Controller::HTTP_OK); + } + } +} + +/* End of file welcome.php */ +/* Location: ./application/controllers/welcome.php */ \ No newline at end of file diff --git a/controllers/api/v1/User.php b/controllers/api/v1/User.php new file mode 100644 index 0000000..ac98fa5 --- /dev/null +++ b/controllers/api/v1/User.php @@ -0,0 +1,559 @@ +load->model('Api_model'); +// $this->load->model('Record_model'); +// $this->load->model('Dept_model', 'Dept'); +// $this->config->load('config', true); + } + + public function index_get() + { + $this->load->view('login_view'); + } + + public function testapi_get() + { + echo "test api ok..."; + + echo APPPATH . "\n"; + echo SELF . "\n"; + echo BASEPATH . "\n"; + echo FCPATH . "\n"; + echo SYSDIR . "\n"; + var_dump($this->config->item('rest_language')); + var_dump($this->config->item('language')); + + var_dump($this->config); + + } + + public function phpinfo_get() + { + phpinfo(); + } + + public function testdb_get() + { + $this->load->database(); + $query = $this->db->query("show tables"); + var_dump($query); + var_dump($query->result()); + var_dump($query->row_array()); +// 有结果表明数据库连接正常 reslut() 与 row_array 结果有时不太一样 +// 一般加载到时model里面使用。 + } + + + /* Helper Methods */ + /** + * 生成 token + * @param + * @return string 40个字符 + */ + private function _generate_token() + { + do { + // Generate a random salt + $salt = base_convert(bin2hex($this->security->get_random_bytes(64)), 16, 36); + + // If an error occurred, then fall back to the previous method + if ($salt === FALSE) { + $salt = hash('sha256', time() . mt_rand()); + } + + $new_key = substr($salt, 0, config_item('rest_key_length')); + } while ($this->_token_exists($new_key)); + + return $new_key; + } + + /* Private Data Methods */ + + private function _token_exists($token) + { + return $this->rest->db + ->where('token', $token) + ->count_all_results('auth') > 0; + } + + private function _insert_token($token, $data) + { + $data['token'] = $token; + $data['date_created'] = function_exists('now') ? now() : time(); + + return $this->rest->db + ->set($data) + ->insert('auth'); + } + + private function _update_token($token, $data) + { + return $this->rest->db + ->where('token', $token) + ->update('auth', $data); + } + + + function login_post() + { + $username = $this->post('username'); // POST param + $password = $this->post('password'); // POST param +// var_dump($username); +// var_dump($password); + $input_account = $username; + $input_password = md5($password); + // $result = $this->Api_model->app_user_login_validate($input_account, $input_password); + // 用户名密码正确 生成token 返回 + if (1) { + $token = $this->_generate_token(); +// "token" => $token + $message = [ + "code" => 20000, + "data" => [ + "token" => "admin-token" + ] + ]; + $this->set_response($message, REST_Controller::HTTP_OK); + } else { + $message = [ + "code" => 60204, + "message" => 'Account and password are incorrect.' + ]; + $this->set_response($message, REST_Controller::HTTP_OK); + } + } + + // 根据token拉取用户信息 get + function info_get() + { +// $result = $this->some_model(); + $result['success'] = TRUE; + + // 获取用户信息成功 + if ($result['success']) { + $info = [ + "roles" => ["editor"], + "introduction" => "I am a super administrator", + "avatar" => "https://wpimg.wallstcn.com/f778738c-e4f8-4870-b634-56703b4acafe.gif", + "name" => "Super Admin", + "identify" => "410000000000000000", + "phone" => "13633838282" + ]; + + $message = [ + "code" => 20000, + "data" => $info, + "_SERVER" => $_SERVER, + "_GET" => $_GET + ]; + $this->set_response($message, REST_Controller::HTTP_OK); + } else { + $message = [ + "code" => 50008, + "message" => 'Login failed, unable to get user details.' + ]; + + $this->set_response($message, REST_Controller::HTTP_OK); + } + + } + + function logout_post() + { + $message = [ + "code" => 20000, + "data" => 'success' + ]; + $this->set_response($message, REST_Controller::HTTP_OK); + } + + function login() + { + $this->SET_HEADER; // 设置php CI 处理 CORS 自定义头部 + + + if ($_SERVER["REQUEST_METHOD"] == 'POST') { // 只处理post请求,否则options请求 500错误 + $json_params = file_get_contents('php://input'); + $data = json_decode($json_params, true); + + if (!empty($data)) { + if (!empty($data['username']) && !empty($data['password'])) { + $username = $data['username']; + $password = $data['password']; + $input_account = $username; + $input_password = md5($password); + // $results = $this->phpIonicLoginAuthValidateLogin($username, $password); + $result = $this->Api_model->app_user_login_validate($input_account, $input_password); + + // $token=$_SERVER['x-auth-token']; + // 用户名密码正确 生成token 返回 + $token = $this->createToken(10000); + + $data = array( + "code" => 20000, + "data" => array( + "token" => "admin-token" +// "token" => $token + ), + "params" => $json_params + ); + + echo json_encode($data); + // 用户名密码不正确 +// return { +// code: +// 60204, +// message: 'Account and password are incorrect.' +// } + + + if ($result['success']) { + echo json_encode($this->saveLoginInfo($result['userinfo'])); + } else { + // 校验失败,写入token + $this->output->set_status_header(300); + echo '{"success": false,"message": "用户名或密码错误","jump":"","user":"' . $username . '"}'; + } + + } else { + $results = array( + "result" => "Error - data incomplete!", + ); + + $jsonData = json_encode($results); + echo $jsonData; + } + } else { // no data post + $results = array( + "result" => "Error - no data!", + ); + $jsonData = json_encode($results); + echo $jsonData; + } + } + } + + // 根据token拉取用户信息 get + function info() + { + $this->SET_HEADER; // 设置php CI 处理 CORS 自定义头部 + + if ($_SERVER["REQUEST_METHOD"] == 'GET') { // 只处理post请求,否则options请求 500错误 + $json_params = file_get_contents('php://input'); + $data = json_decode($json_params, true); + +// $token=$_SERVER['x-auth-token']; + +// 获取用户信息成功 + $info = array( + "roles" => array( + "admin" + ), + "introduction" => "I am a super administrator", + "avatar" => "https://wpimg.wallstcn.com/f778738c-e4f8-4870-b634-56703b4acafe.gif", + "name" => "Super Admin", + ); + + echo json_encode( + array( + "code" => 20000, + "data" => $info, + "_SERVER" => $_SERVER, + "_GET" => $_GET + ) + ); + +// 获取用户信息失败 +// return { +// code: 50008, +// message: 'Login failed, unable to get user details.' +// } +// echo json_encode( +// array( +// "code" => 50008, +// "message" => "Login failed, unable to get user details." +// ) +// ); + + return; + + if (!empty($data)) { + if (!empty($data['username']) && !empty($data['password'])) { + $username = $data['username']; + $password = $data['password']; + $input_account = $username; + $input_password = md5($password); + // $results = $this->phpIonicLoginAuthValidateLogin($username, $password); + $result = $this->Api_model->app_user_login_validate($input_account, $input_password); + + if ($result['success']) { + echo json_encode($this->saveLoginInfo($result['userinfo'])); + } else { + // 校验失败,写入token + $this->output->set_status_header(300); + echo '{"success": false,"message": "用户名或密码错误","jump":"","user":"' . $username . '"}'; + } + + } else { + $results = array( + "result" => "Error - data incomplete!", + ); + + $jsonData = json_encode($results); + echo $jsonData; + } + } else { // no data post + $results = array( + "result" => "Error - no data!", + ); + $jsonData = json_encode($results); + echo $jsonData; + } + } + } + + function logout() + { + $this->SET_HEADER; // 设置php CI 处理 CORS 自定义头部 + if ($_SERVER["REQUEST_METHOD"] == 'POST') { // 只处理post请求,否则options请求 500错误 + echo json_encode(array( + "code" => 20000, + "data" => 'sucess' + )); + } + } + + /* + * For 微信认证及全登录时保留登录日志信息 + */ + function saveLoginInfo($userinfo) + { + $token = md5($userinfo["name"] . date('y-m-d H:i:s', time())); + $arr2 = array('token' => $token); + $userinfo["token"] = $token; + $this->Bas->saveAdd( + 'auth', + array( + 'token' => $token, + 'expiredAt' => date('Y-m-d H:i:s', strtotime('+1 day')), + 'onlineIp' => $this->input->ip_address(), + 'userLoginInfo' => json_encode($userinfo), + 'creatorId' => $userinfo["name"], + 'createdAt' => date('Y-m-d H:i:s') + ) + ); + + // 返回信息 + $results = array( + "success" => true, + "message" => "APP登陆成功", + "user" => $userinfo, + 'session' => $_SESSION, + ); + + $this->Bas->saveEdit('userinfo', array('LASTLOGIN' => date('y-m-d H:i:s', time()), 'LASTIP' => $this->input->ip_address()), array('USERNAME' => $userinfo["name"])); + return $results; + } + + /** + * 执行CURL请求,并封装返回对象 + */ + private function execCURL($ch) + { + $response = curl_exec($ch); + $error = curl_error($ch); + $result = array('header' => '', + 'content' => '', + 'curl_error' => '', + 'http_code' => '', + 'last_url' => ''); + + if ($error != "") { + $result['curl_error'] = $error; + return $result; + } + + $header_size = curl_getinfo($ch, CURLINFO_HEADER_SIZE); + $result['header'] = str_replace(array("\r\n", "\r", "\n"), "
", substr($response, 0, $header_size)); + $result['content'] = substr($response, $header_size); + $result['http_code'] = curl_getinfo($ch, CURLINFO_HTTP_CODE); + $result['last_url'] = curl_getinfo($ch, CURLINFO_EFFECTIVE_URL); + $result["base_resp"] = array(); + $result["base_resp"]["ret"] = $result['http_code'] == 200 ? 0 : $result['http_code']; + $result["base_resp"]["err_msg"] = $result['http_code'] == 200 ? "ok" : $result["curl_error"]; + + return $result; + } + + /** + * GET 请求 + * @param string $url + */ + private function http_get($url) + { + $oCurl = curl_init(); + if (stripos($url, "https://") !== FALSE) { + curl_setopt($oCurl, CURLOPT_SSL_VERIFYPEER, FALSE); + curl_setopt($oCurl, CURLOPT_SSL_VERIFYHOST, FALSE); + curl_setopt($oCurl, CURLOPT_SSLVERSION, 1); //CURL_SSLVERSION_TLSv1 + } + curl_setopt($oCurl, CURLOPT_URL, $url); + curl_setopt($oCurl, CURLOPT_RETURNTRANSFER, 1); + curl_setopt($oCurl, CURLOPT_VERBOSE, 1); + curl_setopt($oCurl, CURLOPT_HEADER, 1); + + // $sContent = curl_exec($oCurl); + // $aStatus = curl_getinfo($oCurl); + $sContent = $this->execCURL($oCurl); + curl_close($oCurl); + + return $sContent; + } + + /** + * POST 请求 + * @param string $url + * @param array $param + * @param boolean $post_file 是否文件上传 + * @return string content + */ + private function http_post($url, $param, $post_file = false) + { + $oCurl = curl_init(); + + if (stripos($url, "https://") !== FALSE) { + curl_setopt($oCurl, CURLOPT_SSL_VERIFYPEER, FALSE); + curl_setopt($oCurl, CURLOPT_SSL_VERIFYHOST, false); + curl_setopt($oCurl, CURLOPT_SSLVERSION, 1); //CURL_SSLVERSION_TLSv1 + } + if (PHP_VERSION_ID >= 50500 && class_exists('\CURLFile')) { + $is_curlFile = true; + } else { + $is_curlFile = false; + if (defined('CURLOPT_SAFE_UPLOAD')) { + curl_setopt($oCurl, CURLOPT_SAFE_UPLOAD, false); + } + } + + if ($post_file) { + if ($is_curlFile) { + foreach ($param as $key => $val) { + if (isset($val["tmp_name"])) { + $param[$key] = new \CURLFile(realpath($val["tmp_name"]), $val["type"], $val["name"]); + } else if (substr($val, 0, 1) == '@') { + $param[$key] = new \CURLFile(realpath(substr($val, 1))); + } + } + } + $strPOST = $param; + } else { + $strPOST = json_encode($param); + } + + curl_setopt($oCurl, CURLOPT_URL, $url); + curl_setopt($oCurl, CURLOPT_RETURNTRANSFER, 1); + curl_setopt($oCurl, CURLOPT_POST, true); + curl_setopt($oCurl, CURLOPT_POSTFIELDS, $strPOST); + curl_setopt($oCurl, CURLOPT_VERBOSE, 1); + curl_setopt($oCurl, CURLOPT_HEADER, 1); + + // $sContent = curl_exec($oCurl); + // $aStatus = curl_getinfo($oCurl); + + $sContent = $this->execCURL($oCurl); + curl_close($oCurl); + + return $sContent; + } + + function weixinAuth() + { + session_start(); + if ($_SERVER["REQUEST_METHOD"] == 'OPTIONS') { + echo "options"; + die(); + } + // $corpId = "wwxxxxxxxx"; + // $agentId = "100000"; + // $appSecret = "fsdfsfsdf"; + // $localAuthUrl = "http://dj.xxx.com:7000/hotcode/"; + + if (!array_key_exists("code", $_REQUEST)) { + $redirectUri = urlencode("http://yw.cttha.com/ksh/get-corp-weixin-code.html?redirect_uri=" . urlencode($localAuthUrl)); + $authUrl = "https://open.weixin.qq.com/connect/oauth2/authorize?appid=" . $corpId . "&redirect_uri=" . $redirectUri . "&response_type=code&scope=snsapi_privateinfo&agentid=" . $agentId . "&state=STATE#wechat_redirect"; + echo json_encode(array("success" => false, "authUrl" => $authUrl)); + die(); + } + $getCorpAccessTokenUrl = "https://qyapi.weixin.qq.com/cgi-bin/gettoken?corpid=" . $corpId . "&corpsecret=" . $appSecret; + $accessToken = ""; + if (false && $_SESSION["weixinAuth_accessToken"] && $_SESSION["weixinAuth_tokenTime"] && $_SESSION["weixinAuth_tokenExpires"] && time() - intval($_SESSION["weixinAuth_tokenTime"]) < intval($_SESSION["tokenExpires"])) { + $accessToken = $_SESSION["weixinAuth_accessToken"]; + } else { + $tokenInfo = $this->http_get($getCorpAccessTokenUrl); + $tokenInfo = json_decode($tokenInfo["content"], true); + if ($tokenInfo["errcode"] == 0) { + $accessToken = $tokenInfo["access_token"]; + $_SESSION["weixinAuth_accessToke"] = $accessToken; + $_SESSION["weixinAuth_tokenTime"] = time(); + $_SESSION["weixinAuth_tokenExpires"] = $tokenInfo["expires_in"]; + } else { + echo json_encode(array("success" => false, "msg" => $tokenInfo["errmsg"] ? $tokenInfo["errmsg"] : "企业认证失败!")); + die(); + } + } + $getUserIdUrl = "https://qyapi.weixin.qq.com/cgi-bin/user/getuserinfo?access_token=" . $accessToken . "&code=" . $_REQUEST["code"]; + $ajaxUserIdInfo = $this->http_get($getUserIdUrl); + // var_dump($ajaxUserIdInfo);die(); + $userIdInfo = json_decode($ajaxUserIdInfo["content"], true); + if ($userIdInfo["errcode"] == 0) { + if (array_key_exists("OpenId", $userIdInfo)) { + echo json_encode(array("success" => false, "msg" => "不是企业成员!请联系企业管理员,添加您的账号的企业通讯录!")); + die(); + // next(U.error("不是企业成员!请联系企业管理员,添加您的账号的企业通讯录!")); + } else if (array_key_exists("UserId", $userIdInfo)) { + $getUserInfoUrl = "https://qyapi.weixin.qq.com/cgi-bin/user/getuserdetail?access_token=" . $accessToken; + // 44468cd93cdfefb8a7f911b5e1f7dfd0 + $data = array("user_ticket" => $userIdInfo["user_ticket"]); + $ajaxUserInfo = $this->http_post($getUserInfoUrl, $data); + $userInfo = json_decode($ajaxUserInfo["content"], true); + if ($userInfo["errcode"] == 0) { + $user = $this->Api_model->getUserByWxUserId($userIdInfo["UserId"]); + if ($user["success"]) { + echo json_encode($this->saveLoginInfo($user['userinfo'])); + die(); + } else { + $_SESSION["wxUserInfo"] = $userInfo; + echo json_encode(array("sessionid" => session_id(), "status" => -1, "success" => false, "msg" => "此微信账号(" . $userInfo["name"] . ")没有与系统账号关联,请用您的账号密码登录一次,完成首次绑定!")); + die(); + } + return; + } else { + echo json_encode(array("success" => false, "msg" => $userInfo["errmsg"])); + die(); + } + } + } else { + echo json_encode(array("success" => false, "msg" => $userIdInfo["errmsg"])); + die(); + } + } +} + +/* End of file welcome.php */ +/* Location: ./application/controllers/welcome.php */ \ No newline at end of file diff --git a/controllers/api/v2/Article.php b/controllers/api/v2/Article.php new file mode 100644 index 0000000..ed176b6 --- /dev/null +++ b/controllers/api/v2/Article.php @@ -0,0 +1,145 @@ +load->model('Base_model'); +// $this->load->model('Record_model'); +// $this->load->model('Dept_model', 'Dept'); +// $this->config->load('config', true); + } + + public function index() + { + $this->load->view('login_view'); + } + + public function testapi() + { + echo "test api ok..."; + } + + public function phpinfo() + { + phpinfo(); + } + + public function testdb() + { + $this->load->database(); + $query = $this->db->query("show tables"); + var_dump($query); + var_dump($query->result()); + var_dump($query->row_array()); +// 有结果表明数据库连接正常 reslut() 与 row_array 结果有时不太一样 +// 一般加载到时model里面使用。 + } + + + function list_get() + { + + $items = [ + ["id" => 1, + "timestamp" => "20180808", + + "author" => "qiaokun", + "reviewer" => "draft", + "title" => "draft", + "content_short" => "我是测试数据", + "content" => "

我是测试数据我是测试数据

", + "forecast" => '3.1515', + "importance" => '1', + "type|1" => 'CN', + "status" => 'published', + "display_time" => "", + "comment_disabled" => true, + "pageviews" => 300, + "image_uri" => "https://wpimg.wallstcn.com/e4558086-631c-425c-9430-56ffb46e70b3'", + "platforms" =>"a-platform" + ], + ["id" => 2, + "timestamp" => "20180808", + + "author" => "qiaokun", + "reviewer" => "draft", + "title" => "draft", + "content_short" => "我是测试数据", + "content" => "

我是测试数据我是测试数据

", + "forecast" => '3.1515', + "importance" => '1', + "type|1" => 'CN', + "status" => 'published', + "display_time" => "", + "comment_disabled" => true, + "pageviews" => 300, + "image_uri" => "https://wpimg.wallstcn.com/e4558086-631c-425c-9430-56ffb46e70b3'", + "platforms" =>"a-platform" + ], + ]; + + $message = [ + "code" => 20000, + "data" => [ + "items" => $items, + "total" => count($items) + ] + + ]; + + $this->set_response($message, REST_Controller::HTTP_OK); + + } + + function goods_get() + { + + $items = array( + array('id' => 1, 'title' => 'iphone 7 ', 'price' => 399, 'num' => 1), + array('id' => 2, 'title' => 'hdcms 7 ', 'price' => 2000, 'num' => 2), + array('id' => 3, 'title' => 'aaaas 7 ', 'price' => 2000, 'num' => 2), + array('id' => 4, 'title' => 'iphone 7 ', 'price' => 399, 'num' => 1), + array('id' => 5, 'title' => 'hdcms 7 ', 'price' => 2000, 'num' => 2), + array('id' => 6, 'title' => 'aaaas 7 ', 'price' => 2000, 'num' => 2), + array('id' => 7, 'title' => 'iphone 7 ', 'price' => 399, 'num' => 1), + array('id' => 8, 'title' => 'hdcms 7 ', 'price' => 2000, 'num' => 2), + array('id' => 9, 'title' => 'aaaas 7 ', 'price' => 2000, 'num' => 2), + array('id' => 10, 'title' => 'iphone 7 ', 'price' => 399, 'num' => 1), + array('id' => 11, 'title' => 'hdcms 7 ', 'price' => 2000, 'num' => 2), + array('id' => 31, 'title' => 'aaaas 7 ', 'price' => 2000, 'num' => 2), + array('id' => 13, 'title' => 'iphone 7 ', 'price' => 399, 'num' => 1), + array('id' => 24, 'title' => 'hdcms 7 ', 'price' => 2000, 'num' => 2), + array('id' => 35, 'title' => 'aaaas 7 ', 'price' => 2000, 'num' => 2), + array('id' => 19, 'title' => 'iphone 7 ', 'price' => 399, 'num' => 1), + array('id' => 22, 'title' => 'hdcms 7 ', 'price' => 2000, 'num' => 2), + array('id' => 33, 'title' => 'aaaas 7 ', 'price' => 2000, 'num' => 2), + ); + + $message = [ + "code" => 20000, + "data" => [ + "items" => $items + ] + ]; + + $this->set_response($message, REST_Controller::HTTP_OK); + + } + +} + +/* End of file welcome.php */ +/* Location: ./application/controllers/welcome.php */ \ No newline at end of file diff --git a/controllers/api/v2/Table.php b/controllers/api/v2/Table.php new file mode 100644 index 0000000..6675225 --- /dev/null +++ b/controllers/api/v2/Table.php @@ -0,0 +1,121 @@ +load->model('Base_model'); +// $this->load->model('Record_model'); +// $this->load->model('Dept_model', 'Dept'); +// $this->config->load('config', true); + } + + public function index() + { + $this->load->view('login_view'); + } + + public function testapi() + { + echo "test api ok..."; + } + + public function phpinfo() + { + phpinfo(); + } + + public function testdb() + { + $this->load->database(); + $query = $this->db->query("show tables"); + var_dump($query); + var_dump($query->result()); + var_dump($query->row_array()); +// 有结果表明数据库连接正常 reslut() 与 row_array 结果有时不太一样 +// 一般加载到时model里面使用。 + } + + + function list_get() + { + + $items = [ + ["id" => 1, + "title" => "www", + "status" => "draft", + "author" => "qiaokun", + "display_time" => "", + "pageviews" => 300 + ], + ["id" => 3, + "title" => "bbb", + "status" => "bbbb", + "author" => "乔锟", + "display_time" => "", + "pageviews" => 300 + ], + ]; + + $message = [ + "code" => 20000, + "data" => [ + "items" => $items + ] + ]; + + $this->set_response($message, REST_Controller::HTTP_OK); + + } + + function goods_get() + { + + $items = array( + array('id' => 1, 'title' => 'iphone 7 ', 'price' => 399, 'num' => 1), + array('id' => 2, 'title' => 'hdcms 7 ', 'price' => 2000, 'num' => 2), + array('id' => 3, 'title' => 'aaaas 7 ', 'price' => 2000, 'num' => 2), + array('id' => 4, 'title' => 'iphone 7 ', 'price' => 399, 'num' => 1), + array('id' => 5, 'title' => 'hdcms 7 ', 'price' => 2000, 'num' => 2), + array('id' => 6, 'title' => 'aaaas 7 ', 'price' => 2000, 'num' => 2), + array('id' => 7, 'title' => 'iphone 7 ', 'price' => 399, 'num' => 1), + array('id' => 8, 'title' => 'hdcms 7 ', 'price' => 2000, 'num' => 2), + array('id' => 9, 'title' => 'aaaas 7 ', 'price' => 2000, 'num' => 2), + array('id' => 10, 'title' => 'iphone 7 ', 'price' => 399, 'num' => 1), + array('id' => 11, 'title' => 'hdcms 7 ', 'price' => 2000, 'num' => 2), + array('id' => 31, 'title' => 'aaaas 7 ', 'price' => 2000, 'num' => 2), + array('id' => 13, 'title' => 'iphone 7 ', 'price' => 399, 'num' => 1), + array('id' => 24, 'title' => 'hdcms 7 ', 'price' => 2000, 'num' => 2), + array('id' => 35, 'title' => 'aaaas 7 ', 'price' => 2000, 'num' => 2), + array('id' => 19, 'title' => 'iphone 7 ', 'price' => 399, 'num' => 1), + array('id' => 22, 'title' => 'hdcms 7 ', 'price' => 2000, 'num' => 2), + array('id' => 33, 'title' => 'aaaas 7 ', 'price' => 2000, 'num' => 2), + ); + + $message = [ + "code" => 20000, + "data" => [ + "items" => $items + ] + ]; + + $this->set_response($message, REST_Controller::HTTP_OK); + + } + +} + +/* End of file welcome.php */ +/* Location: ./application/controllers/welcome.php */ \ No newline at end of file diff --git a/controllers/api/v2/Uploadimg.php b/controllers/api/v2/Uploadimg.php new file mode 100644 index 0000000..285e041 --- /dev/null +++ b/controllers/api/v2/Uploadimg.php @@ -0,0 +1,418 @@ +load->model('Base_model'); + } + + + public function testapi_get() + { + echo "test api ok..."; + + echo APPPATH . "\n"; + echo SELF . "\n"; + echo BASEPATH . "\n"; + echo FCPATH . "\n"; + echo SYSDIR . "\n"; + var_dump($this->config->item('rest_language')); + var_dump($this->config->item('language')); + + var_dump($this->config); + } + + public function upload_post() + { + $uploadDir = FCPATH . 'uploads/'; + $id = 'T' . $this->POST('identify'); + $php_path = dirname(__FILE__) . '/';//dirname($_SERVER['DOCUMENT_ROOT']); dirname(__FILE__) +// $php_url = "";//dirname($_SERVER['HTTP_HOST']) . '/';//PHP_SELF + $php_url = $_SERVER['HTTP_HOST'] . '/'; //PHP_SELF + + $save_path = $uploadDir; + //文件保存目录URL + $save_url = $php_url . 'uploads/'; + // nginx服务器端修改绝对路径 + //$save_url = "http://172.30.3.11/static/home/kindeditor/attached/"; + + // var_dump($save_path); + // var_dump($save_url); + // string(46) "D:\Q\code\vue\CodeIgniter-3.1.10\uploads\imgs\" + // string(28) "www.cirest.com:8889/uploads/" + + + //定义允许上传的文件扩展名 + $ext_arr = array( + 'image' => array('gif', 'jpg', 'jpeg', 'png', 'bmp'), + 'flash' => array('swf', 'flv'), + 'media' => array('swf', 'flv', 'mp3', 'wav', 'wma', 'wmv', 'mid', 'avi', 'mpg', 'asf', 'rm', 'rmvb'), + 'file' => array('doc', 'docx', 'xls', 'xlsx', 'ppt', 'htm', 'html', 'txt', 'zip', 'rar', 'gz', 'bz2'), + ); + //最大文件大小 10M 默认是1M + $max_size = 10000000; + + $save_path = realpath($save_path) . '/'; + $save_path = str_replace('\\', '/', $save_path); + +//PHP上传失败 + if (!empty($_FILES['file']['error'])) { + switch ($_FILES['file']['error']) { + case '1': + $error = '超过php.ini允许的大小。'; + break; + case '2': + $error = '超过表单允许的大小。'; + break; + case '3': + $error = '图片只有部分被上传。'; + break; + case '4': + $error = '请选择图片。'; + break; + case '6': + $error = '找不到临时目录。'; + break; + case '7': + $error = '写文件到硬盘出错。'; + break; + case '8': + $error = 'File upload stopped by extension。'; + break; + case '999': + default: + $error = '未知错误。'; + } + $this->alert($error); + } + +//有上传文件时 + if (empty($_FILES) === false) { + //原文件名 + $file_name = $_FILES['file']['name']; + //服务器上临时文件名 + $tmp_name = $_FILES['file']['tmp_name']; + //文件大小 + $file_size = $_FILES['file']['size']; + //检查文件名 + if (!$file_name) { + $this->alert("请选择文件。"); + } + //检查目录 + if (@is_dir($save_path) === false) { + $this->alert("上传目录不存在。"); + } + //检查目录写权限 + if (@is_writable($save_path) === false) { + $this->alert("上传目录没有写权限。"); + } + //检查是否已上传 + if (@is_uploaded_file($tmp_name) === false) { + $this->alert("上传失败。"); + } + //检查文件大小 + if ($file_size > $max_size) { + $this->alert("上传文件大小超过限制(<10M)。"); + } + //检查目录名 + $dir_name = empty($_GET['dir']) ? 'image' : trim($_GET['dir']); + if (empty($ext_arr[$dir_name])) { + $this->alert("目录名不正确。"); + } + //获得文件扩展名 + $temp_arr = explode(".", $file_name); + $file_ext = array_pop($temp_arr); + $file_ext = trim($file_ext); + $file_ext = strtolower($file_ext); + + //检查扩展名 + if (!in_array($file_ext, $ext_arr[$dir_name])) { + $this->alert("上传文件扩展名是不允许的扩展名。\n只允许" . implode(",", $ext_arr[$dir_name]) . "格式。"); + + } + + /* + * 以 T+身份证号作为临时目录 , 以身份证作为正式目录 + */ + $identify = empty($id) ? '' : trim($id); + + if ($identify == '') { + echo "Invalid session identify."; + exit; + } + //创建文件夹 + if ($dir_name !== '') { + $save_path .= $dir_name . "/" . $identify . "/"; + $save_url .= $dir_name . "/" . $identify . "/"; + if (!file_exists($save_path)) { + mkdir($save_path, 0777, true); // true 允许创建多级目录 + } + } + $ymd = date("Ym"); + $save_path .= $ymd . "/"; + $save_url .= $ymd . "/"; + if (!file_exists($save_path)) { + mkdir($save_path); + } + //新文件名 + $new_file_name = date("YmdHis") . '_' . rand(10000, 99999) . '.' . $file_ext; + //移动文件 + $file_path = $save_path . $new_file_name; + if (move_uploaded_file($tmp_name, $file_path) === false) { + $this->alert("上传文件失败。"); + } + @chmod($file_path, 0644); + $file_url = $save_url . $new_file_name; + + header('Content-type: text/html; charset=UTF-8'); + // Insert file information in the database + // $insert = $db->query("INSERT INTO files (file_name, uploaded_on) VALUES ('".$fileName."', NOW())"); + $link = "http://" . $file_url; + // http://www.cirest.com:8889/uploads/image/T410000000000000000/201902/20190228071354_96833.png + $message = [ + "code" => 20000, + "error" => 0, + "message" => "上传成功", + "link" => $link, + "filepath" => preg_replace('/^http.*uploads/', '/uploads', $link) + ]; + + echo json_encode($message); + // $this->set_response($message, REST_Controller::HTTP_OK); + // alert里面使用时 exit() 产生的是空,或字符串,使用原生的json_encode返回统一的字符串,在客户端在统一处理成对象 + } + } + + public function delimg_post() + { + $php_path = dirname(__FILE__) . '/';//dirname($_SERVER['DOCUMENT_ROOT']); dirname(__FILE__) + + //文件保存目录路径 + $save_path = $php_path . '../../../../'; + + $save_path = realpath($save_path) . '/'; + $save_path = str_replace('\\', '/', $save_path); + // var_dump($save_path); + // "D:/Q/code/vue/CodeIgniter-3.1.10/" + + $DelFileName = $this->POST('filename'); + $DelFileType = $this->POST('isdir'); + + $FilePath = $save_path . $DelFileName; + + // var_dump($FilePath);return; + + if ($DelFileType == 'F') { + if (!is_file($FilePath)) { + $message = [ + "code" => 20000, + "data" => "文件不存在 - " . $DelFileName, + "message" => "文件不存在 - " . $DelFileName + ]; + + echo json_encode($message); + + } else { + + if (!unlink($FilePath)) { + $message = [ + "code" => 20000, + "data" => "Error deleting " . $FilePath, + "message" => "Error deleting " . $FilePath + ]; + echo json_encode($message); + + } else { + // 必须返回code 由于前端vue封装的 request 请求,返回数据对code进行判断 + $message = [ + "code" => 20000, + "data" => '服务器删除成功!', + "message" => '服务器删除成功!' + ]; + echo json_encode($message); + } + } + exit; + } + + if ($DelFileType == 'D') { + if (!@rmdir($FilePath)) { + echo "文件夹 " . $FilePath . " 不为空,不能删除!"; + } else { + echo "succeed"; + } + exit; + } + } + + private function alert($msg) + { + header('Content-type: text/html; charset=UTF-8'); + $message = [ + "code" => 20000, + "error" => 1, + "message" => $msg + ]; + echo json_encode($message); + exit(); + // var_dump($message); + // $this->set_response($message, REST_Controller::HTTP_OK); + // die(); + } + + + public function onsubmit_post() + { + $identify = $this->POST('identify'); + $phone = $this->POST('phone'); + $idinfo = $this->POST('idinfo'); + $bankinfo = $this->POST('bankinfo'); +// $data = [ +// 'identify' => $identify, +// 'phone' => $phone, +// 'idinfo' => $idinfo, +// 'check' => '待审核' +// ]; + + // 写入数据库表 身份证号,手机号,证件照,文件路径等 + $where = [ + 'identify' => $identify, + 'phone' => $phone, + ]; + + $data = [ + 'idinfo' => $idinfo, + 'bankinfo' => $bankinfo, + 'check' => '待审核' + ]; + + $result = $this->Base_model->_update_key('upload_tbl', $data, $where); + + if ($result) { + $message = [ + "code" => 20000, + "message" => '写入数据库表成功,请请待审核通知!', + "data" => array_merge($where, $data) + ]; + $this->set_response($message, REST_Controller::HTTP_OK); + } else { + $message = [ + "code" => 20000, + "message" => '写入数据库表失败!', + "data" => array_merge($where, $data) + ]; + $this->set_response($message, REST_Controller::HTTP_OK); + } + } + + // Chevereto 图床免费版本地址:https://github.com/Chevereto/Chevereto-Free + // https://chevereto.com/docs/api-v1 + // 上传图片测试 + public function chevereto_post() + { + // 1. 上传本地文件时应使用 $fields post base64_encode方法 + // Always use POST when uploading local files. Url encoding may alter the base64 source + // due to encoded characters or just by URL request length limit due to GET request. + // base64编码 会导致过长 url request + // var_dump($_FILES); 参考 uploadimg 可以做一些前置校验处理 // 前置判断 if (empty($_FILES) === false) + $key = '5486424e4dfb6b87453dd4bb25c0dcb0'; + $url = 'http://172.17.1.110/chevereto/api/1/upload'; + + // What do we send to chevereto api? + $fields = array( + 'key' => urlencode($key), + // The image encoded in base64 + 'source' => base64_encode(file_get_contents($_FILES["file"]['tmp_name'])), + // format: txt / json txt 只返回图片地址或错误信息 eg.Duplicated upload 较为简洁 + 'format' => urlencode('json') + ); + + //open connection + $ch = curl_init(); + + //set the url, number of POST vars, POST data + curl_setopt($ch, CURLOPT_URL, $url); + curl_setopt($ch, CURLOPT_POST, sizeof($fields)); + curl_setopt($ch, CURLOPT_HEADER, false); + curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); + curl_setopt($ch, CURLOPT_TIMEOUT, 240); + curl_setopt($ch, CURLOPT_POSTFIELDS, $fields); + curl_setopt($ch, CURLOPT_HTTPHEADER, array('Expect: ')); + + //execute post + $result = curl_exec($ch); + //释放curl句柄 + curl_close($ch); + echo $result; + //close connection + + // 2. 上传远程图片地址可使用 _get source=urlencode{source} 方法即可 + +// $key = '6a55c7f9fa13813c2da613dc7b5b920b'; +// // 设定远程图片地址 +// $source = 'https://img3.doubanio.com/view/group_topic/large/public/p67032015.jpg'; +// // format: txt / json txt 只返回图片地址或错误信息 eg.Duplicated upload 较为简洁 +// $url = 'http://172.17.1.110:8888/api/1/upload/?key={key}&source={source}&format=txt'; +// $url = str_replace(array('{key}','{source}'),array($key,urlencode($source)),$url); +// +// //初始化 +// $ch = curl_init(); +// //设置选项,包括URL +// curl_setopt($ch, CURLOPT_URL, $url); +// curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); +// curl_setopt($ch, CURLOPT_HEADER, 0); +// //执行并获取HTML文档内容 +// $output = curl_exec($ch); +// //释放curl句柄 +// curl_close($ch); +// echo $output; + + +// 失败 +// { +// "status_txt": "Bad Request", +// "error": { +// "context": "Exception", +// "code": 102, +// "message": "Duplicated upload" +// }, +// "status_code": 400 +// } +// 成功 +// { +// "status_txt": "OK", +// "image": { +// "image": { +// "size": "89163", +// "url": "http://172.17.1.110:8888/images/2019/07/09/p67032015.jpg", +// "extension": "jpg", +// "mime": "image/jpeg", +// "name": "p67032015", +// "filename": "p67032015.jpg" +// }, +// }, +// "success": { +// "code": 200, +// "message": "image uploaded" +// }, +// "status_code": 200 +// } + + } + +} diff --git a/controllers/api/v2/sys/Menu.php b/controllers/api/v2/sys/Menu.php new file mode 100644 index 0000000..949b7c7 --- /dev/null +++ b/controllers/api/v2/sys/Menu.php @@ -0,0 +1,358 @@ +load->model('Base_model'); + // $this->config->load('config', true); + } + + public function index_get() + { + $this->load->view('login_view'); + } + + public function insertx_post() + { + // $id = $this->post('id'); // POST param + $parms = $this->post(); // 获取表单参数,类型为数组 + var_dump($parms); + $result = $this->Base_model->_insert_key('sys_role_perm', $parms); + var_dump($result); + } + + public function gettest_post() + { + $result = $this->Base_model->_get_key('sys_perm', 'perm_type,r_id rid', 'perm_type="role" and r_id=1'); + var_dump($result); + var_dump($result[0]['perm_type']); + var_dump($this->uri->uri_string); + var_dump($this->uri); + + } + + + public function testapi_get() + { + echo "test api ok..."; + + echo APPPATH . "\n"; + echo SELF . "\n"; + echo BASEPATH . "\n"; + echo FCPATH . "\n"; + echo SYSDIR . "\n"; + var_dump($this->config->item('rest_language')); + var_dump($this->config->item('language')); + + var_dump($this->config); + +// $message = [ +// "code" => 20000, +// "data" => [ +// "__FUNCTION__" => __FUNCTION__, +// "__CLASS__" => __CLASS__, +// "uri" => $this->uri +// ], +// +// ]; +// "data": { +// "__FUNCTION__": "router_get", +// "__CLASS__": "User", +// "uri": { +// "keyval": [], +// "uri_string": "api/v2/user/router", +// "segments": { +// "1": "api", +// "2": "v2", +// "3": "user", +// "4": "router" +// }, + } + + public function phpinfo_get() + { + phpinfo(); + } + + public function testdb_get() + { + $this->load->database(); + $query = $this->db->query("show tables"); + var_dump($query); + var_dump($query->result()); + var_dump($query->row_array()); +// 有结果表明数据库连接正常 reslut() 与 row_array 结果有时不太一样 +// 一般加载到时model里面使用。 + } + + // 增 + function add_post() + { + $uri = $this->uri->uri_string; + $Token = $this->input->get_request_header('X-Token', TRUE); + $retPerm = $this->permission->HasPermit($Token, $uri); + if ($retPerm['code'] != 50000) { + $this->set_response($retPerm, REST_Controller::HTTP_OK); + return; + } + + // $id = $this->post('id'); // POST param + $parms = $this->post(); // 获取表单参数,类型为数组 + // var_dump($parms); + // var_dump($parms['path']); + + // 参数检验/数据预处理 + // 菜单类型为目录 + if (!$parms['type']) { + $parms['component'] = 'Layout'; + } + + $menu_id = $this->Base_model->_insert_key('sys_menu', $parms); + if (!$menu_id) { + $message = [ + "code" => 20000, + "type" => 'error', + "message" => $parms['title'] . ' - 菜单添加失败' + ]; + $this->set_response($message, REST_Controller::HTTP_OK); + return; + } + + // 生成该菜单对应的权限: sys_perm, 权限类型为: menu, 生成唯一的 perm_id + $perm_id = $this->Base_model->_insert_key('sys_perm', ['perm_type' => 'menu', "r_id" => $menu_id]); + if (!$perm_id) { + var_dump($this->uri->uri_string . ' 生成该菜单对应的权限: sys_perm, 失败...'); + var_dump(['perm_type' => 'menu', "r_id" => $menu_id]); + return; + } + + // 超级管理员角色自动拥有该权限 perm_id + $role_perm_id = $this->Base_model->_insert_key('sys_role_perm', ["role_id" => 1, "perm_id" => $perm_id]); + if (!$role_perm_id) { + var_dump($this->uri->uri_string . ' 超级管理员角色自动拥有该权限 perm_id, 失败...'); + var_dump(["role_id" => 1, "perm_id" => $perm_id]); + return; + } + + $message = [ + "code" => 20000, + "type" => 'success', + "message" => $parms['title'] . ' - 菜单添加成功' + ]; + $this->set_response($message, REST_Controller::HTTP_OK); + } + + // 改 + function edit_post() + { + $uri = $this->uri->uri_string; + $Token = $this->input->get_request_header('X-Token', TRUE); + $retPerm = $this->permission->HasPermit($Token, $uri); + if ($retPerm['code'] != 50000) { + $this->set_response($retPerm, REST_Controller::HTTP_OK); + return; + } + + // $id = $this->post('id'); // POST param + $parms = $this->post(); // 获取表单参数,类型为数组 + // var_dump($parms['path']); + + // 参数检验/数据预处理 + if ($parms['id'] == $parms['pid']) { + $message = [ + "code" => 20000, + "type" => 'error', + "message" => '父节点不能是自己' + ]; + $this->set_response($message, REST_Controller::HTTP_OK); + } + // 菜单类型为目录 + if ($parms['type'] == 0) { + $parms['component'] = 'Layout'; + } + // 菜单类型为功能按钮时 + if ($parms['type'] == 2) { + $parms['component'] = ''; + $parms['icon'] = ''; + } + + $id = $parms['id']; + unset($parms['id']); // 择出索引id + $where = ["id" => $id]; + + if (!$this->Base_model->_update_key('sys_menu', $parms, $where)) { + $message = [ + "code" => 20000, + "type" => 'error', + "message" => $parms['title'] . ' - 菜单更新错误' + ]; + $this->set_response($message, REST_Controller::HTTP_OK); + return; + } + + $message = [ + "code" => 20000, + "type" => 'success', + "message" => $parms['title'] . ' - 菜单更新成功' + ]; + $this->set_response($message, REST_Controller::HTTP_OK); + } + + // 删 + function del_post() + { + $uri = $this->uri->uri_string; + $Token = $this->input->get_request_header('X-Token', TRUE); + $retPerm = $this->permission->HasPermit($Token, $uri); + if ($retPerm['code'] != 50000) { + $this->set_response($retPerm, REST_Controller::HTTP_OK); + return; + } + + $parms = $this->post(); // 获取表单参数,类型为数组 + // var_dump($parms['path']); + + // 参数检验/数据预处理 + // 存在子节点 不能删除返回 + $hasChild = $this->Base_model->hasChildMenu($parms['id']); + if ($hasChild) { + $message = [ + "code" => 20000, + "type" => 'error', + "message" => $parms['title'] . ' - 存在子节点不能删除' + ]; + $this->set_response($message, REST_Controller::HTTP_OK); + return; + } + + // 删除外键关联表 sys_role_perm , sys_perm, sys_menu + // 1. 根据sys_menu id及'menu' 查找 perm_id + // 2. 删除sys_role_perm 中perm_id记录 + // 3. 删除sys_perm中 perm_type='menu' and r_id = menu_id 记录,即第1步中获取的 perm_id, 一一对应 + // 4. 删除sys_menu 中 id = menu_id 的记录 + $where = 'perm_type="menu" and r_id=' . $parms['id']; + $arr = $this->Base_model->_get_key('sys_perm', '*', $where); + if (empty($arr)) { + var_dump($this->uri->uri_string . ' 未查找到 sys_perm 表中记录'); + var_dump($where); + return; + } + + $perm_id = $arr[0]['id']; // 正常只有一条记录 + $this->Base_model->_delete_key('sys_role_perm', ['perm_id' => $perm_id]); + $this->Base_model->_delete_key('sys_perm', ['id' => $perm_id]); + + // 删除基础表 sys_menu + if (!$this->Base_model->_delete_key('sys_menu', $parms)) { + $message = [ + "code" => 20000, + "type" => 'error', + "message" => $parms['title'] . ' - 菜单删除错误' + ]; + $this->set_response($message, REST_Controller::HTTP_OK); + return; + } + + $message = [ + "code" => 20000, + "type" => 'success', + "message" => $parms['title'] . ' - 菜单删除成功' + ]; + $this->set_response($message, REST_Controller::HTTP_OK); + + } + + // 查 + function view_post() + { + $uri = $this->uri->uri_string; + $Token = $this->input->get_request_header('X-Token', TRUE); + + $retPerm = $this->permission->HasPermit($Token, $uri); + if ($retPerm['code'] != 50000) { + $this->set_response($retPerm, REST_Controller::HTTP_OK); + return; + } + + $MenuTreeArr = $this->permission->getPermission($Token, 'menu', true); + $MenuTree = $this->permission->genVueMenuTree($MenuTreeArr, 'id', 'pid', 0); + $message = [ + "code" => 20000, + "data" => $MenuTree, + ]; + $this->set_response($message, REST_Controller::HTTP_OK); + } + + // 根据token拉取 treeselect 下拉选项菜单 + function treeoptions_get() + { + // 此 uri 可不做权限/token过期验证,则在菜单里,可以不加入此项路由path /sys/menu/treeoptions。 + // + // $uri = $this->uri->uri_string; + // $Token = $this->input->get_request_header('X-Token', TRUE); + // $retPerm = $this->permission->HasPermit($Token, $uri); + // if ($retPerm['code'] != 50000) { + // $this->set_response($retPerm, REST_Controller::HTTP_OK); + // return; + // } + + $Token = $this->input->get_request_header('X-Token', TRUE); + + $MenuTreeArr = $this->permission->getPermission($Token, 'menu', false); + array_unshift($MenuTreeArr, ['id' => 0, 'pid' => -1, 'title' => '顶级菜单']); + $MenuTree = $this->permission->genVueMenuTree($MenuTreeArr, 'id', 'pid', -1); + + $message = [ + "code" => 20000, + "data" => $MenuTree, + ]; + $this->set_response($message, REST_Controller::HTTP_OK); + } + + + function list_get() + { +// $result = $this->some_model(); + $result['success'] = TRUE; + + if ($result['success']) { + $List = array( + array('order_no' => '201805138451313131', 'timestamp' => 'iphone 7 ', 'username' => 'iphone 7 ', 'price' => 399, 'status' => 'success'), + array('order_no' => '300000000000000000', 'timestamp' => 'iphone 7 ', 'username' => 'iphone 7 ', 'price' => 399, 'status' => 'pending'), + array('order_no' => '444444444444444444', 'timestamp' => 'iphone 7 ', 'username' => 'iphone 7 ', 'price' => 399, 'status' => 'success'), + array('order_no' => '888888888888888888', 'timestamp' => 'iphone 7 ', 'username' => 'iphone 7 ', 'price' => 399, 'status' => 'pending'), + ); + + $message = [ + "code" => 20000, + "data" => [ + "total" => count($List), + "items" => $List + ] + ]; + $this->set_response($message, REST_Controller::HTTP_OK); + } else { + $message = [ + "code" => 50008, + "message" => 'Login failed, unable to get user details.' + ]; + + $this->set_response($message, REST_Controller::HTTP_OK); + } + + } + +} diff --git a/controllers/api/v2/sys/Role.php b/controllers/api/v2/sys/Role.php new file mode 100644 index 0000000..b53373b --- /dev/null +++ b/controllers/api/v2/sys/Role.php @@ -0,0 +1,478 @@ +load->model('Base_model'); + $this->load->model('Role_model'); + // $this->config->load('config', true); + } + + public function index_get() + { + $this->load->view('login_view'); + } + + public function insertx_post() + { + // $id = $this->post('id'); // POST param + $parms = $this->post(); // 获取表单参数,类型为数组 + var_dump($parms); + $result = $this->Base_model->_insert_key('sys_role_perm', $parms); + var_dump($result); + } + + public function gettest_post() + { + $result = $this->Base_model->_get_key('sys_perm', 'perm_type,r_id rid', 'perm_type="role" and r_id=1'); + var_dump($result); + var_dump($result[0]['perm_type']); + var_dump($this->uri->uri_string); + var_dump($this->uri); + + } + + + public function testapi_get() + { + echo "test api ok..."; + + echo APPPATH . "\n"; + echo SELF . "\n"; + echo BASEPATH . "\n"; + echo FCPATH . "\n"; + echo SYSDIR . "\n"; + var_dump($this->config->item('rest_language')); + var_dump($this->config->item('language')); + + var_dump($this->config); + +// $message = [ +// "code" => 20000, +// "data" => [ +// "__FUNCTION__" => __FUNCTION__, +// "__CLASS__" => __CLASS__, +// "uri" => $this->uri +// ], +// +// ]; +// "data": { +// "__FUNCTION__": "router_get", +// "__CLASS__": "User", +// "uri": { +// "keyval": [], +// "uri_string": "api/v2/user/router", +// "segments": { +// "1": "api", +// "2": "v2", +// "3": "user", +// "4": "router" +// }, + } + + public function phpinfo_get() + { + phpinfo(); + } + + public function testdb_get() + { + $this->load->database(); + $query = $this->db->query("show tables"); + var_dump($query); + var_dump($query->result()); + var_dump($query->row_array()); +// 有结果表明数据库连接正常 reslut() 与 row_array 结果有时不太一样 +// 一般加载到时model里面使用。 + } + + // 增 + function add_post() + { + $uri = $this->uri->uri_string; + $Token = $this->input->get_request_header('X-Token', TRUE); + $retPerm = $this->permission->HasPermit($Token, $uri); + if ($retPerm['code'] != 50000) { + $this->set_response($retPerm, REST_Controller::HTTP_OK); + return; + } + + $parms = $this->post(); // 获取表单参数,类型为数组 + + if ($this->Base_model->_key_exists('sys_role', ['name' => $parms['name']])) { + $message = [ + "code" => 20000, + "type" => 'error', + "message" => $parms['name'] . ' - 角色名重复' + ]; + $this->set_response($message, REST_Controller::HTTP_OK); + return; + } + + // 加入新增时间 + $parms['create_time'] = time(); + + $role_id = $this->Base_model->_insert_key('sys_role', $parms); + if (!$role_id) { + $message = [ + "code" => 20000, + "type" => 'error', + "message" => $parms['name'] . ' - 角色新增失败' + ]; + $this->set_response($message, REST_Controller::HTTP_OK); + return; + } + + // 生成该角色对应的权限: sys_perm, 权限类型为: role, 生成唯一的 perm_id + $perm_id = $this->Base_model->_insert_key('sys_perm', ['perm_type' => 'role', "r_id" => $role_id]); + if (!$perm_id) { + var_dump($this->uri->uri_string . ' 生成该角色对应的权限: sys_perm, 失败...'); + var_dump(['perm_type' => 'role', "r_id" => $role_id]); + return; + } + + // 超级管理员角色自动拥有该权限 perm_id + $role_perm_id = $this->Base_model->_insert_key('sys_role_perm', ["role_id" => 1, "perm_id" => $perm_id]); + if (!$role_perm_id) { + var_dump($this->uri->uri_string . ' 超级管理员角色自动拥有该权限 perm_id, 失败...'); + var_dump(["role_id" => 1, "perm_id" => $perm_id]); + return; + } + + $message = [ + "code" => 20000, + "type" => 'success', + "message" => $parms['name'] . ' - 角色新增成功' + ]; + $this->set_response($message, REST_Controller::HTTP_OK); + } + + // 改 + function edit_post() + { + $uri = $this->uri->uri_string; + $Token = $this->input->get_request_header('X-Token', TRUE); + $retPerm = $this->permission->HasPermit($Token, $uri); + if ($retPerm['code'] != 50000) { + $this->set_response($retPerm, REST_Controller::HTTP_OK); + return; + } + + // $id = $this->post('id'); // POST param + $parms = $this->post(); // 获取表单参数,类型为数组 + // var_dump($parms['path']); + + // 参数检验/数据预处理 + // 超级管理员角色不允许修改 + if ($parms['id'] == 1) { + $message = [ + "code" => 20000, + "type" => 'error', + "message" => $parms['name'] . ' - 角色不允许修改' + ]; + $this->set_response($message, REST_Controller::HTTP_OK); + return; + } + + $id = $parms['id']; + unset($parms['id']); // 剃除索引id + + // 加入更新时间 + $parms['update_time'] = time(); + $where = ["id" => $id]; + + if (!$this->Base_model->_update_key('sys_role', $parms, $where)) { + $message = [ + "code" => 20000, + "type" => 'error', + "message" => $parms['name'] . ' - 角色更新错误' + ]; + $this->set_response($message, REST_Controller::HTTP_OK); + return; + } + + $message = [ + "code" => 20000, + "type" => 'success', + "message" => $parms['name'] . ' - 角色更新成功' + ]; + $this->set_response($message, REST_Controller::HTTP_OK); + } + + // 删 + function del_post() + { + $uri = $this->uri->uri_string; + $Token = $this->input->get_request_header('X-Token', TRUE); + $retPerm = $this->permission->HasPermit($Token, $uri); + if ($retPerm['code'] != 50000) { + $this->set_response($retPerm, REST_Controller::HTTP_OK); + return; + } + + $parms = $this->post(); // 获取表单参数,类型为数组 + // var_dump($parms['path']); + + // 参数检验/数据预处理 + // 超级管理员角色不允许删除 + if ($parms['id'] == 1) { + $message = [ + "code" => 20000, + "type" => 'error', + "message" => $parms['name'] . ' - 角色不允许删除' + ]; + $this->set_response($message, REST_Controller::HTTP_OK); + return; + } + + // 删除外键关联表 sys_role_perm , sys_perm, sys_role + // 1. 根据sys_role id及'menu' 查找 perm_id + // 2. 删除sys_role_perm 中perm_id记录 + // 3. 删除sys_perm中 perm_type='role' and r_id = role_id 记录,即第1步中获取的 perm_id, 一一对应 + // 4. 删除sys_role 中 id = role_id 的记录 + $where = 'perm_type="role" and r_id=' . $parms['id']; + $arr = $this->Base_model->_get_key('sys_perm', '*', $where); + if (empty($arr)) { + var_dump($this->uri->uri_string . ' 未查找到 sys_perm 表中记录'); + var_dump($where); + return; + } + + $perm_id = $arr[0]['id']; // 正常只有一条记录 + $this->Base_model->_delete_key('sys_role_perm', ['perm_id' => $perm_id]); // 必须删除权限id 因为超级管理员角色自动拥有该权限否则会造成删除关联错误 + $this->Base_model->_delete_key('sys_role_perm', ['role_id' => $parms['id']]); // 再删除该角色对应的权限id(原有的菜单) + $this->Base_model->_delete_key('sys_perm', ['id' => $perm_id]); + + $this->Base_model->_delete_key('sys_user_role', ['role_id' => $parms['id']]); + + // 删除基础表 sys_role + if (!$this->Base_model->_delete_key('sys_role', $parms)) { + $message = [ + "code" => 20000, + "type" => 'error', + "message" => $parms['name'] . ' - 角色删除错误' + ]; + $this->set_response($message, REST_Controller::HTTP_OK); + return; + } + + $message = [ + "code" => 20000, + "type" => 'success', + "message" => $parms['name'] . ' - 角色删除成功' + ]; + $this->set_response($message, REST_Controller::HTTP_OK); + + } + + // 查 + function view_post() + { + $uri = $this->uri->uri_string; + $Token = $this->input->get_request_header('X-Token', TRUE); + + $retPerm = $this->permission->HasPermit($Token, $uri); + if ($retPerm['code'] != 50000) { + $this->set_response($retPerm, REST_Controller::HTTP_OK); + return; + } + + $RoleArr = $this->Role_model->getRoleList(); + $message = [ + "code" => 20000, + "data" => $RoleArr, + ]; + $this->set_response($message, REST_Controller::HTTP_OK); + } + + // 获取所有菜单 不需权限验证 + function allmenus_get() + { + $MenuTreeArr = $this->Role_model->getAllMenus(); + if (empty($MenuTreeArr)) { + $message = [ + "code" => 20000, + "data" => $MenuTreeArr, + "message" => "数据库表中没有菜单" + ]; + $this->set_response($message, REST_Controller::HTTP_OK); + return; + } + + $MenuTree = $this->permission->genVueMenuTree($MenuTreeArr, 'id', 'pid', 0); + $message = [ + "code" => 20000, + "data" => $MenuTree, + ]; + $this->set_response($message, REST_Controller::HTTP_OK); + } + + // 获取所有角色带perm_id 不需权限验证 + function allroles_get() + { + $AllRolesArr = $this->Role_model->getAllRoles(); + if (empty($AllRolesArr)) { + $message = [ + "code" => 20000, + "data" => $AllRolesArr, + "message" => "数据库表中没有角色" + ]; + $this->set_response($message, REST_Controller::HTTP_OK); + return; + } + + $message = [ + "code" => 20000, + "data" => $AllRolesArr, + ]; + $this->set_response($message, REST_Controller::HTTP_OK); + } + + // 获取角色拥有的菜单权限 不需权限验证 + function rolemenu_post() + { + $parms = $this->post(); // 获取表单参数,类型为数组 + $RoleId = $parms['roleId']; + + $MenuTreeArr = $this->Role_model->getRoleMenu($RoleId); + $message = [ + "code" => 20000, + "data" => $MenuTreeArr, + ]; + $this->set_response($message, REST_Controller::HTTP_OK); + } + + // 获取角色拥有的角色权限 不需权限验证 + function rolerole_post() + { + $parms = $this->post(); // 获取表单参数,类型为数组 + $RoleId = $parms['roleId']; + + $RoleRoleArr = $this->Role_model->getRoleRole($RoleId); + $message = [ + "code" => 20000, + "data" => $RoleRoleArr, + ]; + $this->set_response($message, REST_Controller::HTTP_OK); + } + + // 保存角色对应权限 + function saveroleperm_post() + { + $parms = $this->post(); // 获取表单参数,类型为数组 + // var_dump($parms['roleId']); + // var_dump($parms['rolePerms']); + // 参数检验/数据预处理 + // 超级管理员角色不允许删除 + if ($parms['roleId'] == 1) { + $message = [ + "code" => 20000, + "type" => 'error', + "message" => '超级管理员角色拥有所有权限,不允许修改!' + ]; + $this->set_response($message, REST_Controller::HTTP_OK); + return; + } + + $RolePermArr = $this->Role_model->getRolePerm($parms['roleId']); + + $AddArr = $this->permission->array_diff_assoc2($parms['rolePerms'], $RolePermArr); + // var_dump('------------只存在于前台传参 做添加操作-------------'); + // var_dump($AddArr); + $failed = false; + $failedArr = []; + foreach ($AddArr as $k => $v) { + $ret = $this->Base_model->_insert_key('sys_role_perm', $v); + if (!$ret) { + $failed = true; + array_push($failedArr, $v); + } + } + if ($failed) { + $message = [ + "code" => 20000, + "type" => 'error', + "message" => '授权失败 ' . json_encode($failedArr) + ]; + $this->set_response($message, REST_Controller::HTTP_OK); + return; + } + + $DelArr = $this->permission->array_diff_assoc2($RolePermArr, $parms['rolePerms']); + // var_dump('------------只存在于后台数据库 删除操作-------------'); + // var_dump($DelArr); + $failed = false; + $failedArr = []; + foreach ($DelArr as $k => $v) { + $ret = $this->Base_model->_delete_key('sys_role_perm', $v); + if (!$ret) { + $failed = true; + array_push($failedArr, $v); + } + } + if ($failed) { + $message = [ + "code" => 20000, + "type" => 'error', + "message" => '授权失败 ' . json_encode($failedArr) + ]; + $this->set_response($message, REST_Controller::HTTP_OK); + return; + } + + $message = [ + "code" => 20000, + "type" => 'success', + "data" => $parms, + "message" => '授权操作成功', + ]; + $this->set_response($message, REST_Controller::HTTP_OK); + } + + + function list_get() + { +// $result = $this->some_model(); + $result['success'] = TRUE; + + if ($result['success']) { + $List = array( + array('order_no' => '201805138451313131', 'timestamp' => 'iphone 7 ', 'username' => 'iphone 7 ', 'price' => 399, 'status' => 'success'), + array('order_no' => '300000000000000000', 'timestamp' => 'iphone 7 ', 'username' => 'iphone 7 ', 'price' => 399, 'status' => 'pending'), + array('order_no' => '444444444444444444', 'timestamp' => 'iphone 7 ', 'username' => 'iphone 7 ', 'price' => 399, 'status' => 'success'), + array('order_no' => '888888888888888888', 'timestamp' => 'iphone 7 ', 'username' => 'iphone 7 ', 'price' => 399, 'status' => 'pending'), + ); + + $message = [ + "code" => 20000, + "data" => [ + "total" => count($List), + "items" => $List + ] + ]; + $this->set_response($message, REST_Controller::HTTP_OK); + } else { + $message = [ + "code" => 50008, + "message" => 'Login failed, unable to get user details.' + ]; + + $this->set_response($message, REST_Controller::HTTP_OK); + } + + } + +} diff --git a/controllers/api/v2/sys/User.php b/controllers/api/v2/sys/User.php new file mode 100644 index 0000000..ee89c57 --- /dev/null +++ b/controllers/api/v2/sys/User.php @@ -0,0 +1,1059 @@ +load->model('Base_model'); + $this->load->model('User_model'); + // $this->config->load('config', true); + } + + public function index_get() + { + $this->load->view('login_view'); + } + + public function testapi_get() + { + echo "test api ok..."; + + echo APPPATH . "\n"; + echo SELF . "\n"; + echo BASEPATH . "\n"; + echo FCPATH . "\n"; + echo SYSDIR . "\n"; + var_dump($this->config->item('rest_language')); + var_dump($this->config->item('language')); + + var_dump($this->config); + +// $message = [ +// "code" => 20000, +// "data" => [ +// "__FUNCTION__" => __FUNCTION__, +// "__CLASS__" => __CLASS__, +// "uri" => $this->uri +// ], +// +// ]; +// "data": { +// "__FUNCTION__": "router_get", +// "__CLASS__": "User", +// "uri": { +// "keyval": [], +// "uri_string": "api/v2/user/router", +// "segments": { +// "1": "api", +// "2": "v2", +// "3": "user", +// "4": "router" +// }, + } + + public function phpinfo_get() + { + phpinfo(); + } + + public function testdb_get() + { + $this->load->database(); + $query = $this->db->query("show tables"); + var_dump($query); + var_dump($query->result()); + var_dump($query->row_array()); +// 有结果表明数据库连接正常 reslut() 与 row_array 结果有时不太一样 +// 一般加载到时model里面使用。 + } + + + /* Helper Methods */ + /** + * 生成 token + * @param + * @return string 40个字符 + */ + private function _generate_token() + { + do { + // Generate a random salt + $salt = base_convert(bin2hex($this->security->get_random_bytes(64)), 16, 36); + + // If an error occurred, then fall back to the previous method + if ($salt === FALSE) { + $salt = hash('sha256', time() . mt_rand()); + } + + $new_key = substr($salt, 0, config_item('rest_key_length')); + } while ($this->_token_exists($new_key)); + + return $new_key; + } + + /* Private Data Methods */ + + private function _token_exists($token) + { + return $this->rest->db + ->where('token', $token) + ->count_all_results('sys_user_token') > 0; + } + + private function _insert_token($token, $data) + { + $data['token'] = $token; + + return $this->rest->db + ->set($data) + ->insert('sys_user_token'); + } + + private function _update_token($token, $data) + { + return $this->rest->db + ->where('token', $token) + ->update('auth', $data); + } + + // 查 + function view_post() + { + $uri = $this->uri->uri_string; + $Token = $this->input->get_request_header('X-Token', TRUE); + + $retPerm = $this->permission->HasPermit($Token, $uri); + if ($retPerm['code'] != 50000) { + $this->set_response($retPerm, REST_Controller::HTTP_OK); + return; + } + + $parms = $this->post(); + // $type = $parms['type']; + $filters = $parms['filters']; + $sort = $parms['sort']; + $page = $parms['page']; + $pageSize = $parms['pageSize']; + + $UserArr = $this->User_model->getUserList($filters, $sort, $page, $pageSize); + + $total = $this->User_model->getUserListCnt($filters); + + // 遍历该用户所属角色信息 + foreach ($UserArr as $k => $v) { + $UserArr[$k]['role'] = []; + $RoleArr = $this->User_model->getUserRoles($v['id']); + foreach ($RoleArr as $kk => $vv) { + array_push($UserArr[$k]['role'], $vv['id']); + } + } + $message = [ + "code" => 20000, + "data" => [ + 'items' => $UserArr, + 'total' => intval($total) + ] + ]; + $this->set_response($message, REST_Controller::HTTP_OK); + } + + function getroleoptions_get() + { + $Token = $this->input->get_request_header('X-Token', TRUE); + + $RoleArr = $this->User_model->getRoleOptions($Token); + // string to boolean + foreach ($RoleArr as $k => $v) { + $v['isDisabled'] === 'true' ? ($RoleArr[$k]['isDisabled'] = true) : ($RoleArr[$k]['isDisabled'] = false); + } + + $message = [ + "code" => 20000, + "data" => $RoleArr, + ]; + $this->set_response($message, REST_Controller::HTTP_OK); + } + + // 增 + function add_post() + { + $uri = $this->uri->uri_string; + $Token = $this->input->get_request_header('X-Token', TRUE); + $retPerm = $this->permission->HasPermit($Token, $uri); + if ($retPerm['code'] != 50000) { + $this->set_response($retPerm, REST_Controller::HTTP_OK); + return; + } + + $parms = $this->post(); // 获取表单参数,类型为数组 + + // 参数数据预处理 + $RoleArr = $parms['role']; + unset($parms['role']); // 剔除role数组 + // 加入新增时间 + $parms['create_time'] = time(); + $parms['password'] = md5($parms['password']); + + $user_id = $this->Base_model->_insert_key('sys_user', $parms); + if (!$user_id) { + $message = [ + "code" => 20000, + "type" => 'error', + "message" => $parms['username'] . ' - 用户新增失败' + ]; + $this->set_response($message, REST_Controller::HTTP_OK); + return; + } + + $failed = false; + $failedArr = []; + foreach ($RoleArr as $k => $v) { + $arr = ['user_id' => $user_id, 'role_id' => $v]; + $ret = $this->Base_model->_insert_key('sys_user_role', $arr); + if (!$ret) { + $failed = true; + array_push($failedArr, $arr); + } + } + + if ($failed) { + $message = [ + "code" => 20000, + "type" => 'error', + "message" => '用户关联角色失败 ' . json_encode($failedArr) + ]; + $this->set_response($message, REST_Controller::HTTP_OK); + return; + } + + $message = [ + "code" => 20000, + "type" => 'success', + "message" => $parms['username'] . ' - 用户新增成功' + ]; + $this->set_response($message, REST_Controller::HTTP_OK); + } + + // 改 + function edit_post() + { + $uri = $this->uri->uri_string; + $Token = $this->input->get_request_header('X-Token', TRUE); + $retPerm = $this->permission->HasPermit($Token, $uri); + if ($retPerm['code'] != 50000) { + $this->set_response($retPerm, REST_Controller::HTTP_OK); + return; + } + + // $id = $this->post('id'); // POST param + $parms = $this->post(); // 获取表单参数,类型为数组 + // var_dump($parms['path']); + + // 参数检验/数据预处理 + // 超级管理员角色不允许修改 + if ($parms['id'] == 1) { + $message = [ + "code" => 20000, + "type" => 'error', + "message" => $parms['username'] . ' - 超级管理员用户不允许修改' + ]; + $this->set_response($message, REST_Controller::HTTP_OK); + return; + } + + $id = $parms['id']; + $RoleArr = []; + foreach ($parms['role'] as $k => $v) { + $RoleArr[$k] = ['user_id' => $id, 'role_id' => $v]; + } + + unset($parms['role']); // 剔除role数组 + unset($parms['id']); // 剔除索引id + unset($parms['password']); // 剔除密码 + + $where = ["id" => $id]; + + if (!$this->Base_model->_update_key('sys_user', $parms, $where)) { + $message = [ + "code" => 20000, + "type" => 'error', + "message" => $parms['username'] . ' - 用户更新错误' + ]; + $this->set_response($message, REST_Controller::HTTP_OK); + return; + } + + $RoleSqlArr = $this->User_model->getRolesByUserId($id); + + $AddArr = $this->permission->array_diff_assoc2($RoleArr, $RoleSqlArr); + // var_dump('------------只存在于前台传参 做添加操作-------------'); + // var_dump($AddArr); + $failed = false; + $failedArr = []; + foreach ($AddArr as $k => $v) { + $ret = $this->Base_model->_insert_key('sys_user_role', $v); + if (!$ret) { + $failed = true; + array_push($failedArr, $v); + } + } + if ($failed) { + $message = [ + "code" => 20000, + "type" => 'error', + "message" => '用户关联角色失败 ' . json_encode($failedArr) + ]; + $this->set_response($message, REST_Controller::HTTP_OK); + return; + } + + $DelArr = $this->permission->array_diff_assoc2($RoleSqlArr, $RoleArr); + // var_dump('------------只存在于后台数据库 删除操作-------------'); + // var_dump($DelArr); + $failed = false; + $failedArr = []; + foreach ($DelArr as $k => $v) { + $ret = $this->Base_model->_delete_key('sys_user_role', $v); + if (!$ret) { + $failed = true; + array_push($failedArr, $v); + } + } + if ($failed) { + $message = [ + "code" => 20000, + "type" => 'error', + "message" => '用户关联角色失败 ' . json_encode($failedArr) + ]; + $this->set_response($message, REST_Controller::HTTP_OK); + return; + } + + $message = [ + "code" => 20000, + "type" => 'success', + "message" => $parms['username'] . ' - 用户更新成功' + ]; + $this->set_response($message, REST_Controller::HTTP_OK); + } + + // 删 + function del_post() + { + $uri = $this->uri->uri_string; + $Token = $this->input->get_request_header('X-Token', TRUE); + $retPerm = $this->permission->HasPermit($Token, $uri); + if ($retPerm['code'] != 50000) { + $this->set_response($retPerm, REST_Controller::HTTP_OK); + return; + } + + $parms = $this->post(); // 获取表单参数,类型为数组 + // var_dump($parms['path']); + + // 参数检验/数据预处理 + // 超级管理员角色不允许删除 + if ($parms['id'] == 1) { + $message = [ + "code" => 20000, + "type" => 'error', + "message" => $parms['username'] . ' - 超级管理员不允许删除' + ]; + $this->set_response($message, REST_Controller::HTTP_OK); + return; + } + + // 删除外键关联表 sys_user_role + $this->Base_model->_delete_key('sys_user_role', ['user_id' => $parms['id']]); + + // 删除基础表 sys_user + if (!$this->Base_model->_delete_key('sys_user', $parms)) { + $message = [ + "code" => 20000, + "type" => 'error', + "message" => $parms['username'] . ' - 用户删除错误' + ]; + $this->set_response($message, REST_Controller::HTTP_OK); + return; + } + + $message = [ + "code" => 20000, + "type" => 'success', + "message" => $parms['username'] . ' - 用户删除成功' + ]; + $this->set_response($message, REST_Controller::HTTP_OK); + + } + + function login_post() + { + $username = $this->post('username'); // POST param + $password = $this->post('password'); // POST param + + $result = $this->User_model->validate($username, md5($password)); + + // 用户名密码正确 生成token 返回 + if ($result['success']) { + $Token = $this->_generate_token(); + $create_time = time(); + $expire_time = $create_time + 2 * 60 * 60; // 2小时过期 + + $data = [ + 'user_id' => $result['userinfo']['id'], + 'expire_time' => $expire_time, + 'create_time' => $create_time + ]; + + if (!$this->_insert_token($Token, $data)) { + $message = [ + "code" => 20000, + "message" => 'Token 创建失败, 请联系管理员.' + ]; + $this->set_response($message, REST_Controller::HTTP_OK); + return; + } + + $message = [ + "code" => 20000, + "data" => [ + "token" => $Token + ] + ]; + $this->set_response($message, REST_Controller::HTTP_OK); + } else { + $message = [ + "code" => 60204, + "message" => 'Account and password are incorrect.' + ]; + $this->set_response($message, REST_Controller::HTTP_OK); + } + } + + // 根据token拉取用户信息 get + function info_get() + { +// $result = $this->some_model(); + $result['success'] = TRUE; + $Token = $this->input->get_request_header('X-Token', TRUE); + + $MenuTreeArr = $this->permission->getPermission($Token, 'menu', false); + $asyncRouterMap = $this->permission->genVueRouter($MenuTreeArr, 'id', 'pid', 0); + $CtrlPerm = $this->permission->getMenuCtrlPerm($Token); + + // 获取用户信息成功 + if ($result['success']) { + $info = [ + "roles" => ["admin", "editor"], + "introduction" => "I am a super administrator", + "avatar" => "https://wpimg.wallstcn.com/f778738c-e4f8-4870-b634-56703b4acafe.gif", + "name" => "Super Admin", + "identify" => "410000000000000000", + "phone" => "13633838282", + "ctrlperm" => $CtrlPerm, +// "ctrlperm" => [ +// [ +// "path" => "/sys/menu/view" +// ], +// [ +// "path" => "/sys/menu/add" +// ], +// [ +// "path" => "/sys/menu/edit" +// ], +// [ +// "path" => "/sys/menu/del" +// ], +// [ +// "path" => "/sys/menu/download" +// ] +// ], + "asyncRouterMap" => $asyncRouterMap +// "asyncRouterMap" => [ +// [ +// "path" => '/sys', +// "name" => 'sys', +// "meta" => [ +// "title" => "系统管理", +// "icon" => "sysset2" +// ], +// "component" => 'Layout', +// "redirect" => '/sys/menu', +// "children" => [ +// [ +// "path" => '/sys/menu', +// "name" => 'menu', +// "meta" => [ +// "title" => "菜单管理", +// "icon" => "menu1" +// ], +// "component" => 'sys/menu/index', +// "redirect" => '', +// "children" => [ +// +// ] +// ], +// [ +// "path" => '/sys/user', +// "name" => 'user', +// "meta" => [ +// "title" => "用户管理", +// "icon" => "user" +// ], +// "component" => 'pdf/index', +// "redirect" => '', +// "children" => [ +// +// ] +// ], +// [ +// "path" => '/sys/icon', +// "name" => 'icon', +// "meta" => [ +// "title" => "图标管理", +// "icon" => "icon" +// ], +// "component" => 'svg-icons/index', +// "redirect" => '', +// "children" => [ +// +// ] +// ] +// ] +// ], +// [ +// "path" => '/sysx', +// "name" => 'sysx', +// "meta" => [ +// "title" => "其他管理", +// "icon" => "plane" +// ], +// "component" => 'Layout', +// "redirect" => '', +// "children" => [ +// +// ] +// ] +// ] + ]; + + $message = [ + "code" => 20000, + "data" => $info, + "_SERVER" => $_SERVER, + "_GET" => $_GET + ]; + $this->set_response($message, REST_Controller::HTTP_OK); + } else { + $message = [ + "code" => 50008, + "message" => 'Login failed, unable to get user details.' + ]; + + $this->set_response($message, REST_Controller::HTTP_OK); + } + + } + + // async router test get + function router_get() + { +// $result = $this->some_model(); + $result['success'] = TRUE; + + // 获取用户信息成功 + if ($result['success']) { +// $info = [ +// "roles" => ["admin", "editor"], +// "introduction" => "I am a super administrator", +// "avatar" => "https://wpimg.wallstcn.com/f778738c-e4f8-4870-b634-56703b4acafe.gif", +// "name" => "Super Admin", +// "identify" => "410000000000000000", +// "phone" => "13633838282", +// "asyncRouterMap" => [ +// +// ] +// ]; + + $message = [ + "code" => 20000, + "data" => [ + "asyncRouterMap" => [ + [ + "path" => '/sys', + "name" => 'sys', + "meta" => [ + "title" => "系统管理", + "icon" => "nested" + ], + "component" => 'Layout', + "children" => [ + [ + "path" => '/sys/menu', + "name" => 'menu', + "meta" => [ + "title" => "菜单管理", + "icon" => "nested" + ], + "component" => 'index', + "children" => [ + + ] + ] + ] + ], + [ + "path" => '/sysx', + "name" => 'sysx', + "meta" => [ + "title" => "其他管理", + "icon" => "nested" + ], + "component" => 'Layout', + "children" => [ + + ] + ] + ], + "__FUNCTION__" => __FUNCTION__, + "__CLASS__" => __CLASS__, + "uri" => $this->uri + ], + + ]; + $this->set_response($message, REST_Controller::HTTP_OK); + } else { + $message = [ + "code" => 50008, + "message" => 'Login failed, unable to get user details.' + ]; + + $this->set_response($message, REST_Controller::HTTP_OK); + } + + } + + function logout_post() + { + $message = [ + "code" => 20000, + "data" => 'success' + ]; + $this->set_response($message, REST_Controller::HTTP_OK); + } + + function list_get() + { +// $result = $this->some_model(); + $result['success'] = TRUE; + + if ($result['success']) { + $List = array( + array('order_no' => '201805138451313131', 'timestamp' => 'iphone 7 ', 'username' => 'iphone 7 ', 'price' => 399, 'status' => 'success'), + array('order_no' => '300000000000000000', 'timestamp' => 'iphone 7 ', 'username' => 'iphone 7 ', 'price' => 399, 'status' => 'pending'), + array('order_no' => '444444444444444444', 'timestamp' => 'iphone 7 ', 'username' => 'iphone 7 ', 'price' => 399, 'status' => 'success'), + array('order_no' => '888888888888888888', 'timestamp' => 'iphone 7 ', 'username' => 'iphone 7 ', 'price' => 399, 'status' => 'pending'), + ); + + $message = [ + "code" => 20000, + "data" => [ + "total" => count($List), + "items" => $List + ] + ]; + $this->set_response($message, REST_Controller::HTTP_OK); + } else { + $message = [ + "code" => 50008, + "message" => 'Login failed, unable to get user details.' + ]; + + $this->set_response($message, REST_Controller::HTTP_OK); + } + + } + + function login() + { + $this->SET_HEADER; // 设置php CI 处理 CORS 自定义头部 + + + if ($_SERVER["REQUEST_METHOD"] == 'POST') { // 只处理post请求,否则options请求 500错误 + $json_params = file_get_contents('php://input'); + $data = json_decode($json_params, true); + + if (!empty($data)) { + if (!empty($data['username']) && !empty($data['password'])) { + $username = $data['username']; + $password = $data['password']; + $input_account = $username; + $input_password = md5($password); + // $results = $this->phpIonicLoginAuthValidateLogin($username, $password); + $result = $this->Api_model->app_user_login_validate($input_account, $input_password); + + // $token=$_SERVER['x-auth-token']; + // 用户名密码正确 生成token 返回 + $token = $this->createToken(10000); + + $data = array( + "code" => 20000, + "data" => array( + "token" => "admin-token" +// "token" => $token + ), + "params" => $json_params + ); + + echo json_encode($data); + // 用户名密码不正确 +// return { +// code: +// 60204, +// message: 'Account and password are incorrect.' +// } + + + if ($result['success']) { + echo json_encode($this->saveLoginInfo($result['userinfo'])); + } else { + // 校验失败,写入token + $this->output->set_status_header(300); + echo '{"success": false,"message": "用户名或密码错误","jump":"","user":"' . $username . '"}'; + } + + } else { + $results = array( + "result" => "Error - data incomplete!", + ); + + $jsonData = json_encode($results); + echo $jsonData; + } + } else { // no data post + $results = array( + "result" => "Error - no data!", + ); + $jsonData = json_encode($results); + echo $jsonData; + } + } + } + + // 根据token拉取用户信息 get + function info() + { + $this->SET_HEADER; // 设置php CI 处理 CORS 自定义头部 + + if ($_SERVER["REQUEST_METHOD"] == 'GET') { // 只处理post请求,否则options请求 500错误 + $json_params = file_get_contents('php://input'); + $data = json_decode($json_params, true); + +// $token=$_SERVER['x-auth-token']; + +// 获取用户信息成功 + $info = array( + "roles" => array( + "admin" + ), + "introduction" => "I am a super administrator", + "avatar" => "https://wpimg.wallstcn.com/f778738c-e4f8-4870-b634-56703b4acafe.gif", + "name" => "Super Admin", + ); + + echo json_encode( + array( + "code" => 20000, + "data" => $info, + "_SERVER" => $_SERVER, + "_GET" => $_GET + ) + ); + +// 获取用户信息失败 +// return { +// code: 50008, +// message: 'Login failed, unable to get user details.' +// } +// echo json_encode( +// array( +// "code" => 50008, +// "message" => "Login failed, unable to get user details." +// ) +// ); + + return; + + if (!empty($data)) { + if (!empty($data['username']) && !empty($data['password'])) { + $username = $data['username']; + $password = $data['password']; + $input_account = $username; + $input_password = md5($password); + // $results = $this->phpIonicLoginAuthValidateLogin($username, $password); + $result = $this->Api_model->app_user_login_validate($input_account, $input_password); + + if ($result['success']) { + echo json_encode($this->saveLoginInfo($result['userinfo'])); + } else { + // 校验失败,写入token + $this->output->set_status_header(300); + echo '{"success": false,"message": "用户名或密码错误","jump":"","user":"' . $username . '"}'; + } + + } else { + $results = array( + "result" => "Error - data incomplete!", + ); + + $jsonData = json_encode($results); + echo $jsonData; + } + } else { // no data post + $results = array( + "result" => "Error - no data!", + ); + $jsonData = json_encode($results); + echo $jsonData; + } + } + } + + function logout() + { + $this->SET_HEADER; // 设置php CI 处理 CORS 自定义头部 + if ($_SERVER["REQUEST_METHOD"] == 'POST') { // 只处理post请求,否则options请求 500错误 + echo json_encode(array( + "code" => 20000, + "data" => 'sucess' + )); + } + } + + /* + * For 微信认证及全登录时保留登录日志信息 + */ + function saveLoginInfo($userinfo) + { + $token = md5($userinfo["name"] . date('y-m-d H:i:s', time())); + $arr2 = array('token' => $token); + $userinfo["token"] = $token; + $this->Bas->saveAdd( + 'auth', + array( + 'token' => $token, + 'expiredAt' => date('Y-m-d H:i:s', strtotime('+1 day')), + 'onlineIp' => $this->input->ip_address(), + 'userLoginInfo' => json_encode($userinfo), + 'creatorId' => $userinfo["name"], + 'createdAt' => date('Y-m-d H:i:s') + ) + ); + + // 返回信息 + $results = array( + "success" => true, + "message" => "APP登陆成功", + "user" => $userinfo, + 'session' => $_SESSION, + ); + + $this->Bas->saveEdit('userinfo', array('LASTLOGIN' => date('y-m-d H:i:s', time()), 'LASTIP' => $this->input->ip_address()), array('USERNAME' => $userinfo["name"])); + return $results; + } + + /** + * 执行CURL请求,并封装返回对象 + */ + private function execCURL($ch) + { + $response = curl_exec($ch); + $error = curl_error($ch); + $result = array('header' => '', + 'content' => '', + 'curl_error' => '', + 'http_code' => '', + 'last_url' => ''); + + if ($error != "") { + $result['curl_error'] = $error; + return $result; + } + + $header_size = curl_getinfo($ch, CURLINFO_HEADER_SIZE); + $result['header'] = str_replace(array("\r\n", "\r", "\n"), "
", substr($response, 0, $header_size)); + $result['content'] = substr($response, $header_size); + $result['http_code'] = curl_getinfo($ch, CURLINFO_HTTP_CODE); + $result['last_url'] = curl_getinfo($ch, CURLINFO_EFFECTIVE_URL); + $result["base_resp"] = array(); + $result["base_resp"]["ret"] = $result['http_code'] == 200 ? 0 : $result['http_code']; + $result["base_resp"]["err_msg"] = $result['http_code'] == 200 ? "ok" : $result["curl_error"]; + + return $result; + } + + /** + * GET 请求 + * @param string $url + */ + private function http_get($url) + { + $oCurl = curl_init(); + if (stripos($url, "https://") !== FALSE) { + curl_setopt($oCurl, CURLOPT_SSL_VERIFYPEER, FALSE); + curl_setopt($oCurl, CURLOPT_SSL_VERIFYHOST, FALSE); + curl_setopt($oCurl, CURLOPT_SSLVERSION, 1); //CURL_SSLVERSION_TLSv1 + } + curl_setopt($oCurl, CURLOPT_URL, $url); + curl_setopt($oCurl, CURLOPT_RETURNTRANSFER, 1); + curl_setopt($oCurl, CURLOPT_VERBOSE, 1); + curl_setopt($oCurl, CURLOPT_HEADER, 1); + + // $sContent = curl_exec($oCurl); + // $aStatus = curl_getinfo($oCurl); + $sContent = $this->execCURL($oCurl); + curl_close($oCurl); + + return $sContent; + } + + /** + * POST 请求 + * @param string $url + * @param array $param + * @param boolean $post_file 是否文件上传 + * @return string content + */ + private function http_post($url, $param, $post_file = false) + { + $oCurl = curl_init(); + + if (stripos($url, "https://") !== FALSE) { + curl_setopt($oCurl, CURLOPT_SSL_VERIFYPEER, FALSE); + curl_setopt($oCurl, CURLOPT_SSL_VERIFYHOST, false); + curl_setopt($oCurl, CURLOPT_SSLVERSION, 1); //CURL_SSLVERSION_TLSv1 + } + if (PHP_VERSION_ID >= 50500 && class_exists('\CURLFile')) { + $is_curlFile = true; + } else { + $is_curlFile = false; + if (defined('CURLOPT_SAFE_UPLOAD')) { + curl_setopt($oCurl, CURLOPT_SAFE_UPLOAD, false); + } + } + + if ($post_file) { + if ($is_curlFile) { + foreach ($param as $key => $val) { + if (isset($val["tmp_name"])) { + $param[$key] = new \CURLFile(realpath($val["tmp_name"]), $val["type"], $val["name"]); + } else if (substr($val, 0, 1) == '@') { + $param[$key] = new \CURLFile(realpath(substr($val, 1))); + } + } + } + $strPOST = $param; + } else { + $strPOST = json_encode($param); + } + + curl_setopt($oCurl, CURLOPT_URL, $url); + curl_setopt($oCurl, CURLOPT_RETURNTRANSFER, 1); + curl_setopt($oCurl, CURLOPT_POST, true); + curl_setopt($oCurl, CURLOPT_POSTFIELDS, $strPOST); + curl_setopt($oCurl, CURLOPT_VERBOSE, 1); + curl_setopt($oCurl, CURLOPT_HEADER, 1); + + // $sContent = curl_exec($oCurl); + // $aStatus = curl_getinfo($oCurl); + + $sContent = $this->execCURL($oCurl); + curl_close($oCurl); + + return $sContent; + } + + function weixinAuth() + { + session_start(); + if ($_SERVER["REQUEST_METHOD"] == 'OPTIONS') { + echo "options"; + die(); + } + // $corpId = "wwxxxxxxxx"; + // $agentId = "100000"; + // $appSecret = "fsdfsfsdf"; + // $localAuthUrl = "http://dj.xxx.com:7000/hotcode/"; + + if (!array_key_exists("code", $_REQUEST)) { + $redirectUri = urlencode("http://yw.cttha.com/ksh/get-corp-weixin-code.html?redirect_uri=" . urlencode($localAuthUrl)); + $authUrl = "https://open.weixin.qq.com/connect/oauth2/authorize?appid=" . $corpId . "&redirect_uri=" . $redirectUri . "&response_type=code&scope=snsapi_privateinfo&agentid=" . $agentId . "&state=STATE#wechat_redirect"; + echo json_encode(array("success" => false, "authUrl" => $authUrl)); + die(); + } + $getCorpAccessTokenUrl = "https://qyapi.weixin.qq.com/cgi-bin/gettoken?corpid=" . $corpId . "&corpsecret=" . $appSecret; + $accessToken = ""; + if (false && $_SESSION["weixinAuth_accessToken"] && $_SESSION["weixinAuth_tokenTime"] && $_SESSION["weixinAuth_tokenExpires"] && time() - intval($_SESSION["weixinAuth_tokenTime"]) < intval($_SESSION["tokenExpires"])) { + $accessToken = $_SESSION["weixinAuth_accessToken"]; + } else { + $tokenInfo = $this->http_get($getCorpAccessTokenUrl); + $tokenInfo = json_decode($tokenInfo["content"], true); + if ($tokenInfo["errcode"] == 0) { + $accessToken = $tokenInfo["access_token"]; + $_SESSION["weixinAuth_accessToke"] = $accessToken; + $_SESSION["weixinAuth_tokenTime"] = time(); + $_SESSION["weixinAuth_tokenExpires"] = $tokenInfo["expires_in"]; + } else { + echo json_encode(array("success" => false, "msg" => $tokenInfo["errmsg"] ? $tokenInfo["errmsg"] : "企业认证失败!")); + die(); + } + } + $getUserIdUrl = "https://qyapi.weixin.qq.com/cgi-bin/user/getuserinfo?access_token=" . $accessToken . "&code=" . $_REQUEST["code"]; + $ajaxUserIdInfo = $this->http_get($getUserIdUrl); + // var_dump($ajaxUserIdInfo);die(); + $userIdInfo = json_decode($ajaxUserIdInfo["content"], true); + if ($userIdInfo["errcode"] == 0) { + if (array_key_exists("OpenId", $userIdInfo)) { + echo json_encode(array("success" => false, "msg" => "不是企业成员!请联系企业管理员,添加您的账号的企业通讯录!")); + die(); + // next(U.error("不是企业成员!请联系企业管理员,添加您的账号的企业通讯录!")); + } else if (array_key_exists("UserId", $userIdInfo)) { + $getUserInfoUrl = "https://qyapi.weixin.qq.com/cgi-bin/user/getuserdetail?access_token=" . $accessToken; + // 44468cd93cdfefb8a7f911b5e1f7dfd0 + $data = array("user_ticket" => $userIdInfo["user_ticket"]); + $ajaxUserInfo = $this->http_post($getUserInfoUrl, $data); + $userInfo = json_decode($ajaxUserInfo["content"], true); + if ($userInfo["errcode"] == 0) { + $user = $this->Api_model->getUserByWxUserId($userIdInfo["UserId"]); + if ($user["success"]) { + echo json_encode($this->saveLoginInfo($user['userinfo'])); + die(); + } else { + $_SESSION["wxUserInfo"] = $userInfo; + echo json_encode(array("sessionid" => session_id(), "status" => -1, "success" => false, "msg" => "此微信账号(" . $userInfo["name"] . ")没有与系统账号关联,请用您的账号密码登录一次,完成首次绑定!")); + die(); + } + return; + } else { + echo json_encode(array("success" => false, "msg" => $userInfo["errmsg"])); + die(); + } + } + } else { + echo json_encode(array("success" => false, "msg" => $userIdInfo["errmsg"])); + die(); + } + } +} diff --git a/controllers/api/v3/Article.php b/controllers/api/v3/Article.php new file mode 100644 index 0000000..2c3a2ba --- /dev/null +++ b/controllers/api/v3/Article.php @@ -0,0 +1,138 @@ +load->model('Base_model'); +// $this->load->model('Record_model'); +// $this->load->model('Dept_model', 'Dept'); +// $this->config->load('config', true); + } + + public function index() + { + $this->load->view('login_view'); + } + + public function testapi() + { + echo "test api ok..."; + } + + public function phpinfo() + { + phpinfo(); + } + + public function testdb() + { + $this->load->database(); + $query = $this->db->query("show tables"); + var_dump($query); + var_dump($query->result()); + var_dump($query->row_array()); +// 有结果表明数据库连接正常 reslut() 与 row_array 结果有时不太一样 +// 一般加载到时model里面使用。 + } + + + function list_get() + { + + $items = [ + ["id" => 1, + "timestamp" => "20180808", + + "author" => "qiaokun", + "reviewer" => "draft", + "title" => "draft", + "content_short" => "我是测试数据", + "content" => "

我是测试数据我是测试数据

", + "forecast" => '3.1515', + "importance" => '1', + "type|1" => 'CN', + "status" => 'published', + "display_time" => "", + "comment_disabled" => true, + "pageviews" => 300, + "image_uri" => "https://wpimg.wallstcn.com/e4558086-631c-425c-9430-56ffb46e70b3'", + "platforms" =>"a-platform" + ], + ["id" => 2, + "timestamp" => "20180808", + + "author" => "pocoyo", + "reviewer" => "draft", + "title" => "draft", + "content_short" => "我是测试数据", + "content" => "

我是测试数据我是测试数据

", + "forecast" => '3.1515', + "importance" => '1', + "type|1" => 'CN', + "status" => 'published', + "display_time" => "", + "comment_disabled" => true, + "pageviews" => 300, + "image_uri" => "https://wpimg.wallstcn.com/e4558086-631c-425c-9430-56ffb46e70b3'", + "platforms" =>"a-platform" + ], + ]; + + $message = [ + "code" => 20000, + "data" => [ + "items" => $items, + "total" => count($items) + ] + + ]; + + $this->set_response($message, RestController::HTTP_OK); + + } + + function goods_get() + { + + $items = array( + array('id' => 1, 'title' => 'iphone 7 ', 'price' => 399, 'num' => 1), + array('id' => 2, 'title' => 'hdcms 7 ', 'price' => 2000, 'num' => 2), + array('id' => 3, 'title' => 'aaaas 7 ', 'price' => 2000, 'num' => 2), + array('id' => 4, 'title' => 'iphone 7 ', 'price' => 399, 'num' => 1), + array('id' => 5, 'title' => 'hdcms 7 ', 'price' => 2000, 'num' => 2), + array('id' => 6, 'title' => 'aaaas 7 ', 'price' => 2000, 'num' => 2), + array('id' => 7, 'title' => 'iphone 7 ', 'price' => 399, 'num' => 1), + array('id' => 8, 'title' => 'hdcms 7 ', 'price' => 2000, 'num' => 2), + array('id' => 9, 'title' => 'aaaas 7 ', 'price' => 2000, 'num' => 2), + array('id' => 10, 'title' => 'iphone 7 ', 'price' => 399, 'num' => 1), + array('id' => 11, 'title' => 'hdcms 7 ', 'price' => 2000, 'num' => 2), + array('id' => 31, 'title' => 'aaaas 7 ', 'price' => 2000, 'num' => 2), + array('id' => 13, 'title' => 'iphone 7 ', 'price' => 399, 'num' => 1), + array('id' => 24, 'title' => 'hdcms 7 ', 'price' => 2000, 'num' => 2), + array('id' => 35, 'title' => 'aaaas 7 ', 'price' => 2000, 'num' => 2), + array('id' => 19, 'title' => 'iphone 7 ', 'price' => 399, 'num' => 1), + array('id' => 22, 'title' => 'hdcms 7 ', 'price' => 2000, 'num' => 2), + array('id' => 33, 'title' => 'aaaas 7 ', 'price' => 2000, 'num' => 2), + ); + + $message = [ + "code" => 20000, + "data" => [ + "items" => $items + ] + ]; + + $this->set_response($message, RestController::HTTP_OK); + + } + +} + +/* End of file welcome.php */ +/* Location: ./application/controllers/welcome.php */ \ No newline at end of file diff --git a/controllers/api/v3/Dashboard.php b/controllers/api/v3/Dashboard.php new file mode 100644 index 0000000..d144b51 --- /dev/null +++ b/controllers/api/v3/Dashboard.php @@ -0,0 +1,20 @@ +[] + ]; + foreach (['sample','customer','sample_upgrade_order'] as $model) { + $this->load->model($model.'_model'); + $ret['count'][$model] = (int)$this->{$model.'_model'}->total(); + } + $ret['count']['order_total'] = 0; + $this->success($ret); + } +} diff --git a/controllers/api/v3/Disease.php b/controllers/api/v3/Disease.php new file mode 100644 index 0000000..964ad52 --- /dev/null +++ b/controllers/api/v3/Disease.php @@ -0,0 +1,80 @@ + 'id', + 'label' => '序号', + 'rules' => 'trim|min_length[0]|max_length[20]' + ), + array( + 'field' => 'name', + 'label' => '名称', + 'rules' => 'trim|min_length[0]|max_length[40]' + ), + array( + 'field' => 'pathogenesis', + 'label' => '致病机理', + 'rules' => 'trim|min_length[0]|max_length[800]' + ), + array( + 'field' => 'clinical_symptoms', + 'label' => '临床症状', + 'rules' => 'trim|min_length[0]|max_length[800]' + ), + array( + 'field' => 'category', + 'label' => '所属类别', + 'rules' => 'trim|min_length[0]|max_length[50]' + ), + array( + 'field' => 'advice_treatment', + 'label' => '诊疗建议', + 'rules' => 'trim|min_length[0]|max_length[800]' + ), + array( + 'field' => 'advice_parenting', + 'label' => '养育建议', + 'rules' => 'trim|min_length[0]|max_length[800]' + ), + array( + 'field' => 'reference', + 'label' => '参考文献', + 'rules' => 'trim|min_length[0]|max_length[800]' + ), + array( + 'field' => 'species', + 'label' => '物种', + 'rules' => 'trim|integer|min_length[0]|max_length[2]' + ), + array( + 'field' => 'gene_type', + 'label' => '基因类别', + 'rules' => 'trim|integer|min_length[0]|max_length[2]' + ), + ); + } + + protected function _import_field_map(){ + return [ + '名称'=>'name', + '致病机理'=>'pathogenesis', + '临床症状'=>'clinical_symptoms', + '所属类别'=>'category', + '诊疗建议'=>'advice_treatment', + '养育建议'=>'advice_parenting', + '参考文献'=>'reference', + 'species'=>'species', + 'gene_type'=>'gene_type', + ]; + } + +} diff --git a/controllers/api/v3/Package.php b/controllers/api/v3/Package.php new file mode 100644 index 0000000..b113e9e --- /dev/null +++ b/controllers/api/v3/Package.php @@ -0,0 +1,128 @@ +_list_get(true); + $package_up_ids = []; + $disease_ids = []; + foreach ($data['items'] as &$item) { + $item['content'] = empty($item['content'])?[]:json_decode($item['content'],true); + $item['structure'] = array_values(array_filter(explode(',',$item['structure']))); + $item['structure_hide'] = array_values(array_filter(explode(',',$item['structure_hide']))); + $item['cert'] = array_values(array_filter(explode(',',$item['cert']))); + $item['disease'] = array_values(array_filter(explode(',',$item['disease']))); + //套餐升级目标 + $package_up_ids[] = $item['package_up']; + //套餐自带疾病 + $disease_ids = array_merge($disease_ids,$item['disease']); + //套餐疾病选项 + foreach ($item['content'] as $val) { + $disease_ids = array_merge($disease_ids,$val['disease_id']); + } + } + //提供所有升级目标套餐的值 + $data['options']['package'] = $this->package_model->get($package_up_ids,null,true,'base.id,base.name'); + //提供所有疾病选项 + $this->load->model('disease_model'); + $data['options']['disease'] = $this->disease_model->get($disease_ids,null,true,'base.id,base.name'); + $this->success($data); + } + + function update_post() + { + $config = array( + array( + 'field' => 'id', + 'label' => '序号', + 'rules' => 'trim|min_length[0]|max_length[20]' + ), + array( + 'field' => 'name', + 'label' => '套餐名称', + 'rules' => 'trim|required|min_length[2]|max_length[20]', + 'errors' => array( + 'required' => 'You must provide a %s.', + ), + ), + array( + 'field' => 'is_breed', + 'label' => '繁育套餐', + 'rules' => 'trim|min_length[1]|max_length[2]', + 'errors' => array( + 'required' => 'You must provide a %s.', + ), + ), + array( + 'field' => 'species', + 'label' => '物种', + 'rules' => 'trim|required|min_length[1]|max_length[2]', + 'errors' => array( + 'required' => 'You must provide a %s.', + ), + ), + array( + 'field' => 'package_up', + 'label' => '升级目标', + 'rules' => 'trim|min_length[1]|max_length[2]', + 'errors' => array( + 'required' => 'You must provide a %s.', + ), + ), + array( + 'field' => 'description', + 'label' => '描述', + 'rules' => 'trim|min_length[0]|max_length[20]' + ), + array( + 'field' => 'price', + 'label' => '价格', + 'rules' => 'trim|min_length[0]|max_length[20]' + ) + ); + //涉及字段序列化的特殊操作 + $data = $this->json_validation($config); + //处理content字段 + if(!is_array($data['content'])){ + $this->error('套餐内容需要传入数组'); + } + if(!empty($data['content']))foreach ($data['content'] as $item) { + if(empty($item['name'])){ + $this->error('套餐选项名称不能为空'); + } + if(empty($item['disease_id'])){ + $this->error('套餐疾病选项不能为空'); + } + } + $data['content'] = json_encode($data['content']); + $data['structure'] = implode(',',$data['structure']); + $data['structure_hide'] = implode(',',$data['structure_hide']); + $data['cert'] = implode(',',$data['cert']); + $data['disease'] = implode(',',$data['disease']); + $fields = array_column($config,'field'); + $fields[] = 'content'; + $fields[] = 'structure'; + $fields[] = 'structure_hide'; + $fields[] = 'cert'; + $fields[] = 'disease'; + foreach ($data as $key => $val) { + if(!in_array($key,$fields)){ + unset($data[$key]); + } + } + //print_r($data);die; + if(empty($data['id'])){ + $ret = $this->{$this->base_model}->add($data); + if($ret === -1){ + $this->error('名称不能与已有的重复'); + } + }else{ + $this->{$this->base_model}->update($data, ['id'=>$data['id']]); + } + $this->success(); + } +} diff --git a/controllers/api/v3/Sample.php b/controllers/api/v3/Sample.php new file mode 100644 index 0000000..a731552 --- /dev/null +++ b/controllers/api/v3/Sample.php @@ -0,0 +1,174 @@ +uri->uri_string; + $Token = $this->input->get_request_header('X-Token', TRUE); +// $retPerm = $this->permission->HasPermit($Token, $uri); +// if ($retPerm['code'] != 50000) { +// $this->response($retPerm, RestController::HTTP_OK); +// } + $dir = 'pet_img_custom/'; + $path = 'uploads/'.$dir; + $config['upload_path'] = './'.$path; + $config['allowed_types'] = 'gif|jpg|jpeg|png'; + $config['max_size'] = 10000; + $config['max_width'] = 4000; + $config['max_height'] = 4000; + //设置文件名,前端传来的文件固定是png + $config['file_name'] = time(); + + $this->load->library('upload', $config); + + if ( ! $this->upload->do_upload('avatar')) + { + $this->error( $this->upload->display_errors()); + } + else + { + $data = $this->upload->data(); + } + + $this->success([ + 'path'=>$dir.$data['file_name'], + 'full_path'=>base_url().$path.$data['file_name'] + ]); + } + + function update_post() + { + $config = array( + array( + 'field' => 'id', + 'label' => '序号', + 'rules' => 'trim|min_length[1]|max_length[10]' + ), + array( + 'field' => 'series_id', + 'label' => '序列号', + 'rules' => 'trim|required|min_length[1]|max_length[20]' + ), + array( + 'field' => 'user_id', + 'label' => '用户', + 'rules' => 'trim|required|min_length[1]|max_length[20]', + 'errors' => array( + 'required' => '需要搜索绑定 %s', + ), + ), + array( + 'field' => 'name', + 'label' => '用户姓名', + 'rules' => 'trim|required|min_length[2]|max_length[20]', + 'errors' => array( + 'required' => 'You must provide a %s.', + ), + ), + array( + 'field' => 'tel', + 'label' => '手机', + 'rules' => 'required' + ), + array( + 'field' => 'pet_name', + 'label' => '宠物名称', + 'rules' => 'required' + ), + array( + 'field' => 'pet_img', + 'label' => '宠物头像', + ), + array( + 'field' => 'pet_sex', + 'label' => '宠物性别', + 'rules' => 'required' + ), + array( + 'field' => 'pet_species', + 'label' => '宠物物种', + ), + array( + 'field' => 'pet_birthday', + 'label' => '宠物生日', + 'rules' => 'required' + ), + array( + 'field' => 'is_sterilized', + 'label' => '是否绝育', + ), + array( + 'field' => 'package_id', + 'label' => '套餐ID' + ) + ); + //读取输入数据 + $data = $this->json_validation($config); + //不允许修改套餐 + //unset($data['package_id']); + //对于新样品,从序列号读取套餐 + if(empty($data['id'])){ + $this->load->model('series_number_model'); + $series = $this->series_number_model->get($data['series_id']); + if(!$series){ + $this->error('序列号不存在'); + } + if(empty($series['package_ori'])){ + $this->error('序列号未绑定套餐'); + } + $data['package_id'] = $series['package_ori']; + } + $this->_update_post($config,$data); + } + + function list_get() + { + $ret = $this->_list_get(true); + $this->load->model('sample_model'); + $ret['step'] = $this->sample_model->step_back; + $this->load->model('package_model'); + $package_map = $this->package_model->get(false,null,true,'id,name'); + $package_map = array_column($package_map,'name','id'); + foreach ($ret['items'] as &$item) { + $item['package_ori_name'] = isset($package_map[$item['package_ori']])?$package_map[$item['package_ori']]:''; + $item['package_name'] = isset($package_map[$item['package_id']])?$package_map[$item['package_id']]:''; + } + $this->success($ret); + } + + //批量更新状态 + function batch_update_status_post() + { + $data_arr = $this->json_input(); + $this->load->model('sample_model'); + if(empty($data_arr['ids']) || !is_array($data_arr['ids'])){ + $this->error('请选择要操作的样品'); + } + if(empty($data_arr['step']) || !isset($this->sample_model->step_back[$data_arr['step']])){ + $this->error('状态错误'); + } + if(empty($data_arr['timestamp'])){ + $data_arr['timestamp'] = time(); + } + $ret = $this->sample_model->update( + ['step'=>$data_arr['step']], + 'id in ('.implode(',',$data_arr['ids']).')', + false + ); + if($ret){ + //记录状态变更时间 + //如果完成,给用户发通知 + if($data_arr['step'] == Sample_model::STEP_COMPLETE){ + $this->sample_model->complete($data_arr['ids']); + } + } + $this->success(); + } +} diff --git a/controllers/api/v3/Sample_upgrade_order.php b/controllers/api/v3/Sample_upgrade_order.php new file mode 100644 index 0000000..755883b --- /dev/null +++ b/controllers/api/v3/Sample_upgrade_order.php @@ -0,0 +1,10 @@ +load->model($model); + $searchText = $this->input->get('name'); + $searchId = $this->input->get('id'); + $param = []; + if(!empty($searchId)){ + $param['id'] = $searchId; + }else{ + $param[$nama_field] = $searchText; + } + $page = 1; + $limit = 100; + $items = $this->$model->listing($param, ($page-1)*$limit,$limit,'base.id,base.'.$nama_field); + $this->success($items); + } + + function user_get() + { + $this->_get('customer_model','nickname'); + } + + function package_get() + { + $this->_get('package_model'); + } + + function disease_get() + { + $this->_get('disease_model'); + } + + function series_number_get() + { + $this->_get('series_number_model','device_id'); + } +} diff --git a/controllers/api/v3/Series_number.php b/controllers/api/v3/Series_number.php new file mode 100644 index 0000000..427f4c0 --- /dev/null +++ b/controllers/api/v3/Series_number.php @@ -0,0 +1,77 @@ +load->model('package_model'); + $package = $this->package_model->get(false,'id,name',true); + $package_map = [ + '0'=>'未绑定套餐' + ]; + foreach ($package as $item) { + $package_map[$item['id']] = $item['name']; + } + foreach ($items['items'] as &$item) { + $item['status_desc'] = !empty($item['sample_id'])?'已激活':'未激活'; + $item['package_name'] = $package_map[$item['package_ori']]; + } + //统计 + $items['stat'] = [ + 'total'=>(int)$this->{$this->base_model}->total(), + 'used'=>(int)$this->{$this->base_model}->total(['s.id>0'],true), + 'unused'=>(int)$this->{$this->base_model}->total(['s.id is null'],true), + ]; + $this->success($items); + } + + //批量新建 + function batch_create_post() + { + $data = $this->json_input(); + if(empty($data['package_ori'])){ + $this->error('套餐不能为空'); + } + $package_id = trim($data['package_ori']); + $number = explode("\n",trim($data['device_id'])); + $devices = []; + foreach ($number as $item) { + $item = trim($item); + if(empty($item)){ + continue; + } + $devices[] = [ + 'device_id'=>$item, + 'package_ori'=>$package_id + ]; + } + if(empty($devices)){ + $this->error('序列号为空'); + } + $config = array( + array( + 'field' => 'device_id', + 'label' => '序号', + 'rules' => 'trim|min_length[0]|max_length[20]' + ), + array( + 'field' => 'package_ori', + 'label' => '套餐名称', + 'rules' => 'trim|required|min_length[1]|max_length[11]', + 'errors' => array( + 'required' => 'You must provide a %s.', + ), + ), + ); + $this->_batch_create_post($config,$devices); + $this->success(); + } +} diff --git a/controllers/api/v3/Ship_order.php b/controllers/api/v3/Ship_order.php new file mode 100644 index 0000000..f73d9f7 --- /dev/null +++ b/controllers/api/v3/Ship_order.php @@ -0,0 +1,10 @@ +load->model('Base_model'); +// $this->load->model('Record_model'); +// $this->load->model('Dept_model', 'Dept'); +// $this->config->load('config', true); + } + + public function index() + { + $this->load->view('login_view'); + } + + public function testapi() + { + echo "test api ok..."; + } + + public function phpinfo() + { + phpinfo(); + } + + public function testdb() + { + $this->load->database(); + $query = $this->db->query("show tables"); + var_dump($query); + var_dump($query->result()); + var_dump($query->row_array()); +// 有结果表明数据库连接正常 reslut() 与 row_array 结果有时不太一样 +// 一般加载到时model里面使用。 + } + + + function list_get() + { + + $items = [ + ["id" => 1, + "title" => "www", + "status" => "draft", + "author" => "qiaokun", + "display_time" => "", + "pageviews" => 300 + ], + ["id" => 3, + "title" => "bbb", + "status" => "bbbb", + "author" => "乔锟", + "display_time" => "", + "pageviews" => 300 + ], + ]; + + $message = [ + "code" => 20000, + "data" => [ + "items" => $items + ] + ]; + + $this->response($message, RestController::HTTP_OK); + + } + + function goods_get() + { + + $items = array( + array('id' => 1, 'title' => 'iphone 7 ', 'price' => 399, 'num' => 1), + array('id' => 2, 'title' => 'hdcms 7 ', 'price' => 2000, 'num' => 2), + array('id' => 3, 'title' => 'aaaas 7 ', 'price' => 2000, 'num' => 2), + array('id' => 4, 'title' => 'iphone 7 ', 'price' => 399, 'num' => 1), + array('id' => 5, 'title' => 'hdcms 7 ', 'price' => 2000, 'num' => 2), + array('id' => 6, 'title' => 'aaaas 7 ', 'price' => 2000, 'num' => 2), + array('id' => 7, 'title' => 'iphone 7 ', 'price' => 399, 'num' => 1), + array('id' => 8, 'title' => 'hdcms 7 ', 'price' => 2000, 'num' => 2), + array('id' => 9, 'title' => 'aaaas 7 ', 'price' => 2000, 'num' => 2), + array('id' => 10, 'title' => 'iphone 7 ', 'price' => 399, 'num' => 1), + array('id' => 11, 'title' => 'hdcms 7 ', 'price' => 2000, 'num' => 2), + array('id' => 31, 'title' => 'aaaas 7 ', 'price' => 2000, 'num' => 2), + array('id' => 13, 'title' => 'iphone 7 ', 'price' => 399, 'num' => 1), + array('id' => 24, 'title' => 'hdcms 7 ', 'price' => 2000, 'num' => 2), + array('id' => 35, 'title' => 'aaaas 7 ', 'price' => 2000, 'num' => 2), + array('id' => 19, 'title' => 'iphone 7 ', 'price' => 399, 'num' => 1), + array('id' => 22, 'title' => 'hdcms 7 ', 'price' => 2000, 'num' => 2), + array('id' => 33, 'title' => 'aaaas 7 ', 'price' => 2000, 'num' => 2), + ); + + $message = [ + "code" => 20000, + "data" => [ + "items" => $items + ] + ]; + + $this->response($message, RestController::HTTP_OK); + + } + +} + +/* End of file welcome.php */ +/* Location: ./application/controllers/welcome.php */ \ No newline at end of file diff --git a/controllers/api/v3/Uploadimg.php b/controllers/api/v3/Uploadimg.php new file mode 100644 index 0000000..cbe9fe3 --- /dev/null +++ b/controllers/api/v3/Uploadimg.php @@ -0,0 +1,410 @@ +load->model('Base_model'); + } + + + public function testapi_get() + { + echo "test api ok..."; + + echo APPPATH . "\n"; + echo SELF . "\n"; + echo BASEPATH . "\n"; + echo FCPATH . "\n"; + echo SYSDIR . "\n"; + var_dump($this->config->item('rest_language')); + var_dump($this->config->item('language')); + + var_dump($this->config); + } + + public function upload_post() + { + $uploadDir = FCPATH . 'uploads/'; + $id = 'T' . $this->POST('identify'); + $php_path = dirname(__FILE__) . '/';//dirname($_SERVER['DOCUMENT_ROOT']); dirname(__FILE__) +// $php_url = "";//dirname($_SERVER['HTTP_HOST']) . '/';//PHP_SELF + $php_url = $_SERVER['HTTP_HOST'] . '/'; //PHP_SELF + + $save_path = $uploadDir; + //文件保存目录URL + $save_url = $php_url . 'uploads/'; + // nginx服务器端修改绝对路径 + //$save_url = "http://172.30.3.11/static/home/kindeditor/attached/"; + + // var_dump($save_path); + // var_dump($save_url); + // string(46) "D:\Q\code\vue\CodeIgniter-3.1.10\uploads\imgs\" + // string(28) "www.cirest.com:8889/uploads/" + + + //定义允许上传的文件扩展名 + $ext_arr = array( + 'image' => array('gif', 'jpg', 'jpeg', 'png', 'bmp'), + 'flash' => array('swf', 'flv'), + 'media' => array('swf', 'flv', 'mp3', 'wav', 'wma', 'wmv', 'mid', 'avi', 'mpg', 'asf', 'rm', 'rmvb'), + 'file' => array('doc', 'docx', 'xls', 'xlsx', 'ppt', 'htm', 'html', 'txt', 'zip', 'rar', 'gz', 'bz2'), + ); + //最大文件大小 10M 默认是1M + $max_size = 10000000; + + $save_path = realpath($save_path) . '/'; + $save_path = str_replace('\\', '/', $save_path); + +//PHP上传失败 + if (!empty($_FILES['file']['error'])) { + switch ($_FILES['file']['error']) { + case '1': + $error = '超过php.ini允许的大小。'; + break; + case '2': + $error = '超过表单允许的大小。'; + break; + case '3': + $error = '图片只有部分被上传。'; + break; + case '4': + $error = '请选择图片。'; + break; + case '6': + $error = '找不到临时目录。'; + break; + case '7': + $error = '写文件到硬盘出错。'; + break; + case '8': + $error = 'File upload stopped by extension。'; + break; + case '999': + default: + $error = '未知错误。'; + } + $this->alert($error); + } + +//有上传文件时 + if (empty($_FILES) === false) { + //原文件名 + $file_name = $_FILES['file']['name']; + //服务器上临时文件名 + $tmp_name = $_FILES['file']['tmp_name']; + //文件大小 + $file_size = $_FILES['file']['size']; + //检查文件名 + if (!$file_name) { + $this->alert("请选择文件。"); + } + //检查目录 + if (@is_dir($save_path) === false) { + $this->alert("上传目录不存在。"); + } + //检查目录写权限 + if (@is_writable($save_path) === false) { + $this->alert("上传目录没有写权限。"); + } + //检查是否已上传 + if (@is_uploaded_file($tmp_name) === false) { + $this->alert("上传失败。"); + } + //检查文件大小 + if ($file_size > $max_size) { + $this->alert("上传文件大小超过限制(<10M)。"); + } + //检查目录名 + $dir_name = empty($_GET['dir']) ? 'image' : trim($_GET['dir']); + if (empty($ext_arr[$dir_name])) { + $this->alert("目录名不正确。"); + } + //获得文件扩展名 + $temp_arr = explode(".", $file_name); + $file_ext = array_pop($temp_arr); + $file_ext = trim($file_ext); + $file_ext = strtolower($file_ext); + + //检查扩展名 + if (!in_array($file_ext, $ext_arr[$dir_name])) { + $this->alert("上传文件扩展名是不允许的扩展名。\n只允许" . implode(",", $ext_arr[$dir_name]) . "格式。"); + + } + + /* + * 以 T+身份证号作为临时目录 , 以身份证作为正式目录 + */ + $identify = empty($id) ? '' : trim($id); + + if ($identify == '') { + echo "Invalid session identify."; + exit; + } + //创建文件夹 + if ($dir_name !== '') { + $save_path .= $dir_name . "/" . $identify . "/"; + $save_url .= $dir_name . "/" . $identify . "/"; + if (!file_exists($save_path)) { + mkdir($save_path, 0777, true); // true 允许创建多级目录 + } + } + $ymd = date("Ym"); + $save_path .= $ymd . "/"; + $save_url .= $ymd . "/"; + if (!file_exists($save_path)) { + mkdir($save_path); + } + //新文件名 + $new_file_name = date("YmdHis") . '_' . rand(10000, 99999) . '.' . $file_ext; + //移动文件 + $file_path = $save_path . $new_file_name; + if (move_uploaded_file($tmp_name, $file_path) === false) { + $this->alert("上传文件失败。"); + } + @chmod($file_path, 0644); + $file_url = $save_url . $new_file_name; + + header('Content-type: text/html; charset=UTF-8'); + // Insert file information in the database + // $insert = $db->query("INSERT INTO files (file_name, uploaded_on) VALUES ('".$fileName."', NOW())"); + $link = "http://" . $file_url; + // http://www.cirest.com:8889/uploads/image/T410000000000000000/201902/20190228071354_96833.png + $message = [ + "code" => 20000, + "error" => 0, + "message" => "上传成功", + "link" => $link, + "filepath" => preg_replace('/^http.*uploads/', '/uploads', $link) + ]; + + echo json_encode($message); + // $this->response($message, RestController::HTTP_OK); + // alert里面使用时 exit() 产生的是空,或字符串,使用原生的json_encode返回统一的字符串,在客户端在统一处理成对象 + } + } + + public function delimg_post() + { + $php_path = dirname(__FILE__) . '/';//dirname($_SERVER['DOCUMENT_ROOT']); dirname(__FILE__) + + //文件保存目录路径 + $save_path = $php_path . '../../../../'; + + $save_path = realpath($save_path) . '/'; + $save_path = str_replace('\\', '/', $save_path); + // var_dump($save_path); + // "D:/Q/code/vue/CodeIgniter-3.1.10/" + + $DelFileName = $this->POST('filename'); + $DelFileType = $this->POST('isdir'); + + $FilePath = $save_path . $DelFileName; + + // var_dump($FilePath);return; + + if ($DelFileType == 'F') { + if (!is_file($FilePath)) { + $message = [ + "code" => 20000, + "data" => "文件不存在 - " . $DelFileName, + "message" => "文件不存在 - " . $DelFileName + ]; + + echo json_encode($message); + + } else { + + if (!unlink($FilePath)) { + $message = [ + "code" => 20000, + "data" => "Error deleting " . $FilePath, + "message" => "Error deleting " . $FilePath + ]; + echo json_encode($message); + + } else { + // 必须返回code 由于前端vue封装的 request 请求,返回数据对code进行判断 + $message = [ + "code" => 20000, + "data" => '服务器删除成功!', + "message" => '服务器删除成功!' + ]; + echo json_encode($message); + } + } + exit; + } + + if ($DelFileType == 'D') { + if (!@rmdir($FilePath)) { + echo "文件夹 " . $FilePath . " 不为空,不能删除!"; + } else { + echo "succeed"; + } + exit; + } + } + + private function alert($msg) + { + header('Content-type: text/html; charset=UTF-8'); + $message = [ + "code" => 20000, + "error" => 1, + "message" => $msg + ]; + echo json_encode($message); + exit(); + // var_dump($message); + // $this->response($message, RestController::HTTP_OK); + // die(); + } + + + public function onsubmit_post() + { + $identify = $this->POST('identify'); + $phone = $this->POST('phone'); + $idinfo = $this->POST('idinfo'); + $bankinfo = $this->POST('bankinfo'); +// $data = [ +// 'identify' => $identify, +// 'phone' => $phone, +// 'idinfo' => $idinfo, +// 'check' => '待审核' +// ]; + + // 写入数据库表 身份证号,手机号,证件照,文件路径等 + $where = [ + 'identify' => $identify, + 'phone' => $phone, + ]; + + $data = [ + 'idinfo' => $idinfo, + 'bankinfo' => $bankinfo, + 'check' => '待审核' + ]; + + $result = $this->Base_model->_update_key('upload_tbl', $data, $where); + + if ($result) { + $message = [ + "code" => 20000, + "message" => '写入数据库表成功,请请待审核通知!', + "data" => array_merge($where, $data) + ]; + $this->response($message, RestController::HTTP_OK); + } else { + $message = [ + "code" => 20000, + "message" => '写入数据库表失败!', + "data" => array_merge($where, $data) + ]; + $this->response($message, RestController::HTTP_OK); + } + } + + // Chevereto 图床免费版本地址:https://github.com/Chevereto/Chevereto-Free + // https://chevereto.com/docs/api-v1 + // 上传图片测试 + public function chevereto_post() + { + // 1. 上传本地文件时应使用 $fields post base64_encode方法 + // Always use POST when uploading local files. Url encoding may alter the base64 source + // due to encoded characters or just by URL request length limit due to GET request. + // base64编码 会导致过长 url request + // var_dump($_FILES); 参考 uploadimg 可以做一些前置校验处理 // 前置判断 if (empty($_FILES) === false) + $key = '5486424e4dfb6b87453dd4bb25c0dcb0'; + $url = 'http://172.17.1.110/chevereto/api/1/upload'; + + // What do we send to chevereto api? + $fields = array( + 'key' => urlencode($key), + // The image encoded in base64 + 'source' => base64_encode(file_get_contents($_FILES["file"]['tmp_name'])), + // format: txt / json txt 只返回图片地址或错误信息 eg.Duplicated upload 较为简洁 + 'format' => urlencode('json') + ); + + //open connection + $ch = curl_init(); + + //set the url, number of POST vars, POST data + curl_setopt($ch, CURLOPT_URL, $url); + curl_setopt($ch, CURLOPT_POST, sizeof($fields)); + curl_setopt($ch, CURLOPT_HEADER, false); + curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); + curl_setopt($ch, CURLOPT_TIMEOUT, 240); + curl_setopt($ch, CURLOPT_POSTFIELDS, $fields); + curl_setopt($ch, CURLOPT_HTTPHEADER, array('Expect: ')); + + //execute post + $result = curl_exec($ch); + //释放curl句柄 + curl_close($ch); + echo $result; + //close connection + + // 2. 上传远程图片地址可使用 _get source=urlencode{source} 方法即可 + +// $key = '6a55c7f9fa13813c2da613dc7b5b920b'; +// // 设定远程图片地址 +// $source = 'https://img3.doubanio.com/view/group_topic/large/public/p67032015.jpg'; +// // format: txt / json txt 只返回图片地址或错误信息 eg.Duplicated upload 较为简洁 +// $url = 'http://172.17.1.110:8888/api/1/upload/?key={key}&source={source}&format=txt'; +// $url = str_replace(array('{key}','{source}'),array($key,urlencode($source)),$url); +// +// //初始化 +// $ch = curl_init(); +// //设置选项,包括URL +// curl_setopt($ch, CURLOPT_URL, $url); +// curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); +// curl_setopt($ch, CURLOPT_HEADER, 0); +// //执行并获取HTML文档内容 +// $output = curl_exec($ch); +// //释放curl句柄 +// curl_close($ch); +// echo $output; + + +// 失败 +// { +// "status_txt": "Bad Request", +// "error": { +// "context": "Exception", +// "code": 102, +// "message": "Duplicated upload" +// }, +// "status_code": 400 +// } +// 成功 +// { +// "status_txt": "OK", +// "image": { +// "image": { +// "size": "89163", +// "url": "http://172.17.1.110:8888/images/2019/07/09/p67032015.jpg", +// "extension": "jpg", +// "mime": "image/jpeg", +// "name": "p67032015", +// "filename": "p67032015.jpg" +// }, +// }, +// "success": { +// "code": 200, +// "message": "image uploaded" +// }, +// "status_code": 200 +// } + + } + +} diff --git a/controllers/api/v3/User.php b/controllers/api/v3/User.php new file mode 100644 index 0000000..7fafdcb --- /dev/null +++ b/controllers/api/v3/User.php @@ -0,0 +1,10 @@ + 'id', + 'label' => '序号', + 'rules' => 'trim|min_length[0]|max_length[20]' + ), + array( + 'field' => 'name', + 'label' => '名称', + 'rules' => 'trim|min_length[0]|max_length[100]' + ), + array( + 'field' => 'origin', + 'label' => '历史起源', + 'rules' => 'trim|min_length[0]|max_length[100]' + ), + array( + 'field' => 'migration', + 'label' => '迁徙发展', + 'rules' => 'trim|min_length[0]|max_length[100]' + ), + array( + 'field' => 'characteristic', + 'label' => '品种特点', + 'rules' => 'trim|min_length[0]|max_length[2000]' + ), + array( + 'field' => 'fun_story', + 'label' => '趣事', + 'rules' => 'trim|min_length[0]|max_length[2000]' + ), + array( + 'field' => 'gene_disease', + 'label' => '常见遗传病', + 'rules' => 'trim|min_length[0]|max_length[2000]' + ), + array( + 'field' => 'species', + 'label' => '物种', + 'rules' => 'trim|integer|min_length[0]|max_length[2]' + ), + ); + } + + protected function _import_field_map(){ + return [ + '名称'=>'name', + '历史起源'=>'origin', + '迁徙发展'=>'migration', + '犬种特点'=>'characteristic', + '品种特点'=>'characteristic', + '趣事'=>'fun_story', + '常见遗传病'=>'gene_disease', + 'species'=>'species', + ]; + } + +} diff --git a/controllers/api/v3/sys/Dept.php b/controllers/api/v3/sys/Dept.php new file mode 100644 index 0000000..f4e0696 --- /dev/null +++ b/controllers/api/v3/sys/Dept.php @@ -0,0 +1,186 @@ +load->model('Base_model'); + $this->load->model('Dept_model'); + // $this->config->load('config', true); + } + + // 增 + function add_post() + { + $uri = $this->uri->uri_string; + $Token = $this->input->get_request_header('X-Token', TRUE); + $retPerm = $this->permission->HasPermit($Token, $uri); + if ($retPerm['code'] != 50000) { + $this->response($retPerm, RestController::HTTP_OK); + } + + $parms = $this->post(); // 获取表单参数,类型为数组 + +// var_dump($parms);return; + if ($this->Base_model->_key_exists('sys_dept', ['name' => $parms['name']])) { + $message = [ + "code" => 20000, + "type" => 'error', + "message" => $parms['name'] . ' - 机构名称重复' + ]; + $this->response($message, RestController::HTTP_OK); + } + + $dept_id = $this->Base_model->_insert_key('sys_dept', $parms); + if (!$dept_id) { + $message = [ + "code" => 20000, + "type" => 'error', + "message" => $parms['name'] . ' - 机构新增失败' + ]; + $this->response($message, RestController::HTTP_OK); + } + + // 超级管理员用户的超级管理员角色自动归属该机构 + $user_role_id = $this->Base_model->_insert_key('sys_user_role', ["user_id" => 1, "role_id" => 1, "dept_id" => $dept_id]); + if (!$user_role_id) { + var_dump($this->uri->uri_string . ' 超级管理员用户的超级管理员角色自动归属该机构, 失败...'); + var_dump(["user_id" => 1, "role_id" => 1, "dept_id" => $dept_id]); + return; + } + + $message = [ + "code" => 20000, + "type" => 'success', + "message" => $parms['name'] . ' - 机构新增成功' + ]; + $this->response($message, RestController::HTTP_OK); + } + + // 改 + function edit_post() + { + $uri = $this->uri->uri_string; + $Token = $this->input->get_request_header('X-Token', TRUE); + $retPerm = $this->permission->HasPermit($Token, $uri); + if ($retPerm['code'] != 50000) { + $this->response($retPerm, RestController::HTTP_OK); + } + + // $id = $this->post('id'); // POST param + $parms = $this->post(); // 获取表单参数,类型为数组 + // var_dump($parms['path']); + + // 参数检验/数据预处理 + $id = $parms['id']; + unset($parms['id']); // 剃除索引id + unset($parms['children']); // 剃除传递上来的子节点信息 + + if ($id == $parms['pid']) { + $message = [ + "code" => 20000, + "type" => 'error', + "message" => $parms['name'] . ' - 上级机构不能为自己' + ]; + $this->response($message, RestController::HTTP_OK); + } + + $where = ["id" => $id]; + + if (!$this->Base_model->_update_key('sys_dept', $parms, $where)) { + $message = [ + "code" => 20000, + "type" => 'error', + "message" => $parms['name'] . ' - 机构更新错误' + ]; + $this->response($message, RestController::HTTP_OK); + } + + $message = [ + "code" => 20000, + "type" => 'success', + "message" => $parms['name'] . ' - 机构更新成功' + ]; + $this->response($message, RestController::HTTP_OK); + } + + // 删 + function del_post() + { + $uri = $this->uri->uri_string; + $Token = $this->input->get_request_header('X-Token', TRUE); + $retPerm = $this->permission->HasPermit($Token, $uri); + if ($retPerm['code'] != 50000) { + $this->response($retPerm, RestController::HTTP_OK); + } + + $parms = $this->post(); // 获取表单参数,类型为数组 + // var_dump($parms['path']); + + // 参数检验/数据预处理 + // 含有子节点不允许删除 + $hasChild = $this->Dept_model->hasChildDept($parms['id']); + if ($hasChild) { + $message = [ + "code" => 20000, + "type" => 'error', + "message" => $parms['name'] . ' - 存在子节点不能删除' + ]; + $this->response($message, RestController::HTTP_OK); + } + + // 先删除外键关联表 + if (!$this->Base_model->_delete_key('sys_user_role', ['dept_id' => $parms['id']])) { + $message = [ + "code" => 20000, + "type" => 'error', + "message" => '删除关联表失败 ' . json_encode($parms) + ]; + $this->response($message, RestController::HTTP_OK); + } + + // 删除基础表 sys_dept + if (!$this->Base_model->_delete_key('sys_dept', ['id' => $parms['id']])) { + $message = [ + "code" => 20000, + "type" => 'error', + "message" => $parms['name'] . ' - 机构删除失败' + ]; + $this->response($message, RestController::HTTP_OK); + } + + $message = [ + "code" => 20000, + "type" => 'success', + "message" => $parms['name'] . ' - 机构删除成功' + ]; + $this->response($message, RestController::HTTP_OK); + } + + // 查 + function view_post() + { + $uri = $this->uri->uri_string; + $Token = $this->input->get_request_header('X-Token', TRUE); + + $retPerm = $this->permission->HasPermit($Token, $uri); + if ($retPerm['code'] != 50000) { + $this->response($retPerm, RestController::HTTP_OK); + } + + $DeptArr = $this->Dept_model->getDeptList(); + $DeptTree = $this->permission->genDeptTree($DeptArr, 'id', 'pid', 0); + + $message = [ + "code" => 20000, + "data" => $DeptTree, + ]; + $this->response($message, RestController::HTTP_OK); + } + +} diff --git a/controllers/api/v3/sys/Menu.php b/controllers/api/v3/sys/Menu.php new file mode 100644 index 0000000..bd022a9 --- /dev/null +++ b/controllers/api/v3/sys/Menu.php @@ -0,0 +1,342 @@ +load->model('Base_model'); + // $this->config->load('config', true); + } + + public function index_get() + { + $this->load->view('login_view'); + } + + public function insertx_post() + { + // $id = $this->post('id'); // POST param + $parms = $this->post(); // 获取表单参数,类型为数组 + var_dump($parms); + $result = $this->Base_model->_insert_key('sys_role_perm', $parms); + var_dump($result); + } + + public function gettest_post() + { + $result = $this->Base_model->_get_key('sys_perm', 'perm_type,r_id rid', 'perm_type="role" and r_id=1'); + var_dump($result); + var_dump($result[0]['perm_type']); + var_dump($this->uri->uri_string); + var_dump($this->uri); + + } + + + public function testapi_get() + { + echo "test api ok..."; + + echo APPPATH . "\n"; + echo SELF . "\n"; + echo BASEPATH . "\n"; + echo FCPATH . "\n"; + echo SYSDIR . "\n"; + var_dump($this->config->item('rest_language')); + var_dump($this->config->item('language')); + + var_dump($this->config); + +// $message = [ +// "code" => 20000, +// "data" => [ +// "__FUNCTION__" => __FUNCTION__, +// "__CLASS__" => __CLASS__, +// "uri" => $this->uri +// ], +// +// ]; +// "data": { +// "__FUNCTION__": "router_get", +// "__CLASS__": "User", +// "uri": { +// "keyval": [], +// "uri_string": "api/v2/user/router", +// "segments": { +// "1": "api", +// "2": "v2", +// "3": "user", +// "4": "router" +// }, + } + + public function phpinfo_get() + { + phpinfo(); + } + + public function testdb_get() + { + $this->load->database(); + $query = $this->db->query("show tables"); + var_dump($query); + var_dump($query->result()); + var_dump($query->row_array()); +// 有结果表明数据库连接正常 reslut() 与 row_array 结果有时不太一样 +// 一般加载到时model里面使用。 + } + + // 增 + function add_post() + { + $uri = $this->uri->uri_string; + $Token = $this->input->get_request_header('X-Token', TRUE); + $retPerm = $this->permission->HasPermit($Token, $uri); + if ($retPerm['code'] != 50000) { + $this->response($retPerm, RestController::HTTP_OK); + } + + // $id = $this->post('id'); // POST param + $parms = $this->post(); // 获取表单参数,类型为数组 + // var_dump($parms); + // var_dump($parms['path']); + + // 参数检验/数据预处理 + // 菜单类型为目录 + if (!$parms['type']) { + $parms['component'] = 'Layout'; + } + + $menu_id = $this->Base_model->_insert_key('sys_menu', $parms); + if (!$menu_id) { + $message = [ + "code" => 20000, + "type" => 'error', + "message" => $parms['title'] . ' - 菜单添加失败' + ]; + $this->response($message, RestController::HTTP_OK); + } + + // 生成该菜单对应的权限: sys_perm, 权限类型为: menu, 生成唯一的 perm_id + $perm_id = $this->Base_model->_insert_key('sys_perm', ['perm_type' => 'menu', "r_id" => $menu_id]); + if (!$perm_id) { + var_dump($this->uri->uri_string . ' 生成该菜单对应的权限: sys_perm, 失败...'); + var_dump(['perm_type' => 'menu', "r_id" => $menu_id]); + return; + } + + // 超级管理员角色自动拥有该权限 perm_id + $role_perm_id = $this->Base_model->_insert_key('sys_role_perm', ["role_id" => 1, "perm_id" => $perm_id]); + if (!$role_perm_id) { + var_dump($this->uri->uri_string . ' 超级管理员角色自动拥有该权限 perm_id, 失败...'); + var_dump(["role_id" => 1, "perm_id" => $perm_id]); + return; + } + + $message = [ + "code" => 20000, + "type" => 'success', + "message" => $parms['title'] . ' - 菜单添加成功' + ]; + $this->response($message, RestController::HTTP_OK); + } + + // 改 + function edit_post() + { + $uri = $this->uri->uri_string; + $Token = $this->input->get_request_header('X-Token', TRUE); + $retPerm = $this->permission->HasPermit($Token, $uri); + if ($retPerm['code'] != 50000) { + $this->response($retPerm, RestController::HTTP_OK); + } + + // $id = $this->post('id'); // POST param + $parms = $this->post(); // 获取表单参数,类型为数组 + // var_dump($parms['path']); + + // 参数检验/数据预处理 + if ($parms['id'] == $parms['pid']) { + $message = [ + "code" => 20000, + "type" => 'error', + "message" => '父节点不能是自己' + ]; + $this->response($message, RestController::HTTP_OK); + } + // 菜单类型为目录 + if ($parms['type'] == 0) { + $parms['component'] = 'Layout'; + } + // 菜单类型为功能按钮时 + if ($parms['type'] == 2) { + $parms['component'] = ''; + $parms['icon'] = ''; + } + + $id = $parms['id']; + unset($parms['id']); // 择出索引id + $where = ["id" => $id]; + + if (!$this->Base_model->_update_key('sys_menu', $parms, $where)) { + $message = [ + "code" => 20000, + "type" => 'error', + "message" => $parms['title'] . ' - 菜单更新错误' + ]; + $this->response($message, RestController::HTTP_OK); + } + + $message = [ + "code" => 20000, + "type" => 'success', + "message" => $parms['title'] . ' - 菜单更新成功' + ]; + $this->response($message, RestController::HTTP_OK); + } + + // 删 + function del_post() + { + $uri = $this->uri->uri_string; + $Token = $this->input->get_request_header('X-Token', TRUE); + $retPerm = $this->permission->HasPermit($Token, $uri); + if ($retPerm['code'] != 50000) { + $this->response($retPerm, RestController::HTTP_OK); + } + + $parms = $this->post(); // 获取表单参数,类型为数组 + // var_dump($parms['path']); + + // 参数检验/数据预处理 + // 存在子节点 不能删除返回 + $hasChild = $this->Base_model->hasChildMenu($parms['id']); + if ($hasChild) { + $message = [ + "code" => 20000, + "type" => 'error', + "message" => $parms['title'] . ' - 存在子节点不能删除' + ]; + $this->response($message, RestController::HTTP_OK); + } + + // 删除外键关联表 sys_role_perm , sys_perm, sys_menu + // 1. 根据sys_menu id及'menu' 查找 perm_id + // 2. 删除sys_role_perm 中perm_id记录 + // 3. 删除sys_perm中 perm_type='menu' and r_id = menu_id 记录,即第1步中获取的 perm_id, 一一对应 + // 4. 删除sys_menu 中 id = menu_id 的记录 + $where = 'perm_type="menu" and r_id=' . $parms['id']; + $arr = $this->Base_model->_get_key('sys_perm', '*', $where); + if (empty($arr)) { + var_dump($this->uri->uri_string . ' 未查找到 sys_perm 表中记录'); + var_dump($where); + return; + } + + $perm_id = $arr[0]['id']; // 正常只有一条记录 + $this->Base_model->_delete_key('sys_role_perm', ['perm_id' => $perm_id]); + $this->Base_model->_delete_key('sys_perm', ['id' => $perm_id]); + + // 删除基础表 sys_menu + if (!$this->Base_model->_delete_key('sys_menu', $parms)) { + $message = [ + "code" => 20000, + "type" => 'error', + "message" => $parms['title'] . ' - 菜单删除错误' + ]; + $this->response($message, RestController::HTTP_OK); + } + + $message = [ + "code" => 20000, + "type" => 'success', + "message" => $parms['title'] . ' - 菜单删除成功' + ]; + $this->response($message, RestController::HTTP_OK); + } + + // 查 + function view_post() + { + $uri = $this->uri->uri_string; + $Token = $this->input->get_request_header('X-Token', TRUE); + + $retPerm = $this->permission->HasPermit($Token, $uri); + if ($retPerm['code'] != 50000) { + $this->response($retPerm, RestController::HTTP_OK); + } + + $MenuTreeArr = $this->permission->getPermission($Token, 'menu', true); + $MenuTree = $this->permission->genVueMenuTree($MenuTreeArr, 'id', 'pid', 0); + $message = [ + "code" => 20000, + "data" => $MenuTree, + ]; + $this->response($message, RestController::HTTP_OK); + } + + // 根据token拉取 treeselect 下拉选项菜单 + function treeoptions_get() + { + // 此 uri 可不做权限/token过期验证,则在菜单里,可以不加入此项路由path /sys/menu/treeoptions。 + // + // $uri = $this->uri->uri_string; + // $Token = $this->input->get_request_header('X-Token', TRUE); + // $retPerm = $this->permission->HasPermit($Token, $uri); + // if ($retPerm['code'] != 50000) { + // $this->response($retPerm, RestController::HTTP_OK); + // return; + // } + + $Token = $this->input->get_request_header('X-Token', TRUE); + + $MenuTreeArr = $this->permission->getPermission($Token, 'menu', false); + array_unshift($MenuTreeArr, ['id' => 0, 'pid' => -1, 'title' => '顶级菜单']); + $MenuTree = $this->permission->genVueMenuTree($MenuTreeArr, 'id', 'pid', -1); + + $message = [ + "code" => 20000, + "data" => $MenuTree, + ]; + $this->response($message, RestController::HTTP_OK); + } + + + function list_get() + { +// $result = $this->some_model(); + $result['success'] = TRUE; + + if ($result['success']) { + $List = array( + array('order_no' => '201805138451313131', 'timestamp' => 'iphone 7 ', 'username' => 'iphone 7 ', 'price' => 399, 'status' => 'success'), + array('order_no' => '300000000000000000', 'timestamp' => 'iphone 7 ', 'username' => 'iphone 7 ', 'price' => 399, 'status' => 'pending'), + array('order_no' => '444444444444444444', 'timestamp' => 'iphone 7 ', 'username' => 'iphone 7 ', 'price' => 399, 'status' => 'success'), + array('order_no' => '888888888888888888', 'timestamp' => 'iphone 7 ', 'username' => 'iphone 7 ', 'price' => 399, 'status' => 'pending'), + ); + + $message = [ + "code" => 20000, + "data" => [ + "total" => count($List), + "items" => $List + ] + ]; + $this->response($message, RestController::HTTP_OK); + } else { + $message = [ + "code" => 50008, + "message" => 'Login failed, unable to get user details.' + ]; + + $this->response($message, RestController::HTTP_OK); + } + + } + +} diff --git a/controllers/api/v3/sys/Role.php b/controllers/api/v3/sys/Role.php new file mode 100644 index 0000000..85a9479 --- /dev/null +++ b/controllers/api/v3/sys/Role.php @@ -0,0 +1,455 @@ +load->model('Base_model'); + $this->load->model('Role_model'); + // $this->config->load('config', true); + } + + public function index_get() + { + $this->load->view('login_view'); + } + + public function insertx_post() + { + // $id = $this->post('id'); // POST param + $parms = $this->post(); // 获取表单参数,类型为数组 + var_dump($parms); + $result = $this->Base_model->_insert_key('sys_role_perm', $parms); + var_dump($result); + } + + public function gettest_post() + { + $result = $this->Base_model->_get_key('sys_perm', 'perm_type,r_id rid', 'perm_type="role" and r_id=1'); + var_dump($result); + var_dump($result[0]['perm_type']); + var_dump($this->uri->uri_string); + var_dump($this->uri); + + } + + + public function testapi_get() + { + echo "test api ok..."; + + echo APPPATH . "\n"; + echo SELF . "\n"; + echo BASEPATH . "\n"; + echo FCPATH . "\n"; + echo SYSDIR . "\n"; + var_dump($this->config->item('rest_language')); + var_dump($this->config->item('language')); + + var_dump($this->config); + +// $message = [ +// "code" => 20000, +// "data" => [ +// "__FUNCTION__" => __FUNCTION__, +// "__CLASS__" => __CLASS__, +// "uri" => $this->uri +// ], +// +// ]; +// "data": { +// "__FUNCTION__": "router_get", +// "__CLASS__": "User", +// "uri": { +// "keyval": [], +// "uri_string": "api/v2/user/router", +// "segments": { +// "1": "api", +// "2": "v2", +// "3": "user", +// "4": "router" +// }, + } + + public function phpinfo_get() + { + phpinfo(); + } + + public function testdb_get() + { + $this->load->database(); + $query = $this->db->query("show tables"); + var_dump($query); + var_dump($query->result()); + var_dump($query->row_array()); +// 有结果表明数据库连接正常 reslut() 与 row_array 结果有时不太一样 +// 一般加载到时model里面使用。 + } + + // 增 + function add_post() + { + $uri = $this->uri->uri_string; + $Token = $this->input->get_request_header('X-Token', TRUE); + $retPerm = $this->permission->HasPermit($Token, $uri); + if ($retPerm['code'] != 50000) { + $this->response($retPerm, RestController::HTTP_OK); + } + + $parms = $this->post(); // 获取表单参数,类型为数组 + + if ($this->Base_model->_key_exists('sys_role', ['name' => $parms['name']])) { + $message = [ + "code" => 20000, + "type" => 'error', + "message" => $parms['name'] . ' - 角色名重复' + ]; + $this->response($message, RestController::HTTP_OK); + } + + // 加入新增时间 + $parms['create_time'] = time(); + + $role_id = $this->Base_model->_insert_key('sys_role', $parms); + if (!$role_id) { + $message = [ + "code" => 20000, + "type" => 'error', + "message" => $parms['name'] . ' - 角色新增失败' + ]; + $this->response($message, RestController::HTTP_OK); + } + + // 生成该角色对应的权限: sys_perm, 权限类型为: role, 生成唯一的 perm_id + $perm_id = $this->Base_model->_insert_key('sys_perm', ['perm_type' => 'role', "r_id" => $role_id]); + if (!$perm_id) { + var_dump($this->uri->uri_string . ' 生成该角色对应的权限: sys_perm, 失败...'); + var_dump(['perm_type' => 'role', "r_id" => $role_id]); + return; + } + + // 超级管理员角色自动拥有该权限 perm_id + $role_perm_id = $this->Base_model->_insert_key('sys_role_perm', ["role_id" => 1, "perm_id" => $perm_id]); + if (!$role_perm_id) { + var_dump($this->uri->uri_string . ' 超级管理员角色自动拥有该权限 perm_id, 失败...'); + var_dump(["role_id" => 1, "perm_id" => $perm_id]); + return; + } + + $message = [ + "code" => 20000, + "type" => 'success', + "message" => $parms['name'] . ' - 角色新增成功' + ]; + $this->response($message, RestController::HTTP_OK); + } + + // 改 + function edit_post() + { + $uri = $this->uri->uri_string; + $Token = $this->input->get_request_header('X-Token', TRUE); + $retPerm = $this->permission->HasPermit($Token, $uri); + if ($retPerm['code'] != 50000) { + $this->response($retPerm, RestController::HTTP_OK); + } + + // $id = $this->post('id'); // POST param + $parms = $this->post(); // 获取表单参数,类型为数组 + // var_dump($parms['path']); + + // 参数检验/数据预处理 + // 超级管理员角色不允许修改 + if ($parms['id'] == 1) { + $message = [ + "code" => 20000, + "type" => 'error', + "message" => $parms['name'] . ' - 角色不允许修改' + ]; + $this->response($message, RestController::HTTP_OK); + } + + $id = $parms['id']; + unset($parms['id']); // 剃除索引id + + // 加入更新时间 + $parms['update_time'] = time(); + $where = ["id" => $id]; + + if (!$this->Base_model->_update_key('sys_role', $parms, $where)) { + $message = [ + "code" => 20000, + "type" => 'error', + "message" => $parms['name'] . ' - 角色更新错误' + ]; + $this->response($message, RestController::HTTP_OK); + } + + $message = [ + "code" => 20000, + "type" => 'success', + "message" => $parms['name'] . ' - 角色更新成功' + ]; + $this->response($message, RestController::HTTP_OK); + } + + // 删 + function del_post() + { + $uri = $this->uri->uri_string; + $Token = $this->input->get_request_header('X-Token', TRUE); + $retPerm = $this->permission->HasPermit($Token, $uri); + if ($retPerm['code'] != 50000) { + $this->response($retPerm, RestController::HTTP_OK); + } + + $parms = $this->post(); // 获取表单参数,类型为数组 + // var_dump($parms['path']); + + // 参数检验/数据预处理 + // 超级管理员角色不允许删除 + if ($parms['id'] == 1) { + $message = [ + "code" => 20000, + "type" => 'error', + "message" => $parms['name'] . ' - 角色不允许删除' + ]; + $this->response($message, RestController::HTTP_OK); + } + + // 删除外键关联表 sys_role_perm , sys_perm, sys_role, sys_user_role + // 1. 根据sys_role id及'role' 查找 perm_id + // 2. 删除sys_role_perm 中perm_id记录 + // 3. 删除sys_perm中 perm_type='role' and r_id = role_id 记录,即第1步中获取的 perm_id, 一一对应 + // 4. 删除sys_user_role role_id 记录 + // 5. 删除sys_role 中 id = role_id 的记录 + $where = 'perm_type="role" and r_id=' . $parms['id']; + $arr = $this->Base_model->_get_key('sys_perm', '*', $where); + if (empty($arr)) { + var_dump($this->uri->uri_string . ' 未查找到 sys_perm 表中记录'); + var_dump($where); + return; + } + + $perm_id = $arr[0]['id']; // 正常只有一条记录 + $this->Base_model->_delete_key('sys_role_perm', ['perm_id' => $perm_id]); // 必须删除权限id 因为超级管理员角色自动拥有该权限否则会造成删除关联错误 + $this->Base_model->_delete_key('sys_role_perm', ['role_id' => $parms['id']]); // 再删除该角色对应的权限id(原有的菜单) + $this->Base_model->_delete_key('sys_perm', ['id' => $perm_id]); + + $this->Base_model->_delete_key('sys_user_role', ['role_id' => $parms['id']]); + // 删除基础表 sys_role + if (!$this->Base_model->_delete_key('sys_role', $parms)) { + $message = [ + "code" => 20000, + "type" => 'error', + "message" => $parms['name'] . ' - 角色删除错误' + ]; + $this->response($message, RestController::HTTP_OK); + } + + $message = [ + "code" => 20000, + "type" => 'success', + "message" => $parms['name'] . ' - 角色删除成功' + ]; + $this->response($message, RestController::HTTP_OK); + } + + // 查 + function view_post() + { + $uri = $this->uri->uri_string; + $Token = $this->input->get_request_header('X-Token', TRUE); + + $retPerm = $this->permission->HasPermit($Token, $uri); + if ($retPerm['code'] != 50000) { + $this->response($retPerm, RestController::HTTP_OK); + } + + $RoleArr = $this->Role_model->getRoleList(); + $message = [ + "code" => 20000, + "data" => $RoleArr, + ]; + $this->response($message, RestController::HTTP_OK); + } + + // 获取所有菜单 不需权限验证 + function allmenus_get() + { + $MenuTreeArr = $this->Role_model->getAllMenus(); + if (empty($MenuTreeArr)) { + $message = [ + "code" => 20000, + "data" => $MenuTreeArr, + "message" => "数据库表中没有菜单" + ]; + $this->response($message, RestController::HTTP_OK); + } + + $MenuTree = $this->permission->genVueMenuTree($MenuTreeArr, 'id', 'pid', 0); + $message = [ + "code" => 20000, + "data" => $MenuTree, + ]; + $this->response($message, RestController::HTTP_OK); + } + + // 获取所有角色带perm_id 不需权限验证 + function allroles_get() + { + $AllRolesArr = $this->Role_model->getAllRoles(); + if (empty($AllRolesArr)) { + $message = [ + "code" => 20000, + "data" => $AllRolesArr, + "message" => "数据库表中没有角色" + ]; + $this->response($message, RestController::HTTP_OK); + } + + $message = [ + "code" => 20000, + "data" => $AllRolesArr, + ]; + $this->response($message, RestController::HTTP_OK); + } + + // 获取角色拥有的菜单权限 不需权限验证 + function rolemenu_post() + { + $parms = $this->post(); // 获取表单参数,类型为数组 + $RoleId = $parms['roleId']; + + $MenuTreeArr = $this->Role_model->getRoleMenu($RoleId); + $message = [ + "code" => 20000, + "data" => $MenuTreeArr, + ]; + $this->response($message, RestController::HTTP_OK); + } + + // 获取角色拥有的角色权限 不需权限验证 + function rolerole_post() + { + $parms = $this->post(); // 获取表单参数,类型为数组 + $RoleId = $parms['roleId']; + + $RoleRoleArr = $this->Role_model->getRoleRole($RoleId); + $message = [ + "code" => 20000, + "data" => $RoleRoleArr, + ]; + $this->response($message, RestController::HTTP_OK); + } + + // 保存角色对应权限 + function saveroleperm_post() + { + $parms = $this->post(); // 获取表单参数,类型为数组 + // var_dump($parms['roleId']); + // var_dump($parms['rolePerms']); + // 参数检验/数据预处理 + // 超级管理员角色不允许删除 + if ($parms['roleId'] == 1) { + $message = [ + "code" => 20000, + "type" => 'error', + "message" => '超级管理员角色拥有所有权限,不允许修改!' + ]; + $this->response($message, RestController::HTTP_OK); + } + + $RolePermArr = $this->Role_model->getRolePerm($parms['roleId']); + + $AddArr = $this->permission->array_diff_assoc2($parms['rolePerms'], $RolePermArr); + // var_dump('------------只存在于前台传参 做添加操作-------------'); + // var_dump($AddArr); + $failed = false; + $failedArr = []; + foreach ($AddArr as $k => $v) { + $ret = $this->Base_model->_insert_key('sys_role_perm', $v); + if (!$ret) { + $failed = true; + array_push($failedArr, $v); + } + } + if ($failed) { + $message = [ + "code" => 20000, + "type" => 'error', + "message" => '授权失败 ' . json_encode($failedArr) + ]; + $this->response($message, RestController::HTTP_OK); + } + + $DelArr = $this->permission->array_diff_assoc2($RolePermArr, $parms['rolePerms']); + // var_dump('------------只存在于后台数据库 删除操作-------------'); + // var_dump($DelArr); + $failed = false; + $failedArr = []; + foreach ($DelArr as $k => $v) { + $ret = $this->Base_model->_delete_key('sys_role_perm', $v); + if (!$ret) { + $failed = true; + array_push($failedArr, $v); + } + } + if ($failed) { + $message = [ + "code" => 20000, + "type" => 'error', + "message" => '授权失败 ' . json_encode($failedArr) + ]; + $this->response($message, RestController::HTTP_OK); + } + + $message = [ + "code" => 20000, + "type" => 'success', + "data" => $parms, + "message" => '授权操作成功', + ]; + $this->response($message, RestController::HTTP_OK); + } + + + function list_get() + { +// $result = $this->some_model(); + $result['success'] = TRUE; + + if ($result['success']) { + $List = array( + array('order_no' => '201805138451313131', 'timestamp' => 'iphone 7 ', 'username' => 'iphone 7 ', 'price' => 399, 'status' => 'success'), + array('order_no' => '300000000000000000', 'timestamp' => 'iphone 7 ', 'username' => 'iphone 7 ', 'price' => 399, 'status' => 'pending'), + array('order_no' => '444444444444444444', 'timestamp' => 'iphone 7 ', 'username' => 'iphone 7 ', 'price' => 399, 'status' => 'success'), + array('order_no' => '888888888888888888', 'timestamp' => 'iphone 7 ', 'username' => 'iphone 7 ', 'price' => 399, 'status' => 'pending'), + ); + + $message = [ + "code" => 20000, + "data" => [ + "total" => count($List), + "items" => $List + ] + ]; + $this->response($message, RestController::HTTP_OK); + } else { + $message = [ + "code" => 50008, + "message" => 'Login failed, unable to get user details.' + ]; + + $this->response($message, RestController::HTTP_OK); + } + + } + +} diff --git a/controllers/api/v3/sys/User.php b/controllers/api/v3/sys/User.php new file mode 100644 index 0000000..87dcd6a --- /dev/null +++ b/controllers/api/v3/sys/User.php @@ -0,0 +1,1518 @@ +load->model('Base_model'); + $this->load->model('User_model'); + $this->load->database(); + // $this->config->load('config', true); + } + + public function index_get() + { + $this->load->view('login_view'); + } + + public function testapi_get() + { + phpinfo(); + echo "test api ok..."; + echo APPPATH . "\n"; + echo SELF . "\n"; + echo BASEPATH . "\n"; + echo FCPATH . "\n"; + echo SYSDIR . "\n"; + var_dump($this->config->item('rest_language')); + var_dump($this->config->item('language')); + + var_dump($this->config); + +// $message = [ +// "code" => 20000, +// "data" => [ +// "__FUNCTION__" => __FUNCTION__, +// "__CLASS__" => __CLASS__, +// "uri" => $this->uri +// ], +// +// ]; +// "data": { +// "__FUNCTION__": "router_get", +// "__CLASS__": "User", +// "uri": { +// "keyval": [], +// "uri_string": "api/v2/user/router", +// "segments": { +// "1": "api", +// "2": "v2", +// "3": "user", +// "4": "router" +// }, + } + + public function phpinfo_get() + { + phpinfo(); + } + + public function testdb_get() + { + $this->load->database(); + $query = $this->db->query("show tables"); + var_dump($query); + var_dump($query->result()); + var_dump($query->row_array()); +// 有结果表明数据库连接正常 reslut() 与 row_array 结果有时不太一样 +// 一般加载到时model里面使用。 + } + + + /* Helper Methods */ + /** + * 生成 token + * @param + * @return string 40个字符 + */ + private function _generate_token() + { + do { + // Generate a random salt + $salt = base_convert(bin2hex($this->security->get_random_bytes(64)), 16, 36); + + // If an error occurred, then fall back to the previous method + if ($salt === FALSE) { + $salt = hash('sha256', time() . mt_rand()); + } + + $new_key = substr($salt, 0, config_item('rest_key_length')); + } while ($this->_token_exists($new_key)); + + return $new_key; + } + + /* Private Data Methods */ + + private function _token_exists($token) + { + return $this->db + ->where('token', $token) + ->count_all_results('sys_user_token') > 0; + } + + private function _insert_token($token, $data) + { + $data['token'] = $token; + + return $this->db + ->set($data) + ->insert('sys_user_token'); + } + + private function _update_token($token, $data) + { + return $this->db + ->where('token', $token) + ->update('auth', $data); + } + + // 查 + function view_post() + { + $uri = $this->uri->uri_string; + $Token = $this->input->get_request_header('X-Token', TRUE); + + $retPerm = $this->permission->HasPermit($Token, $uri); + if ($retPerm['code'] != 50000) { + $this->response($retPerm, RestController::HTTP_OK); + } + + $parms = $this->post(); + // $type = $parms['type']; + $filters = $parms['filters']; + $sort = $parms['sort']; + $page = $parms['page']; + $pageSize = $parms['pageSize']; + + // 1. 找出用户角色拥有的机构查看权限 + // 2. 用户列表只能是这些机构下的用户 + $DeptArr = $this->User_model->getCurrentDeptByToken($Token); + $DeptListArr = []; + foreach ($DeptArr as $k => $v) { + array_push($DeptListArr, $v['id']); + } + + $deptIdStr = implode(",", $DeptListArr); // string(9) "1,2,3,4,5" + + $UserArr = $this->User_model->getUserList($deptIdStr, $filters, $sort, $page, $pageSize); + + $total = $this->User_model->getUserListCnt($deptIdStr, $filters); + + // 遍历所有用户所属角色的机构信息 + foreach ($UserArr as $k => $v) { + $UserArr[$k]['role'] = []; + $UserArr[$k]['roledept'] = []; + $RoleArr = $this->User_model->getUserRoles($v['id']); + foreach ($RoleArr as $kk => $vv) { + array_push($UserArr[$k]['role'], $vv['id']); + $RoleDeptArr = $this->User_model->getUserRolesDept($v['id'], $vv['id']); + + $UserArr[$k]['roledept'][$vv['name'] . '-' . $vv['id']] = []; + foreach ($RoleDeptArr as $kkk => $vvv) { + array_push($UserArr[$k]['roledept'][$vv['name'] . '-' . $vv['id']], $vvv['dept_id']); + } + } + } + + $message = [ + "code" => 20000, + "data" => [ + 'items' => $UserArr, + 'total' => intval($total) + ] + ]; + $this->response($message, RestController::HTTP_OK); + } + + // 增 + function add_post() + { + $uri = $this->uri->uri_string; + $Token = $this->input->get_request_header('X-Token', TRUE); + $retPerm = $this->permission->HasPermit($Token, $uri); + if ($retPerm['code'] != 50000) { + $this->response($retPerm, RestController::HTTP_OK); + } + + $parms = $this->post(); // 获取表单参数,类型为数组 + + // 参数数据预处理 + $failed = false; + foreach ($parms['roledepts'] as $k => $v) { + if (!array_key_exists('dept_id', $v) || !count($v['dept_id'])) { + unset($parms['roledepts'][$k]); + } + } + + if (!count($parms['roledepts'])) { + $failed = true; + } + + if ($failed) { + $message = [ + "code" => 20000, + "type" => 'error', + "message" => '所选的角色没有关联对应机构, 请检查' + ]; + $this->response($message, RestController::HTTP_OK); + } + + $RoleDeptArr = $parms['roledepts']; + unset($parms['role']); // 剔除role数组 + unset($parms['roledept']); // 前台传参过来多余的空数组 + unset($parms['roledepts']); // 剔除role数组 + + // 加入新增时间 + $parms['create_time'] = time(); + $parms['password'] = md5($parms['password']); + + $user_id = $this->Base_model->_insert_key('sys_user', $parms); + if (!$user_id) { + $message = [ + "code" => 20000, + "type" => 'error', + "message" => $parms['username'] . ' - 用户新增失败' + ]; + $this->response($message, RestController::HTTP_OK); + } + + $failed = false; + $failedArr = []; + foreach ($RoleDeptArr as $k => $v) { + foreach ($v['dept_id'] as $kk => $vv) { + $arr = ['user_id' => $user_id, 'role_id' => $v['role_id'], 'dept_id' => $vv]; + $ret = $this->Base_model->_insert_key('sys_user_role', $arr); + if (!$ret) { + $failed = true; + array_push($failedArr, $arr); + } + } + } + + if ($failed) { + $message = [ + "code" => 20000, + "type" => 'error', + "message" => '用户关联角色机构失败 ' . json_encode($failedArr) + ]; + $this->response($message, RestController::HTTP_OK); + } + + $message = [ + "code" => 20000, + "type" => 'success', + "message" => $parms['username'] . ' - 用户新增成功' + ]; + $this->response($message, RestController::HTTP_OK); + } + + // 改 + function edit_post() + { + $uri = $this->uri->uri_string; + $Token = $this->input->get_request_header('X-Token', TRUE); + $retPerm = $this->permission->HasPermit($Token, $uri); + if ($retPerm['code'] != 50000) { + $this->response($retPerm, RestController::HTTP_OK); + } + + // $id = $this->post('id'); // POST param + $parms = $this->post(); // 获取表单参数,类型为数组 + // var_dump($parms['path']); + + // 参数检验/数据预处理 + // 超级管理员角色不允许修改 + /* + if ($parms['id'] == 1) { + $message = [ + "code" => 20000, + "type" => 'error', + "message" => $parms['username'] . ' - 超级管理员用户不允许修改' + ]; + $this->response($message, RestController::HTTP_OK); + }*/ + + $failed = false; + foreach ($parms['roledepts'] as $k => $v) { + if (!array_key_exists('dept_id', $v) || !count($v['dept_id'])) { + unset($parms['roledepts'][$k]); + } + } + + if (!count($parms['roledepts'])) { + $failed = true; + } + + if ($failed) { + $message = [ + "code" => 20000, + "type" => 'error', + "message" => '所选的角色没有关联对应机构, 请检查' + ]; + $this->response($message, RestController::HTTP_OK); + } + + $id = $parms['id']; + $RoleArr = []; // 前台传参数过来的 role_id, dept_id对 + foreach ($parms['roledepts'] as $k => $v) { + foreach ($v['dept_id'] as $kk => $vv) { + array_push($RoleArr, ['user_id' => $id, 'role_id' => $v['role_id'], 'dept_id' => $vv]); + } + } + + unset($parms['role']); // 剔除role数组 多余 使用roledepts替换 + unset($parms['roledept']); // 剔除role数组 多余 使用roledepts替换 + unset($parms['roledepts']); + unset($parms['id']); // 剔除索引id + //unset($parms['password']); // 剔除密码 + $parms['password'] = md5($parms['password']); + + $where = ["id" => $id]; + + if (!$this->Base_model->_update_key('sys_user', $parms, $where)) { + $message = [ + "code" => 20000, + "type" => 'error', + "message" => $parms['username'] . ' - 用户更新错误' + ]; + $this->response($message, RestController::HTTP_OK); + } + + $RoleSqlArr = $this->User_model->getRolesByUserId($id); + + $AddArr = $this->permission->array_diff_assoc2($RoleArr, $RoleSqlArr); + // var_dump('------------只存在于前台传参 做添加操作-------------'); + // var_dump($AddArr); + $failed = false; + $failedArr = []; + foreach ($AddArr as $k => $v) { + $ret = $this->Base_model->_insert_key('sys_user_role', $v); + if (!$ret) { + $failed = true; + array_push($failedArr, $v); + } + } + if ($failed) { + $message = [ + "code" => 20000, + "type" => 'error', + "message" => '用户关联角色失败 ' . json_encode($failedArr) + ]; + $this->response($message, RestController::HTTP_OK); + } + + $DelArr = $this->permission->array_diff_assoc2($RoleSqlArr, $RoleArr); + // var_dump('------------只存在于后台数据库 删除操作-------------'); + // var_dump($DelArr); + $failed = false; + $failedArr = []; + foreach ($DelArr as $k => $v) { + $ret = $this->Base_model->_delete_key('sys_user_role', $v); + if (!$ret) { + $failed = true; + array_push($failedArr, $v); + } + } + if ($failed) { + $message = [ + "code" => 20000, + "type" => 'error', + "message" => '用户关联角色失败 ' . json_encode($failedArr) + ]; + $this->response($message, RestController::HTTP_OK); + } + + $message = [ + "code" => 20000, + "type" => 'success', + "message" => $parms['username'] . ' - 用户更新成功' + ]; + $this->response($message, RestController::HTTP_OK); + } + + // 删 + function del_post() + { + $uri = $this->uri->uri_string; + $Token = $this->input->get_request_header('X-Token', TRUE); + $retPerm = $this->permission->HasPermit($Token, $uri); + if ($retPerm['code'] != 50000) { + $this->response($retPerm, RestController::HTTP_OK); + } + + $parms = $this->post(); // 获取表单参数,类型为数组 + // var_dump($parms['path']); + + // 参数检验/数据预处理 + // 超级管理员角色不允许删除 + if ($parms['id'] == 1) { + $message = [ + "code" => 20000, + "type" => 'error', + "message" => $parms['username'] . ' - 超级管理员不允许删除' + ]; + $this->response($message, RestController::HTTP_OK); + } + + // 删除外键关联表 sys_user_role + $this->Base_model->_delete_key('sys_user_role', ['user_id' => $parms['id']]); + + // 删除基础表 sys_user + if (!$this->Base_model->_delete_key('sys_user', $parms)) { + $message = [ + "code" => 20000, + "type" => 'error', + "message" => $parms['username'] . ' - 用户删除错误' + ]; + $this->response($message, RestController::HTTP_OK); + } + + $message = [ + "code" => 20000, + "type" => 'success', + "message" => $parms['username'] . ' - 用户删除成功' + ]; + $this->response($message, RestController::HTTP_OK); + + } + + function login_post() + { + $username = $this->post('username'); // POST param + $password = $this->post('password'); // POST param + $verify = $this->post('verify'); // POST param + $verifycode = $this->post('verifycode'); // POST param + + $this->load->driver('cache'); + if ($verifycode !== $this->cache->redis->get($verify)) { + $message = [ + "code" => 60205, + "message" => '验证码错误!' + ]; + $this->response($message, RestController::HTTP_OK); + } + + $result = $this->User_model->validate($username, md5($password)); + + // 用户名密码正确 生成token 返回 + if ($result['success']) { + $Token = $this->_generate_token(); + $create_time = time(); + $expire_time = $create_time + 2 * 60 * 60; // 2小时过期 + + $lastLoginRet = $this->User_model->getLastLoginRole($result['userinfo']['id']); + + if ($lastLoginRet['code'] == '20000') { + $CurrentRole = $lastLoginRet['role_id']; + } else { + $ret = $this->User_model->getCurrentRole($result['userinfo']['id']); + if ($ret['code'] !== '20000') { + // 自定义code 未分配角色或角色被删除,用户没有可用角色 + $this->response($ret, RestController::HTTP_OK); + + } + $CurrentRole = $ret['role_id']; + } + + $data = [ + 'user_id' => $result['userinfo']['id'], + 'role_id' => $CurrentRole, + 'expire_time' => $expire_time, + 'create_time' => $create_time + ]; + + if (!$this->_insert_token($Token, $data)) { + $message = [ + "code" => 20000, + "message" => 'Token 创建失败, 请联系管理员.' + ]; + $this->response($message, RestController::HTTP_OK); + } + + $message = [ + "code" => 20000, + "data" => [ + "token" => $Token + ] + ]; + $this->response($message, RestController::HTTP_OK); + } else { + $message = [ + "code" => 60204, + "message" => 'Account and password are incorrect.' + ]; + $this->response($message, RestController::HTTP_OK); + } + } + + // 根据token拉取用户信息 getUserInfo + function info_get() + { + // $result = $this->some_model(); // 获取用户信息 + // var_dump($this->get('token')); + $result['success'] = TRUE; + + // 真实token + $Token = $this->input->get_request_header('X-Token', TRUE); + // $this->get('token') // get 参数token + + $result = $this->User_model->getUserInfo($Token); + + // 获取用户信息成功 + if ($result['success']) { + $info = $result['userinfo']; + + if ($Token !== $this->get('token')) { + // 由前台切换角色 修改sys_user_token 表里 role_id 字段 并替换用户信息中的默认role_id + // 判断切换后的角色是否有对应机构 + if (!$this->User_model->roleHasDept($this->get('token'), $info['id'])) { + $message = [ + "code" => 20000, + "type" => 'error', + "message" => '角色切换失败,该角色没有对应的部门机构,请联系管理员分配' + ]; + $this->response($message, RestController::HTTP_OK); + } + + if (!$this->Base_model->_update_key('sys_user_token', ['role_id' => $this->get('token')], ['token' => $Token])) { + $message = [ + "code" => 20000, + "type" => 'error', + "message" => '角色切换失败' + ]; + $this->response($message, RestController::HTTP_OK); + } + } + + // 附加信息 + $info['roles'] = $this->User_model->getUserRolesByToken($Token); + $info['role_id'] = $this->User_model->getCurrentRoleByToken($Token); // 当前选择角色 + $info['introduction'] = "I am a super administrator"; + // $info['avatar'] = "https://wpimg.wallstcn.com/f778738c-e4f8-4870-b634-56703b4acafe.gif"; + $info['name'] = "Super Admin"; + $info['identify'] = "410000000000000000"; + $info['phone'] = "13633838282"; + + // 当前用户的当前角色拥有的部门 +// $info['depts'] = $this->User_model->getCurrentDeptByToken($Token); // 当前选择部门; +// $info['roleoptions'] = $this->User_model->getRoleOptions($Token); // 角色选择选项; + + $MenuTreeArr = $this->permission->getPermission($Token, 'menu', false); + $asyncRouterMap = $this->permission->genVueRouter($MenuTreeArr, 'id', 'pid', 0); + $CtrlPerm = $this->permission->getMenuCtrlPerm($Token); + + $info['ctrlperm'] = $CtrlPerm; + // "ctrlperm" => [ + // [ + // "path" => "/sys/menu/view" + // ], + // [ + // "path" => "/sys/menu/add" + // ], + // [ + // "path" => "/sys/menu/edit" + // ], + // [ + // "path" => "/sys/menu/del" + // ], + // [ + // "path" => "/sys/menu/download" + // ] + // ], + $info['asyncRouterMap'] = $asyncRouterMap; + // [ + // [ + // "path" => '/sys', + // "name" => 'sys', + // "meta" => [ + // "title" => "系统管理", + // "icon" => "sysset2" + // ], + // "component" => 'Layout', + // "redirect" => '/sys/menu', + // "children" => [ + // [ + // "path" => '/sys/menu', + // "name" => 'menu', + // "meta" => [ + // "title" => "菜单管理", + // "icon" => "menu1" + // ], + // "component" => 'sys/menu/index', + // "redirect" => '', + // "children" => [ + // + // ] + // ], + // [ + // "path" => '/sys/user', + // "name" => 'user', + // "meta" => [ + // "title" => "用户管理", + // "icon" => "user" + // ], + // "component" => 'pdf/index', + // "redirect" => '', + // "children" => [ + // + // ] + // ], + // [ + // "path" => '/sys/icon', + // "name" => 'icon', + // "meta" => [ + // "title" => "图标管理", + // "icon" => "icon" + // ], + // "component" => 'svg-icons/index', + // "redirect" => '', + // "children" => [ + // + // ] + // ] + // ] + // ], + // [ + // "path" => '/sysx', + // "name" => 'sysx', + // "meta" => [ + // "title" => "其他管理", + // "icon" => "plane" + // ], + // "component" => 'Layout', + // "redirect" => '', + // "children" => [ + // + // ] + // ] + // ] + + $message = [ + "code" => 20000, + "data" => $info, + "_SERVER" => $_SERVER, + "_GET" => $_GET + ]; + $this->response($message, RestController::HTTP_OK); + } else { + $message = [ + "code" => 50008, + "message" => 'Login failed, unable to get user details.' + ]; + + $this->response($message, RestController::HTTP_OK); + } + + } + + // 根据token拉取 treeselect 下拉选项菜单 + function roleoptions_get() + { + // 此 uri 可不做权限/token过期验证,则在菜单里,可以不加入此项路由path /sys/menu/treeoptions。 + // + // $uri = $this->uri->uri_string; + // $Token = $this->input->get_request_header('X-Token', TRUE); + // $retPerm = $this->permission->HasPermit($Token, $uri); + // if ($retPerm['code'] != 50000) { + // $this->response($retPerm, RestController::HTTP_OK); + // return; + // } + + $Token = $this->input->get_request_header('X-Token', TRUE); + $RoleArr = $this->User_model->getRoleOptions($Token); + + $message = [ + "code" => 20000, + "data" => $RoleArr, + ]; + $this->response($message, RestController::HTTP_OK); + } + + function deptoptions_get() + { + // 此 uri 可不做权限/token过期验证,则在菜单里,可以不加入此项路由path /sys/menu/treeoptions。 + // + // $uri = $this->uri->uri_string; + // $Token = $this->input->get_request_header('X-Token', TRUE); + // $retPerm = $this->permission->HasPermit($Token, $uri); + // if ($retPerm['code'] != 50000) { + // $this->response($retPerm, RestController::HTTP_OK); + // return; + // } + + $Token = $this->input->get_request_header('X-Token', TRUE); + $DeptArr = $this->User_model->getCurrentDeptByToken($Token); + + $message = [ + "code" => 20000, + "data" => $DeptArr, + ]; + $this->response($message, RestController::HTTP_OK); + } + + // async router test get + function router_get() + { +// $result = $this->some_model(); + $result['success'] = TRUE; + + // 获取用户信息成功 + if ($result['success']) { +// $info = [ +// "roles" => ["admin", "editor"], +// "introduction" => "I am a super administrator", +// "avatar" => "https://wpimg.wallstcn.com/f778738c-e4f8-4870-b634-56703b4acafe.gif", +// "name" => "Super Admin", +// "identify" => "410000000000000000", +// "phone" => "13633838282", +// "asyncRouterMap" => [ +// +// ] +// ]; + + $message = [ + "code" => 20000, + "data" => [ + "asyncRouterMap" => [ + [ + "path" => '/sys', + "name" => 'sys', + "meta" => [ + "title" => "系统管理", + "icon" => "nested" + ], + "component" => 'Layout', + "children" => [ + [ + "path" => '/sys/menu', + "name" => 'menu', + "meta" => [ + "title" => "菜单管理", + "icon" => "nested" + ], + "component" => 'index', + "children" => [ + + ] + ] + ] + ], + [ + "path" => '/sysx', + "name" => 'sysx', + "meta" => [ + "title" => "其他管理", + "icon" => "nested" + ], + "component" => 'Layout', + "children" => [ + + ] + ] + ], + "__FUNCTION__" => __FUNCTION__, + "__CLASS__" => __CLASS__, + "uri" => $this->uri + ], + + ]; + $this->response($message, RestController::HTTP_OK); + } else { + $message = [ + "code" => 50008, + "message" => 'Login failed, unable to get user details.' + ]; + + $this->response($message, RestController::HTTP_OK); + } + + } + + function logout_post() + { + $message = [ + "code" => 20000, + "data" => 'success' + ]; + $this->response($message, RestController::HTTP_OK); + } + + function list_get() + { +// $result = $this->some_model(); + $result['success'] = TRUE; + + if ($result['success']) { + $List = array( + array('order_no' => '201805138451313131', 'timestamp' => 'iphone 7 ', 'username' => 'iphone 7 ', 'price' => 399, 'status' => 'success'), + array('order_no' => '300000000000000000', 'timestamp' => 'iphone 7 ', 'username' => 'iphone 7 ', 'price' => 399, 'status' => 'pending'), + array('order_no' => '444444444444444444', 'timestamp' => 'iphone 7 ', 'username' => 'iphone 7 ', 'price' => 399, 'status' => 'success'), + array('order_no' => '888888888888888888', 'timestamp' => 'iphone 7 ', 'username' => 'iphone 7 ', 'price' => 399, 'status' => 'pending'), + ); + + $message = [ + "code" => 20000, + "data" => [ + "total" => count($List), + "items" => $List + ] + ]; + $this->response($message, RestController::HTTP_OK); + } else { + $message = [ + "code" => 50008, + "message" => 'Login failed, unable to get user details.' + ]; + + $this->response($message, RestController::HTTP_OK); + } + + } + + function login() + { + $this->SET_HEADER; // 设置php CI 处理 CORS 自定义头部 + + + if ($_SERVER["REQUEST_METHOD"] == 'POST') { // 只处理post请求,否则options请求 500错误 + $json_params = file_get_contents('php://input'); + $data = json_decode($json_params, true); + + if (!empty($data)) { + if (!empty($data['username']) && !empty($data['password'])) { + $username = $data['username']; + $password = $data['password']; + $input_account = $username; + $input_password = md5($password); + // $results = $this->phpIonicLoginAuthValidateLogin($username, $password); + $result = $this->Api_model->app_user_login_validate($input_account, $input_password); + + // $token=$_SERVER['x-auth-token']; + // 用户名密码正确 生成token 返回 + $token = $this->createToken(10000); + + $data = array( + "code" => 20000, + "data" => array( + "token" => "admin-token" +// "token" => $token + ), + "params" => $json_params + ); + + echo json_encode($data); + // 用户名密码不正确 +// return { +// code: +// 60204, +// message: 'Account and password are incorrect.' +// } + + + if ($result['success']) { + echo json_encode($this->saveLoginInfo($result['userinfo'])); + } else { + // 校验失败,写入token + $this->output->set_status_header(300); + echo '{"success": false,"message": "用户名或密码错误","jump":"","user":"' . $username . '"}'; + } + + } else { + $results = array( + "result" => "Error - data incomplete!", + ); + + $jsonData = json_encode($results); + echo $jsonData; + } + } else { // no data post + $results = array( + "result" => "Error - no data!", + ); + $jsonData = json_encode($results); + echo $jsonData; + } + } + } + + // 根据token拉取用户信息 get + function info() + { + $this->SET_HEADER; // 设置php CI 处理 CORS 自定义头部 + + if ($_SERVER["REQUEST_METHOD"] == 'GET') { // 只处理post请求,否则options请求 500错误 + $json_params = file_get_contents('php://input'); + $data = json_decode($json_params, true); + +// $token=$_SERVER['x-auth-token']; + +// 获取用户信息成功 + $info = array( + "roles" => array( + "admin" + ), + "introduction" => "I am a super administrator", + "avatar" => "https://wpimg.wallstcn.com/f778738c-e4f8-4870-b634-56703b4acafe.gif", + "name" => "Super Admin", + ); + + echo json_encode( + array( + "code" => 20000, + "data" => $info, + "_SERVER" => $_SERVER, + "_GET" => $_GET + ) + ); + +// 获取用户信息失败 +// return { +// code: 50008, +// message: 'Login failed, unable to get user details.' +// } +// echo json_encode( +// array( +// "code" => 50008, +// "message" => "Login failed, unable to get user details." +// ) +// ); + + return; + + if (!empty($data)) { + if (!empty($data['username']) && !empty($data['password'])) { + $username = $data['username']; + $password = $data['password']; + $input_account = $username; + $input_password = md5($password); + // $results = $this->phpIonicLoginAuthValidateLogin($username, $password); + $result = $this->Api_model->app_user_login_validate($input_account, $input_password); + + if ($result['success']) { + echo json_encode($this->saveLoginInfo($result['userinfo'])); + } else { + // 校验失败,写入token + $this->output->set_status_header(300); + echo '{"success": false,"message": "用户名或密码错误","jump":"","user":"' . $username . '"}'; + } + + } else { + $results = array( + "result" => "Error - data incomplete!", + ); + + $jsonData = json_encode($results); + echo $jsonData; + } + } else { // no data post + $results = array( + "result" => "Error - no data!", + ); + $jsonData = json_encode($results); + echo $jsonData; + } + } + } + + function logout() + { + $this->SET_HEADER; // 设置php CI 处理 CORS 自定义头部 + if ($_SERVER["REQUEST_METHOD"] == 'POST') { // 只处理post请求,否则options请求 500错误 + echo json_encode(array( + "code" => 20000, + "data" => 'sucess' + )); + } + } + + /* + * For 微信认证及全登录时保留登录日志信息 + */ + function saveLoginInfo($userinfo) + { + $token = md5($userinfo["name"] . date('y-m-d H:i:s', time())); + $arr2 = array('token' => $token); + $userinfo["token"] = $token; + $this->Bas->saveAdd( + 'auth', + array( + 'token' => $token, + 'expiredAt' => date('Y-m-d H:i:s', strtotime('+1 day')), + 'onlineIp' => $this->input->ip_address(), + 'userLoginInfo' => json_encode($userinfo), + 'creatorId' => $userinfo["name"], + 'createdAt' => date('Y-m-d H:i:s') + ) + ); + + // 返回信息 + $results = array( + "success" => true, + "message" => "APP登陆成功", + "user" => $userinfo, + 'session' => $_SESSION, + ); + + $this->Bas->saveEdit('userinfo', array('LASTLOGIN' => date('y-m-d H:i:s', time()), 'LASTIP' => $this->input->ip_address()), array('USERNAME' => $userinfo["name"])); + return $results; + } + + /** + * 执行CURL请求,并封装返回对象 + */ + private + function execCURL($ch) + { + $response = curl_exec($ch); + $error = curl_error($ch); + $result = array('header' => '', + 'content' => '', + 'curl_error' => '', + 'http_code' => '', + 'last_url' => ''); + + if ($error != "") { + $result['curl_error'] = $error; + return $result; + } + + $header_size = curl_getinfo($ch, CURLINFO_HEADER_SIZE); + $result['header'] = str_replace(array("\r\n", "\r", "\n"), "
", substr($response, 0, $header_size)); + $result['content'] = substr($response, $header_size); + $result['http_code'] = curl_getinfo($ch, CURLINFO_HTTP_CODE); + $result['last_url'] = curl_getinfo($ch, CURLINFO_EFFECTIVE_URL); + $result["base_resp"] = array(); + $result["base_resp"]["ret"] = $result['http_code'] == 200 ? 0 : $result['http_code']; + $result["base_resp"]["err_msg"] = $result['http_code'] == 200 ? "ok" : $result["curl_error"]; + + return $result; + } + + /** + * GET 请求 + * @param string $url + */ + private function http_get($url) + { + $oCurl = curl_init(); + if (stripos($url, "https://") !== FALSE) { + curl_setopt($oCurl, CURLOPT_SSL_VERIFYPEER, FALSE); + curl_setopt($oCurl, CURLOPT_SSL_VERIFYHOST, FALSE); + curl_setopt($oCurl, CURLOPT_SSLVERSION, 1); //CURL_SSLVERSION_TLSv1 + } + curl_setopt($oCurl, CURLOPT_URL, $url); + curl_setopt($oCurl, CURLOPT_RETURNTRANSFER, 1); + curl_setopt($oCurl, CURLOPT_VERBOSE, 1); + curl_setopt($oCurl, CURLOPT_HEADER, 1); + + // $sContent = curl_exec($oCurl); + // $aStatus = curl_getinfo($oCurl); + $sContent = $this->execCURL($oCurl); + curl_close($oCurl); + + return $sContent; + } + + /** + * POST 请求 + * @param string $url + * @param array $param + * @param boolean $post_file 是否文件上传 + * @return string content + */ + private + function http_post($url, $param, $post_file = false) + { + $oCurl = curl_init(); + + if (stripos($url, "https://") !== FALSE) { + curl_setopt($oCurl, CURLOPT_SSL_VERIFYPEER, FALSE); + curl_setopt($oCurl, CURLOPT_SSL_VERIFYHOST, false); + curl_setopt($oCurl, CURLOPT_SSLVERSION, 1); //CURL_SSLVERSION_TLSv1 + } + if (PHP_VERSION_ID >= 50500 && class_exists('\CURLFile')) { + $is_curlFile = true; + } else { + $is_curlFile = false; + if (defined('CURLOPT_SAFE_UPLOAD')) { + curl_setopt($oCurl, CURLOPT_SAFE_UPLOAD, false); + } + } + + if ($post_file) { + if ($is_curlFile) { + foreach ($param as $key => $val) { + if (isset($val["tmp_name"])) { + $param[$key] = new \CURLFile(realpath($val["tmp_name"]), $val["type"], $val["name"]); + } else if (substr($val, 0, 1) == '@') { + $param[$key] = new \CURLFile(realpath(substr($val, 1))); + } + } + } + $strPOST = $param; + } else { + $strPOST = json_encode($param); + } + + curl_setopt($oCurl, CURLOPT_URL, $url); + curl_setopt($oCurl, CURLOPT_RETURNTRANSFER, 1); + curl_setopt($oCurl, CURLOPT_POST, true); + curl_setopt($oCurl, CURLOPT_POSTFIELDS, $strPOST); + curl_setopt($oCurl, CURLOPT_VERBOSE, 1); + curl_setopt($oCurl, CURLOPT_HEADER, 1); + + // $sContent = curl_exec($oCurl); + // $aStatus = curl_getinfo($oCurl); + + $sContent = $this->execCURL($oCurl); + curl_close($oCurl); + + return $sContent; + } + + function weixinAuth() + { + session_start(); + if ($_SERVER["REQUEST_METHOD"] == 'OPTIONS') { + echo "options"; + die(); + } + // $corpId = "wwxxxxxxxx"; + // $agentId = "100000"; + // $appSecret = "fsdfsfsdf"; + // $localAuthUrl = "http://dj.xxx.com:7000/hotcode/"; + + if (!array_key_exists("code", $_REQUEST)) { + + // $redirectUri = urlencode("http://yw.xxx.com/xxx/get-corp-weixin-code.html?redirect_uri=" . urlencode($localAuthUrl)); + $authUrl = "https://open.weixin.qq.com/connect/oauth2/authorize?appid=" . $corpId . "&redirect_uri=" . $redirectUri . "&response_type=code&scope=snsapi_privateinfo&agentid=" . $agentId . "&state=STATE#wechat_redirect"; + echo json_encode(array("success" => false, "authUrl" => $authUrl)); + die(); + } + $getCorpAccessTokenUrl = "https://qyapi.weixin.qq.com/cgi-bin/gettoken?corpid=" . $corpId . "&corpsecret=" . $appSecret; + $accessToken = ""; + if (false && $_SESSION["weixinAuth_accessToken"] && $_SESSION["weixinAuth_tokenTime"] && $_SESSION["weixinAuth_tokenExpires"] && time() - intval($_SESSION["weixinAuth_tokenTime"]) < intval($_SESSION["tokenExpires"])) { + $accessToken = $_SESSION["weixinAuth_accessToken"]; + } else { + $tokenInfo = $this->http_get($getCorpAccessTokenUrl); + $tokenInfo = json_decode($tokenInfo["content"], true); + if ($tokenInfo["errcode"] == 0) { + $accessToken = $tokenInfo["access_token"]; + $_SESSION["weixinAuth_accessToke"] = $accessToken; + $_SESSION["weixinAuth_tokenTime"] = time(); + $_SESSION["weixinAuth_tokenExpires"] = $tokenInfo["expires_in"]; + } else { + echo json_encode(array("success" => false, "msg" => $tokenInfo["errmsg"] ? $tokenInfo["errmsg"] : "企业认证失败!")); + die(); + } + } + $getUserIdUrl = "https://qyapi.weixin.qq.com/cgi-bin/user/getuserinfo?access_token=" . $accessToken . "&code=" . $_REQUEST["code"]; + $ajaxUserIdInfo = $this->http_get($getUserIdUrl); + // var_dump($ajaxUserIdInfo);die(); + $userIdInfo = json_decode($ajaxUserIdInfo["content"], true); + if ($userIdInfo["errcode"] == 0) { + if (array_key_exists("OpenId", $userIdInfo)) { + echo json_encode(array("success" => false, "msg" => "不是企业成员!请联系企业管理员,添加您的账号的企业通讯录!")); + die(); + // next(U.error("不是企业成员!请联系企业管理员,添加您的账号的企业通讯录!")); + } else if (array_key_exists("UserId", $userIdInfo)) { + $getUserInfoUrl = "https://qyapi.weixin.qq.com/cgi-bin/user/getuserdetail?access_token=" . $accessToken; + // 44468cd93cdfefb8a7f911b5e1f7dfd0 + $data = array("user_ticket" => $userIdInfo["user_ticket"]); + $ajaxUserInfo = $this->http_post($getUserInfoUrl, $data); + $userInfo = json_decode($ajaxUserInfo["content"], true); + if ($userInfo["errcode"] == 0) { + $user = $this->Api_model->getUserByWxUserId($userIdInfo["UserId"]); + if ($user["success"]) { + echo json_encode($this->saveLoginInfo($user['userinfo'])); + die(); + } else { + $_SESSION["wxUserInfo"] = $userInfo; + echo json_encode(array("sessionid" => session_id(), "status" => -1, "success" => false, "msg" => "此微信账号(" . $userInfo["name"] . ")没有与系统账号关联,请用您的账号密码登录一次,完成首次绑定!")); + die(); + } + return; + } else { + echo json_encode(array("success" => false, "msg" => $userInfo["errmsg"])); + die(); + } + } + } else { + echo json_encode(array("success" => false, "msg" => $userIdInfo["errmsg"])); + die(); + } + } + + // 使用 composer gregwar/captcha 库生成验证码 + function verifycode_get() + { + $phraseBuilder = new PhraseBuilder(4, '0123456789'); + $builder = new CaptchaBuilder(null, $phraseBuilder); + $builder->build(80, 40, realpath('vendor/gregwar/captcha/src/Gregwar/Captcha/Font/captcha5.ttf')); + $code = $builder->getPhrase(); // 获取验证码 + + $this->load->driver('cache'); + $ret = $this->cache->redis->save($this->get('verify'), $code, 60); + // response header 出现 redis_hit_verifycode: 1 表示 redis 连接正常且保存k/v + header("redis_hit_verifycode: " . $ret); + // header("veryfiycode: " . $this->get('verify') . "/" . $code); + header('Content-type: image/jpeg'); + $builder->output(); // 生成验证码图片 + } + + // 验证码库2 + function verifycode2_get() + { + $this->load->library('Captcha'); + // redis/mysql 保存 code 与 verify + $code = $this->captcha->getCaptcha(); // 获取验证码 + $this->load->driver('cache'); + $ret = $this->cache->redis->save($this->get('verify'), $code, 60); + // response header 出现 redis_hit_verifycode: 1 表示 redis 连接正常且保存k/v + header("redis_hit_verifycode: " . $ret); + // header("veryfiycode: " . $this->get('verify') . "/" . $code); + $this->captcha->showImg(); // 生成验证码图片 + } + + function corpauth_get() + { + $code = $this->get('code'); + + // $corpId = 'xxxxxx'; + // $appSecret = 'xxxxxx'; + + // code: 60206 微信认证失败统一代码 + if (!$code) { + $message = [ + "code" => 60206, + "data" => ["status" => 'fail', "msg" => 'code参数为空'], + "message" => "code参数为空" + ]; + $this->response($message, RestController::HTTP_OK); + } + + // 根据上面的回调参数获取用户详细信息。 已经传递过来code数据。 + $getCorpAccessTokenUrl = 'https://qyapi.weixin.qq.com/cgi-bin/gettoken?corpid=' . $corpId . '&corpsecret=' . $appSecret; + + $tokenInfo = $this->http_get($getCorpAccessTokenUrl); + $tokenInfo = json_decode($tokenInfo["content"], true); // 获取的原始数据解码成json格式,如下 + // array(4) { + // ["errcode"]=> + // int(0) + // ["errmsg"]=> + // string(2) "ok" + // ["access_token"]=> + // string(214) "vP2TgGlg8-_N23PleQnq2q9SBnIfqCkkNMGZ71YoZ8V3R0lB8sJOy15ixco4kOxo8GZMlcgiJHm0hDXzbL6lG2BWleAqmJCrMEPdQj9goZaogVNBICmVrr-Fxz8YCIBUdf36BOq4E-Mt64OCrIUw1254Pxupi9RGOEFoWmMrJKgHnR_F0pjD-hJFZfTOIt7W2VujJq6hsle8SD9qTOZwzA" + // ["expires_in"]=> + // int(7200) + // } + if ($tokenInfo["errcode"] == 0) { + $accessToken = $tokenInfo["access_token"]; + } else { + $message = [ + "code" => 60206, + "data" => ["status" => 'fail', "msg" => $tokenInfo["errmsg"] ? $tokenInfo["errmsg"] : "企业认证失败!"], + "message" => $tokenInfo["errmsg"] ? $tokenInfo["errmsg"] : "企业认证失败!" + ]; + $this->response($message, RestController::HTTP_OK); + } + + $getUserIdUrl = 'https://qyapi.weixin.qq.com/cgi-bin/user/getuserinfo?access_token=' . $accessToken . '&code=' . $code; + $ajaxUserIdInfo = $this->http_get($getUserIdUrl); + $userIdInfo = json_decode($ajaxUserIdInfo["content"], true); // 获取的原始数据解码成json格式,如下 + // array(4) { + // ["UserId"]=> + // ["DeviceId"]=> + // string(0) "" + // ["errcode"]=> + // int(0) + // ["errmsg"]=> + // string(2) "ok" + // } + + if ($userIdInfo["errcode"] == 0) { + if (array_key_exists("OpenId", $userIdInfo)) { + $message = [ + "code" => 60206, + "data" => ["success" => 'fail', "msg" => "不是企业成员!请联系企业管理员,添加您的账号的企业通讯录!"], + "message" => "不是企业成员!请联系企业管理员,添加您的账号的企业通讯录!" + ]; + $this->response($message, RestController::HTTP_OK); + + } else if (array_key_exists("UserId", $userIdInfo)) { + $getUserInfoUrl = 'https://qyapi.weixin.qq.com/cgi-bin/user/get?access_token=' . $accessToken . '&userid=' . $userIdInfo["UserId"]; + $ajaxUserInfo = $this->http_get($getUserInfoUrl); + $userInfo = json_decode($ajaxUserInfo["content"], true); // 获取的原始数据解码成json格式,如下 + // array(21) { + // ["errcode"]=> + // int(0) + // ["errmsg"]=> + // string(2) "ok" + // ["userid"]=> + // ["name"]=> + // ["position"]=> + // string(0) "" + // ["mobile"]=> + // ["gender"]=> + // string(1) "1" + // ["email"]=> + // ["avatar"]=> + // string(85) "http://p.qlogo.cn/bizmail/rZXu0u7ma4vOiaEWia7MTnUDmdDnfgh7R6iafX5832RczKmViadvgbVAhw/" + // ["status"]=> + // int(1) + // } + + if ($userInfo["errcode"] == 0) { + $user = $this->User_model->getUserInfoByTel($userInfo["mobile"]); + // array(1) { + // [0]=> + // array(12) { + // ["id"]=> + // string(1) "1" + // ["username"]=> + // string(5) "admin" + // ["tel"]=> + // ["email"]=> + // string(17) "lmxdawn@gmail.com" + // + // } + // } + + if (!empty($user)) { + // 成功,生成token 并根据token生成loginfo 并且将信息及 token 返回前台登录 + $Token = $this->_generate_token(); + $create_time = time(); + $expire_time = $create_time + 2 * 60 * 60; // 2小时过期 + + $lastLoginRet = $this->User_model->getLastLoginRole($user[0]['id']); + + if ($lastLoginRet['code'] == '20000') { + $CurrentRole = $lastLoginRet['role_id']; + } else { + $ret = $this->User_model->getCurrentRole($user[0]['id']); + if ($ret['code'] !== '20000') { + // 自定义code 未分配角色或角色被删除,用户没有可用角色 + $this->response($ret, RestController::HTTP_OK); + } + $CurrentRole = $ret['role_id']; + } + + $data = [ + 'user_id' => $user[0]['id'], + 'role_id' => $CurrentRole, + 'expire_time' => $expire_time, + 'create_time' => $create_time + ]; + + // TODO: 考虑sys_user_token 表加入类型字段判断是微信登录生成 token 还是账号密码登录生成 token + if (!$this->_insert_token($Token, $data)) { + $message = [ + "code" => 60206, + "data" => ["status" => 'fail', "msg" => "Token 创建失败, 请联系管理员."], + "message" => 'Token 创建失败, 请联系管理员.' + ]; + $this->response($message, RestController::HTTP_OK); + } + + $message = [ + "code" => 20000, + "data" => [ + "status" => 'ok', + "token" => $Token + ] + ]; + $this->response($message, RestController::HTTP_OK); + + } else { + $message = [ + "code" => 60206, + "data" => ["status" => 'fail', "msg" => "此微信账号(" . $userInfo['name'] . ")没有与系统账号关联,请联系系统管理员!"], + "message" => "此微信账号(" . $userInfo['name'] . ")没有与系统账号关联,请联系系统管理员!" + ]; + $this->response($message, RestController::HTTP_OK); + } + + } else { + $message = [ + "code" => 60206, + "data" => ["status" => 'fail', "msg" => $userInfo["errmsg"]], + "message" => $userInfo["errmsg"] + ]; + $this->response($message, RestController::HTTP_OK); + } + } + } else { + $message = [ + "code" => 60206, + "data" => ["status" => 'fail', "msg" => $userIdInfo["errmsg"]], + "message" => $userIdInfo["errmsg"] + ]; + $this->response($message, RestController::HTTP_OK); + } + } + + // vux coprauth example + function corpauth1_get() + { + $code = $this->get('code'); + + // $corpId = 'xxxxxx'; + // $appSecret = 'xxxxxx'; + + // code: 60206 微信认证失败统一代码 + if (!$code) { + $authUrl = "https://open.weixin.qq.com/connect/oauth2/authorize?appid=" . $corpId . "&redirect_uri=" . $redirectUri . "&response_type=code&scope=snsapi_privateinfo&agentid=" . $agentId . "&state=STATE#wechat_redirect"; + + $message = [ + "success" => false, + "authUrl" => $authUrl + ]; + $this->response($message, RestController::HTTP_OK); + } + + // 根据上面的回调参数获取用户详细信息。 已经传递过来code数据。 + $getCorpAccessTokenUrl = 'https://qyapi.weixin.qq.com/cgi-bin/gettoken?corpid=' . $corpId . '&corpsecret=' . $appSecret; + + $tokenInfo = $this->http_get($getCorpAccessTokenUrl); + $tokenInfo = json_decode($tokenInfo["content"], true); // 获取的原始数据解码成json格式,如下 + // array(4) { + // ["errcode"]=> + // int(0) + // ["errmsg"]=> + // string(2) "ok" + // ["access_token"]=> + // string(214) "vP2TgGlg8-_N23PleQnq2q9SBnIfqCkkNMGZ71YoZ8V3R0lB8sJOy15ixco4kOxo8GZMlcgiJHm0hDXzbL6lG2BWleAqmJCrMEPdQj9goZaogVNBICmVrr-Fxz8YCIBUdf36BOq4E-Mt64OCrIUw1254Pxupi9RGOEFoWmMrJKgHnR_F0pjD-hJFZfTOIt7W2VujJq6hsle8SD9qTOZwzA" + // ["expires_in"]=> + // int(7200) + // } + if ($tokenInfo["errcode"] == 0) { + $accessToken = $tokenInfo["access_token"]; + } else { + $message = [ + "code" => 60206, + "data" => ["status" => 'fail', "msg" => $tokenInfo["errmsg"] ? $tokenInfo["errmsg"] : "企业认证失败!"], + "message" => $tokenInfo["errmsg"] ? $tokenInfo["errmsg"] : "企业认证失败!" + ]; + $this->response($message, RestController::HTTP_OK); + } + + $getUserIdUrl = 'https://qyapi.weixin.qq.com/cgi-bin/user/getuserinfo?access_token=' . $accessToken . '&code=' . $code; + $ajaxUserIdInfo = $this->http_get($getUserIdUrl); + $userIdInfo = json_decode($ajaxUserIdInfo["content"], true); // 获取的原始数据解码成json格式,如下 + // array(4) { + // ["UserId"]=> + // ["DeviceId"]=> + // string(0) "" + // ["errcode"]=> + // int(0) + // ["errmsg"]=> + // string(2) "ok" + // } + + if ($userIdInfo["errcode"] == 0) { + if (array_key_exists("OpenId", $userIdInfo)) { + $message = [ + "code" => 60206, + "data" => ["success" => 'fail', "msg" => "不是企业成员!请联系企业管理员,添加您的账号的企业通讯录!"], + "message" => "不是企业成员!请联系企业管理员,添加您的账号的企业通讯录!" + ]; + $this->response($message, RestController::HTTP_OK); + + } else if (array_key_exists("UserId", $userIdInfo)) { + $getUserInfoUrl = 'https://qyapi.weixin.qq.com/cgi-bin/user/get?access_token=' . $accessToken . '&userid=' . $userIdInfo["UserId"]; + $ajaxUserInfo = $this->http_get($getUserInfoUrl); + $userInfo = json_decode($ajaxUserInfo["content"], true); // 获取的原始数据解码成json格式,如下 + $message = [ + "code" => 20000, + "data" => $userInfo, + "message" => "微信获取 userInfo 成功!" + ]; + $this->response($message, RestController::HTTP_OK); + // array(21) { + // ["errcode"]=> + // int(0) + // ["errmsg"]=> + // string(2) "ok" + // ["userid"]=> + // ["name"]=> + // ["position"]=> + // string(0) "" + // ["mobile"]=> + // ["gender"]=> + // string(1) "1" + // ["email"]=> + // ["avatar"]=> + // string(85) "http://p.qlogo.cn/bizmail/rZXu0u7ma4vOiaEWia7MTnUDmdDnfgh7R6iafX5832RczKmViadvgbVAhw/" + // ["status"]=> + // int(1) + // } + + } + } else { + $message = [ + "code" => 60206, + "data" => ["status" => 'fail', "msg" => $userIdInfo["errmsg"]], + "message" => $userIdInfo["errmsg"] + ]; + $this->response($message, RestController::HTTP_OK); + } + } +} diff --git a/controllers/api/widgets.php b/controllers/api/widgets.php new file mode 100644 index 0000000..852f9c5 --- /dev/null +++ b/controllers/api/widgets.php @@ -0,0 +1,116 @@ + array('id' => 1, 'name' => 'sprocket'), + 2 => array('id' => 2, 'name' => 'gear') + ); + + // get参数为空 + if (!$id) { + $id = $this->get('id'); + var_dump($id); + } + if (!$id) { + //$widgets = $this->widgets_model->getWidgets(); + if ($widgets) + $this->response($widgets, 200); // 200 being the HTTP response code + else + $this->response(array('error' => 'Couldn\'t find any widgets!'), 404); + } + + // get参数不为空 + //$widget = $this->widgets_model->getWidget($id); + $widget = @$widgets[$id]; // test code + + if ($widget) + $this->response($widget, 200); // 200 being the HTTP response code + else + $this->response(array('error' => 'Widget could not be found'), 404); + } + + function index_post() + { + $data = $this->_post_args; + echo json_encode($data); + try { + //$id = $this->widgets_model->createWidget($data); + $id = 3; // test code + //throw new Exception('Invalid request data', 400); // test code + //throw new Exception('Widget already exists', 409); // test code + } catch (Exception $e) { + // Here the model can throw exceptions like the following: + // * For invalid input data: new Exception('Invalid request data', 400) + // * For a conflict when attempting to create, like a resubmit: new Exception('Widget already exists', 409) + $this->response(array('error' => $e->getMessage()), $e->getCode()); + } + if ($id) { + $widget = array('id' => $id, 'name' => $data['name']); // test code + //$widget = $this->widgets_model->getWidget($id); + $this->response($widget, 201); // 201 being the HTTP response code + } else + $this->response(array('error' => 'Widget could not be created'), 404); + } + + public function index_put() + { + $data = $this->_put_args; + try { + //$id = $this->widgets_model->updateWidget($data); + $id = $data['id']; // test code + //throw new Exception('Invalid request data', 400); // test code + } catch (Exception $e) { + // Here the model can throw exceptions like the following: + // * For invalid input data: new Exception('Invalid request data', 400) + // * For a conflict when attempting to create, like a resubmit: new Exception('Widget already exists', 409) + $this->response(array('error' => $e->getMessage()), $e->getCode()); + } + if ($id) { + $widget = array('id' => $data['id'], 'name' => $data['name']); // test code + //$widget = $this->widgets_model->getWidget($id); + $this->response($widget, 200); // 200 being the HTTP response code + } else + $this->response(array('error' => 'Widget could not be found'), 404); + } + + function index_delete($id = '') + { + + // Example data for testing. + $widgets = array( + 1 => array('id' => 1, 'name' => 'sprocket'), + 2 => array('id' => 2, 'name' => 'gear'), + 3 => array('id' => 3, 'name' => 'nut') + ); + if (!$id) { + $id = $this->get('id'); + } + if (!$id) { + $this->response(array('error' => 'An ID must be supplied to delete a widget'), 400); + } + + //$widget = $this->widgets_model->getWidget($id); + $widget = @$widgets[$id]; // test code + + if ($widget) { + try { + //$this->widgets_model->deleteWidget($id); + //throw new Exception('Forbidden', 403); // test code + } catch (Exception $e) { + // Here the model can throw exceptions like the following: + // * Client is not authorized: new Exception('Forbidden', 403) + $this->response(array('error' => $e->getMessage()), $e->getCode()); + } + $this->response($widget, 200); // 200 being the HTTP response code + } else + $this->response(array('error' => 'Widget could not be found'), 404); + } +} diff --git a/controllers/api/zto/Notify_accpet.php b/controllers/api/zto/Notify_accpet.php new file mode 100644 index 0000000..0e09209 --- /dev/null +++ b/controllers/api/zto/Notify_accpet.php @@ -0,0 +1,383 @@ +load->library('session'); + $this->load->model('series_number_model'); + $this->load->model('package_model'); + $this->load->model('series_number_model'); + $this->load->model('sample_model'); + $this->load->model('customer_model'); + + //跨域 + header("Access-Control-Allow-Origin: ".$this->config->config['allow-origin']['user']); + header("Access-Control-Allow-Methods: POST, GET, OPTIONS, PUT, DELETE"); + header('Access-Control-Allow-Headers:x-requested-with,content-type'); + header('Access-Control-Allow-Credentials: true'); + //未登录告警 + if(empty($this->session->{Customer_model::SESSION_KEY})){ + $this->error('您的授权信息不存在或已过期,请从微信公众号菜单进入'); + } + $this->_user_id = $this->session->{Customer_model::SESSION_KEY}; + } + + public function ticket_get() + { + $config = [ + 'app_id' => WEIXIN_APPID, + 'secret' => WEIXIN_APPSECERT, + 'token' => WEIXIN_TOKEN, + 'aes_key' => WEIXIN_EncodingAESKey, + 'response_type' => 'array', + ]; + $app = new OfficialAccount($config); + $app->js->setUrl($_SERVER['HTTP_REFERER']); + $config = $app->js->config(array('updateAppMessageShareData', 'updateTimelineShareData', 'scanQRCode'), $debug = false, $beta = false, $json = true); + $this->success(['config'=>json_decode($config)]); + } + + public function check_number_post() + { + $config = array( + array( + 'field' => 'device_id', + 'label' => '序列号', + 'rules' => 'trim|required|min_length[5]|max_length[20]' + ), + ); + $data = $this->json_validation($config); + $series = $this->series_number_model->get($data['device_id'],'device_id'); + if(!$series){ + $this->error('序列号不存在'); + } + $sample = $this->sample_model->get($series['id'],'series_id'); + if($sample){ + $this->error('序列号已使用'); + } + $package = $this->package_model->get($series['package_ori']); + if(!$package){ + $this->error('套餐不存在'); + } + $this->success(['package'=>$package]); + + } + + public function create_post() + { + $config = array( + array( + 'field' => 'device_id', + 'label' => '序列号', + 'rules' => 'trim|required|min_length[5]|max_length[20]' + ), + array( + 'field' => 'name', + 'label' => '用户姓名', + 'rules' => 'trim|required|min_length[2]|max_length[20]', + 'errors' => array( + 'required' => 'You must provide a %s.', + ), + ), + array( + 'field' => 'tel', + 'label' => '手机', + 'rules' => 'required' + ), + array( + 'field' => 'email', + 'label' => '邮箱', + 'rules' => 'required' + ), + array( + 'field' => 'pet_name', + 'label' => '宠物名称', + 'rules' => 'required' + ), + array( + 'field' => 'pet_age', + 'label' => '宠物年龄', + 'rules' => 'required' + ), + array( + 'field' => 'pet_breed', + 'label' => '宠物品系', + 'rules' => 'required' + ), + array( + 'field' => 'pet_sex', + 'label' => '宠物性别', + 'rules' => 'required' + ), + array( + 'field' => 'pet_birthday', + 'label' => '宠物生日', + 'rules' => 'required' + ), + array( + 'field' => 'pet_species', + 'label' => '物种', + 'rules' => 'required' + ), + array( + 'field' => 'pet_img', + 'label' => '宠物头像地址', + 'rules' => 'required' + ), + array( + 'field' => 'package_id', + 'label' => '检测套餐', + 'rules' => 'required' + ), + array( + 'field' => 'note', + 'label' => '其他需求', + 'rules' => 'required' + ) + ); + $data = $this->json_validation($config); + $series = $this->series_number_model->get($data['device_id'],'device_id'); + if(!$series){ + $this->error('序列号不存在'); + } + $sample = $this->sample_model->get($series['id'],'series_id'); + if($sample){ + $this->error('序列号已使用'); + } + $package = $this->package_model->get($series['package_ori']); + if(!$package){ + $this->error('套餐不存在'); + } + $ret = $this->sample_model->add( + array_intersect_key(array_column($config,'field'),$data) + ); + if($ret){ + $this->success(); + }else{ + $this->error('提交失败'); + } + } + + //获取需回寄的样品 + public function ship_get() + { + $ret = $this->sample_model->get($this->_user_id,'user_id',true); + //只展示需回寄样品 + foreach ($ret as $key=>$item) { + if($item['step'] >= Sample_model::STEP_SENT){ + unset($ret[$key]); + } + } + $this->success($ret); + } + + //样品回寄 + public function ship_post() + { + $config = array( + array( + 'field' => 'device_id', + 'label' => '序列号', + 'rules' => 'trim|required|min_length[5]|max_length[20]' + ), + array( + 'field' => 'name', + 'label' => '用户姓名', + 'rules' => 'trim|required|min_length[2]|max_length[20]', + 'errors' => array( + 'required' => 'You must provide a %s.', + ), + ), + array( + 'field' => 'tel', + 'label' => '手机', + 'rules' => 'required' + ), + array( + 'field' => 'email', + 'label' => '邮箱', + 'rules' => 'required' + ), + array( + 'field' => 'pet_name', + 'label' => '宠物名称', + 'rules' => 'required' + ), + array( + 'field' => 'pet_age', + 'label' => '宠物年龄', + 'rules' => 'required' + ), + array( + 'field' => 'pet_breed', + 'label' => '宠物品系', + 'rules' => 'required' + ), + array( + 'field' => 'pet_sex', + 'label' => '宠物性别', + 'rules' => 'required' + ), + array( + 'field' => 'pet_birthday', + 'label' => '宠物生日', + 'rules' => 'required' + ), + array( + 'field' => 'pet_species', + 'label' => '物种', + 'rules' => 'required' + ), + array( + 'field' => 'pet_img', + 'label' => '宠物头像地址', + 'rules' => 'required' + ), + array( + 'field' => 'package_id', + 'label' => '检测套餐', + 'rules' => 'required' + ), + array( + 'field' => 'note', + 'label' => '其他需求', + 'rules' => 'required' + ) + ); + $data = $this->json_validation($config); + $series = $this->series_number_model->get($data['device_id'],'device_id'); + + } + + //进度查询:样品列表 + public function list_get() + { + $ret = $this->sample_model->get($this->_user_id,'user_id',true); + $this->success($ret); + } + + //进度查询:样品进度详情 + public function detail_get() + { + $config = array( + array( + 'field' => 'id', + 'label' => '样品ID', + 'rules' => 'trim|required|min_length[5]|max_length[20]' + ) + ); + $this->load->library('form_validation'); + $data = $this->input->get(); + $this->form_validation->set_data($data); + $this->form_validation->set_rules($config); + if ($this->form_validation->run() === FALSE) + { + $this->error('参数错误',$this->form_validation->error_array()); + } + $row = $this->sample_model->get(trim($data['id']),'device_id'); + if($row['user_id'] != $this->_user_id){ + $this->error('您没有权限查看该样品'); + } + $this->success($row); + } + + //进度查询:快递详情 + public function track_get() + { + $json_params = file_get_contents('php://input'); + $data = json_decode($json_params, true); + + $config = array( + array( + 'field' => 'device_id', + 'label' => '序列号', + 'rules' => 'trim|required|min_length[5]|max_length[20]' + ), + array( + 'field' => 'name', + 'label' => '用户姓名', + 'rules' => 'trim|required|min_length[2]|max_length[20]', + 'errors' => array( + 'required' => 'You must provide a %s.', + ), + ), + array( + 'field' => 'tel', + 'label' => '手机', + 'rules' => 'required' + ), + array( + 'field' => 'email', + 'label' => '邮箱', + 'rules' => 'required' + ), + array( + 'field' => 'pet_name', + 'label' => '宠物名称', + 'rules' => 'required' + ), + array( + 'field' => 'pet_age', + 'label' => '宠物年龄', + 'rules' => 'required' + ), + array( + 'field' => 'pet_breed', + 'label' => '宠物品系', + 'rules' => 'required' + ), + array( + 'field' => 'pet_sex', + 'label' => '宠物性别', + 'rules' => 'required' + ), + array( + 'field' => 'pet_birthday', + 'label' => '宠物生日', + 'rules' => 'required' + ), + array( + 'field' => 'pet_species', + 'label' => '物种', + 'rules' => 'required' + ), + array( + 'field' => 'pet_img', + 'label' => '宠物头像地址', + 'rules' => 'required' + ), + array( + 'field' => 'package_id', + 'label' => '检测套餐', + 'rules' => 'required' + ), + array( + 'field' => 'note', + 'label' => '其他需求', + 'rules' => 'required' + ) + ); + $this->load->library('form_validation'); + $this->load->model('package_model'); + $this->form_validation->set_data($data); + $this->form_validation->set_rules($config); + + if ($this->form_validation->run() == FALSE) + { + print_r($this->form_validation->error_array()); + $this->error('错误'); + } + else + { + echo '成功'; + } + + $this->success(); + + } +} diff --git a/controllers/cron/Report.php b/controllers/cron/Report.php new file mode 100644 index 0000000..11711cb --- /dev/null +++ b/controllers/cron/Report.php @@ -0,0 +1,56 @@ +load->model('Model_UsersInfo'); + $this->load->model('report_model'); + } + + + //新报告检测 + public function index() + { + //未完成的检测 + $list = $this->Model_UsersInfo->get_uncompleted_list(); + //扫描目录 + foreach ($list as $userInfo) { + //print_r($this->report_model->get_report_file($userInfo['device_id']));die; + if($this->report_model->is_report_ready($userInfo['device_id'])){ + //设置完成 + $this->Model_UsersInfo->set_completed($userInfo['id']); + //发送微信通知 + } + } + } + + + //快递 + public function ship() + { + die('dfdfd'); + //未完成的检测 + $list = $this->Model_UsersInfo->get_uncompleted_list(); + //扫描目录 + foreach ($list as $userInfo) { + //print_r($this->report_model->get_report_file($userInfo['device_id']));die; + if($this->report_model->is_report_ready($userInfo['device_id'])){ + //设置完成 + $this->Model_UsersInfo->set_completed($userInfo['id']); + //发送微信通知 + } + } + } + + //快递 + public function test() + { + die('dfdfd'); + } + +} diff --git a/controllers/index.html b/controllers/index.html new file mode 100644 index 0000000..b702fbc --- /dev/null +++ b/controllers/index.html @@ -0,0 +1,11 @@ + + + + 403 Forbidden + + + +

Directory access is forbidden.

+ + + diff --git a/core/MY_Controller.php b/core/MY_Controller.php new file mode 100644 index 0000000..e3e239e --- /dev/null +++ b/core/MY_Controller.php @@ -0,0 +1,322 @@ +400 + ]; + + protected function json_input($require=TRUE){ + $json_params = file_get_contents('php://input'); + if(empty($json_params)){ + if($require){ + $this->error('请输入参数'); + } + return []; + } + try{ + return json_decode($json_params, true); + }catch (Exception $e){ + return []; + } + + } + + protected function error($msg='',$data=[]){ + $message = [ + "code" => 50000, + "data" => $data, + "message" => $msg + ]; + $this->response($message, parent::HTTP_OK); + die; + } + + public function success($data=[],$msg=''){ + $message = [ + "code" => 20000, + "data" => $data, + "message" => $msg + ]; + $this->response($message, parent::HTTP_OK); + die; + } + + + //接收请求检验 + function json_validation($config){ + $data = $this->json_input(); + $this->load->library('form_validation'); + $this->form_validation->set_data($data); + $this->form_validation->set_rules($config); + if ($this->form_validation->run() === FALSE) + { + $error_arr = $this->form_validation->error_array(); + $this->error(reset($error_arr),$error_arr); + } + return $data; + } + + /** + * 服务器端请求校验 + * @DATE 20220522 + **/ + function checkUser(){ + //尝试跟服务端对接 + $ret = $this->serverSign(); + if($ret !== null){ + if(!$ret){ + $this->error('您的签名错误'); + } + //通过头部的open id获取用户信息 + $this->load->model('customer_model'); + $customer = $this->customer_model->get( + $this->_head_args['Uah-Open-Id'], + 'openid' + ); + if(!$customer){ + $this->error('用户OPENID不存在'); + } + $this->_user_id = $customer['id']; + return; + } + //跟前端对接,未登录告警 + if(empty($this->session->{Customer_model::SESSION_KEY})){ + $this->error('您的授权信息不存在或已过期,请从微信公众号菜单进入'); + } + $this->_user_id = $this->session->{Customer_model::SESSION_KEY}; + } + + /** + * 服务器端请求校验 + * @DATE 20220522 + **/ + function serverSign(){ + $str = ''; + foreach (['Uah-Open-Id','Uah-Timestamp'] as $val) { + if(empty($this->_head_args[$val])){ + return null; + } + $str.=$this->_head_args[$val]; + } + if(empty($this->_head_args['Uah-Sign'])){ + return null; + } + $conf = $this->config->item('uah_server_token'); + //echo $str.$conf; + //echo md5($str.$conf); + //echo $this->_head_args['Uah-Sign']; + return md5($str.$conf) == $this->_head_args['Uah-Sign']; + } + +} + +//提供后台的统一方法 +class AdminController extends ApiController +{ + protected $base_model = 'sample_model'; + + public function __construct() + { + parent::__construct(); + $this->load->model($this->base_model); + + $uri = $this->uri->uri_string; + $Token = $this->input->get_request_header('X-Token', TRUE); + $retPerm = $this->permission->HasPermit($Token, $uri); + if ($retPerm['code'] != 50000) { + $this->response($retPerm, RestController::HTTP_OK); + } + } + + //单条更新的校验规则 + protected function _validate_rule(){ + return []; + } + + //批量导入的字段对应表 + protected function _import_field_map(){ + return []; + } + + function list_get() + { + return $this->_list_get(); + } + + function _list_get($is_return = false, $select = null) + { + $filters = $this->input->get(); + $page = $this->input->get('page'); + $limit = $this->input->get('limit'); + $page = empty($page)?1:$page; + $limit = empty($limit)?50:$limit; + $sort = $this->input->get('sort'); + $sort_type = substr($sort,0,1); + $sort_name = 'base.'.substr($sort,1); + $sort_type = $sort_type=='-'?'DESC':'ASC'; + unset($filters['sort']); + unset($filters['limit']); + unset($filters['page']); + $items = $this->{$this->base_model}->listing($filters, ($page-1)*$limit,$limit,$select,$sort_name,$sort_type); + if($is_return){ + return $items; + } + $this->success($items); + } + + function detail_get() + { + return $this->_detail_get(); + } + + function _detail_get($is_return = false) + { + $id = $this->security->xss_clean($this->input->get('id')); + $item = $this->{$this->base_model}->get($id); + if($is_return){ + return $item; + } + $this->success([ + "item" => $item + ]); + + } + + function update_post() + { + $this->_update_post($this->_validate_rule()); + } + + function _update_post($validate_config,$data = []) + { + if(empty($data)){ + $data = $this->json_validation($validate_config); + } + $fields = array_column($validate_config,'field'); + foreach ($data as $key => $val) { + if(!in_array($key,$fields)){ + unset($data[$key]); + } + } + if(empty($data['id'])){ + $ret = $this->{$this->base_model}->add($data); + if($ret === -1){ + $this->error('名称重复'); + } + }else{ + $this->{$this->base_model}->update($data, ['id'=>$data['id']]); + } + $this->success(); + } + + function delete_post() + { + return $this->_delete_post(); + } + + function _delete_post() + { + $data = $this->json_input(); + $this->{$this->base_model}->batchDel($data); + $this->success(); + } + + //批量新建 + function _batch_create_post($validate_config,$data_arr=[]) + { + if(empty($data_arr)){ + $data_arr = $this->json_input(); + } + $this->load->library('form_validation'); + foreach ($data_arr as $item) { + $this->form_validation->set_data($item); + $this->form_validation->set_rules($validate_config); + if ($this->form_validation->run() === FALSE) + { + $error_arr = $this->form_validation->error_array(); + $this->error(reset($error_arr),$error_arr); + } + $ret = $this->{$this->base_model}->batchAdd($data_arr); + if(is_string($ret)){ + $this->error($ret); + } + $this->success(); + } + } + + //批量更新单一属性 + function batch_update_post() + { + $data_arr = $this->json_input(); + //id必传,其他字段检查规则中有没有 + if(empty($data_arr['id'])){ + $this->error('请传入id'); + } + $ids = []; + foreach ($data_arr['id'] as $id) { + $ids[] = (int)$id; + } + unset($data_arr['id']); + $this->{$this->base_model}->update($data_arr, 'id in ('.implode(',',$ids).')'); + $this->success(); + } + + //批量更新插入 + function batch_update_insert_post() + { + $data = $this->_arr_fill($this->_import_field_map(),$this->json_input()); + $this->_batch_update_insert_post($this->_validate_rule(),$data); + $this->success(); + } + + //批量更新插入 + function _batch_update_insert_post($validate_config,$data_arr=[]) + { + if(empty($data_arr)){ + $data_arr = $this->json_input(); + } + $this->load->library('form_validation'); + foreach ($data_arr as $item) { + $this->form_validation->set_data($item); + $this->form_validation->set_rules($validate_config); + if ($this->form_validation->run() === FALSE) + { + $error_arr = $this->form_validation->error_array(); + $this->error(reset($error_arr),$error_arr); + } + $ret = $this->{$this->base_model}->batchUpdateInsert($data_arr); + $this->success(); + } + } + + //数组字段映射并补充不存在的字段 + function _arr_fill($map,$input) + { + $data = []; + foreach ($input as $item) { + $tmp = []; + //中文改成英文 + foreach ($item as $k=>$v) { + if(!isset($map[$k])){ + continue; + } + $tmp[$map[$k]] = $v; + } + //补充不存在的字段 + foreach ($map as $k=>$v) { + if(!isset($tmp[$v])){ + $tmp[$v] = ''; + } + } + $data[] = $tmp; + } + return $data; + } +} diff --git a/core/MY_Model.php b/core/MY_Model.php new file mode 100644 index 0000000..e49c2c7 --- /dev/null +++ b/core/MY_Model.php @@ -0,0 +1,257 @@ +load->database(); + } + + function listing($filters = [], $offset, $segment, $select=null, $order_field='base.id',$order='DESC') + { + if(empty($select)){ + $select = $this->list_field; + } + $this->db->select('SQL_CALC_FOUND_ROWS '.$select,false); + $this->db->from($this->table.' as base'); + if(!empty($this->join)){ + foreach ($this->join as $_join) { + $this->db->join($_join['table'], $_join['on'],$_join['type']); + } + } + if(!empty($order_field)){ + $this->db->order_by($order_field,$order); + } + + //包含筛选条件 + if(!empty($filters)) foreach ($filters as $key=>$val) { + if($val === ''){ + continue; + } + //容易冲突的键 + if(in_array($key,['id','name','create_time'])){ + $key = 'base.'.$key; + } + //字段别名 + if(isset($this->where_field_map[$key])){ + $key = $this->where_field_map[$key]; + } + //某些字段的0值填充为null + if($val == '0' && in_array($key,$this->null_field)){ + $this->db->where("$key is null"); + continue; + } + //含有关键词 + if(!empty($this->keyword_field)) { + if($key === 'title'){ + //对于关键词,拼合所有筛选条件 + $likeCriteria = []; + foreach ($this->keyword_field as $_field) { + $likeCriteria[] = $_field." LIKE '%".$val."%'"; + } + $this->db->where('('.implode(' OR ',$likeCriteria).')'); + continue; + }elseif(in_array($key,$this->keyword_field)){ + $this->db->where($key." LIKE '%".$val."%'"); + continue; + } + } + //对于数组 + if(is_array($val)){ + $this->db->where("$key BETWEEN {$val[0]} and {$val[1]}"); + continue; + } + //含有比较符号 + $op = substr($val,0,1); + if(in_array($op,['>','<'])){ + $this->db->where($key.' '.$op,substr($val,1)); + continue; + } + //普通值 + $this->db->where($key,$val); + continue; + } + + $this->db->limit($segment, $offset); + $query = $this->db->get(); + $result['items'] = $query->result_array(); + //echo $this->db->last_query(); die; + $query = $this->db->query('SELECT FOUND_ROWS() AS `Count`'); + $result['total'] = (int)$query->row()->Count; + + return $result; + } + + public function get($id=false, $field='base.id', $is_list=false, $select=null) + { + if(empty($select)){ + $select = $this->list_field; + } + $this->db->select($select); + $this->db->from($this->table.' as base'); + if(!empty($this->join)){ + foreach ($this->join as $_join) { + $this->db->join($_join['table'], $_join['on'],$_join['type']); + } + } + if($id !== false){ + if(is_array($id)){ + $this->db->where_in($field, $id); + }else{ + $this->db->where($field, $id); + } + } + $query = $this->db->get(); + if($is_list){ + return $query->result_array(); + }else{ + return $query->row_array(); + } + } + + //更新单个或多个 + public function update($data, $where, $one_row = true) + { + if($one_row){ + if(!empty($this->unique_field)){ + $ret = $this->get($data[$this->unique_field],$this->unique_field); + if($ret && $ret['id'] != $data['id']){ + return -1; + } + } + } + if($this->has_update_time){ + $data['update_time'] = empty($data['update_time'])?time():$data['update_time']; + } + $this->db->where($where); + $this->db->update($this->table,$data); + return $this->db->affected_rows(); + } + + public function add($data) + { + if($this->has_create_time){ + $data['create_time'] = empty($data['create_time'])?time():$data['create_time']; + } + if(!empty($this->unique_field)){ + $ret = $this->get($data[$this->unique_field],$this->unique_field); + if($ret){ + return -1; + } + } + $this->db->insert($this->table,$data); + return $this->db->insert_id(); + } + + function batchAdd($data) + { + if(!empty($this->unique_field)){ + $val = array_column($data,$this->unique_field); + $ret = $this->get($val,$this->unique_field); + if($ret){ + return $ret[$this->unique_field].'已存在,不能重复添加'; + } + } + if($this->has_create_time){ + $time = time(); + foreach ($data as &$item) { + $item['create_time'] = $time; + } + } + return $this->db->insert_batch($this->table, $data); + } + + //与批量新建的区别是检测到重复字段则更新 + function batchUpdateInsert($data) + { + //需要新增的条目 + $left = []; + foreach ($data as $item) { + //有id则更新 + if(!empty($item['id'])){ + $this->update($item,'id = '.$item['id']); + continue; + } + if(!empty($this->unique_field)){ + $val = array_column($item,$this->unique_field); + $this->get($val,$this->unique_field); + //存在则更新 + $this->update($item,$this->unique_field.' = "'.$item[$this->unique_field].'"'); + continue; + } + $left[] = $item; + } + if($this->has_create_time){ + $time = time(); + unset($item); + foreach ($left as &$item) { + $item['create_time'] = $time; + } + } + + /*$temp1 = array_keys($left[0]); + * 检查字段情况 + foreach ($left as $k=>$item) { + foreach ($temp1 as $key) { + if(!in_array($key, array_keys($item))){ + die($k.$key); + } + } + } + die(''); + */ + return $this->db->insert_batch($this->table, $left); + } + + function batchDel($id, $field='id') + { + $this->db->where_in($field, $id); + return $this->db->delete($this->table); + } + + //获取总数 + function total($filters=[],$join=false) + { + $this->db->select('count(*) as count'); + $this->db->from($this->table.' base'); + //支持筛选条件 + if($filters){ + foreach ($filters as $filter) { + $this->db->where($filter); + } + } + //支持连表 + if($join && !empty($this->join)){ + foreach ($this->join as $_join) { + $this->db->join($_join['table'], $_join['on'],$_join['type']); + } + } + $query = $this->db->get(); + $row = $query->row_array(); + return $row['count']; + } + + //按天统计 + function sumByDay($start=0,$end=0) + { + $this->db->select('count(*) as count'); + $this->db->from($this->table); + $this->db->where('create_time>=', $start); + $this->db->where('create_time<=', $end); + $this->db->group_by('DATE_FORMAT(from_unixtime(create_time),\'%Y-%m-%d\')'); + $query = $this->db->get(); + return $query->result_array(); + } +} diff --git a/core/index.html b/core/index.html new file mode 100644 index 0000000..b702fbc --- /dev/null +++ b/core/index.html @@ -0,0 +1,11 @@ + + + + 403 Forbidden + + + +

Directory access is forbidden.

+ + + diff --git a/helpers/index.html b/helpers/index.html new file mode 100644 index 0000000..b702fbc --- /dev/null +++ b/helpers/index.html @@ -0,0 +1,11 @@ + + + + 403 Forbidden + + + +

Directory access is forbidden.

+ + + diff --git a/hooks/ManageAuth.php b/hooks/ManageAuth.php new file mode 100644 index 0000000..7a6132a --- /dev/null +++ b/hooks/ManageAuth.php @@ -0,0 +1,49 @@ +CI = &get_instance(); //获取CI对象 + } + + // var_dump(uri_string()); => api/v2/sys/user/login + + //token及权限认证 + public function auth() + { + $uri_no_prefix = str_replace(config_item('jwt_api_prefix'), '', uri_string()); // /sys/user/login 不带 api/v2 前缀 + + if (!in_array($uri_no_prefix, config_item('jwt_white_list'))) { // 不在白名单里需要校验 token + $headers = $this->CI->input->request_headers(); + $Token = $headers['X-Token']; + + try { + $decoded = JWT::decode($Token, config_item('jwt_key'), ['HS256']); //HS256方式,这里要和签发的时候对应 + $userId = $decoded->user_id; + $retPerm = $this->CI->permission->HasPermit($userId, uri_string()); + if ($retPerm['code'] != 50000) { + $this->CI->response($retPerm, RestController::HTTP_OK); + } + } catch (\Firebase\JWT\ExpiredException $e) { // access_token过期 + $message = [ + "code" => 50014, + "message" => $e->getMessage() + ]; + $this->CI->response($message, RestController::HTTP_UNAUTHORIZED); + } catch (Exception $e) { //其他错误 + $message = [ + "code" => 50015, + "message" => $e->getMessage() + ]; + $this->CI->response($message, RestController::HTTP_UNAUTHORIZED); + } + } + } // public function auth() end +} // class ManageAuth end \ No newline at end of file diff --git a/hooks/index.html b/hooks/index.html new file mode 100644 index 0000000..b702fbc --- /dev/null +++ b/hooks/index.html @@ -0,0 +1,11 @@ + + + + 403 Forbidden + + + +

Directory access is forbidden.

+ + + diff --git a/index.html b/index.html new file mode 100644 index 0000000..b702fbc --- /dev/null +++ b/index.html @@ -0,0 +1,11 @@ + + + + 403 Forbidden + + + +

Directory access is forbidden.

+ + + diff --git a/language/english/index.html b/language/english/index.html new file mode 100644 index 0000000..b702fbc --- /dev/null +++ b/language/english/index.html @@ -0,0 +1,11 @@ + + + + 403 Forbidden + + + +

Directory access is forbidden.

+ + + diff --git a/language/english/rest_controller_lang.php b/language/english/rest_controller_lang.php new file mode 100644 index 0000000..06bf4b9 --- /dev/null +++ b/language/english/rest_controller_lang.php @@ -0,0 +1,18 @@ + + + + 403 Forbidden + + + +

Directory access is forbidden.

+ + + diff --git a/language/simplified-chinese/index.html b/language/simplified-chinese/index.html new file mode 100644 index 0000000..69df4e1 --- /dev/null +++ b/language/simplified-chinese/index.html @@ -0,0 +1,11 @@ + + + + 403 Forbidden + + + +

Directory access is forbidden.

+ + + diff --git a/language/simplified-chinese/rest_controller_lang.php b/language/simplified-chinese/rest_controller_lang.php new file mode 100644 index 0000000..f32e9e7 --- /dev/null +++ b/language/simplified-chinese/rest_controller_lang.php @@ -0,0 +1,18 @@ +width = $width; + $this->height = $height; + $this->codeNum = $codeNum; + } + + function showImg() + { + //创建图片 + $this->createImg(); + //设置干扰元素 + $this->setDisturb(); + //设置验证码 + $this->setCaptcha(); + //输出图片 + $this->outputImg(); + } + + function getCaptcha() + { + $this->createCode(); + return $this->code; + } + + private function createImg() + { + $this->im = imagecreatetruecolor($this->width, $this->height); +// $bgColor = imagecolorallocate($this->im, 0, 0, 0); + $bgColor = imagecolorallocate($this->im, 255, 255, 255); + imagefill($this->im, 0, 0, $bgColor); + } + + private function setDisturb() + { + $area = ($this->width * $this->height) / 20; + $disturbNum = ($area > 250) ? 250 : $area; + //加入点干扰 + for ($i = 0; $i < $disturbNum; $i++) { + $color = imagecolorallocate($this->im, rand(0, 255), rand(0, 255), rand(0, 255)); + imagesetpixel($this->im, rand(1, $this->width - 2), rand(1, $this->height - 2), $color); + } + //加入弧线 + for ($i = 0; $i <= 5; $i++) { + $color = imagecolorallocate($this->im, rand(128, 255), rand(125, 255), rand(100, 255)); + imagearc($this->im, rand(0, $this->width), rand(0, $this->height), rand(30, 300), rand(20, 200), 50, 30, $color); + } + } + + private function createCode() + { +// $str = "23456789abcdefghijkmnpqrstuvwxyzABCDEFGHIJKMNPQRSTUVWXYZ"; + $str = "0123456789"; + + for ($i = 0; $i < $this->codeNum; $i++) { + $this->code .= $str{rand(0, strlen($str) - 1)}; + } + } + + private function setCaptcha() + { + for ($i = 0; $i < $this->codeNum; $i++) { +// $color = imagecolorallocate($this->im, rand(50, 250), rand(100, 250), rand(128, 250)); + $color = imagecolorallocate($this->im, rand(0, 50), rand(0, 100), rand(0, 128)); + $size = rand(floor($this->height / 5), floor($this->height / 3)); + $x = floor($this->width / $this->codeNum) * $i + 5; + $y = rand(0, $this->height - 20); + imagechar($this->im, $size, $x, $y, $this->code{$i}, $color); + } + } + + private function outputImg() + { + if (imagetypes() & IMG_JPG) { + header('Content-type:image/jpeg'); + imagejpeg($this->im); + } elseif (imagetypes() & IMG_GIF) { + header('Content-type: image/gif'); + imagegif($this->im); + } elseif (imagetype() & IMG_PNG) { + header('Content-type: image/png'); + imagepng($this->im); + } else { + die("Don't support image type!"); + } + } + +} \ No newline at end of file diff --git a/libraries/MakeZip.php b/libraries/MakeZip.php new file mode 100644 index 0000000..06f6571 --- /dev/null +++ b/libraries/MakeZip.php @@ -0,0 +1,51 @@ +open($zipName, ZipArchive::CREATE | ZipArchive::OVERWRITE); + + // Create recursive directory iterator + /** @var SplFileInfo[] $files */ + $files = new RecursiveIteratorIterator( + new RecursiveDirectoryIterator($rootPath), + RecursiveIteratorIterator::LEAVES_ONLY + ); + + foreach ($files as $name => $file) + { + // Skip directories (they would be added automatically) + if (!$file->isDir()) + { + // Get real and relative path for current file + $filePath = $file->getRealPath(); + $relativePath = substr($filePath, strlen($rootPath) + 1); + + // Add current file to archive + $zip->addFile($filePath, $relativePath); + } + } + + // Zip archive will be created only after closing object + $zip->close(); + return true; + } + +} diff --git a/libraries/Permission-v2.php b/libraries/Permission-v2.php new file mode 100644 index 0000000..56edbae --- /dev/null +++ b/libraries/Permission-v2.php @@ -0,0 +1,340 @@ +idKey = $idKey; + if ($fidKey) $this->fidKey = $fidKey; + if ($root) $this->root = $root; + + if ($data) { + //var_dump($data); + $this->data = $data; + $this->getChildren($this->root, $closed); + + } + + //去掉键名 + //var_dump($this->treeArray); + return array_values($this->treeArray); + } + + /** + * @param int $root 父id值 + * @return null or array + */ + private function getChildren($root, $closed) + { + $children = ''; + + foreach ($this->data as &$node) { + if ($root == $node[$this->fidKey]) { + $node['children'] = $this->getChildren($node[$this->idKey], $closed); + $children[] = $node; + } + //只要一级节点 + if ($this->root == $node[$this->fidKey]) { + //$s=array('state'=>'close'); + //array_push($node,'close'); + if ($closed) { + $node['state'] = $this->state; + } + + $this->treeArray[$node[$this->idKey]] = $node; + + } + } + return $children; + } + + /** + * 根据 $token , 权限类型 获取该 token->userid->role 对应的所有权限 + * @parms,$type 根据$perm_type = 'menu'时,判断是否菜单带有功能控件 + * return array + */ + function getPermission($token, $perm_type, $menuCtrl = true) + { + $CI = &get_instance(); + $CI->load->model('Base_model'); + + $BasetblArr = $CI->Base_model->getBaseTable($perm_type); + if (empty($BasetblArr)) { + var_dump($this->uri->uri_string . '$this->Base_model->getBaseTable 获取基础表失败...'); + return; + } + $tblname = $BasetblArr[0]['r_table']; + + $PermArr = $CI->Base_model->getPerm($tblname, $token, $perm_type, $menuCtrl); + + return $PermArr; + } + + /** + * @parms, 根据$token获取拥有的菜单功能按钮控件权限 与vue前台perm.js 配合判断按钮隐藏与否 + * return array + */ + function getMenuCtrlPerm($token) + { + $CI = &get_instance(); + $CI->load->model('Base_model'); + $PermArr = $CI->Base_model->getCtrlPerm($token); + // 返回样例 + // array(2) { + // [0]=> + // array(1) { + // ["path"]=> + // string(13) "/sys/menu/add" + // } + // [1]=> + // array(1) { + // ["path"]=> + // string(14) "/sys/menu/edit" + // } + // } + return $PermArr; + } + + /** + * 后端根据 $token,$uri 判断是否该用户是否过期及拥有的功能按钮控件操作权限 + * 增/删/改/查 控制器引用 + * @parms $token,$uri + * return Array + * return ['code' => 50008, 'message' => "非法的token"]; + * return ['code' => 50014, 'message' => "Token 过期了"]; + * return ['code' => 50016, 'message' => "无操作权限"]; + * return ['code' => 50000, 'message' => "有操作权限"]; + */ + function HasPermit($token, $uri) + { + $CI = &get_instance(); + $CI->load->model('Base_model'); + // 50008:非法的token; 50012:其他客户端登录了; 50014:Token 过期了; + $tokenArr = $CI->Base_model->TokenExpired($token); + + if ($tokenArr['code'] != 20000) { + return $tokenArr; + } + + $PermArr = $CI->Base_model->getCtrlPerm($token); + // getCtrlPerm 返回样例 + // array(2) { + // [0]=> + // array(1) { + // ["path"]=> + // string(13) "/sys/menu/add" + // } + // [1]=> + // array(1) { + // ["path"]=> + // string(14) "/sys/menu/edit" + // } + // } + if (empty($PermArr)) { + return ['code' => 50016, 'message' => "无操作权限 " . $uri, 'data' => $PermArr]; + } + + // var_dump($this->uri->uri_string); // string(19) "api/v2/sys/menu/add" + foreach ($PermArr as $k => $v) { + if (strpos($uri, $v['path'])) { + return ['code' => 50000, 'message' => "有操作权限 " . $uri, 'data' => $PermArr]; + } + } + return ['code' => 50016, 'message' => "无操作权限 " . $uri, 'data' => $PermArr]; + } + + /** + * 将数据格式化成树形结构路由菜单 + */ + function genVueRouter($data, $idKey, $fidKey, $pId) + { + $tree = array(); + foreach ($data as $k => $v) { + // 找到父节点为$pId的节点,然后进行递归查找其子节点, + if ($v[$fidKey] == $pId) { + // 数据库取出为string类型,强制类型转换成整形,方便前端使用 + isset($v['id']) ? $v['id'] = intval($v['id']) : ''; + isset($v['pid']) ? $v['pid'] = intval($v['pid']) : ''; + isset($v['type']) ? $v['type'] = intval($v['type']) : ''; + isset($v['hidden']) ? $v['hidden'] = intval($v['hidden']) : ''; + isset($v['listorder']) ? $v['listorder'] = intval($v['listorder']) : ''; + + // 构造 vue-admin 路由结构 meta + $v['meta'] = [ + 'title' => $v['title'], + 'icon' => $v['icon'] + ]; + + unset($v['title']); + unset($v['icon']); + + $v['children'] = $this->genVueRouter($data, $idKey, $fidKey, $v[$idKey]); + $tree[] = $v; // 循环数组添加元素 属于同一层级 + } + } + // print_r($tree); + return $tree; + } + + // 菜单管理 -> 菜单列表 + function genVueMenuTree($data, $idKey, $fidKey, $pId) + { + $tree = array(); + foreach ($data as $k => $v) { + // 找到父节点为$pId的节点,然后进行递归查找其子节点, + if ($v[$fidKey] == $pId) { + // 数据库取出为string类型,强制类型转换成整形,方便前端使用 + isset($v['id']) ? $v['id'] = intval($v['id']) : ''; + isset($v['pid']) ? $v['pid'] = intval($v['pid']) : ''; + isset($v['type']) ? $v['type'] = intval($v['type']) : ''; + isset($v['hidden']) ? $v['hidden'] = intval($v['hidden']) : ''; + isset($v['listorder']) ? $v['listorder'] = intval($v['listorder']) : ''; + + $v['children'] = $this->genVueMenuTree($data, $idKey, $fidKey, $v[$idKey]); + + // vue treeselect 组件子节点为空时会列出,将空的子节点删除 children key. + if (empty($v['children'])) { + unset($v['children']); + } + $tree[] = $v; // 循环数组添加元素 属于同一层级 + // print_r($tree); + } + } + return $tree; + } + + /** + * 指定格式两个二维数组比较差集 + * @param $array1 + * @param $array2 + * @return array + */ + // $arr1 = [ + // ['role_id'=>1,'perm_id'=>1], + // ['role_id'=>1,'perm_id'=>2] + // ]; + function array_diff_assoc2($array1, $array2) + { + $ret = array(); + foreach ($array1 as $k => $v) { +# var_dump($v); + $isExist = false; + foreach ($array2 as $k2 => $v2) { + if (empty(array_diff_assoc($v, $v2))) { + $isExist = true; + break; + } + } + if (!$isExist) array_push($ret, $v); + } + return $ret; + } + + /** + * 将数据格式化成树形结构 + */ + function genTree($data, $idKey, $fidKey, $pId) + { +// $tree = ''; + $tree = array(); + foreach ($data as $k => $v) { + // 找到父节点为$pId的节点,然后进行递归查找其子节点, + // 同时将子节点赋值至该节点的'children'元素,同时判断是否叶子节点 + if ($v[$fidKey] == $pId) { + $v['children'] = $this->genTree($data, $idKey, $fidKey, $v[$idKey]); + // print_r($pId); +// $v['isLeaf']=$v['children']?0:1; +// $v['state']=$v['children']?'closed':'open'; + $tree[] = $v; // 循环数组添加元素 属于同一层级 +// print_r($v); + // print_r($tree); + } + } + return $tree; + } + + /** + * 将数据格式化成树形结构 ___非递归方式,使用了数组指针,与前面json方式一样,array 必须以1开头___ + * @author Xuefen.Tong + * @param array $items + * @return array + */ + function genTree9($items) + { + $tree = array(); //格式化好的树 + foreach ($items as $item) + if (isset($items[$item['pid']])) + $items[$item['pid']]['son'][] = &$items[$item['id']]; + else + $tree[] = &$items[$item['id']]; + return $tree; + } + + /** + * 获取全部机构 + * TODO:根据当前USERID 获取用户最高级机构所有下属机构 + */ + function getDept() + { + $CI = &get_instance(); + $CI->load->model('Dept_model', 'Dept'); + + $array = $CI->Dept->getDeptids(); +// var_dump($array); + $max = 10000; + $j = 0; + for ($i = 0; $i < count($array); $i++) { +// var_dump($array[$i]->DeptId); + $arr = $CI->Dept->getDeptFatherId($array[$i]->DeptId); +// var_dump($arr[0]->FatherLst); +// var_dump(explode(",",$arr[0]->FatherLst)); +// var_dump(count(explode(",",$arr[0]->FatherLst))); + $fid_length = count(explode(",", $arr[0]->FatherLst)); + + if ($fid_length < $max) { + $max = $fid_length; + $j = $i; // 指针父机构最小长度 + } + } + + $fdeptid = $array[$j]->DeptId; // 最高机构ID + $data = $CI->Dept->getOptDept($fdeptid); //获取下属所有机构树 + + $ret = $CI->Dept->getFahterId($fdeptid); //获取最高机构直属父ID作为终止节点 + $root = $ret[0]->FatherId; // treelib 需要终止节点 +// $root 最顶层fid +// $b=$this->treelib->getTreeArray($data,'Id','FatherId',$root,1); + +// $b=$this->treelib->getTreeArray($data,'Id','FatherId',$root,1); +// $b=str_replace(',"state":"closed","children":""',',"state":"open","children":""',json_encode($b)); +// echo json_encode($b); + +// $b=$this->genTree($data,'Id','FatherId',$root); + + $b = $this->genTree($data, 'id', 'FatherId', $root); + echo json_encode($b); + + } + + +} \ No newline at end of file diff --git a/libraries/Permission.php b/libraries/Permission.php new file mode 100644 index 0000000..28ce4ab --- /dev/null +++ b/libraries/Permission.php @@ -0,0 +1,368 @@ +idKey = $idKey; + if ($fidKey) $this->fidKey = $fidKey; + if ($root) $this->root = $root; + + if ($data) { + //var_dump($data); + $this->data = $data; + $this->getChildren($this->root, $closed); + + } + + //去掉键名 + //var_dump($this->treeArray); + return array_values($this->treeArray); + } + + /** + * @param int $root 父id值 + * @return null or array + */ + private function getChildren($root, $closed) + { + $children = ''; + + foreach ($this->data as &$node) { + if ($root == $node[$this->fidKey]) { + $node['children'] = $this->getChildren($node[$this->idKey], $closed); + $children[] = $node; + } + //只要一级节点 + if ($this->root == $node[$this->fidKey]) { + //$s=array('state'=>'close'); + //array_push($node,'close'); + if ($closed) { + $node['state'] = $this->state; + } + + $this->treeArray[$node[$this->idKey]] = $node; + + } + } + return $children; + } + + /** + * 根据 $token , 权限类型 获取该 token->userid->role 对应的所有权限 + * @parms,$type 根据$perm_type = 'menu'时,判断是否菜单带有功能控件 + * return array + */ + function getPermission($token, $perm_type, $menuCtrl = true) + { + $CI = &get_instance(); + $CI->load->model('Base_model'); + + $BasetblArr = $CI->Base_model->getBaseTable($perm_type); + if (empty($BasetblArr)) { + var_dump($this->uri->uri_string . '$this->Base_model->getBaseTable 获取基础表失败...'); + return; + } + $tblname = $BasetblArr[0]['r_table']; + + $PermArr = $CI->Base_model->getPerm($tblname, $token, $perm_type, $menuCtrl); + + return $PermArr; + } + + /** + * @parms, 根据$token获取拥有的菜单功能按钮控件权限 与vue前台perm.js 配合判断按钮隐藏与否 + * return array + */ + function getMenuCtrlPerm($token) + { + $CI = &get_instance(); + $CI->load->model('Base_model'); + $PermArr = $CI->Base_model->getCtrlPerm($token); + // 返回样例 + // array(2) { + // [0]=> + // array(1) { + // ["path"]=> + // string(13) "/sys/menu/add" + // } + // [1]=> + // array(1) { + // ["path"]=> + // string(14) "/sys/menu/edit" + // } + // } + return $PermArr; + } + + + /** + * 后端根据 $token,$uri 判断是否该用户是否过期及拥有的功能按钮控件操作权限 + * 增/删/改/查 控制器引用 + * @parms $token,$uri + * return Array + * return ['code' => 50008, 'message' => "非法的token"]; + * return ['code' => 50014, 'message' => "Token 过期了"]; + * return ['code' => 50016, 'message' => "无操作权限"]; + * return ['code' => 50000, 'message' => "有操作权限"]; + */ + function HasPermit($token, $uri) + { + $CI = &get_instance(); + $CI->load->model('Base_model'); + // 50008:非法的token; 50012:其他客户端登录了; 50014:Token 过期了; + $tokenArr = $CI->Base_model->TokenExpired($token); + + if ($tokenArr['code'] != 20000) { + return $tokenArr; + } + + $PermArr = $CI->Base_model->getCtrlPerm($token); + // getCtrlPerm 返回样例 + // array(2) { + // [0]=> + // array(1) { + // ["path"]=> + // string(13) "/sys/menu/add" + // } + // [1]=> + // array(1) { + // ["path"]=> + // string(14) "/sys/menu/edit" + // } + // } + + //暂不细分后台权限 + return ['code' => 50000, 'message' => "有操作权限 " . $uri, 'data' => $PermArr]; + + if (empty($PermArr)) { + return ['code' => 50016, 'message' => "无操作权限 " . $uri, 'data' => $PermArr]; + } + + // var_dump($this->uri->uri_string); // string(19) "api/v2/sys/menu/add" + foreach ($PermArr as $k => $v) { + if (strpos($uri, $v['path'])) { + return ['code' => 50000, 'message' => "有操作权限 " . $uri, 'data' => $PermArr]; + } + } + return ['code' => 50016, 'message' => "无操作权限 " . $uri, 'data' => $PermArr]; + } + + /** + * 将数据格式化成树形结构路由菜单 + */ + function genVueRouter($data, $idKey, $fidKey, $pId) + { + $tree = array(); + foreach ($data as $k => $v) { + // 找到父节点为$pId的节点,然后进行递归查找其子节点, + if ($v[$fidKey] == $pId) { + // 数据库取出为string类型,强制类型转换成整形,方便前端使用 + isset($v['id']) ? $v['id'] = intval($v['id']) : ''; + isset($v['pid']) ? $v['pid'] = intval($v['pid']) : ''; + isset($v['type']) ? $v['type'] = intval($v['type']) : ''; + isset($v['hidden']) ? $v['hidden'] = intval($v['hidden']) : ''; + isset($v['listorder']) ? $v['listorder'] = intval($v['listorder']) : ''; + + // 构造 vue-admin 路由结构 meta + $v['meta'] = [ + 'title' => $v['title'], + 'icon' => $v['icon'] + ]; + + unset($v['title']); + unset($v['icon']); + + $v['children'] = $this->genVueRouter($data, $idKey, $fidKey, $v[$idKey]); + $tree[] = $v; // 循环数组添加元素 属于同一层级 + } + } + // print_r($tree); + return $tree; + } + + // 菜单管理 -> 菜单列表 + function genVueMenuTree($data, $idKey, $fidKey, $pId) + { + $tree = array(); + foreach ($data as $k => $v) { + // 找到父节点为$pId的节点,然后进行递归查找其子节点, + if ($v[$fidKey] == $pId) { + // 数据库取出为string类型,强制类型转换成整形,方便前端使用 + isset($v['id']) ? $v['id'] = intval($v['id']) : ''; + isset($v['pid']) ? $v['pid'] = intval($v['pid']) : ''; + isset($v['type']) ? $v['type'] = intval($v['type']) : ''; + isset($v['hidden']) ? $v['hidden'] = intval($v['hidden']) : ''; + isset($v['listorder']) ? $v['listorder'] = intval($v['listorder']) : ''; + + $v['children'] = $this->genVueMenuTree($data, $idKey, $fidKey, $v[$idKey]); + + // vue treeselect 组件子节点为空时会列出,将空的子节点删除 children key. + if (empty($v['children'])) { + unset($v['children']); + } + $tree[] = $v; // 循环数组添加元素 属于同一层级 + // print_r($tree); + } + } + return $tree; + } + + // 生成部门机构树 + function genDeptTree($data, $idKey, $fidKey, $pId) + { + $tree = array(); + foreach ($data as $k => $v) { + // 找到父节点为$pId的节点,然后进行递归查找其子节点, + if ($v[$fidKey] == $pId) { + // 数据库取出为string类型,强制类型转换成整形,方便前端使用 + isset($v['id']) ? $v['id'] = intval($v['id']) : ''; + isset($v['pid']) ? $v['pid'] = intval($v['pid']) : ''; + isset($v['listorder']) ? $v['listorder'] = intval($v['listorder']) : ''; + + $v['children'] = $this->genDeptTree($data, $idKey, $fidKey, $v[$idKey]); + // vue treeselect 组件子节点为空时会列出,将空的子节点删除 children key. + if (empty($v['children'])) { + unset($v['children']); + } + $tree[] = $v; // 循环数组添加元素 属于同一层级 + } + } + return $tree; + } + + /** + * 指定格式两个二维数组比较差集 + * @param $array1 + * @param $array2 + * @return array + */ + // $arr1 = [ + // ['role_id'=>1,'perm_id'=>1], + // ['role_id'=>1,'perm_id'=>2] + // ]; + function array_diff_assoc2($array1, $array2) + { + $ret = array(); + foreach ($array1 as $k => $v) { +# var_dump($v); + $isExist = false; + foreach ($array2 as $k2 => $v2) { + if (empty(array_diff_assoc($v, $v2))) { + $isExist = true; + break; + } + } + if (!$isExist) array_push($ret, $v); + } + return $ret; + } + + /** + * 将数据格式化成树形结构 + */ + function genTree($data, $idKey, $fidKey, $pId) + { +// $tree = ''; + $tree = array(); + foreach ($data as $k => $v) { + // 找到父节点为$pId的节点,然后进行递归查找其子节点, + // 同时将子节点赋值至该节点的'children'元素,同时判断是否叶子节点 + if ($v[$fidKey] == $pId) { + $v['children'] = $this->genTree($data, $idKey, $fidKey, $v[$idKey]); + // print_r($pId); +// $v['isLeaf']=$v['children']?0:1; +// $v['state']=$v['children']?'closed':'open'; + $tree[] = $v; // 循环数组添加元素 属于同一层级 +// print_r($v); + // print_r($tree); + } + } + return $tree; + } + + /** + * 将数据格式化成树形结构 ___非递归方式,使用了数组指针,与前面json方式一样,array 索引必须以1开头___ + * @author Xuefen.Tong + * @param array $items + * @return array + */ + function genTree9($items) + { + $tree = array(); //格式化好的树 + foreach ($items as $item) + if (isset($items[$item['pid']])) + $items[$item['pid']]['son'][] = &$items[$item['id']]; + else + $tree[] = &$items[$item['id']]; + return $tree; + } + + /** + * 获取全部机构 + * TODO:根据当前USERID 获取用户最高级机构所有下属机构 + */ + function getDept() + { + $CI = &get_instance(); + $CI->load->model('Dept_model', 'Dept'); + + $array = $CI->Dept->getDeptids(); +// var_dump($array); + $max = 10000; + $j = 0; + for ($i = 0; $i < count($array); $i++) { +// var_dump($array[$i]->DeptId); + $arr = $CI->Dept->getDeptFatherId($array[$i]->DeptId); +// var_dump($arr[0]->FatherLst); +// var_dump(explode(",",$arr[0]->FatherLst)); +// var_dump(count(explode(",",$arr[0]->FatherLst))); + $fid_length = count(explode(",", $arr[0]->FatherLst)); + + if ($fid_length < $max) { + $max = $fid_length; + $j = $i; // 指针父机构最小长度 + } + } + + $fdeptid = $array[$j]->DeptId; // 最高机构ID + $data = $CI->Dept->getOptDept($fdeptid); //获取下属所有机构树 + + $ret = $CI->Dept->getFahterId($fdeptid); //获取最高机构直属父ID作为终止节点 + $root = $ret[0]->FatherId; // treelib 需要终止节点 +// $root 最顶层fid +// $b=$this->treelib->getTreeArray($data,'Id','FatherId',$root,1); + +// $b=$this->treelib->getTreeArray($data,'Id','FatherId',$root,1); +// $b=str_replace(',"state":"closed","children":""',',"state":"open","children":""',json_encode($b)); +// echo json_encode($b); + +// $b=$this->genTree($data,'Id','FatherId',$root); + + $b = $this->genTree($data, 'id', 'FatherId', $root); + echo json_encode($b); + + } + + +} \ No newline at end of file diff --git a/libraries/Uploads.php b/libraries/Uploads.php new file mode 100644 index 0000000..1c51e0a --- /dev/null +++ b/libraries/Uploads.php @@ -0,0 +1,192 @@ +get_upload_path(); + $pet_img_path = Uploads::DIR_PER_CERT_IMG.DIRECTORY_SEPARATOR.$device_id.DIRECTORY_SEPARATOR; + $type = $this->base64_image_save( + $content, + $upload_path.$pet_img_path, + $filename + ); + if(!$type){ + return false; + } + //png转为jpg,降低文件大小 + $img = imagecreatefrompng($upload_path.$pet_img_path.$filename.'.'.$type); + if($img){ + imagejpeg($img, $upload_path.$pet_img_path.$filename.'.jpg',75); + imagedestroy($img); + unlink($upload_path.$pet_img_path.$filename.'.'.$type); + } + return $filename.'.jpg'; + } + + + /** + * 上传宠物头像 + */ + public function save_pet_img_base64($content,$device_id) + { + $device_id = strtoupper($device_id); + $upload_path = $this->get_upload_path(); + $pet_img_path = Uploads::DIR_PET_IMG.DIRECTORY_SEPARATOR; + $type = $this->base64_image_save( + $content, + $upload_path.$pet_img_path, + $device_id.'_ori' + ); + if(!$type){ + return false; + } + $source = $pet_img_path.$device_id.'_ori.'.$type; + $target = $pet_img_path.$device_id.'_300.'.$type; + $ret = $this->image_center_crop($upload_path.$source, 300, 300, $upload_path.$target); + if(!$ret){ + return $source; + } + return $target; + } + + /** + * 上传图片 + */ + public function upload_img($arr) + { + $list = array(); + foreach ($arr as $k => $v) { + + $name = $v['name']; + $type = strtolower(substr($name, strrpos($name, '.') + 1)); // 得到文件类型,并且都转化成小写 + $allow_type = array( + 'jpg', + 'jpeg', + 'gif', + 'png', + 'mp4', + ); // 定义允许上传的类型 + // 判断文件类型是否被允许上传 + if (! in_array($type, $allow_type)) { + // 如果不被允许,则直接停止程序运行 + return; + } + // 判断是否是通过HTTP POST上传的 + if (! is_uploaded_file($v['tmp_name'])) { + // 如果不是通过HTTP POST上传的 + return; + } + + $upload_path = FCPATH.self::DIR.DIRECTORY_SEPARATOR."users_info_img/"; + if (! file_exists($upload_path)) { + mkdir($upload_path); + } + + $img_id = time() . rand(1, 100) . "." . $type; + + $list[$k] ='users_info_img/'.$img_id; + if (move_uploaded_file($v['tmp_name'], $upload_path . $img_id)) { + + } else { + return; + } + } + return $list[0]; + } + + /* base64格式编码转换为图片并保存对应文件夹 */ + function base64_image_save($base64_image_content,$path,$name) + { + //匹配出图片的格式 + if (preg_match('/^(data:\s*image\/(\w+);base64,)/', $base64_image_content, $result)) { + $type = $result[2] === 'jpeg'?'jpg':$result[2]; + if (!file_exists($path)) { + //检查是否有该文件夹,如果没有就创建,并给予最高权限 + mkdir($path, 0755); + } + $new_file = $name . ".{$type}"; + if (file_put_contents($path . $new_file, base64_decode(str_replace($result[1], '', $base64_image_content)))) { + return $type; + } else { + return false; + } + } else { + return false; + } + } + + /** + * 居中裁剪图片 + * @param string $source [原图路径] + * @param int $width [设置宽度] + * @param int $height [设置高度] + * @param string $target [目标路径] + * @return bool [裁剪结果] + */ + public function image_center_crop($source, $width, $height, $target) + { + if (!file_exists($source)) return false; + /* 根据类型载入图像 */ + switch (exif_imagetype($source)) { + case IMAGETYPE_JPEG: + $image = imagecreatefromjpeg($source); + break; + case IMAGETYPE_PNG: + $image = imagecreatefrompng($source); + break; + case IMAGETYPE_GIF: + $image = imagecreatefromgif($source); + break; + } + if (!isset($image)) return false; + /* 获取图像尺寸信息 */ + $target_w = $width; + $target_h = $height; + $source_w = imagesx($image); + $source_h = imagesy($image); + /* 计算裁剪宽度和高度 */ + $judge = (($source_w / $source_h) > ($target_w / $target_h)); + $resize_w = $judge ? ($source_w * $target_h) / $source_h : $target_w; + $resize_h = !$judge ? ($source_h * $target_w) / $source_w : $target_h; + $start_x = $judge ? ($resize_w - $target_w) / 2 : 0; + $start_y = !$judge ? ($resize_h - $target_h) / 2 : 0; + /* 绘制居中缩放图像 */ + $resize_img = imagecreatetruecolor($resize_w, $resize_h); + imagecopyresampled($resize_img, $image, 0, 0, 0, 0, $resize_w, $resize_h, $source_w, $source_h); + $target_img = imagecreatetruecolor($target_w, $target_h); + imagecopy($target_img, $resize_img, 0, 0, $start_x, $start_y, $resize_w, $resize_h); + /* 将图片保存至文件 */ + if (!file_exists(dirname($target))) mkdir(dirname($target), 0777, true); + switch (exif_imagetype($source)) { + case IMAGETYPE_JPEG: + imagejpeg($target_img, $target); + break; + case IMAGETYPE_PNG: + imagepng($target_img, $target); + break; + case IMAGETYPE_GIF: + imagegif($target_img, $target); + break; + } + return boolval(file_exists($target)); + } + +} diff --git a/libraries/index.html b/libraries/index.html new file mode 100644 index 0000000..b702fbc --- /dev/null +++ b/libraries/index.html @@ -0,0 +1,11 @@ + + + + 403 Forbidden + + + +

Directory access is forbidden.

+ + + diff --git a/models/Base_model-v2.php b/models/Base_model-v2.php new file mode 100644 index 0000000..9dde06e --- /dev/null +++ b/models/Base_model-v2.php @@ -0,0 +1,258 @@ +load->database(); + } + + /************************ + * 数据库操作模型部分 + ***********************/ + + /** + * 获取值 + * $table: 表名 + * $select: 查找项, $select = '*' 或 $select = 'id,title' + * $where: 条件项 $where= 'id=1' 或 $where = 'id=1 and title="blah"' + * $order: $order = 'id desc' + * 返回值是数组 + */ + function _get_key($table, $select = '', $where = '', $order = '') + { + if ($select) { + $this->db->select($select); + } + if ($where) { + $this->db->where($where); + } + if ($order) { + $this->db->order_by($order); + } + + $query = $this->db->get($table); + return $query->result_array(); + } + + function _insert_key($table, $data) + { + $this->db->insert($table, $data); + // 如果$table没有配置自增主键,则insert_id返回值为0 + return $this->db->insert_id(); + } + + // TODO: 更新错误判断 https://stackoverflow.com/questions/20030642/check-if-db-update-successful-with-codeigniter-when-potentially-no-rows-are-upd + function _update_key($table, $data, $where) + { + $this->db->trans_start(); + $this->db->where($where); + $this->db->update($table, $data); + $this->db->trans_complete(); + // return $this->db->affected_rows(); + // was there any update or error? + if ($this->db->affected_rows() == '1') { + return TRUE; + } else { + // any trans error? + if ($this->db->trans_status() === FALSE) { + return FALSE; + } + return TRUE; + } + } + + function _key_exists($table, $where) + { + $this->db->where($where); + $this->db->from($table); + return $this->db->count_all_results(); + } + + function _delete_key($table, $where) + { + $this->db->where($where); + $this->db->delete($table); + return $this->db->affected_rows(); + } + + function _total($table) + { + $sql = "select count(*) cnt from $table"; + $query = $this->db->query($sql); + if (($query->row_array()) == null) { + return 0; + } else { + $result = $query->result_array(); + return $result[0]->cnt; + } + } + + function total($table, $field, $keyword) + { + $sql = "select count(*) numrows from $table where $field like '%$keyword%' "; + $query = $this->db->query($sql); + if (($query->row_array()) == null) { + return 0; + } else { + $result = $query->result_array(); + return $result; + } + } + + /************************ + * 数据库操作模型部分结束 + ***********************/ + + /************************ + * 权限模型部分 + ***********************/ + + /** 根据perm_type 获取关联的基础表名称 + * @return array + */ + function getBaseTable($perm_type) + { + $sql = "select r_table from sys_perm_type where type = '" . $perm_type . "'"; + $query = $this->db->query($sql); + return $query->result_array(); + } + + /** + * 根据token, perm_type 获取 perm_id,perm_type,r_id + * @return array + */ + function getPerm($basetable, $token, $perm_type, $menuCtrl) + { + $hasCtrl = $menuCtrl ? "" : " WHERE basetbl.type != 2"; + + $sql = "SELECT + DISTINCT t.id perm_id, + basetbl.* + FROM + ( + SELECT + p.* + FROM + sys_user_token ut, + sys_user_role ur, + sys_role_perm rp, + sys_perm p, + sys_role r + WHERE + ut.token = '" . $token . "' + AND ur.user_id = ut.user_id + AND rp.role_id = ur.role_id + AND p.id = rp.perm_id + AND r.id = ur.role_id + AND r.status=1 + AND p.perm_type = '" . $perm_type . "' + ) t + LEFT JOIN " . $basetable . " basetbl ON t.r_id = basetbl.id" . $hasCtrl . " order by basetbl.listorder"; + + $query = $this->db->query($sql); + return $query->result_array(); + + } + + function getCtrlPerm($token) + { + $sql = "SELECT + basetbl.path + FROM + ( + SELECT + p.* + FROM + sys_user_token ut, + sys_user_role ur, + sys_role_perm rp, + sys_perm p, + sys_role r + WHERE + ut.token = '" . $token . "' + AND ur.user_id = ut.user_id + AND rp.role_id = ur.role_id + AND p.id = rp.perm_id + AND r.id = ur.role_id + AND r.status=1 + AND p.perm_type = 'menu' + ) t + LEFT JOIN sys_menu basetbl ON t.r_id = basetbl.id + WHERE basetbl.type = 2"; + + $query = $this->db->query($sql); + return $query->result_array(); + } + + + /** + * 判断 token 是否过期 + * // 50008:非法的token; 50012:其他客户端登录了; 50014:Token 过期了; + */ + function TokenExpired($token) + { + $sql = "SELECT + * + FROM + `sys_user_token` + WHERE + token = '$token'"; + $query = $this->db->query($sql); + $Arr = $query->result_array(); + if (empty($Arr)) { + return ['code' => 50008, 'message' => "非法的token"]; + } + + $now = time(); + if ($now > $Arr[0]['expire_time']) { + return ['code' => 50014, 'message' => "Token 过期了"]; + } + + // TODO: 当token合法时,自动续期? + $update_time = time(); + $expire_time = $update_time + 2 * 60 * 60; // 2小时过期 + $data = [ + 'expire_time' => $expire_time, + 'last_update_time' => $update_time + ]; + $this->_update_key('sys_user_token', $data, ['token' => $token]); + + return ['code' => 20000, 'message' => "Token 合法"]; + } + + /*********************** + * 权限模型部分结束 + ***********************/ + + /************************ + * 菜单模型部分 + ************************/ + + /** + * 菜单是否拥有子节点 + */ + function hasChildMenu($id) + { + $sql = "SELECT getChildLst(" . $id . ") children"; + $query = $this->db->query($sql); + // var_dump($query->result_array()[0]["children"]); + // string(14) "$,2,5,6,8,9,10" + $array = explode(",", $query->result_array()[0]["children"]); + + if (count($array) > 2) { + return true; + } else { + return false; + } + } + + /*********************** + * 菜单模型部分结束 + ***********************/ +} \ No newline at end of file diff --git a/models/Base_model.php b/models/Base_model.php new file mode 100644 index 0000000..de039f7 --- /dev/null +++ b/models/Base_model.php @@ -0,0 +1,261 @@ +load->database(); + } + + /************************ + * 数据库操作模型部分 + ***********************/ + + /** + * 获取值 + * $table: 表名 + * $select: 查找项, $select = '*' 或 $select = 'id,title' + * $where: 条件项 $where= 'id=1' 或 $where = 'id=1 and title="blah"' + * $order: $order = 'id desc' + * 返回值是数组 + */ + function _get_key($table, $select = '', $where = '', $order = '') + { + if ($select) { + $this->db->select($select); + } + if ($where) { + $this->db->where($where); + } + if ($order) { + $this->db->order_by($order); + } + + $query = $this->db->get($table); + return $query->result_array(); + } + + function _insert_key($table, $data) + { + $this->db->insert($table, $data); + // 如果$table没有配置自增主键,则insert_id返回值为0 + return $this->db->insert_id(); + } + + // TODO: 更新错误判断 https://stackoverflow.com/questions/20030642/check-if-db-update-successful-with-codeigniter-when-potentially-no-rows-are-upd + function _update_key($table, $data, $where) + { + $this->db->trans_start(); + $this->db->where($where); + $this->db->update($table, $data); + $this->db->trans_complete(); + // return $this->db->affected_rows(); + // was there any update or error? + if ($this->db->affected_rows() == '1') { + return TRUE; + } else { + // any trans error? + if ($this->db->trans_status() === FALSE) { + return FALSE; + } + return TRUE; + } + } + + function _key_exists($table, $where) + { + $this->db->where($where); + $this->db->from($table); + return $this->db->count_all_results(); + } + + function _delete_key($table, $where) + { + $this->db->where($where); + $this->db->delete($table); + return $this->db->affected_rows(); + } + + function _total($table) + { + $sql = "select count(*) cnt from $table"; + $query = $this->db->query($sql); + if (($query->row_array()) == null) { + return 0; + } else { + $result = $query->result_array(); + return $result[0]->cnt; + } + } + + function total($table, $field, $keyword) + { + $sql = "select count(*) numrows from $table where $field like '%$keyword%' "; + $query = $this->db->query($sql); + if (($query->row_array()) == null) { + return 0; + } else { + $result = $query->result_array(); + return $result; + } + } + + /************************ + * 数据库操作模型部分结束 + ***********************/ + + /************************ + * 权限模型部分 + ***********************/ + + /** 根据perm_type 获取关联的基础表名称 + * @return array + */ + function getBaseTable($perm_type) + { + $sql = "select r_table from sys_perm_type where type = '" . $perm_type . "'"; + $query = $this->db->query($sql); + return $query->result_array(); + } + + /** + * 根据token, perm_type 获取 perm_id,perm_type,r_id + * @return array + */ + function getPerm($basetable, $token, $perm_type, $menuCtrl) + { + $hasCtrl = $menuCtrl ? "" : " WHERE basetbl.type != 2"; + + $sql = "SELECT + DISTINCT t.id perm_id, + basetbl.* + FROM + ( + SELECT + p.* + FROM + sys_user_token ut, + sys_user_role ur, + sys_role_perm rp, + sys_perm p, + sys_role r + WHERE + ut.token = '" . $token . "' + AND ur.role_id = ut.role_id + AND rp.role_id = ur.role_id + AND p.id = rp.perm_id + AND r.id = ur.role_id + AND r.status=1 + AND p.perm_type = '" . $perm_type . "' + ) t + LEFT JOIN " . $basetable . " basetbl ON t.r_id = basetbl.id" . $hasCtrl . " order by basetbl.listorder"; + + $query = $this->db->query($sql); + return $query->result_array(); + + } + + function getCtrlPerm($token) + { + $sql = "SELECT + basetbl.path + FROM + ( + SELECT + DISTINCT p.* + FROM + sys_user_token ut, + sys_user_role ur, + sys_role_perm rp, + sys_perm p, + sys_role r + WHERE + ut.token = '" . $token . "' + AND ur.role_id = ut.role_id + AND rp.role_id = ur.role_id + AND p.id = rp.perm_id + AND r.id = ur.role_id + AND r.status=1 + AND p.perm_type = 'menu' + ) t + LEFT JOIN sys_menu basetbl ON t.r_id = basetbl.id + WHERE basetbl.type = 2"; + + $query = $this->db->query($sql); + return $query->result_array(); + } + + + /** + * 判断 token 是否过期 + * // 50008:非法的token; 50012:其他客户端登录了; 50014:Token 过期了; + */ + function TokenExpired($token) + { + $sql = "SELECT + * + FROM + `sys_user_token` + WHERE + token = '$token'"; + $query = $this->db->query($sql); + $Arr = $query->result_array(); + if (empty($Arr)) { + return ['code' => 50008, 'message' => "非法的token"]; + } + + $now = time(); + if ($now > $Arr[0]['expire_time']) { + return ['code' => 50014, 'message' => "Token 过期了"]; + } + + // TODO: 当token合法时,到期前30分钟内如果有操作,则自动续期,可减少插入次数? + if (($Arr[0]['expire_time'] - $now) < 0.5 * 60 * 60) { + $expire_time = $now + 2 * 60 * 60; // 2小时过期 + $data = [ + 'expire_time' => $expire_time, + 'last_update_time' => $now + ]; + $this->_update_key('sys_user_token', $data, ['token' => $token]); + } + + return ['code' => 20000, 'message' => "Token 合法"]; + } + + + + /*********************** + * 权限模型部分结束 + ***********************/ + + /************************ + * 菜单模型部分 + ************************/ + + /** + * 菜单是否拥有子节点 + */ + function hasChildMenu($id) + { + $sql = "SELECT getChildLst(" . $id . ") children"; + $query = $this->db->query($sql); + // var_dump($query->result_array()[0]["children"]); + // string(14) "$,2,5,6,8,9,10" + $array = explode(",", $query->result_array()[0]["children"]); + + if (count($array) > 2) { + return true; + } else { + return false; + } + } + + /*********************** + * 菜单模型部分结束 + ***********************/ +} \ No newline at end of file diff --git a/models/Breeding_plan_model.php b/models/Breeding_plan_model.php new file mode 100644 index 0000000..84775c3 --- /dev/null +++ b/models/Breeding_plan_model.php @@ -0,0 +1,23 @@ +db->select('count(*) as count'); + $this->db->from($this->table); + $this->db->where('user_id', $user_id); + $list = $this->db->get()->row_array(); + return $list['count']; + } + +} diff --git a/models/Cat_disease_desc_model.php b/models/Cat_disease_desc_model.php new file mode 100644 index 0000000..6d770d4 --- /dev/null +++ b/models/Cat_disease_desc_model.php @@ -0,0 +1,550 @@ +[ + '检测项目'=>'原发性青光眼', + '检测手段'=>'Sanger 测序', + '基因型'=>'CTCC/CTCCCTCC', + '检测结果'=>[ + 'N/N'=>'无目标突变导致的遗传患病风险', + 'N/F'=>'杂合突变', + 'F/F'=>'纯合突变', + ], + '结果说明'=>[ + 'N/N'=>'不携带突变基因。不会患病,也不会传递给下一代', + 'N/F'=>'携带一份突变基因。不会患原发性青光眼,但会传递给一半的后代', + 'F/F'=>'携带两份突变基因。患病严重', + ] + ], + '先天性肌无力'=>[ + '检测项目'=>'先天性肌无力', + '检测手段'=>'Sanger 测序', + '基因型'=>'C/T', + '检测结果'=>[ + 'N/N'=>'无目标突变导致的遗传患病风险', + 'N/F'=>'杂合突变', + 'F/F'=>'纯合突变', + ], + '结果说明'=>[ + 'N/N'=>'不携带突变基因。不会患病,也不会传递给下一代', + 'N/F'=>'携带一份突变基因。不会患先天性肌无力,但会传递给一半的后代', + 'F/F'=>'携带两份突变基因。患病严重', + ] + ], + '糖原贮积病IV型'=>[ + '检测项目'=>'糖原贮积病IV型', + '检测手段'=>'Sanger 测序', + '基因型'=>'无6.2Kb缺失和334bp插入/ 6.2Kb缺失和334bp插入', + '检测结果'=>[ + 'N/N'=>'无目标突变导致的遗传患病风险', + 'N/F'=>'杂合突变', + 'F/F'=>'纯合突变', + ], + '结果说明'=>[ + 'N/N'=>'不携带突变基因。不会患病,也不会传递给下一代', + 'N/F'=>'携带一份突变基因。不会出现糖原贮积病症状,但会传递给一半的后代', + 'F/F'=>'携带两份突变基因。患病严重', + ] + ], + '低钾血症'=>[ + '检测项目'=>'低钾血症', + '检测手段'=>'Sanger 测序', + '基因型'=>'C/ T', + '检测结果'=>[ + 'N/N'=>'无目标突变导致的遗传患病风险', + 'N/F'=>'杂合突变', + 'F/F'=>'纯合突变', + ], + '结果说明'=>[ + 'N/N'=>'不携带突变基因。不会患病,也不会传递给下一代', + 'N/F'=>'携带一份突变基因。不会患低钾血症,但会传递给一半的后代', + 'F/F'=>'携带两份突变基因。患病严重', + ] + ], + '视网膜萎缩症'=>[ + '检测项目'=>'视网膜萎缩症', + '检测手段'=>'Sanger 测序', + '基因型'=>'A/C', + '检测结果'=>[ + 'N/N'=>'无目标突变导致的遗传患病风险', + 'N/F'=>'杂合突变', + 'F/F'=>'纯合突变', + ], + '结果说明'=>[ + 'N/N'=>'不携带突变基因。不会患病,也不会传递给下一代', + 'N/F'=>'携带一份突变基因。不会患视网膜萎缩症,但会传递给一半的后代', + 'F/F'=>'携带两份突变基因。视网膜萎缩严重', + ] + ], + '丙酮酸激酶缺乏症'=>[ + '检测项目'=>'丙酮酸激酶缺乏症', + '检测手段'=>'Sanger 测序', + '基因型'=>'G/A', + '检测结果'=>[ + 'N/N'=>'无目标突变导致的遗传患病风险', + 'N/F'=>'杂合突变', + 'F/F'=>'纯合突变', + ], + '结果说明'=>[ + 'N/N'=>'不携带突变基因。不会患病,也不会传递给下一代', + 'N/F'=>'携带一份突变基因。不会出现丙酮酸激酶缺乏症症状,但会传递给一半的后代', + 'F/F'=>'携带两份突变基因。丙酮酸激酶缺乏症症状严重', + ] + ], + '肥厚性心肌病'=>[ + '检测项目'=>'肥厚性心肌病', + '检测手段'=>'Sanger 测序', + '基因型'=>' +C/G(p.A31P) +G/A(p.R820W', + '检测结果'=>[ + 'N/N'=>'无目标突变导致的遗传患病风险', + 'N/F'=>'杂合突变', + 'F/F'=>'纯合突变', + ], + '结果说明'=>[ + 'N/N'=>'不携带突变基因。不会患病,也不会传递给下一代', + 'N/F'=>'携带一份突变基因。可能会出现一定程度的肥厚性心肌病的症状,会传递给一半的后代', + 'F/F'=>'携带两份突变基因。心肌肥厚症状严重', + ] + ], + 'GM1神经节苷脂沉积症'=>[ + '检测项目'=>'GM1神经节苷脂沉积症', + '检测手段'=>'Sanger 测序', + '基因型'=>'C/G', + '检测结果'=>[ + 'N/N'=>'无目标突变导致的遗传患病风险', + 'N/F'=>'杂合突变', + 'F/F'=>'纯合突变', + ], + '结果说明'=>[ + 'N/N'=>'不携带突变基因。不会患病,也不会传递给下一代', + 'N/F'=>'携带一份突变基因。不会出现GM1神经节苷脂累积病的症状,但会传递给一半的后代', + 'F/F'=>'携带两份突变基因。GM1神经节苷脂累积病症状严重', + ] + ], + '多囊肾病'=>[ + '检测项目'=>'多囊肾病', + '检测手段'=>'Sanger 测序', + '基因型'=>'C/A', + '检测结果'=>[ + 'N/N'=>'无目标突变导致的遗传患病风险', + 'N/F'=>'杂合突变', + 'F/F'=>'纯合突变', + ], + '结果说明'=>[ + 'N/N'=>'不携带突变基因。不会患病,也不会传递给下一代', + 'N/F'=>'携带一份突变基因。患多囊肾病,会传递给一半的后代', + 'F/F'=>'携带两份突变基因。多囊肾病症状严重', + ] + ], + '折耳和软骨发育不良'=>[ + '检测项目'=>'折耳和软骨发育不良', + '检测手段'=>'Sanger 测序', + '基因型'=>'G/T', + '检测结果'=>[ + 'N/N'=>'无目标突变导致的遗传患病风险', + 'N/F'=>'杂合突变', + 'F/F'=>'纯合突变', + ], + '结果说明'=>[ + 'N/N'=>': 立耳,不携带突变基因。不会患病,也不会传递给下一代', + 'N/F'=>': 折耳,携带一份突变基因。会传递给一半的后代', + 'F/F'=>': 折耳,携带两份突变基因。可能带有严重软骨发育不良症', + ] + ], + '脊髓肌肉萎缩'=>[ + '检测项目'=>'脊髓肌肉萎缩', + '检测手段'=>'Sanger 测序', + '基因型'=>'无140kb缺失/ 140kb缺失', + '检测结果'=>[ + 'N/N'=>'无目标突变导致的遗传患病风险', + 'N/F'=>'杂合突变', + 'F/F'=>'纯合突变', + ], + '结果说明'=>[ + 'N/N'=>'不携带突变基因。不会患病,也不会传递给下一代', + 'N/F'=>'携带一份突变基因。不会出现脊髓肌肉萎缩症状,但会传递给一半的后代', + 'F/F'=>'携带两份突变基因。脊髓肌肉萎缩严重', + ] + ], + 'GM2神经节苷脂沉积症'=>[ + '检测项目'=>'GM2神经节苷脂沉积症', + '检测手段'=>'Sanger 测序', + '基因型'=>'TAATGTAGGTTCTCA / -(intron11exon1215bp_del) +TACTGGATATTGTGACTATGAATAC/inr(c.1467_1491inv) +GACC/-(del GACC', + '检测结果'=>[ + 'N/N'=>'无目标突变导致的遗传患病风险', + 'N/F'=>'杂合突变', + 'F/F'=>'纯合突变', + ], + '结果说明'=>[ + 'N/N'=>'不携带突变基因。不会患病,也不会传递给下一代', + 'N/F'=>'携带一份突变基因。不会出现GM2神经节苷脂沉积症症状,但会传递给一半的后代', + 'F/F'=>'携带两份突变基因。GM2神经节苷脂沉积症症状严重', + ] + ], + '急性间歇性卟啉症'=>[ + '检测项目'=>'急性间歇性卟啉症', + '检测手段'=>'Sanger 测序', + '基因型'=>'ACAG / -(c.107_110delACAG) +G/A(c.826-1G>A) +-/-(c.189dupT) +GAG/-(c.844delGAG', + '检测结果'=>[ + 'N/N'=>'无目标突变导致的遗传患病风险', + 'N/F'=>'杂合突变', + 'F/F'=>'纯合突变', + ], + '结果说明'=>[ + 'N/N'=>'不携带突变基因。不会患病,也不会传递给下一代', + 'N/F'=>'携带一份突变基因。患有急性间歇性卟啉症,会传递给一半的后代', + 'F/F'=>'携带两份突变基因。急性间歇性卟啉症症状严重', + ] + ], + '凝血因子XII缺乏症'=>[ + '检测项目'=>'凝血因子XII缺乏症', + '检测手段'=>'Sanger 测序', + '基因型'=>' G / C', + '检测结果'=>[ + 'N/N'=>'无目标突变导致的遗传患病风险', + 'N/F'=>'杂合突变', + 'F/F'=>'纯合突变', + ], + '结果说明'=>[ + 'N/N'=>'不携带突变基因。不会患病,也不会传递给下一代', + 'N/F'=>'携带一份突变基因。不会出现凝血因子XII缺乏症症状,但会传递给一半的后代', + 'F/F'=>'携带两份突变基因。凝血因子XII缺乏症症状严重', + ] + ], + '先天性红细胞生成性卟啉症'=>[ + '检测项目'=>'先天性红细胞生成性卟啉症', + '检测手段'=>'Sanger 测序', + '基因型'=>' +G / A(c.140C>T) +C/T(c. 331G>A', + '检测结果'=>[ + 'N/N'=>'无目标突变导致的遗传患病风险', + 'N/F'=>'杂合突变', + 'F/F'=>'纯合突变', + ], + '结果说明'=>[ + 'N/N'=>'不携带突变基因。不会患病,也不会传递给下一代', + 'N/F'=>'携带一份突变基因。不会出现先天性红细胞生成性卟啉症症状,但会传递给一半的后代', + 'F/F'=>'携带两份突变基因。先天性红细胞生成性卟啉症症状严重', + ] + ], + '自身免疫性淋巴细胞增生综合症'=>[ + '检测项目'=>'自身免疫性淋巴细胞增生综合症', + '检测手段'=>'Sanger 测序', + '基因型'=>'-/A(c.413_414insA', + '检测结果'=>[ + 'N/N'=>'无目标突变导致的遗传患病风险', + 'N/F'=>'杂合突变', + 'F/F'=>'纯合突变', + ], + '结果说明'=>[ + 'N/N'=>'不携带突变基因。不会患病,也不会传递给下一代', + 'N/F'=>'携带一份突变基因。不会患自身免疫性淋巴细胞增生综合症,但会传递给一半的后代', + 'F/F'=>'携带两份突变基因。自身免疫性淋巴细胞增生综合症症状严重', + ] + ], + '头部缺陷'=>[ + '检测项目'=>'头部缺陷', + '检测手段'=>'Sanger 测序', + '基因型'=>'CTCTCAGGACTG/-', + '检测结果'=>[ + 'N/N'=>'无目标突变导致的遗传患病风险', + 'N/F'=>'杂合突变', + 'F/F'=>'纯合突变', + ], + '结果说明'=>[ + 'N/N'=>'不携带突变基因。不会患病,也不会传递给下一代', + 'N/F'=>'携带一份突变基因。出现一定程度的头部缺陷症状,会传递给一半的后代', + 'F/F'=>'携带两份突变基因。头部缺陷症状严重', + ] + ], + '高乳糜微粒血症'=>[ + '检测项目'=>'高乳糜微粒血症', + '检测手段'=>'Sanger 测序', + '基因型'=>'C/T', + '检测结果'=>[ + 'N/N'=>'无目标突变导致的遗传患病风险', + 'N/F'=>'杂合突变', + 'F/F'=>'纯合突变', + ], + '结果说明'=>[ + 'N/N'=>'不携带突变基因。不会患病,也不会传递给下一代', + 'N/F'=>'携带一份突变基因。不会出现乳糜微粒血症症状,但会传递给一半的后代', + 'F/F'=>'携带两份突变基因。高乳糜微粒血症症状严重', + ] + ], + '先天性肾上腺增生'=>[ + '检测项目'=>'先天性肾上腺增生', + '检测手段'=>'Sanger 测序', + '基因型'=>'G/A', + '检测结果'=>[ + 'N/N'=>'无目标突变导致的遗传患病风险', + 'N/F'=>'杂合突变', + 'F/F'=>'纯合突变', + ], + '结果说明'=>[ + 'N/N'=>'不携带突变基因。不会患病,也不会传递给下一代', + 'N/F'=>'携带一份突变基因。不会出现先天性肾上腺增生,但会传递给一半的后代', + 'F/F'=>'携带两份突变基因。先天性肾上腺增生严重', + ] + ], + '预期寿命较短的先天性少毛症'=>[ + '检测项目'=>'预期寿命较短的先天性少毛症', + '检测手段'=>'Sanger 测序', + '基因型'=>'ACAG/-', + '检测结果'=>[ + 'N/N'=>'无目标突变导致的遗传患病风险', + 'N/F'=>'杂合突变', + 'F/F'=>'纯合突变', + ], + '结果说明'=>[ + 'N/N'=>'不携带突变基因。不会患病,也不会传递给下一代', + 'N/F'=>'携带一份突变基因。不会出现预期寿命较短的先天性少毛症症状,但会传递给一半的后代', + 'F/F'=>'携带两份突变基因。预期寿命较短的先天性少毛症症状严重', + ] + ], + '胱氨酸尿症'=>[ + '检测项目'=>'胱氨酸尿症', + '检测手段'=>'Sanger 测序', + '基因型'=>' +C/T(c.1342C>T) +A/G(c.1846A>G) +C/T(c.1175C>T) +G/A(c.706G>A) +T/A(c.881T>A', + '检测结果'=>[ + 'N/N'=>'无目标突变导致的遗传患病风险', + 'N/F'=>'杂合突变', + 'F/F'=>'纯合突变', + ], + '结果说明'=>[ + 'N/N'=>'不携带突变基因。不会患病,也不会传递给下一代', + 'N/F'=>'携带一份突变基因。患胱氨酸尿症,会传递给一半的后代', + 'F/F'=>'携带两份突变基因。胱氨酸尿症症状严重', + ] + ], + '二氢嘧啶酶缺陷症'=>[ + '检测项目'=>'二氢嘧啶酶缺陷症', + '检测手段'=>'Sanger 测序', + '基因型'=>'C/T', + '检测结果'=>[ + 'N/N'=>'无目标突变导致的遗传患病风险', + 'N/F'=>'杂合突变', + 'F/F'=>'纯合突变', + ], + '结果说明'=>[ + 'N/N'=>'不携带突变基因。不会患病,也不会传递给下一代', + 'N/F'=>'携带一份突变基因。不会出现二氢嘧啶酶缺陷症症状,但会传递给一半的后代', + 'F/F'=>'携带两份突变基因。二氢嘧啶酶缺陷症症状严重', + ] + ], + '乙型血友病'=>[ + '检测项目'=>'乙型血友病', + '检测手段'=>'Sanger 测序', + '基因型'=>' +C/T(c.1014C>T) +G/A(c.247G>A', + '检测结果'=>[ + 'N/N'=>'无目标突变导致的遗传患病风险', + 'N/F'=>'杂合突变', + 'F/F'=>'纯合突变', + ], + '结果说明'=>[ + 'N/N'=>'不携带突变基因。不会患病,也不会传递给下一代', + 'N/F'=>'携带一份突变基因。可能出现乙型血友病症状,会传递给一半的后代', + 'F/F'=>'携带两份突变基因。乙型血友病症状严重', + ] + ], + '高草酸尿症'=>[ + '检测项目'=>'高草酸尿症', + '检测手段'=>'Sanger 测序', + '基因型'=>'G/A', + '检测结果'=>[ + 'N/N'=>'无目标突变导致的遗传患病风险', + 'N/F'=>'杂合突变', + 'F/F'=>'纯合突变', + ], + '结果说明'=>[ + 'N/N'=>'不携带突变基因。不会患病,也不会传递给下一代', + 'N/F'=>'携带一份突变基因。不会出现高草酸尿症症状,但会传递给一半的后代', + 'F/F'=>'携带两份突变基因。高草酸尿症症状严重', + ] + ], + '黏多糖贮积症I型'=>[ + '检测项目'=>'黏多糖贮积症I型', + '检测手段'=>'Sanger 测序', + '基因型'=>'TCG/-', + '检测结果'=>[ + 'N/N'=>'无目标突变导致的遗传患病风险', + 'N/F'=>'杂合突变', + 'F/F'=>'纯合突变', + ], + '结果说明'=>[ + 'N/N'=>'不携带突变基因。不会患病,也不会传递给下一代', + 'N/F'=>'携带一份突变基因。不会出现黏多糖贮积症症状,但会传递给一半的后代', + 'F/F'=>'携带两份突变基因。黏多糖贮积症症状严重', + ] + ], + '黏多糖贮积症VI型'=>[ + '检测项目'=>'黏多糖贮积症VI型', + '检测手段'=>'Sanger 测序', + '基因型'=>'T/C', + '检测结果'=>[ + 'N/N'=>'无目标突变导致的遗传患病风险', + 'N/F'=>'杂合突变', + 'F/F'=>'纯合突变', + ], + '结果说明'=>[ + 'N/N'=>'不携带突变基因。不会患病,也不会传递给下一代', + 'N/F'=>'携带一份突变基因。不会出现黏多糖贮积症症状,但会传递给一半的后代', + 'F/F'=>'携带两份突变基因。黏多糖贮积症症状严重', + ] + ], + '黏多糖贮积症VII型'=>[ + '检测项目'=>'黏多糖贮积症VII型', + '检测手段'=>'Sanger 测序', + '基因型'=>'G/A(c.1051G>A) +C/T(c.C1424T) +T/G(c.1421T>G', + '检测结果'=>[ + 'N/N'=>'无目标突变导致的遗传患病风险', + 'N/F'=>'杂合突变', + 'F/F'=>'纯合突变', + ], + '结果说明'=>[ + 'N/N'=>'不携带突变基因。不会患病,也不会传递给下一代', + 'N/F'=>'携带一份突变基因。不会出现黏多糖贮积症症状,但会传递给一半的后代', + 'F/F'=>'携带两份突变基因。黏多糖贮积症症状严重', + ] + ], + '先天性肌强直'=>[ + '检测项目'=>'先天性肌强直', + '检测手段'=>'Sanger 测序', + '基因型'=>'G/T', + '检测结果'=>[ + 'N/N'=>'无目标突变导致的遗传患病风险', + 'N/F'=>'杂合突变', + 'F/F'=>'纯合突变', + ], + '结果说明'=>[ + 'N/N'=>'不携带突变基因。不会患病,也不会传递给下一代', + 'N/F'=>'携带一份突变基因。有可能出现先天性肌强直症状,会传递给一半的后代', + 'F/F'=>'携带两份突变基因。先天性肌强直症状严重', + ] + ], + 'C1型尼曼匹克氏病'=>[ + '检测项目'=>'C1型尼曼匹克氏病', + '检测手段'=>'Sanger 测序', + '基因型'=>'C/G', + '检测结果'=>[ + 'N/N'=>'无目标突变导致的遗传患病风险', + 'N/F'=>'杂合突变', + 'F/F'=>'纯合突变', + ], + '结果说明'=>[ + 'N/N'=>'不携带突变基因。不会患病,也不会传递给下一代', + 'N/F'=>'携带一份突变基因。不会出现尼曼-匹克式 C1病症状,但会传递给一半的后代', + 'F/F'=>'携带两份突变基因。尼曼-匹克式 C1病症状严重', + ] + ], + 'C2型尼曼匹克氏病'=>[ + '检测项目'=>'C2型尼曼匹克氏病', + '检测手段'=>'Sanger 测序', + '基因型'=>'C/T', + '检测结果'=>[ + 'N/N'=>'无目标突变导致的遗传患病风险', + 'N/F'=>'杂合突变', + 'F/F'=>'纯合突变', + ], + '结果说明'=>[ + 'N/N'=>'不携带突变基因。不会患病,也不会传递给下一代', + 'N/F'=>'携带一份突变基因。不会出现尼曼-匹克式C2病症状,但会传递给一半的后代', + 'F/F'=>'携带两份突变基因。尼曼-匹克式C2病症状严重', + ] + ], + '维生素D依赖性佝偻病'=>[ + '检测项目'=>'维生素D依赖性佝偻病', + '检测手段'=>'Sanger 测序', + '基因型'=>'C/A', + '检测结果'=>[ + 'N/N'=>'无目标突变导致的遗传患病风险', + 'N/F'=>'杂合突变', + 'F/F'=>'纯合突变', + ], + '结果说明'=>[ + 'N/N'=>'不携带突变基因。不会患病,也不会传递给下一代', + 'N/F'=>'携带一份突变基因。不会出现维生素D依赖性佝偻病症状,但会传递给一半的后代', + 'F/F'=>'携带两份突变基因。维生素D依赖性佝偻病症状严重', + ] + ], + '渐进性视网膜萎缩'=>[ + '检测项目'=>'渐进性视网膜萎缩', + '检测手段'=>'Sanger 测序', + '基因型'=>'AG/-', + '检测结果'=>[ + 'N/N'=>'无目标突变导致的遗传患病风险', + 'N/F'=>'杂合突变', + 'F/F'=>'纯合突变', + ], + '结果说明'=>[ + 'N/N'=>'不携带突变基因。不会患病,也不会传递给下一代', + 'N/F'=>'携带一份突变基因。不会出现渐进性视网膜萎缩,但会传递给一半的后代', + 'F/F'=>'携带两份突变基因。渐进性视网膜萎缩严重', + ] + ], + '白细胞粘附缺陷症Ⅰ型'=>[ + '检测项目'=>'白细胞粘附缺陷症Ⅰ型', + '检测手段'=>'Sanger 测序', + '基因型'=>'GCCCTCTGGTCCGGTGAGTTCCGC/-', + '检测结果'=>[ + 'N/N'=>'无目标突变导致的遗传患病风险', + 'N/F'=>'杂合突变', + 'F/F'=>'纯合突变', + ], + '结果说明'=>[ + 'N/N'=>'不携带突变基因。不会患病,也不会传递给下一代', + 'N/F'=>'携带一份突变基因。不会患白细胞黏附缺陷症Ⅰ型,但会传递给一半的后代', + 'F/F'=>'携带两份突变基因。白细胞黏附缺陷症症状严重', + ] + ], + '炎性线性疣状表皮痣'=>[ + '检测项目'=>'炎性线性疣状表皮痣', + '检测手段'=>'Sanger 测序', + '基因型'=>'A/G', + '检测结果'=>[ + 'N/N'=>'无目标突变导致的遗传患病风险', + 'N/F'=>'杂合突变', + 'F/F'=>'纯合突变', + ], + '结果说明'=>[ + 'N/N'=>'不携带突变基因。不会患病,也不会传递给下一代', + 'N/F'=>'携带一份突变基因。会炎性线性疣状表皮痣,也会传递给一半的后代', + 'F/F'=>'携带两份突变基因。炎性线性疣状表皮痣症状严重', + ] + ] + + ]; + + function breeding_single_detail($name) + { + if(!isset($this->list[$name])){ + return []; + } + return $this->list[$name]; + } + + +} diff --git a/models/Customer_model.php b/models/Customer_model.php new file mode 100644 index 0000000..7998876 --- /dev/null +++ b/models/Customer_model.php @@ -0,0 +1,54 @@ + $data['openid'], + 'unionid' => $data['unionid'], + 'nickname' => $data['nickname'], + 'sex' => $data['sex'], + 'language' => $data['language'], + 'city' => $data['city'], + 'province' => $data['province'], + 'country' => $data['country'], + 'headimgurl' => $data['headimgurl'], + 'is_server' => isset($data['is_server'])?$data['is_server']:0, + 'update_time' => time() + ); + $row = $this->get($data['unionid'], 'unionid'); + if ($row) { + // 更新操作 + $data['update_time'] = time(); + $this->db->where('id', $row['id']); + $this->db->update('user', $data); + return $row['id']; + } else { + //新增操作 + $data['create_time'] = $data['update_time'] = time(); + $this->db->insert('user', $data); + return $this->db->insert_id(); + } + } catch (Exception $ex) { + return FALSE; + } + } +} + diff --git a/models/Dept_model.php b/models/Dept_model.php new file mode 100644 index 0000000..e6f1e66 --- /dev/null +++ b/models/Dept_model.php @@ -0,0 +1,48 @@ +load->database(); + } + + /** + * 获取所有机构列表 + */ + function getDeptList() + { + $sql = "SELECT + d.id, + d.pid, + d.name, + d.aliasname, + d.listorder, + d.status + FROM + sys_dept d + ORDER BY + d.listorder"; + $query = $this->db->query($sql); + return $query->result_array(); + } + + /** + * @param $Id + * @return bool + * 含有子节点返回真 + */ + function hasChildDept($Id){ + $sql ="SELECT * FROM `sys_dept` where pid=" . $Id; + $query = $this->db->query($sql); + if(empty($query->result_array())) { + return FALSE; + } else { + return TRUE; + } + } +} \ No newline at end of file diff --git a/models/Disease_model.php b/models/Disease_model.php new file mode 100644 index 0000000..ee35dd9 --- /dev/null +++ b/models/Disease_model.php @@ -0,0 +1,14 @@ +'uahpet/database/犬/JSON/', + //猫 + 2=>'uahpet/database/猫/JSON/', + ]; + + /** + * __construct function. + * + * @access public + * @return void + */ + public function __construct() { + + parent::__construct(); + //$this->load->database(); + + } + + //报告路径 + public function report_file_path($deviceID,$petSpecies=1){ + $path = $petSpecies == 1?self::DIR_REPORT_DATA:self::DIR_REPORT_DATA_CAT; + return APPPATH.$path.($deviceID).'.json'; + } + + //报告路径 + public function get_report_json($deviceID,$petSpecies=1){ + //报告文件 + $file = $this->report_file_path($deviceID,$petSpecies); + if(!file_exists($file)){ + return []; + } + $reportJson = file_get_contents($file); + return json_decode($reportJson,true); + } + + + //报告是否生成 + public function is_report_ready($deviceID){ + return file_exists( + $this->report_file_path($deviceID) + ); + } + + //获取家族树 + public function family_tree_img($deviceID){ + $file = Report_model::DIR_REPORT_FAMILY_TREE.strtoupper($deviceID).'.jpg'; + if(file_exists(APPPATH.$file)){ + return base_url('views/'.$file); + } + $file = Report_model::DIR_REPORT_DATA.strtoupper($deviceID).'.jpg'; + if(file_exists(APPPATH.$file)){ + return base_url('views/'.$file); + } + return false; + } + + //报告统计 + public function get_report_count() { + + $files = scandir(APPPATH.self::DIR_REPORT_DATA); + $count = 0; + foreach($files as $file){ + if($file === '.' || $file === '..'){ + continue; + } + if(substr($file,-5) === '.json'){ + $count++; + } + } + return $count; + + } + + //素材 + public function get_material($petSpecies=1,$isBreeding=false){ + if(!is_null($this->_material)){ + return $this->_material; + } + //区分繁育版 + $diseaseSingleGene = [ + //狗 + 1=>'犬类单基因疾病', + //猫 + 2=>$isBreeding?'猫类单基因遗传病繁育版':'猫类单基因遗传病', + ]; + //根据报告内容,解析建议文字 + $materialFileName = [ + //狗 + 1=>[ + //'交互式报告素材', + //'猫类单基因疾病', + $diseaseSingleGene[1]=>'单基因疾病', + '犬类单基因疾病医护建议'=>'单基因疾病医护建议', + '犬类复杂疾病'=>'多基因疾病', + '犬类品系'=>'品系', + ], + //猫 + 2=>[ + //'交互式报告素材', + //'猫类单基因疾病', + $diseaseSingleGene[2]=>'单基因疾病', + '猫类单基因疾病医护建议'=>'单基因疾病医护建议', + '猫类复杂疾病'=>'多基因疾病', + '猫品系'=>'品系', + '猫血型'=>'血型', + ], + ]; + //报告素材 + $material = []; + foreach ($materialFileName[$petSpecies] as $name=>$uni_name) { + if(PHP_OS == 'WINNT'){ + $name = iconv('UTF-8','GB2312',$name); + } + //猫没有多基因疾病与医护建议 + if(in_array($name,['猫类单基因疾病医护建议','猫类复杂疾病'])){ + $material[$uni_name] = []; + continue; + } + $_content = file_get_contents(APPPATH.self::DIR_MATERIAL[$petSpecies].$name.'.json'); + $material[$uni_name] = json_decode($_content,true); + } + //猫的品系资料转换 + if($petSpecies == 2){ + foreach ($material['品系'] as $key=>$val) { + $material['品系'][$key]['犬种特点'] = $val['猫种特点']; + } + } + $this->_material = $material; + return $material; + } + + //获取疾病解锁信息 + public function get_disease_unlock($sample=[],$package=[]){ + if(!is_null($this->_disease_unlock)){ + return $this->_disease_unlock; + } + //解锁疾病 + $unlockDisease = []; + if(!empty($package['disease'])){ + $package['disease'] = explode(',',$package['disease']); + $this->load->model('disease_model'); + $unlockDisease = $this->disease_model->get($package['disease'],'base.id',true,'base.name'); + $unlockDisease = array_column($unlockDisease,'name'); + foreach ($unlockDisease as &$item) { + $item = trim($item); + } + } + + //如果样品选择了某个套餐,就直接解锁 + $custom = $this->get_disease_custom($sample); + + + if(!empty($custom['disease_name'])){ + $unlockDisease = array_merge($unlockDisease,$custom['disease_name']); + } + $this->_disease_unlock = $unlockDisease; + return $unlockDisease; + } + + //获取疾病自选信息 + public function get_disease_custom($sample=[]){ + if(!is_null($this->_disease_custom)){ + return $this->_disease_custom; + } + $unlockDisease = []; + if(!empty($sample['package_custom'])){ + $unlockDisease = json_decode($sample['package_custom'],true); + } + $this->_disease_custom = $unlockDisease; + return $this->_disease_custom; + } + + /** + * 获取疾病列表带锁定信息 + * @param $gene_type int 基因类型 1单基因 2多基因 + * @param $sample array 样品资料,需要用它获取选择的疾病 + * @param $report_json array 报告数据文件,用它获取是否已得病 + * @param $package array 套餐数据,获取锁定套餐 + * @param $need_category int 是否需要分类 + * @param $need_detail int 是否需要明细 + * @param $hidden_locked bool 锁定时,是否隐藏明细 + * @return mixed + */ + public function get_disease_list($gene_type=0,$sample=[],$report_json=[],$package=[],$need_category=0,$need_detail=0,$hidden_locked=true){ + $material = $this->get_material($sample['pet_species'],$package['is_breed']); + //区分单基因/多基因 1单基因 2多基因,便于检测不出来时区分显示风险描述 + foreach ($material['单基因疾病'] as $key=>$val) { + $material['单基因疾病'][$key]['gene_type'] = 1; + } + foreach ($material['多基因疾病'] as $key=>$val) { + $material['多基因疾病'][$key]['gene_type'] = 1; + } + if(empty($gene_type)){ + $list = array_merge($material['单基因疾病'],$material['多基因疾病']); + }elseif($gene_type=='1'){ + $list = array_merge($material['单基因疾病']); + }else{ + $list = array_merge($material['多基因疾病']); + } + + + //分类对应 + $map = [ + '代谢类疾病'=>'代谢免疫', + '代谢类遗传病'=>'代谢免疫', + '代谢类遗传疾病'=>'代谢免疫', + '代谢性遗传病'=>'代谢免疫', + '耳科疾病'=>'五官皮肤', + '关节类疾病'=>'内科', + '泌尿生殖系统遗传疾病'=>'内科', + '泌尿系统疾病'=>'内科', + '泌尿系统类遗传疾病'=>'内科', + '泌尿系统遗传病'=>'内科', + '免疫缺陷遗传病'=>'代谢免疫', + '免疫系统遗传病'=>'代谢免疫', + '内分泌系统遗传病'=>'内科', + '皮肤类疾病'=>'五官皮肤', + '皮肤类遗传病'=>'五官皮肤', + '皮肤类肿瘤疾病'=>'五官皮肤', + '皮肤肿瘤疾病'=>'五官皮肤', + '其他遗传疾病'=>'内科', + '神经类遗传病'=>'神经系统', + '神经系统疾病'=>'神经系统', + '神经系统遗传病'=>'神经系统', + '神经系统遗传疾病'=>'神经系统', + '睡眠病'=>'神经系统', + '糖类代谢类遗传疾病'=>'代谢免疫', + '消化系统疾病'=>'内科', + '消化系统遗传病'=>'内科', + '心血管系统疾病'=>'血液心脏', + '心血管系统遗传病'=>'血液心脏', + '血液类遗传病'=>'血液心脏', + '血液类遗传疾病'=>'血液心脏', + '血液淋巴系统疾病'=>'血液心脏', + '血液系统遗传病'=>'血液心脏', + '血液遗传病'=>'血液心脏', + '血液遗传疾病'=>'血液心脏', + '眼科遗传病'=>'五官皮肤', + '药物代谢类遗传疾病'=>'代谢免疫', + '代谢免疫类疾病'=>'代谢免疫', + '遗传性眼病'=>'五官皮肤', + '骨科遗传病'=>'内科', + '骨骼肌肉类疾病'=>'内科', + '骨骼肌肉系统遗传病'=>'内科', + '骨骼肌肉遗传病'=>'内科', + '骨骼类遗传病'=>'内科', + '骨骼类肿瘤疾病'=>'内科', + '骨骼系统遗传病'=>'内科', + '骨骼肌肉类遗传病'=>'内科', + '肌肉骨骼系统遗传病'=>'内科', + '肌肉骨骼类遗传病'=>'内科', + '肌肉类遗传病'=>'内科', + '肌肉系统类遗传病'=>'内科', + '肌肉系统遗传病'=>'内科', + '肌肉遗传病'=>'内科', + ]; + + //猫品系额外处理 + $map_cat = [ + '泌尿生殖系统遗传病'=>'泌尿生殖', + '骨科遗传病'=>'肌肉骨骼', + '骨骼肌肉类疾病'=>'肌肉骨骼', + '骨骼肌肉系统遗传病'=>'肌肉骨骼', + '骨骼肌肉遗传病'=>'肌肉骨骼', + '骨骼类遗传病'=>'肌肉骨骼', + '骨骼类肿瘤疾病'=>'肌肉骨骼', + '骨骼系统遗传病'=>'肌肉骨骼', + '骨骼肌肉类遗传病'=>'肌肉骨骼', + '肌肉骨骼系统遗传病'=>'肌肉骨骼', + '肌肉骨骼类遗传病'=>'肌肉骨骼', + '肌肉类遗传病'=>'肌肉骨骼', + '肌肉系统类遗传病'=>'肌肉骨骼', + '肌肉系统遗传病'=>'肌肉骨骼', + '肌肉遗传病'=>'肌肉骨骼', + ]; + if($sample['pet_species'] == 2){ + $map = array_merge($map,$map_cat); + } + + //锁定疾病,里面已经考虑了套餐选择项 + $unlockDisease = $this->get_disease_unlock($sample,$package); +// var_dump(array_keys($list)); +// var_dump($unlockDisease);die; + + + //是否存在风险 + $riskDisease = $report_json['遗传疾病']['body']['单基因疾病']['body']; + if(isset($report_json['健康风险']['body']['复杂疾病性状']['body'])){ + $riskDisease = array_merge($riskDisease,$report_json['健康风险']['body']['复杂疾病性状']['body']); + } + + $out = []; + foreach ($list as $name=>$val) { + $name = trim($name); + $tmp = [ + //是否锁定 + 'lock'=>!in_array($name,$unlockDisease), + 'name'=>$name, + 'gene_type'=>$val['gene_type'], + 'risk'=>false, + 'risk_detail'=>false, + ]; + //详情 + if($need_detail){ + $tmp['detail'] = $val; + } + + //风险项,没有锁定时才展示 + if((!$hidden_locked || !$tmp['lock']) && isset($riskDisease[$name])){ + $tmp['risk'] = true; + + //区分猫狗,猫没有放body + if($sample['pet_species'] == 2) { + $tmp['risk_detail'] = $riskDisease[$name]; + if($tmp['risk_detail']["检测结果"] == "纯合突变" OR $tmp['risk_detail']["遗传模式"] == "显性遗传"){ + $tmp['risk_level'] = 2; + }else{ + $tmp['risk_level'] = 1; + } + //为“折耳和软骨发育不良”单独判定 + if($name == '折耳和软骨发育不良'){ + if($tmp['risk_detail']["检测结果"] == "纯合突变"){ + $tmp['risk_level'] = 2; + }else{ + $tmp['risk_level'] = 1; + } + } + }else{ + $tmp['risk_detail'] = $riskDisease[$name]['body']; + //风险等级 + switch ($tmp['risk_detail']['检测结果']) { + case '患病': + case '中等风险': + case '高风险': + case '有极高的发病风险'://风险解读 + $tmp['risk_level'] = 2; + break; + case '携带致病突变': + case '普通风险': + case '低风险': + case '低发病风险'://风险解读 + $tmp['risk_level'] = 1; + break; + } + } + } + + //是否分类 + if(!empty($need_category)){ + //部分素材不是疾病,是禁用药物罗列 + if(empty($val['所属类别'])){ + continue; + } + if(empty($map[$val['所属类别']])){ + continue; + } + $out[$map[$val['所属类别']]][] = $tmp; + }else{ + $out[] = $tmp; + } + } + + return $out; + } + + //拼装报告结构 + public function get_result($deviceID,$ignoreStep=false){ + //样品及套餐信息 + $this->load->model('sample_model'); + $this->load->model('package_model'); + $sample = $this->sample_model->get($deviceID,'device_id'); + if(!$sample){ + return []; + } + //样品未完成是否返回 + if(!$ignoreStep && $sample['step']!=Sample_model::STEP_COMPLETE){ + return []; + } + //资料来源:json + $json = $this->get_report_json($deviceID,$sample['pet_species']); + if(empty($json)){ + return []; + } + //补充图片,物种 + if(empty($sample['pet_img'])){ + $sample['pet_img'] = base_url().'uploads/default/common.jpg'; + } + //套餐设置成1,上线后删除 + //$sample['package_id'] = 1; + $package = $this->package_model->get($sample['package_id']); + if(!$package){ + return []; + } + $package['structure'] = explode(',',$package['structure']); + $package['structure_hide'] = explode(',',$package['structure_hide']); + $package['cert'] = array_filter(explode(',',$package['cert'])); + //素材对应 + $material = $this->get_material($sample['pet_species'],$package['is_breed']); + //模块对应 + /* + $main = [ + '爱宠大揭秘'=>[], + '健康大调查'=>[], + '养育大宝典'=>[], + '基因全解锁'=>[], + ]; + */ + $block_list = [ + '品系鉴定', + '智力评估', + '性格行为', + '遗传疾病', + '健康风险', + '用药指导', + '繁育建议', + '饮食建议', + '毛发美护', + '可训练性', + '血型筛查', + ]; + + $blocks = []; + foreach ($block_list as $val) { + $blocks[$val] = $this->get_block($val,$json,$sample,$package,$material,$json['header']['宠物名']); + } + + //营养结果固化 + if(empty($sample['diet_nutrition']) && !empty($blocks['饮食建议']['营养代谢'])){ + $this->sample_model->update([ + 'diet_nutrition'=>json_encode($blocks['饮食建议']['营养代谢'],JSON_UNESCAPED_UNICODE) + ],[ + 'id'=>$sample['id'] + ]); + } + + //绑定套餐信息:版块、证书;疾病、升级目标不处理 + $ret = [ + '信息'=>[ + '编号'=>$deviceID, + '宠物照片'=>$sample['pet_img'], + //'昵称'=>$json['header']['宠物名'], + '昵称'=>$sample['pet_name'], + '养育人'=>$sample['name'], + '测试日期'=>date('Y-m-d',$sample['create_time']), + '物种'=>$package['species'],//1狗2猫 + '个性标签'=>$this->get_speciality($sample,$json,$package), + '证书'=>$package['cert'], + '是繁育版'=>!empty($package['is_breed']), + //'证书'=>'健康证书', + //防止疾病被过滤之后 + '遗传疾病'=>$this->get_focus_disease($blocks['遗传疾病'],1), + '健康风险'=>$this->get_focus_disease($blocks['健康风险'],2), + '可升级'=>!empty($package['package_up']) && $package['package_up'] != $package['id'], + ], + ]; + //套餐不允许展示的版块不展示 + //$blocks = array_intersect(array_merge($package['structure'],'信息'),$blocks); + $package['structure'][] = '信息'; + //开放版块排序在前 + $blocks_open = []; + $blocks_lock = []; + foreach ($blocks as $key=>$val) { + if(in_array($key,$package['structure'])){ + $val['lock'] = false; + $val['view'] = true; + $blocks_open[$key] = $val; + continue; + } + $val = [ + 'lock'=>true, + 'view'=>!in_array($key,$package['structure_hide']) + ]; + $blocks_lock[$key] = $val; + } + $ret = array_merge($blocks_open,$blocks_lock,$ret); + return $ret; + + } + + + /** + * @param $block 版块名称 + * @param $reportJson 报告json + * @param $material 素材 + * @param $name 宠物名称 + * @param $sample 样品数据 + * @param $package 套餐数据 + * @return array + */ + public function get_block($block,$reportJson,$sample,$package,$material,$name){ + switch ($block){ + case '品系鉴定': + //血统分析-家族树 + //品系素材文字提取 + $temp = []; + if(!empty($reportJson['血统分析']['body']['品系纯度'])){ + $list = $reportJson['血统分析']['body']['品系纯度']; + array_multisort($list,SORT_DESC, SORT_NUMERIC ,$list); + foreach ($list as $key => $val){ + $temp[] = [ + '名称'=>$key, + '占比'=>$val, + '介绍'=>!empty($material['品系'][$key])?$material['品系'][$key]:'', + ]; + } + } + /* + $temp = [ + '品系鉴定'=>'', + '血统分析'=>'', + '品种分析'=>'', + '遗传特征'=>[ + '遗传特征'=>'', + '基因毛色'=>'', + '基因毛型'=>'' + ] + ];*/ + $temp = ['列表'=>$temp]; + break; + case '智力评估': + //print_r($reportJson);die; + $rate = $reportJson['遗传特征']['body']['智商指数']['body']['智商指数']; + $rate = round($rate); + //狗狗智商评分内容 + $map[1] = [ + 3=>[ + '检测结果'=>'优秀汪', + '结论'=>"{$name}是只聪明的狗狗,新指令重复15-25次后根据个体差异,会有不同程度的掌握。它对第一次指令作出的回应几率是70%,表现的优劣取决于练习时间的多寡。整体来说,有时反应慢半拍,但依然不妨碍它学习的很好。但如果训练者缺乏经验,或过于严厉或没耐心,狗狗的表现也会受到影响。", + '描述'=>"对于新的指令,在重复15-25次后可以理解新的指令,70%以上的时间服从主人的第一个命令", + ], + 4=>[ + '检测结果'=>'学霸汪', + '结论'=>"{$name}是一只智力上等的狗狗,简单指令学习5-15次便能学会。它遵守第一次指令的机率是85%,对于稍微复杂的指令只要多练习就能掌握。当主人离它们较远时,它也会有反应。即使训练人员经验稍微不足,还是有办法将这些狗调教得很优秀。", + '描述'=>"对于新的指令,在重复5-15次后可以理解新的指令,85%以上的时间服从主人的第一个命令", + ], + 5=>[ + '检测结果'=>'天才汪', + '结论'=>"恭喜您,{$name}是一只智力超群的天才狗,一般情况下听到新指令5次以内,就会理解需要完成的动作并牢牢记住。主人下达命令时,它的完成度高达95%以上,并且能够在3秒内做出反应。即使训练它们的人经验不足,它也可以学习得很好。", + '描述'=>"对于新的指令,不用下达超过5次,就能理解是什么意思,并且95%以上的时间对主人的第一个命令是服从的。", + ] + ]; + // 猫智力 + $map[2] = [ + 5=>[ + "检测结果"=>"天才喵", + "描述"=>"{$name}是猫中天才,只要稍加训练,甚至能像狗那样听话,比如把东西叼回对它们来说就是小菜一碟。" + ], + 4=> [ + "检测结果"=>"学霸喵", + "描述"=> "{$name}不仅有超高的智商,还有超强的服从性,可以和人很好的互动,稍加训练甚至可以带出门遛弯,可以通过看你做事情而去学习,比如开门,比如自己偷翻吃的。" + ], + 3=> [ + "检测结果"=>"优秀喵", + "描述"=> "{$name}聪明,性格好,拥有很强的观察力和学习能力,会粘人,但又总保持着自己的本性。" + ] + ]; + $map = $map[$sample['pet_species']]; + $temp = [ + '智力指数'=>$rate, + '智力描述'=>$map[$rate], + ]; + + break; + case '遗传疾病': + /* + $temp = [ + '关键数据结果'=>'', + '检测类目'=>'', + ]; + */ + $list = $reportJson['遗传疾病']['body']['单基因疾病']['body']; + //获取疾病列表检测是否被锁定,如被锁定,隐藏关键信息 + $diseaseList = $this->get_disease_list(1,$sample,$reportJson,$package,false,true,false); + $temp = $this->get_disease_block($sample,$list,$diseaseList,true); + break; + case '健康风险': + $list = isset($reportJson['健康风险']['body']['复杂疾病性状']['body'])?$reportJson['健康风险']['body']['复杂疾病性状']['body']:[]; + //健康风险,按照风险值排序 + $temp = []; + foreach ($list as $key => $val) { + $val['body']['风险解读'] = explode(',',$val['body']['风险解读']); + $temp[] = (int)str_replace('高于','',$val['body']['风险解读'][1]); + } + array_multisort($temp,SORT_DESC, SORT_NUMERIC ,$list); + rsort($temp); + /* + $temp = [ + '风险系数'=>'', + '风险介绍'=>[ + '致病机理'=>'', + '临床症状'=>'', + '所属类别'=>'', + ], + '养育建议'=>'', + ];*/ + //获取疾病列表检测是否被锁定,如被锁定,隐藏关键信息 + $diseaseList = $this->get_disease_list(2,$sample,$reportJson,$package,false,true,false); + $temp = $this->get_disease_block($sample,$list,$diseaseList,false); + break; + case '用药指导': + $riskDisease = $reportJson['遗传疾病']['body']['单基因疾病']['body']; + $temp = $this->drug( + isset($riskDisease['恶性高热']), + isset($riskDisease['多重药物敏感风险']) || isset($riskDisease['多重药物敏感']) + ); + $temp = ['列表'=>$temp]; + break; + case '饮食建议': + $result = [ + '蛋白质'=>'正常', + '钠'=>'正常', + '牛磺酸'=>'正常', + 'omega-3'=>'正常', + 'EPA和DHA'=>'正常', + '抗氧化剂'=>'正常', + 'L-肉碱'=>'正常', + '叶酸'=>'正常', + '维生素B'=>'正常', + '维生素C'=>'正常', + '维生素E'=>'正常', + '铁'=>'正常', + '氨基葡萄糖和硫酸软骨素'=>'正常', + '碳水化合物'=>'正常', + '水'=>'正常', + '辅酶Q10'=>'正常', + '磷'=>'正常' + ]; + //饮食指导 + //区分单基因/多基因 1单基因 2多基因 + $map = $material['单基因疾病医护建议']; + //依赖遗传病 + $diseaseList = $this->get_disease_list(1,$sample,$reportJson,$package,false,false,false); + $suggestion = []; + foreach ($diseaseList as $disease) { + if($disease['risk'] && !$disease['lock'] && isset($map[$disease['name']]["喂养建议 "])){ + $suggestion[] = $map[$disease['name']]["喂养建议 "]; + break; + } + } + $suggestion = implode('',$suggestion); + //营养代谢结果,增加随机性,并保存到sample里 + if(!empty($sample['diet_nutrition'])){ + $result = json_decode($sample['diet_nutrition']); + }else{ + $nutrition = isset($reportJson['营养代谢']['body']['营养代谢综合结果'])?$reportJson['营养代谢']['body']['营养代谢综合结果']:[]; + if(!is_null($nutrition)){ + $result = array_merge($result,$nutrition); + } + foreach ($result as $key=>$val) { + $v = 0; + switch ($val){ + case '微量': + $v = 1; + break; + case '少量': + $v = rand(2,3); + break; + case '正常': + $v = rand(4,7); + break; + case '稍高': + $v = rand(8,9); + break; + case '稍多': + $v = rand(8,9); + break; + case '多量': + $v = 10; + break; + } + $result[$key] = [ + '结果'=>$val, + '值'=>$v, + ]; + } + } + $temp = [ + '饮食结构'=>isset($reportJson['营养代谢']['body']['饮食结构'])?$reportJson['营养代谢']['body']['饮食结构']:'', + '饮食指导'=>$suggestion, + '营养代谢'=>$result, + ]; + //猫 + if($sample['pet_species'] == 2){ + unset($temp['营养代谢']); + } + break; + case '繁育建议': + //毛色 + $color = $reportJson['进阶项目研究']['body']['毛色分析']['body']['成年毛色预测']; + $type = $reportJson['进阶项目研究']['body']['毛型分析']['body']['成年毛型预测']; + //echo $color;die; + //$color = '白色或者黑色'; + $colors = str_replace([',','或者','或'],',',$color); + $colors = explode(',',$colors); + $color_out = []; + foreach ($colors as $key=>$val) { + //括号内的描述去掉 + $val = str_replace(['(','('],',',$val); + $val = explode(',',$val); + $val = $val[0]; + //还剩一种情况,用/分隔 + $val = explode('/',$val); + foreach ($val as $v) { + $color_out[] = trim($v); + } + } + $color_out = array_values(array_filter($color_out)); + //遗传病 + $material = $this->get_material($sample['pet_species'],$package['is_breed']); + //区分单基因/多基因 1单基因 2多基因 + $map = [ + //狗 + 1=>$material['单基因疾病医护建议'], + //猫 + 2=>$material['单基因疾病'], + ]; + $map = $map[$sample['pet_species']]; + //建议中的节点 + $map_key = [ + //狗 + 1=>'育种建议', + //猫 + 2=>'繁育建议', + ]; + $map_key = $map_key[$sample['pet_species']]; + //依赖遗传病 + $resultNotice = '可繁育'; + $diseaseList = $this->get_disease_list(1,$sample,$reportJson,$package,false,false,false); + $suggestion = []; + foreach ($diseaseList as $disease) { + if($disease['risk'] && !$disease['lock'] && isset($map[$disease['name']][$map_key])){ + $resultNotice = '不建议繁育'; + $suggestion[] = $map[$disease['name']][$map_key]; + break; + } + } + if(empty($suggestion)){ + //对于狗,还要检查健康风险 + if($sample['pet_species'] == 1){ + //重新获取健康风险,这里需要考虑解锁情况 + $diseaseList = $this->get_disease_list(2,$sample,$reportJson,$package,false,false,false); + //print_r($diseaseList);die; + foreach ($diseaseList as $disease) { + if($disease['risk'] && !$disease['lock']){ + //分析相对风险值,例如:相对风险值73.93, 高于99.9%犬只 + $temp = explode('高于',$disease['risk_detail']['风险解读']); + $temp = (int)$temp[1]; + if($temp>=90){ + $resultNotice = '不建议繁育'; + $suggestion[] = $disease['name'].':'.$disease['risk_detail']['检测结果'].','.$disease['risk_detail']['风险解读']; + break; + } + } + } + } + if(empty($suggestion)){ + $suggestion[] = '您的爱宠没有检测出遗传隐患,可放心繁育下一代,生出健康漂亮的宝宝。'; + } + } + $suggestion = implode('',$suggestion); + + $temp = [ + '结果'=>$resultNotice, + '建议'=>$suggestion, + '毛色'=>$color_out, + '毛型'=>$type, + '毛型类别'=>strpos($type,'直') === false?'卷':'直',//1直2卷 + ]; + //猫 + /* + if($sample['pet_species'] == 2){ + unset($temp['毛色'],$temp['毛型'],$temp['毛型类别']); + }*/ + break; + case '毛发美护': + $rate = round($reportJson['洗护建议']['body']['梳毛护理星级']); + $map = [ + //狗 + 1=>[ + "梳毛护理相关知识点"=>"星星表明你的爱犬需要梳理的频度,以保持它被毛的最佳状态。", + 1=>"每周1次:{$name}的被毛几乎不用特别梳理就可以有型,但不能保证地毯沙发上没有狗毛,定期梳理可大程度减少狗因褪毛而到处飞扬的狗毛。", + 2=>"每周2-3次:{$name}的被毛不会太难打理,定期梳理可大程度减少狗毛乱飞,同时也有助于你们的感情培养哦。", + 3=>"每天1次:{$name}的被毛褪毛较多,频繁的梳理可以尽量去除掉落的被毛并防止里层被毛缠结,另外每天梳理有助于你与它感情的培养哦。", + ], + 2=>[ + "梳毛护理相关知识点"=> "指猫咪被毛需要梳理的频率,得分越高,需要梳理的次数越多。", + "1"=> "每周1次:{$name}的被毛几乎不用特别梳理就可以有型,但不能保证地毯沙发上没有猫毛,定期梳理可大程度减少猫因褪毛而到处飞扬的猫毛。", + "2"=> "每周2-3次:{$name}的被毛不会太难打理,定期梳理可大程度减少猫毛乱飞,同时也是预防毛球症很好的方式之一。", + "3"=> "每天1次:{$name}的被毛褪毛较多,频繁的梳理可以尽量去除掉落的被毛并防止里层被毛缠结,同时也是预防毛球症很好的方式之一。另外每天梳理有助于你与它感情的培养哦。", + ] + ]; + $map = $map[$sample['pet_species']]; + //疾病 + $diseaseList = $this->get_disease_list(0,$sample,$reportJson,$package,false,false,false); + $washMap = [ + "GM2神经节苷脂沉着症"=> "{$name}需要舒适的床上用品,如空气床垫、水床、休闲椅垫、人用床垫、羊毛、睡袋、毯子、稻草或其他柔软舒适的东西。你需要经常更换床上用品的外层,并且需要定期帮它洗澡,以防它由于大小便失禁引起褥疮、尿烧伤、皮肤溃疡等其他疾病。在尾巴和肛门周围的毛发应该经常修剪。", + "多发性神经病"=> "{$name}需要舒适的床上用品,如空气床垫、水床、休闲椅垫、人用床垫、羊毛、睡袋、毯子、稻草或其他柔软舒适的东西。你需要经常更换床上用品的外层,并且需要定期帮它洗澡,以防它由于大小便失禁引起褥疮、尿烧伤、皮肤溃疡等其他疾病。在尾巴和肛门周围的毛发应该经常修剪。", + "感觉神经失调性神经病"=> "{$name}长期缺乏运动,需要给它提供足够柔软的睡垫并注意清洁,避免褥疮及皮肤疾病。", + "皮肤脆性综合征"=> "{$name}需要限制运动,生活环境以柔软为主,玩耍时注意力度,避免撕裂皮肤。增加剪指甲频率,防止它抓挠身体,避免受外伤。由于它的皮肤免疫力较低,应注意生活环境清洁,不要与有皮肤病的宠物接触,避免继发或加重皮肤疾病。当发现它的皮肤出现撕裂,发红,瘙痒,脱毛,化脓等异常时及时送诊。", + "球形细胞脑白质营养不良"=> "{$name}需要舒适的床上用品,如空气床垫、水床、休闲椅垫、人用床垫、羊毛、睡袋、毯子、稻草或其他柔软舒适的东西。你需要经常更换床上用品的外层,并且需要定期帮它洗澡,以防它由于大小便失禁引起褥疮、尿烧伤、皮肤溃疡等其他疾病。在尾巴和肛门周围的毛发应该经常修剪。", + "神经节苷脂病-1型"=> "{$name}需要舒适的床上用品,如空气床垫、水床、休闲椅垫、人用床垫、羊毛、睡袋、毯子、稻草或其他柔软舒适的东西。你需要经常更换床上用品的外层,并且需要定期帮它洗澡,以防它由于大小便失禁引起褥疮、尿烧伤、皮肤溃疡等其他疾病。在尾巴和肛门周围的毛发应该经常修剪。", + "退行性脊髓病"=> "{$name}需要舒适的床上用品,如空气床垫、水床、休闲椅垫、人用床垫、羊毛、睡袋、毯子、稻草或其他柔软舒适的东西。你需要经常更换床上用品的外层,并且需要定期帮它洗澡,以防它由于大小便失禁引起褥疮、尿烧伤、皮肤溃疡等其他疾病。在尾巴和肛门周围的毛发应该经常修剪。", + "岩藻糖苷贮积症"=> "{$name}需要舒适的床上用品,如空气床垫、水床、休闲椅垫、人用床垫、羊毛、睡袋、毯子、稻草或其他柔软舒适的东西。你需要经常更换床上用品的外层,并且需要定期帮它洗澡,以防它由于大小便失禁引起褥疮、尿烧伤、皮肤溃疡等其他疾病。在尾巴和肛门周围的毛发应该经常修剪。", + "鱼鳞病"=> "可使用香波冲洗皮肤,刷牙和毛发梳理等物理手段进行症状的缓解。皮肤可使用温和的抗脂溢性香波和保湿霜可用来在宠物皮肤上创造一个保护层,减少水分流失。" + ]; + //var_dump($diseaseList);die; + $washNotice = '无特别洗护要求'; + foreach ($diseaseList as $disease) { + if($disease['risk'] && !$disease['lock'] && isset($washMap[$disease['name']])){ + $washNotice = $washMap[$disease['name']]; + break; + } + } + $temp = [ + '梳毛护理星级'=>$rate, + '梳毛建议'=>$map[$rate], + '梳毛说明'=>$map["梳毛护理相关知识点"], + '洗护要求'=>$washNotice, + ]; + break; + case '性格行为': + /* + $temp = [ + '活力值'=>'', + '胆量值'=>'', + '暴躁值'=>'', + '吠叫值'=>'', + '独处值'=>'', + '排尿值'=>'', + ];*/ + //狗 + $map[1] = [ + "胆量值"=>[ + "描述"=>"指犬只对陌生事物的恐惧感及焦虑情绪,分数越高,越容易有恐惧或焦虑的情绪。", + "1"=>"{$name}是只胆大包天的狗狗,这个世界上似乎没有它害怕的事物。", + "2"=>"{$name}是只勇敢的狗狗,内心平静,是很稳重的孩子。", + "3"=>"{$name}是只勇敢的狗狗,内心平静,是很稳重的孩子。", + "4"=>"{$name}稍微有点胆小,容易焦虑,希望世界对它温柔以待。", + "5"=>"{$name}稍微有点胆小,容易焦虑,希望世界对它温柔以待。", + ], + "暴躁值"=>[ + "描述"=>"指犬只的攻击性,得分越高,越容易产生攻击行为,与战斗力无关。", + "1"=>"{$name}是只人畜无害的狗子,狗中铁憨憨。", + "2"=>"{$name}是典型的人不犯我我不犯人的狗子,不去惹毛它就不会炸毛。", + "3"=>"{$name}是典型的人不犯我我不犯人的狗子,不去惹毛它就不会炸毛。", + "4"=>"{$name}性子比较急,不要尝试去挑战它的底线,别老虎不发威就把它当HelloKitty。", + "5"=>"{$name}性子比较急,不要尝试去挑战它的底线,别老虎不发威就把它当HelloKitty。", + ], + + "吠叫值"=>[ + "描述"=>"指犬只的持续吠叫程度,分数越高,表示当犬只兴奋或受到刺激时,持续吠叫的情况越严重。", + "1"=>"{$name}可以说是最不爱说话的一类狗子了,这种不吵闹的狗子是多少人的理想型。", + "2"=>"{$name}兴奋或受到刺激的时候喜欢叫,注意观察它在说什么,它可不是随便说说而已哦。", + "3"=>"{$name}兴奋或受到刺激的时候喜欢叫,注意观察它在说什么,它可不是随便说说而已哦。", + "4"=>"{$name}天生是个话痨,有事没事就爱瞎哔哔,如果它并没有这么做,那么恭喜你,它为了融入你的生活改变了天性。", + "5"=>"{$name}天生是个话痨,有事没事就爱瞎哔哔,如果它并没有这么做,那么恭喜你,它为了融入你的生活改变了天性。", + ], + "独处值"=>[ + "描述"=>"指犬只对孤独的感知度,是否容易产生分离焦虑,分数越高,孤独的感知能力越强,独处能力越低。", + "1"=>"{$name}是只学会享受孤独的狗子,独处能力很强,但并不代表它不想和你在一起,要知道,和你在一起的时光才是它最开心的。", + "2"=>"{$name}是懂事的狗子,能够自己独处上一段时间,但是它同时也很想你,不要让它等太久。", + "3"=>"{$name}是懂事的狗子,能够自己独处上一段时间,但是它同时也很想你,不要让它等太久。", + "4"=>"{$name}觉得与你分离是世界上最难过的事,尽量多陪陪它吧,你不在的时候,它可能偷偷伤心了很久。", + "5"=>"{$name}觉得与你分离是世界上最难过的事,尽量多陪陪它吧,你不在的时候,它可能偷偷伤心了很久。", + ], + "排尿值"=>[ + "描述"=>"指犬只独自在家时乱排尿的情况,得分越高,乱排尿的可能性越大。", + "1"=>"{$name}是只讲规则的狗子,只要你事先与它确定了规则,它是不会随地尿尿的。", + "2"=>"{$name}通常不会随意尿尿,除非它忍不住或者它想通过尿尿告诉你什么。", + "3"=>"{$name}通常不会随意尿尿,除非它忍不住或者它想通过尿尿告诉你什么。", + "4"=>"{$name}在你看不到的情况下,可能会随意尿一尿,它知道这样做不太好,但是它就是想试一试。", + "5"=>"{$name}在你看不到的情况下,可能会随意尿一尿,它知道这样做不太好,但是它就是想试一试。", + ], + "活力值"=>[ + "描述"=>"指犬只的活跃度,得分越高越活泼,精力越充沛,性格更有趣喧闹,需要的运动量越大。", + "1"=>"{$name}是只喜欢安静的肥宅,请让它一只汪静静。", + "2"=>"{$name}是只动静皆宜的狗子,静如处子,动如脱兔说的就是它。", + "3"=>"{$name}是只动静皆宜的狗子,静如处子,动如脱兔说的就是它。", + "4"=>"{$name}是只喜欢蹦D的狗子,内心住着野狼DISCO本狼,请尽情陪它玩耍,释放你们的天性。", + "5"=>"{$name}是只喜欢蹦D的狗子,内心住着野狼DISCO本狼,请尽情陪它玩耍,释放你们的天性。", + ], + ]; + //猫 + $map[2] = [ + "外出频率"=> [ + "描述"=> "指猫咪的外出频率,得分越高,携带外出的可能性越高,出门受刺激的反应越低。", + "1"=> "{$name}是只害羞的猫咪,携带外出受刺激的可能性大,若没有进行专业的训练,不建议强制外出。", + "2"=> "{$name}是只可宅可外出的猫咪,值得注意的是,需要进行足够多的社会化,循序渐进的携带外出,如果外出反应大,应立即带回。", + "3"=> "{$name}是只可宅可外出的猫咪,值得注意的是,需要进行足够多的社会化,循序渐进的携带外出,如果外出反应大,应立即带回。", + "4"=> "{$name}是猫咪里的汪,是可以像狗一样外出溜达的猫咪,前期做好循序渐进的外出训练,直到在外毫无压力时便可携带外出。", + "5"=> "{$name}是猫咪里的汪,是可以像狗一样外出溜达的猫咪,前期做好循序渐进的外出训练,直到在外毫无压力时便可携带外出。" + ], + + "活力值"=> [ + "描述"=> "指猫咪的活跃度,得分越高越活泼,精力越充沛,性格更有趣喧闹,需要的运动量越大。", + "1"=> "{$name}是只喜欢安静的肥宅,请让它一只喵静静。", + "2"=> "{$name}是只动静皆宜的猫咪,静如处子,动如脱兔说的就是它。", + "3"=> "{$name}是只动静皆宜的猫咪,静如处子,动如脱兔说的就是它。", + "4"=> "{$name}是只喜欢蹦D的猫咪,内心住着野狼DISCO本狼,请尽情陪它玩耍,释放你们的天性。", + "5"=> "{$name}是只喜欢蹦D的猫咪,内心住着野狼DISCO本狼,请尽情陪它玩耍,释放你们的天性。" + ], + + "与人亲近值"=> [ + "描述"=> "指猫咪与人类的友好度,得分越高,与人的相处越轻松,越自然友爱。", + "1"=> "{$name}只喜欢它自己,内心OS:愚蠢的人类请离本喵远一点。", + "2"=> "{$name}与人类可以和谐相处,自然友爱,前提是没有受过人类的伤害。", + "3"=> "{$name}与人类可以和谐相处,自然友爱,前提是没有受过人类的伤害。", + "4"=> "{$name}是人类的好朋友,是所有猫咪中最愿意与人亲近的物种,请好好珍惜。", + "5"=> "{$name}是人类的好朋友,是所有猫咪中最愿意与人亲近的物种,请好好珍惜。" + ], + + "对陌生人的敌意"=> [ + "描述"=> "指猫咪的对陌生人的敌意,得分越高,受刺激的反应越大,越容易产生攻击行为。", + "1"=> "{$name}对陌生人很友好,如果人类没有主动攻击,基本上相安无事。", + "2"=> "{$name}对陌生人友善但警惕,受到刺激的话会产生攻击行为。", + "3"=> "{$name}对陌生人友善但警惕,受到刺激的话会产生攻击行为。", + "4"=> "{$name}对陌生人戒心很重,不要轻易让它接触陌生人,受刺激的可能性大,容易产生攻击行为。", + "5"=> "{$name}对陌生人戒心很重,不要轻易让它接触陌生人,受刺激的可能性大,容易产生攻击行为。" + ], + + "对主人的敌意"=> [ + "描述"=> "指猫咪的对主人的敌意,得分越高,服从性越低,不愿意遵守命令。", + "1"=> "{$name}很爱主人,出生自带服从性高的属性,甚至比较黏人。", + "2"=> "{$name}眼里的主人是与它平等的物种,大家相敬如宾平安无事,如果你可爱的话,它甚至有点爱你。", + "3"=> "{$name}眼里的主人是与它平等的物种,大家相敬如宾平安无事,如果你可爱的话,它甚至有点爱你。", + "4"=> "{$name}的内心住着哈士奇,自我且叛逆,可能听话的可能性很低,但也不能说它不爱你。", + "5"=> "{$name}的内心住着哈士奇,自我且叛逆,可能听话的可能性很低,但也不能说它不爱你。" + ], + + "对其它猫的敌意"=> [ + "描述"=> "指猫咪的对其它猫的敌意,得分越高,越容易产生攻击行为,与战斗力无关。", + "1"=> "{$name}对其它小伙伴很友好,是猫咪中的铁憨憨 。", + "2"=> "{$name}对其它猫友善但警惕,不会轻易接受同类,一旦接受了便会友好相处,如果被欺负也会回击。", + "3"=> "{$name}对其它猫友善但警惕,不会轻易接受同类,一旦接受了便会友好相处,如果被欺负也会回击。", + "4"=> "{$name}对同类不是很友好,如非必要,不要轻易让它们接触,相处不当会经常打架。", + "5"=> "{$name}对同类不是很友好,如非必要,不要轻易让它们接触,相处不当会经常打架。" + ], + + "对新事物的害羞程度"=> [ + "描述"=> "指猫咪对陌生事物的恐惧感及焦虑情绪,分数越高,越容易有恐惧或焦虑的情绪,害羞程度就越高。", + "1"=> "{$name}是只神经大条的猫咪,任何新事物在它眼里都很有趣。", + "2"=> "{$name}对新事物比较警惕,但只要适应一段时间便能很好的接受。", + "3"=> "{$name}对新事物比较警惕,但只要适应一段时间便能很好的接受。", + "4"=> "{$name}是只爱守旧的猫咪,比较难接受新事物,需要更多的时间和耐心让它放下戒心。", + "5"=> "{$name}是只爱守旧的猫咪,比较难接受新事物,需要更多的时间和耐心让它放下戒心。" + ], + + "对陌生人的害羞程度"=> [ + "描述"=> "指猫咪对陌生人的恐惧感及焦虑情绪,分数越高,越容易有恐惧或焦虑的情绪,害羞程度就越高。", + "1"=> "{$name}是只没皮没脸的猫咪,毫不认生,人见人爱。", + "2"=> "{$name}不排斥见陌生人但也没有那么喜欢,如果非得相处的话,请给它缓一缓的时间和空间。", + "3"=> "{$name}不排斥见陌生人但也没有那么喜欢,如果非得相处的话,请给它缓一缓的时间和空间。", + "4"=> "{$name}是只娇羞的猫咪,比较害怕见到陌生人,若非必要,不要让它们单独与陌生人相处,产生应激的机率很高。", + "5"=> "{$name}是只娇羞的猫咪,比较害怕见到陌生人,若非必要,不要让它们单独与陌生人相处,产生应激的机率很高。" + ], + + "舔毛倾向"=> [ + "描述"=> "指猫咪除自身清洁需要外,利用舔毛行为缓解压力的倾向,得分越高,感受压力越大,释放压力需求越高。", + "1"=> "{$name}除了给自己梳洗以外,偶尔也会舔舔毛来舒缓压力,是一只心理健康的猫咪。", + "2"=> "{$name}除了给自己梳洗以外,时不时用舔毛来舒缓压力,可以给它置放一些释放压力的猫抓板,防止过度舔毛引起毛球症。", + "3"=> "{$name}除了给自己梳洗以外,时不时用舔毛来舒缓压力,可以给它置放一些释放压力的猫抓板,防止过度舔毛引起毛球症。", + "4"=> "{$name}除了给自己梳洗以外,经常用舔毛来舒缓压力,主人可以多陪它玩,并放置一些释放压力的猫抓板或玩具,不要给孩子那么大的压力。", + "5"=> "{$name}除了给自己梳洗以外,经常用舔毛来舒缓压力,主人可以多陪它玩,并放置一些释放压力的猫抓板或玩具,不要给孩子那么大的压力。" + ], + ]; + $map = $map[$sample['pet_species']]; + //排序,宠物在后 + $body = $reportJson['秉性行为']['body']; + $pet_rate = $body[$name]; + $body_sorted = []; + foreach ($body as $key=>$val) { + if($key != $name){ + $body_sorted[$key] = $val; + //对于猫,直接指定数值,转换程序修改后改回来 + /* + if($sample['pet_species'] == 2){ + $body_sorted[$key] = [ + "外出指数"=> 2.44, + "活力值"=> 3.04, + "与人亲近值"=> 3.32, + "对陌生人的敌意"=> 1.36, + "对主人的敌意"=> 1.44, + "对其它猫的敌意"=> 3.12, + "对新事物害羞程度"=> 2.76, + "对陌生人害羞程度"=> 2.24, + "舔毛倾向"=> 1.76 + ]; + }*/ + } + } + $body_sorted[$name] = $pet_rate; + $temp = [ + '数值'=> $body_sorted, + '描述'=>[] + ]; + foreach ($temp['数值'] as $key=>$val) { + unset($temp['数值'][$key]['兴奋值']); + } + foreach ($map as $key=>$val) { + $_rate = round($pet_rate[$key]); + $_rate = $_rate == 0?1:$_rate; + $_rate = $_rate > 5?5:$_rate; + $temp['描述'][$key]['描述'] = $val['描述']; + $temp['描述'][$key]['检测结果'] = $val[$_rate]; + } + break; + case '可训练性': + /* + $temp = [ + '专注度'=>'', + '游戏欲'=>'', + '兴奋值'=>'', + '服从性'=>'', + '聪明值'=>'', + '逃逸值'=>'', + ];*/ + $map = [ + "专注度"=>[ + "描述"=>"指犬只在集中注意力时受外界刺激的影响程度,例如被柏油马路上的一片树叶、许多断续而短促的声音中的一个长声、被风吹起的塑料袋所吸引,或追逐飞过的小鸟及其它小动物,得分越低,表面受到外界刺激的影响程度越高,专注度越低。", + "1"=>"{$name}是只敏感的狗子,一点风吹草动都会影响它的专注度。", + "2"=>"{$name}也会集中注意力,但有时会被其它事物打断,如果训练的话,建议先从无干扰物开始。", + "3"=>"{$name}也会集中注意力,但有时会被其它事物打断,如果训练的话,建议先从无干扰物开始。", + "4"=>"{$name}天生专注度极高,它把注意力放在你身上时,其它事物很难打断它。", + "5"=>"{$name}天生专注度极高,它把注意力放在你身上时,其它事物很难打断它。", + ], + "游戏欲"=>[ + "描述"=>"指犬只的活跃度,玩游戏的欲望,得分越高越活跃,精力越充沛,游戏欲望越强。", + "1"=>"{$name}可能觉得玩游戏太幼稚了,它只想安静的睡一会儿。", + "2"=>"{$name}是喜欢玩游戏的狗子,你陪它玩儿的时间越多,它就越活泼。", + "3"=>"{$name}是喜欢玩游戏的狗子,你陪它玩儿的时间越多,它就越活泼。", + "4"=>"{$name}是个不折不扣的活力狗,爱玩更爱你陪它玩,你有多少精力它都会奉陪到底。", + "5"=>"{$name}是个不折不扣的活力狗,爱玩更爱你陪它玩,你有多少精力它都会奉陪到底。", + ], + "兴奋值"=>[ + "描述"=>"指犬只受到刺激后的反应,分数越高,表明受到刺激或引起兴奋的反应越强烈,例如散步,开车,门铃响,客人到访,主人在一段时间后回家,犬只的兴奋情况。", + "1"=>"{$name}是只佛系汪,似乎很少事情能让它感兴趣。", + "2"=>"{$name}受到刺激的时候会兴奋起来,它的兴奋程度取决于刺激它的点有多大。", + "3"=>"{$name}受到刺激的时候会兴奋起来,它的兴奋程度取决于刺激它的点有多大。", + "4"=>"{$name}是个人来疯,兴奋点太低,随随便便就激动起来。", + "5"=>"{$name}是个人来疯,兴奋点太低,随随便便就激动起来。", + ], + "服从性"=>[ + "描述"=>"得分高的犬只,表示对主人更关心,愿意遵守命令,反应积极,快速学习,服从性高。", + "1"=>"{$name}有自己的想法,不要指望它顺着你,它的行动指南就是它的心情。", + "2"=>"{$name}是孺子可教型,只要你方法得当,好好跟它说,它还是很愿意和你一起学习的。", + "3"=>"{$name}是孺子可教型,只要你方法得当,好好跟它说,它还是很愿意和你一起学习的。", + "4"=>"{$name}的心里只有你,“百依百顺”可以说是它给主人最高规格的诚意了。", + "5"=>"{$name}的心里只有你,“百依百顺”可以说是它给主人最高规格的诚意了。", + ], + "聪明值"=>[ + "描述"=>"指犬只的智商指数,得分越高,越聪明。", + "3"=>"{$name}对于新的指令,在重复15-25次后可以理解新的指令,70%以上的时间服从主人的第一个命令。", + "4"=>"{$name}对于新的指令,在重复5-15次后可以理解新的指令,85%以上的时间服从主人的第一个命令。", + "5"=>"{$name}对于新的指令,不用下达超过5次,就能理解是什么意思,并且95%以上的时间对主人的第一个命令是服从的。", + ], + "逃逸值"=>[ + "描述"=>"指犬只一有机会就逃跑,或逃离家里或主人的可能性,分数越高,可能性越大。", + "1"=>"{$name}只想和你在一起,只要你不逃走。", + "2"=>"{$name}不会轻易逃走,但经常也会因为看见更感兴趣的事物而逃离你身边,大多数情况下能唤回,这取决于你们之间的关系,出门记得栓绳哦。", + "3"=>"{$name}不会轻易逃走,但经常也会因为看见更感兴趣的事物而逃离你身边,大多数情况下能唤回,这取决于你们之间的关系,出门记得栓绳哦。", + "4"=>"{$name}它可能更向往远方,一有机会就想逃走,恭喜你,喜提一只撒手没。", + "5"=>"{$name}它可能更向往远方,一有机会就想逃走,恭喜你,喜提一只撒手没。", + ], + ]; + + $temp = [ + '数值'=> isset($reportJson['可训练性']['body'])?array_reverse($reportJson['可训练性']['body'],true):[], + '描述'=>[] + ]; + //数值的第一项是当前宠物的值 + $pet_rate = $temp['数值'][$name]; + foreach ($map as $key=>$val) { + $_rate = round($pet_rate[$key]); + $_rate = $_rate == 0?1:$_rate; + $_rate = $_rate > 5?5:$_rate; + $temp['描述'][$key]['描述'] = $val['描述']; + $temp['描述'][$key]['检测结果'] = $val[$_rate]; + } + break; + case '血型筛查': + $temp = $reportJson['B型血筛查']; + $temp['检测结果说明'] = $material['血型'][$reportJson['B型血筛查']['检测结果']]; + break; + default: + $temp=[]; + } + return $temp; + } + + // 疾病部分,对锁定的信息做隐藏及特殊处理 + protected function get_disease_block($sample,$riskDisease,$diseaseList,$addVirtualByLevel=false){ + + //按照风险内容输出,没锁定的风险项放前面 + $unlock_risk = []; + + //所有解锁项目,包括非风险项 + $unlock_all = []; + + //所有低风险项目 + $risk_low_all = []; + + //所有高风险项目 + $risk_high_all = []; + + //转化为名字对应内容 + $temp = []; + foreach ($diseaseList as $item) { + $temp[$item['name']] = $item; + if(!$item['lock']){ + $unlock_all[] = $item; + } + if($item['risk']){ + if($item['risk_level'] == 1){ + $risk_low_all[] = $item; + }else{ + $risk_high_all[] = $item; + } + + } + } + $diseaseList = $temp; + + //不同风险等级对应的锁定内容 + $lock = [ + 1=>[], + 2=>[], + ]; + + foreach ($riskDisease as $key=>$val) { + if(empty($diseaseList[$key])){ + //疾病列表里没有这一项,直接去除,否则无法做后续处理,这会造成检测结果的数量减少 + continue; + } + //锁定项目隐藏,后面会给锁定项目增加虚拟项目 + if(!$diseaseList[$key]['lock']){ + $unlock_risk[] = $diseaseList[$key]; + } + } + + //判断样品是否需要锁定一些疾病 + $is_lock = !empty($lock[1]) || !empty($lock[2]); + if(!$is_lock){ + foreach ($diseaseList as $val) { + if($val['lock']){ + $is_lock = true; + break; + } + } + } + + //如果列表中有疾病锁定了,但风险项中没有,则虚拟一些风险项,便于统一展示逻辑 + //(不考虑套餐自选疾病解锁了所有的锁定疾病的情况) + if($is_lock){ + $virtual = [ + 'lock'=>true, + 'risk'=>true, + 'risk_level'=>1, + 'name'=>'解锁后可查看细节', + ]; + //是否需要根据风险等级添加虚拟疾病 + $lock[1][] = $virtual; + $lock[1][] = $virtual; + if($addVirtualByLevel){ + $virtual['risk_level'] = 2; + $lock[2][] = $virtual; + $lock[2][] = $virtual; + } + } + //总列表 + $list = array_merge($unlock_risk,$lock[1],$lock[2]); + + //强调列表:解锁疾病数量少于10个则显示 + $list_notice = []; + if(count($unlock_all)<10){ + $custom = $this->get_disease_custom($sample); + if(!empty($custom)){ + //对于自选,展示自选,不必做解锁项目的过滤 + $list_notice = [ + 'name'=>$custom['name'], + 'list'=>$unlock_all + ]; + }else{ + $list_notice = [ + 'name'=>'遗传疾病'.count($unlock_all).'项', + 'list'=>$unlock_all + ]; + } + } + + //输出结果 + $temp = [ + '总计'=>$is_lock?'?':count($list), + '总计低风险'=>$is_lock?'?':count($risk_low_all), + '总计高风险'=>$is_lock?'?':count($risk_high_all), + '疾病总数'=>count($diseaseList), + '列表'=>$list, + '强调列表'=>$list_notice, + ]; + return $temp; + } + + // 突出特质 + protected function get_speciality($sample,$reportJson,$package){ + $map = [ + //狗 + '1'=>[ + '健康宝宝'=>['遗传病'=>[0]], + '爱因斯坦·汪'=>['智力评估'=>[5]], + '智商担当'=>['智力评估'=>[4]], + '胆大包天'=>['胆量值'=>[1]], + '铁憨憨'=>['暴躁值'=>[1]], + '安静的美狗子'=>['吠叫值'=>[1]], + '当代独立汪'=>['独处值'=>[1]], + '分离焦虑本汪'=>['独处值'=>[4,5]], + '轻度洁癖'=>['排尿值'=>[1]], + '乱尿之汪'=>['排尿值'=>[4,5]], + '蹦迪汪'=>['活力值'=>[4,5]], + '资深肥宅'=>['活力值'=>[1]], + '学习委员'=>['专注度'=>[4,5]], + '天生爱玩'=>['游戏欲'=>[4,5]], + '佛系汪'=>['兴奋值'=>[1]], + '天使宝宝'=>['服从性'=>[4,5]], + '撒手没'=>['逃逸值'=>[4,5]], + ], + //猫 + '2'=>[ + '健康宝宝'=>['遗传病'=>[0]], + '爱因斯坦·喵'=>['智力评估'=>[5]], + '智商担当'=>['智力评估'=>[4]], + '蹦迪喵'=>['活力值'=>[4,5]], + '佛系喵'=>['活力值'=>[1]], + '喵中汪'=>['外出频率'=>[4,5]], + '喵中汪 '=>['外出数值'=>[4,5]], + '黏人小妖精'=>['与人亲近值'=>[4,5]], + '满眼都是你'=>['对主人的敌意'=>[1]], + '目中无主人'=>['对主人的敌意'=>[4,5]], + '毫无畏惧'=>['对新事物的害羞程度'=>[1]], + '毫无畏惧 '=>['对新事物害羞程度'=>[1]], + ] + ]; + $pet_name = $reportJson['header']['宠物名']; + if($sample['pet_species'] == 1){ + //狗 + $value = [ + '遗传病'=>0, + '智力评估'=>$reportJson['遗传特征']['body']['智商指数']['body']['智商指数'], + '胆量值'=>$reportJson['秉性行为']['body'][$pet_name]['胆量值'], + '暴躁值'=>$reportJson['秉性行为']['body'][$pet_name]['暴躁值'], + '吠叫值'=>$reportJson['秉性行为']['body'][$pet_name]['吠叫值'], + '独处值'=>$reportJson['秉性行为']['body'][$pet_name]['独处值'], + '排尿值'=>$reportJson['秉性行为']['body'][$pet_name]['排尿值'], + '活力值'=>$reportJson['秉性行为']['body'][$pet_name]['活力值'], + '专注度'=>$reportJson['可训练性']['body'][$pet_name]['专注度'], + '游戏欲'=>$reportJson['可训练性']['body'][$pet_name]['游戏欲'], + '兴奋值'=>$reportJson['可训练性']['body'][$pet_name]['兴奋值'], + '服从性'=>$reportJson['可训练性']['body'][$pet_name]['服从性'], + '逃逸值'=>$reportJson['可训练性']['body'][$pet_name]['逃逸值'], + ]; + }else{ + //猫 + $value = [ + '遗传病'=>0, + '智力评估'=>$reportJson['遗传特征']['body']['智商指数']['body']['智商指数'], + '外出频率'=>$reportJson['秉性行为']['body'][$pet_name]['外出频率'], + //'外出数值'=>$reportJson['秉性行为']['body'][$pet_name]['外出数值'], + '与人亲近值'=>$reportJson['秉性行为']['body'][$pet_name]['与人亲近值'], + '对主人的敌意'=>$reportJson['秉性行为']['body'][$pet_name]['对主人的敌意'], + '对新事物的害羞程度'=>$reportJson['秉性行为']['body'][$pet_name]['对新事物的害羞程度'], + //'对新事物害羞程度'=>$reportJson['秉性行为']['body'][$pet_name]['对新事物害羞程度'], + //'胆量值'=>$reportJson['秉性行为']['body'][$pet_name]['胆量值'], + //'暴躁值'=>$reportJson['秉性行为']['body'][$pet_name]['暴躁值'], + //'吠叫值'=>$reportJson['秉性行为']['body'][$pet_name]['吠叫值'], + //'独处值'=>$reportJson['秉性行为']['body'][$pet_name]['独处值'], + //'排尿值'=>$reportJson['秉性行为']['body'][$pet_name]['排尿值'], + '活力值'=>$reportJson['秉性行为']['body'][$pet_name]['活力值'], + '专注度'=>$reportJson['可训练性']['body'][$pet_name]['专注度'], + '游戏欲'=>$reportJson['可训练性']['body'][$pet_name]['游戏欲'], + '兴奋值'=>$reportJson['可训练性']['body'][$pet_name]['兴奋值'], + '服从性'=>$reportJson['可训练性']['body'][$pet_name]['服从性'], + '逃逸值'=>$reportJson['可训练性']['body'][$pet_name]['逃逸值'], + ]; + } + + //是否全部疾病解锁且没有遗传病 + $diseaseList = $this->get_disease_list(0,$sample,$reportJson,$package,false,false,true); + foreach ($diseaseList as $item) { + if($item['lock'] || $item['risk']){ + $value['遗传病'] = 1; + break; + } + } + //提取特质 + $ret = []; + foreach ($map[$sample['pet_species']] as $name => $cond) { + + //数据名称 + $value_key = array_keys($cond)[0]; + if(!isset($value[$value_key])){ + continue; + } + $value_rate = round($value[$value_key]); + if(in_array($value_rate,$cond[$value_key])){ + $ret[] = $name; + } + } + + //特质少于3个,做补充 + $more = ['可爱多','独一无二','美食家']; + for($i=count($ret);$i<3;$i++){ + $ret[] = array_shift($more); + } + + return $ret; + } + + //重点关注的疾病,$gene_type = 1 遗传风险,2健康疾病 + protected function get_focus_disease($block_disease,$gene_type){ + //不必做以上过滤 + if($gene_type==2){ + //重点关注里只展示中高风险的疾病,注意锁定了不要过滤 + foreach ($block_disease['列表'] as $key=>$val) { + if($val['risk_level'] < 2 && !$val['lock']){ + unset($block_disease['列表'][$key]); + } + /*由前端修改 + if($gene_type == 2){ + $tmp = explode(', ',$val['risk_detail']['风险解读']); + $val['risk_detail']['风险解读'] = $tmp[0]; + }*/ + } + //解锁状态,重新统计数量 + if($block_disease['总计']!='?'){ + $block_disease['总计'] = count($block_disease['列表']); + } + } + + //信息里面的遗传疾病,锁定不超过2个,因这部分根据不同风险等级添加了2个虚拟疾病 + $disease_lock_count = 0; + foreach ($block_disease['列表'] as $key=>$val) { + if($val['lock']){ + $disease_lock_count++; + } + if($disease_lock_count>2){ + unset($block_disease['列表'][$key]); + } + } + + return $block_disease; + } + + // 用药指导-内容太多,独立出来 + protected function drug($has_mh,$has_mdr1){ + return [ + [ + 'name'=>'恶性高热', + '携带'=>$has_mh?'是':'否', + 'get'=>$has_mh, + 'tag'=>'MH', + 'limit'=>$has_mh?'1项限制':'以下药物可遵医嘱使用', + 'data'=>[ + [ + 'name'=>'所有', + 'tag'=>'ALL', + 'data'=>[ + [ + 'name'=>'禁用药物', + 'tag'=>'jinyongyaowu', + 'data'=>[ + [ + 'name'=>'氟烷', + 'tag'=>'', + ], + [ + 'name'=>'七氟醚', + 'tag'=>'', + ], + [ + 'name'=>'地氟醚', + 'tag'=>'', + ], + [ + 'name'=>'异氟醚', + 'tag'=>'', + ], + [ + 'name'=>'安氟醚', + 'tag'=>'', + ], + [ + 'name'=>'琥珀胆碱', + 'tag'=>'', + ], + [ + 'name'=>'十烃季铵', + 'tag'=>'', + ], + ] + ] + ] + ] + ] + ], + [ + 'name'=>'MDR1', + '携带'=>$has_mdr1?'是':'否', + 'get'=>$has_mdr1, + 'limit'=>$has_mdr1?'4项限制':'以下药物可遵医嘱使用', + 'tag'=>'MDR1', + 'data'=>[ + [ + 'name'=>'抗寄生虫药', + 'tag'=>'ANTIPARASITIC', + 'data'=>[ + [ + 'name'=>'禁用药物', + 'tag'=>'jinyongyaowu', + 'data'=>[ + [ + 'name'=>'Alstomec', + 'tag'=>'伊维菌素', + ], + + [ + 'name'=>'Animec', + 'tag'=>'伊维菌素', + ], + + [ + 'name'=>'Bimectin', + 'tag'=>'伊维菌素', + ], + + [ + 'name'=>'Ivomec', + 'tag'=>'伊维菌素', + ], + + [ + 'name'=>'Panomec', + 'tag'=>'伊维菌素', + ], + + [ + 'name'=>'Qualimintic', + 'tag'=>'伊维菌素', + ], + + [ + 'name'=>'Vibamec', + 'tag'=>'伊维菌素', + ], + + [ + 'name'=>'Xeno 450', + 'tag'=>'伊维菌素', + ], + + [ + 'name'=>'Xeno 450/Xeno 450-mini', + 'tag'=>'伊维菌素', + ], + + [ + 'name'=>'Dectomax', + 'tag'=>'伊维菌素', + ], + + [ + 'name'=>'Miteguard', + 'tag'=>'伊维菌素', + ], + + [ + 'name'=>'Abamectin', + 'tag'=>'伊维菌素', + ], + + [ + 'name'=>'Profender', + 'tag'=>'伊维菌素', + ] + ], + ], + [ + 'name'=>'有潜在高风险药物', + 'tag'=>'qianzaifengxian', + 'data'=>[ + [ + 'name'=>'Milbemax', + 'tag'=>'米尔倍霉素', + ], + + [ + 'name'=>'Program plus', + 'tag'=>'米尔倍霉素', + ], + + [ + 'name'=>'Advocate', + 'tag'=>'莫昔克丁', + ], + + [ + 'name'=>'Stronghold', + 'tag'=>'塞拉菌素', + ] + ], + ], + [ + 'name'=>'密切关注副作用的药物', + 'tag'=>'miqieguanzhu', + 'data'=>[ + [ + 'name'=>'Metronidazole', + 'tag'=>'甲硝唑', + ], + + [ + 'name'=>'Stomorgyl', + 'tag'=>'甲硝唑', + ], + + [ + 'name'=>'Flagyl', + 'tag'=>'甲硝唑', + ], + + [ + 'name'=>'Metrolyl', + 'tag'=>'甲硝唑', + ] + ], + ], + [ + 'name'=>'部分犬只存在副作用的药物', + 'tag'=>'xianliangshiyong', + 'data'=>[ + [ + 'name'=>'Bob Martin Dog Wormer', + 'tag'=>'硝硫氰醚', + ], + + [ + 'name'=>'Lopatol', + 'tag'=>'硝硫氰醚', + ], + + [ + 'name'=>'Troscan', + 'tag'=>'硝硫氰醚', + ] + ], + ], + ] + ], + [ + 'name'=>'止泻药', + 'tag'=>'ANTIDIARRHEAL', + 'data'=>[ + [ + 'name'=>'禁用药物', + 'tag'=>'jinyongyaowu', + 'data'=>[ + [ + 'name'=>'Diareze', + 'tag'=>'洛哌丁胺', + ], + + [ + 'name'=>'Imodium', + 'tag'=>'洛哌丁胺', + ], + + [ + 'name'=>'Norimode', + 'tag'=>'洛哌丁胺', + ] + ], + ], + ], + ], + + [ + 'name'=>'止吐药', + 'tag'=>'ANTIEMETIC', + 'data'=>[ + [ + 'name'=>'禁用药物', + 'tag'=>'jinyongyaowu', + 'data'=>[ + [ + 'name'=>'Imodium', + 'tag'=>'甲氧氯普安', + ], + + [ + 'name'=>'Maxolon', + 'tag'=>'甲氧氯普安', + ], + + [ + 'name'=>'Metoclopramide', + 'tag'=>'甲氧氯普安', + ] + ], + ], + ], + ], + + [ + 'name'=>'镇静/镇痛药', + 'tag'=>'PRE-ANESTHETIC/ANELGESIC', + 'data'=>[ + [ + 'name'=>'密切关注副作用的药物', + 'tag'=>'miqieguanzhu', + 'data'=>[ + [ + 'name'=>'ACP', + 'tag'=>'乙酰丙嗪', + ], + + [ + 'name'=>'Alvegesic', + 'tag'=>'布托啡诺', + ], + + [ + 'name'=>'Dolorex', + 'tag'=>'布托啡诺', + ], + + [ + 'name'=>'Torbugesic', + 'tag'=>'布托啡诺', + ], + + [ + 'name'=>'Torbutrol', + 'tag'=>'布托啡诺', + ], + [ + 'name'=>'Torphasol', + 'tag'=>'布托啡诺', + ], + [ + 'name'=>'吗啡', + 'tag'=>'吗啡', + ], + [ + 'name'=>'Duramorph', + 'tag'=>'吗啡', + ], + [ + 'name'=>'Oramorph', + 'tag'=>'吗啡', + ], + [ + 'name'=>'Subutex', + 'tag'=>'丁丙诺啡', + ], + [ + 'name'=>'芬太尼', + 'tag'=>'芬太尼', + ], + [ + 'name'=>'Durogesic', + 'tag'=>'芬太尼', + ], + [ + 'name'=>'Fentora', + 'tag'=>'芬太尼', + ], + [ + 'name'=>'Sublimaze', + 'tag'=>'芬太尼', + ] + + ], + ], + + ], + ], + + [ + 'name'=>'抗癫痫药', + 'tag'=>'ANTIEPILEPTIC', + 'data'=>[ + [ + 'name'=>'密切关注副作用的药物', + 'tag'=>'miqieguanzhu', + 'data'=>[ + [ + 'name'=>'Diphenylhydantoin', + 'tag'=>'苯妥英钠', + ], + + [ + 'name'=>'Epanutin', + 'tag'=>'苯妥英钠', + ], + + [ + 'name'=>'Pentran', + 'tag'=>'苯妥英钠', + ] + ], + ], + ], + ], + + [ + 'name'=>'溃疡愈合药', + 'tag'=>'ANTIULCER', + 'data'=>[ + [ + 'name'=>'有潜在高风险药物的药物', + 'tag'=>'qianzaifengxian', + 'data'=>[ + [ + 'name'=>'多潘立酮', + 'tag'=>'多潘立酮', + ], + + [ + 'name'=>'多潘立酮', + 'tag'=>'多潘立酮', + ] + ] + ], + [ + 'name'=>'密切关注副作用的药物', + 'tag'=>'miqieguanzhu', + 'data'=>[ + [ + 'name'=>'西咪替丁', + 'tag'=>'西咪替丁', + ], + + [ + 'name'=>'Zitac', + 'tag'=>'西咪替丁', + ], + + [ + 'name'=>'Dyspamet', + 'tag'=>'西咪替丁', + ], + [ + 'name'=>'Tagamet', + 'tag'=>'西咪替丁', + ], + + [ + 'name'=>'雷尼替丁', + 'tag'=>'雷尼替丁', + ], + + [ + 'name'=>'Zantac', + 'tag'=>'雷尼替丁', + ], + + [ + 'name'=>'Zofran', + 'tag'=>'恩丹西酮', + ] + + ] + ], + ], + ], + + [ + 'name'=>'类固醇药', + 'tag'=>'STEROID', + 'data'=>[ + [ + 'name'=>'密切关注副作用的药物', + 'tag'=>'miqieguanzhu', + 'data'=>[ + [ + 'name'=>'Oestradiol benzoate', + 'tag'=>'雌二醇', + ], + + [ + 'name'=>'Mesalin', + 'tag'=>'雌二醇', + ] + ], + ], + ], + ], + + [ + 'name'=>'抗原虫药', + 'tag'=>'ANTIPROTOZOAL', + 'data'=>[ + [ + 'name'=>'部分犬只存在副作用的药物', + 'tag'=>'xianliangshiyong', + 'data'=>[ + [ + 'name'=>'Milteforan', + 'tag'=>'米替福新', + ] + ], + ], + ], + ], + + [ + 'name'=>'免疫调节剂', + 'tag'=>'IMMUNOMODULATOR', + 'data'=>[ + [ + 'name'=>'部分犬只存在副作用的药物', + 'tag'=>'xianliangshiyong', + 'data'=>[ + [ + 'name'=>'Ergamisol', + 'tag'=>'左旋咪唑', + ] + ], + ], + ], + ], + + [ + 'name'=>'免疫抑制剂', + 'tag'=>'IMMUNOSUPPRESSIVE', + 'data'=>[ + [ + 'name'=>'密切关注副作用的药物', + 'tag'=>'miqieguanzhu', + 'data'=>[ + [ + 'name'=>'Atopica', + 'tag'=>'环孢素', + ], + [ + 'name'=>'Optimmune', + 'tag'=>'环孢素', + ], + [ + 'name'=>'Neoral', + 'tag'=>'环孢素', + ], + [ + 'name'=>'Sandimmun', + 'tag'=>'环孢素', + ], + [ + 'name'=>'Aurizon', + 'tag'=>'地塞米松', + ], + [ + 'name'=>'Dexadreson', + 'tag'=>'地塞米松', + ], + [ + 'name'=>'Dexafort', + 'tag'=>'地塞米松', + ], + [ + 'name'=>'Rapidexon', + 'tag'=>'地塞米松', + ], + [ + 'name'=>'Voren', + 'tag'=>'地塞米松', + ], + [ + 'name'=>'Maxidex', + 'tag'=>'地塞米松', + ], + [ + 'name'=>'Maxitrol', + 'tag'=>'地塞米松', + ] + + ], + ], + ], + ], + + [ + 'name'=>'心血管药', + 'tag'=>'CARDIAC', + 'data'=>[ + [ + 'name'=>'密切关注副作用的药物', + 'tag'=>'miqieguanzhu', + 'data'=>[ + [ + 'name'=>'地高辛', + 'tag'=>'地高辛', + ], + [ + 'name'=>'Lanoxin', + 'tag'=>'地高辛', + ], + [ + 'name'=>'LanoxinPG', + 'tag'=>'地高辛', + ], + [ + 'name'=>'Digitoxin', + 'tag'=>'洋地黄毒苷', + ], + [ + 'name'=>'Kinidin Durules', + 'tag'=>'奎尼丁', + ], + [ + 'name'=>'硫酸奎尼丁', + 'tag'=>'奎尼丁', + ], + [ + 'name'=>'Hypercard', + 'tag'=>'地尔硫䓬', + ], + [ + 'name'=>'Dilcardia SR', + 'tag'=>'地尔硫䓬', + ], + [ + 'name'=>'维拉帕米', + 'tag'=>'维拉帕米', + ], + [ + 'name'=>'Cordilox', + 'tag'=>'维拉帕米', + ], + [ + 'name'=>'Securon', + 'tag'=>'维拉帕米', + ] + + ], + ], + ], + ], + + [ + 'name'=>'抗生素', + 'tag'=>'ANTIBACTERIAL', + 'data'=>[ + [ + 'name'=>'有潜在高风险药物', + 'tag'=>'qianzaifengxian', + 'data'=>[ + [ + 'name'=>'红霉素', + 'tag'=>'红霉素', + ], + [ + 'name'=>'Eyrthrocin', + 'tag'=>'红霉素', + ], + [ + 'name'=>'Erythroped', + 'tag'=>'红霉素', + ], + [ + 'name'=>'Stomorgyl', + 'tag'=>'螺旋霉素', + ], + [ + 'name'=>'拜有利', + 'tag'=>'恩诺沙星', + ], + [ + 'name'=>'Enrocare', + 'tag'=>'恩诺沙星', + ], + [ + 'name'=>'Enrotab', + 'tag'=>'恩诺沙星', + ], + [ + 'name'=>'Enrox', + 'tag'=>'恩诺沙星', + ], + [ + 'name'=>'Enroxil', + 'tag'=>'恩诺沙星', + ], + [ + 'name'=>'Floxabactin', + 'tag'=>'恩诺沙星', + ], + [ + 'name'=>'Floxibac', + 'tag'=>'恩诺沙星', + ], + [ + 'name'=>'Powerflox', + 'tag'=>'恩诺沙星', + ], + [ + 'name'=>'Xeden', + 'tag'=>'恩诺沙星', + ] + + ], + ], + + [ + 'name'=>'密切关注副作用的药物', + 'tag'=>'miqieguanzhu', + 'data'=>[ + [ + 'name'=>'Doxyseptin 300', + 'tag'=>'多西环素', + ], + [ + 'name'=>'Ornicure', + 'tag'=>'多西环素', + ], + [ + 'name'=>'Pulmodox', + 'tag'=>'多西环素', + ], + [ + 'name'=>'Ronaxan', + 'tag'=>'多西环素', + ], + [ + 'name'=>'Vibramycin', + 'tag'=>'多西环素', + ], + [ + 'name'=>'Vibravenos', + 'tag'=>'多西环素', + ], + [ + 'name'=>'Raxar', + 'tag'=>'格帕沙星', + ], + [ + 'name'=>'Zagam', + 'tag'=>'司氟沙星', + ], + [ + 'name'=>'利福平', + 'tag'=>'利福平', + ], + [ + 'name'=>'Rifadin', + 'tag'=>'利福平', + ], + [ + 'name'=>'Rimactane', + 'tag'=>'利福平', + ], + + ], + ], + ], + ], + [ + 'name'=>'抗真菌药', + 'tag'=>'ANTIFUNGAL', + 'data'=>[ + [ + 'name'=>'密切关注副作用的药物', + 'tag'=>'miqieguanzhu', + 'data'=>[ + [ + 'name'=>'Nizoral', + 'tag'=>'酮康唑', + ], + [ + 'name'=>'Itrafungol', + 'tag'=>'伊曲康唑', + ], + [ + 'name'=>'Sporanox', + 'tag'=>'伊曲康唑', + ], + ], + ], + ], + ], + + [ + 'name'=>'抗肿瘤药', + 'tag'=>'ANTINEOPLASTIC', + 'data'=>[ + [ + 'name'=>'密切关注副作用的药物', + 'tag'=>'miqieguanzhu', + 'data'=>[ + [ + 'name'=>'长春碱', + 'tag'=>'长春碱', + ], + [ + 'name'=>'Velbe', + 'tag'=>'长春碱', + ], + [ + 'name'=>'长春新碱', + 'tag'=>'长春新碱', + ], + [ + 'name'=>'Oncovin', + 'tag'=>'长春新碱', + ], + [ + 'name'=>'多柔比星', + 'tag'=>'多柔比星', + ], + [ + 'name'=>'Taxol', + 'tag'=>'紫杉醇', + ], + [ + 'name'=>'放线菌素', + 'tag'=>'放线菌素', + ], + [ + 'name'=>'Cosmegen', + 'tag'=>'放线菌素', + ], + [ + 'name'=>'Lyovac', + 'tag'=>'放线菌素', + ], + [ + 'name'=>'Novantrone', + 'tag'=>'米托蒽醌', + ], + [ + 'name'=>'Etopophos ', + 'tag'=>'依托泊甙', + ], + [ + 'name'=>'Toposar', + 'tag'=>'依托泊甙', + ] + ], + ], + ], + ], + + + ] + ], + ]; + } + +} diff --git a/models/Report_model.php.bak b/models/Report_model.php.bak new file mode 100644 index 0000000..d6a2e39 --- /dev/null +++ b/models/Report_model.php.bak @@ -0,0 +1,2175 @@ +'uahpet/database/犬/JSON/', + //猫 + 2=>'uahpet/database/猫/JSON/', + ]; + + /** + * __construct function. + * + * @access public + * @return void + */ + public function __construct() { + + parent::__construct(); + //$this->load->database(); + + } + + //报告路径 + public function report_file_path($deviceID,$petSpecies=1){ + $path = $petSpecies == 1?self::DIR_REPORT_DATA:self::DIR_REPORT_DATA_CAT; + return APPPATH.$path.($deviceID).'.json'; + } + + //报告路径 + public function get_report_json($deviceID,$petSpecies=1){ + //报告文件 + $file = $this->report_file_path($deviceID,$petSpecies); + if(!file_exists($file)){ + return []; + } + $reportJson = file_get_contents($file); + return json_decode($reportJson,true); + } + + + //报告是否生成 + public function is_report_ready($deviceID){ + return file_exists( + $this->report_file_path($deviceID) + ); + } + + //获取家族树 + public function family_tree_img($deviceID){ + $file = Report_model::DIR_REPORT_FAMILY_TREE.strtoupper($deviceID).'.jpg'; + if(file_exists(APPPATH.$file)){ + return base_url('views/'.$file); + } + $file = Report_model::DIR_REPORT_DATA.strtoupper($deviceID).'.jpg'; + if(file_exists(APPPATH.$file)){ + return base_url('views/'.$file); + } + return false; + } + + //报告统计 + public function get_report_count() { + + $files = scandir(APPPATH.self::DIR_REPORT_DATA); + $count = 0; + foreach($files as $file){ + if($file === '.' || $file === '..'){ + continue; + } + if(substr($file,-5) === '.json'){ + $count++; + } + } + return $count; + + } + + //素材 + public function get_material($petSpecies=1,$isBreeding=false){ + if(!is_null($this->_material)){ + return $this->_material; + } + //区分繁育版 + $diseaseSingleGene = [ + //狗 + 1=>'犬类单基因疾病', + //猫 + 2=>$isBreeding?'猫类单基因遗传病繁育版':'猫类单基因遗传病', + ]; + //根据报告内容,解析建议文字 + $materialFileName = [ + //狗 + 1=>[ + //'交互式报告素材', + //'猫类单基因疾病', + $diseaseSingleGene[1]=>'单基因疾病', + '犬类单基因疾病医护建议'=>'单基因疾病医护建议', + '犬类复杂疾病'=>'多基因疾病', + '犬类品系'=>'品系', + ], + //猫 + 2=>[ + //'交互式报告素材', + //'猫类单基因疾病', + $diseaseSingleGene[2]=>'单基因疾病', + '猫类单基因疾病医护建议'=>'单基因疾病医护建议', + '猫类复杂疾病'=>'多基因疾病', + '猫品系'=>'品系', + '猫血型'=>'血型', + ], + ]; + //报告素材 + $material = []; + foreach ($materialFileName[$petSpecies] as $name=>$uni_name) { + if(PHP_OS == 'WINNT'){ + $name = iconv('UTF-8','GB2312',$name); + } + //猫没有多基因疾病与医护建议 + if(in_array($name,['猫类单基因疾病医护建议','猫类复杂疾病'])){ + $material[$uni_name] = []; + continue; + } + $_content = file_get_contents(APPPATH.self::DIR_MATERIAL[$petSpecies].$name.'.json'); + $material[$uni_name] = json_decode($_content,true); + } + //猫的品系资料转换 + if($petSpecies == 2){ + foreach ($material['品系'] as $key=>$val) { + $material['品系'][$key]['犬种特点'] = $val['猫种特点']; + } + } + $this->_material = $material; + return $material; + } + + //获取疾病解锁信息 + public function get_disease_unlock($sample=[],$package=[]){ + if(!is_null($this->_disease_unlock)){ + return $this->_disease_unlock; + } + //解锁疾病 + $unlockDisease = []; + if(!empty($package['disease'])){ + $package['disease'] = explode(',',$package['disease']); + $this->load->model('disease_model'); + $unlockDisease = $this->disease_model->get($package['disease'],'base.id',true,'base.name'); + $unlockDisease = array_column($unlockDisease,'name'); + foreach ($unlockDisease as &$item) { + $item = trim($item); + } + } + + //如果样品选择了某个套餐,就直接解锁 + $custom = $this->get_disease_custom($sample); + + + if(!empty($custom['disease_name'])){ + $unlockDisease = array_merge($unlockDisease,$custom['disease_name']); + } + $this->_disease_unlock = $unlockDisease; + return $unlockDisease; + } + + //获取疾病自选信息 + public function get_disease_custom($sample=[]){ + if(!is_null($this->_disease_custom)){ + return $this->_disease_custom; + } + $unlockDisease = []; + if(!empty($sample['package_custom'])){ + $unlockDisease = json_decode($sample['package_custom'],true); + } + $this->_disease_custom = $unlockDisease; + return $this->_disease_custom; + } + + /** + * 获取疾病列表带锁定信息 + * @param $gene_type int 基因类型 1单基因 2多基因 + * @param $sample array 样品资料,需要用它获取选择的疾病 + * @param $report_json array 报告数据文件,用它获取是否已得病 + * @param $package array 套餐数据,获取锁定套餐 + * @param $need_category int 是否需要分类 + * @param $need_detail int 是否需要明细 + * @param $hidden_locked bool 锁定时,是否隐藏明细 + * @return mixed + */ + public function get_disease_list($gene_type=0,$sample=[],$report_json=[],$package=[],$need_category=0,$need_detail=0,$hidden_locked=true){ + $material = $this->get_material($sample['pet_species'],$package['is_breed']); + //区分单基因/多基因 1单基因 2多基因,便于检测不出来时区分显示风险描述 + foreach ($material['单基因疾病'] as $key=>$val) { + $material['单基因疾病'][$key]['gene_type'] = 1; + } + foreach ($material['多基因疾病'] as $key=>$val) { + $material['多基因疾病'][$key]['gene_type'] = 1; + } + if(empty($gene_type)){ + $list = array_merge($material['单基因疾病'],$material['多基因疾病']); + }elseif($gene_type=='1'){ + $list = array_merge($material['单基因疾病']); + }else{ + $list = array_merge($material['多基因疾病']); + } + + + //分类对应 + $map = [ + '代谢类疾病'=>'代谢免疫', + '代谢类遗传病'=>'代谢免疫', + '代谢类遗传疾病'=>'代谢免疫', + '代谢性遗传病'=>'代谢免疫', + '耳科疾病'=>'五官皮肤', + '关节类疾病'=>'内科', + '泌尿生殖系统遗传疾病'=>'内科', + '泌尿系统疾病'=>'内科', + '泌尿系统类遗传疾病'=>'内科', + '泌尿系统遗传病'=>'内科', + '免疫缺陷遗传病'=>'代谢免疫', + '免疫系统遗传病'=>'代谢免疫', + '内分泌系统遗传病'=>'内科', + '皮肤类疾病'=>'五官皮肤', + '皮肤类遗传病'=>'五官皮肤', + '皮肤类肿瘤疾病'=>'五官皮肤', + '皮肤肿瘤疾病'=>'五官皮肤', + '其他遗传疾病'=>'内科', + '神经类遗传病'=>'神经系统', + '神经系统疾病'=>'神经系统', + '神经系统遗传病'=>'神经系统', + '神经系统遗传疾病'=>'神经系统', + '睡眠病'=>'神经系统', + '糖类代谢类遗传疾病'=>'代谢免疫', + '消化系统疾病'=>'内科', + '消化系统遗传病'=>'内科', + '心血管系统疾病'=>'血液心脏', + '心血管系统遗传病'=>'血液心脏', + '血液类遗传病'=>'血液心脏', + '血液类遗传疾病'=>'血液心脏', + '血液淋巴系统疾病'=>'血液心脏', + '血液系统遗传病'=>'血液心脏', + '血液遗传病'=>'血液心脏', + '血液遗传疾病'=>'血液心脏', + '眼科遗传病'=>'五官皮肤', + '药物代谢类遗传疾病'=>'代谢免疫', + '代谢免疫类疾病'=>'代谢免疫', + '遗传性眼病'=>'五官皮肤', + '骨科遗传病'=>'内科', + '骨骼肌肉类疾病'=>'内科', + '骨骼肌肉系统遗传病'=>'内科', + '骨骼肌肉遗传病'=>'内科', + '骨骼类遗传病'=>'内科', + '骨骼类肿瘤疾病'=>'内科', + '骨骼系统遗传病'=>'内科', + '骨骼肌肉类遗传病'=>'内科', + '肌肉骨骼系统遗传病'=>'内科', + '肌肉骨骼类遗传病'=>'内科', + '肌肉类遗传病'=>'内科', + '肌肉系统类遗传病'=>'内科', + '肌肉系统遗传病'=>'内科', + '肌肉遗传病'=>'内科', + ]; + + //猫品系额外处理 + $map_cat = [ + '泌尿生殖系统遗传病'=>'泌尿生殖', + '骨科遗传病'=>'肌肉骨骼', + '骨骼肌肉类疾病'=>'肌肉骨骼', + '骨骼肌肉系统遗传病'=>'肌肉骨骼', + '骨骼肌肉遗传病'=>'肌肉骨骼', + '骨骼类遗传病'=>'肌肉骨骼', + '骨骼类肿瘤疾病'=>'肌肉骨骼', + '骨骼系统遗传病'=>'肌肉骨骼', + '骨骼肌肉类遗传病'=>'肌肉骨骼', + '肌肉骨骼系统遗传病'=>'肌肉骨骼', + '肌肉骨骼类遗传病'=>'肌肉骨骼', + '肌肉类遗传病'=>'肌肉骨骼', + '肌肉系统类遗传病'=>'肌肉骨骼', + '肌肉系统遗传病'=>'肌肉骨骼', + '肌肉遗传病'=>'肌肉骨骼', + ]; + if($sample['pet_species'] == 2){ + $map = array_merge($map,$map_cat); + } + + //锁定疾病,里面已经考虑了套餐选择项 + $unlockDisease = $this->get_disease_unlock($sample,$package); +// var_dump(array_keys($list)); +// var_dump($unlockDisease);die; + + + //是否存在风险 + $riskDisease = $report_json['遗传疾病']['body']['单基因疾病']['body']; + if(isset($report_json['健康风险']['body']['复杂疾病性状']['body'])){ + $riskDisease = array_merge($riskDisease,$report_json['健康风险']['body']['复杂疾病性状']['body']); + } + + $out = []; + foreach ($list as $name=>$val) { + $name = trim($name); + $tmp = [ + //是否锁定 + 'lock'=>!in_array($name,$unlockDisease), + 'name'=>$name, + 'gene_type'=>$val['gene_type'], + 'risk'=>false, + 'risk_detail'=>false, + ]; + //详情 + if($need_detail){ + $tmp['detail'] = $val; + } + + //风险项,没有锁定时才展示 + if((!$hidden_locked || !$tmp['lock']) && isset($riskDisease[$name])){ + $tmp['risk'] = true; + + //区分猫狗,猫没有放body + if($sample['pet_species'] == 2) { + $tmp['risk_detail'] = $riskDisease[$name]; + if($tmp['risk_detail']["检测结果"] == "纯合突变" OR $tmp['risk_detail']["遗传模式"] == "显性遗传"){ + $tmp['risk_level'] = 2; + }else{ + $tmp['risk_level'] = 1; + } + //为“折耳和软骨发育不良”单独判定 + if($name == '折耳和软骨发育不良'){ + if($tmp['risk_detail']["检测结果"] == "纯合突变"){ + $tmp['risk_level'] = 2; + }else{ + $tmp['risk_level'] = 1; + } + } + }else{ + $tmp['risk_detail'] = $riskDisease[$name]['body']; + //风险等级 + switch ($tmp['risk_detail']['检测结果']) { + case '患病': + case '中等风险': + case '高风险': + case '有极高的发病风险'://风险解读 + $tmp['risk_level'] = 2; + break; + case '携带致病突变': + case '普通风险': + case '低风险': + case '低发病风险'://风险解读 + $tmp['risk_level'] = 1; + break; + } + } + } + + //是否分类 + if(!empty($need_category)){ + //部分素材不是疾病,是禁用药物罗列 + if(empty($val['所属类别'])){ + continue; + } + if(empty($map[$val['所属类别']])){ + continue; + } + $out[$map[$val['所属类别']]][] = $tmp; + }else{ + $out[] = $tmp; + } + } + + return $out; + } + + //拼装报告结构 + public function get_result($deviceID,$ignoreStep=false){ + //样品及套餐信息 + $this->load->model('sample_model'); + $this->load->model('package_model'); + $sample = $this->sample_model->get($deviceID,'device_id'); + if(!$sample){ + return []; + } + //样品未完成是否返回 + if(!$ignoreStep && $sample['step']!=Sample_model::STEP_COMPLETE){ + return []; + } + //资料来源:json + $json = $this->get_report_json($deviceID,$sample['pet_species']); + if(empty($json)){ + return []; + } + //补充图片,物种 + if(empty($sample['pet_img'])){ + $sample['pet_img'] = base_url().'uploads/default/common.jpg'; + } + //套餐设置成1,上线后删除 + //$sample['package_id'] = 1; + $package = $this->package_model->get($sample['package_id']); + if(!$package){ + return []; + } + $package['structure'] = explode(',',$package['structure']); + $package['structure_hide'] = explode(',',$package['structure_hide']); + $package['cert'] = array_filter(explode(',',$package['cert'])); + //素材对应 + $material = $this->get_material($sample['pet_species'],$package['is_breed']); + //模块对应 + /* + $main = [ + '爱宠大揭秘'=>[], + '健康大调查'=>[], + '养育大宝典'=>[], + '基因全解锁'=>[], + ]; + */ + $block_list = [ + '品系鉴定', + '智力评估', + '性格行为', + '遗传疾病', + '健康风险', + '用药指导', + '繁育建议', + '饮食建议', + '毛发美护', + '可训练性', + '血型筛查', + ]; + + $blocks = []; + foreach ($block_list as $val) { + $blocks[$val] = $this->get_block($val,$json,$sample,$package,$material,$json['header']['宠物名']); + } + + //营养结果固化 + if(empty($sample['diet_nutrition']) && !empty($blocks['饮食建议']['营养代谢'])){ + $this->sample_model->update([ + 'diet_nutrition'=>json_encode($blocks['饮食建议']['营养代谢'],JSON_UNESCAPED_UNICODE) + ],[ + 'id'=>$sample['id'] + ]); + } + + //绑定套餐信息:版块、证书;疾病、升级目标不处理 + $ret = [ + '信息'=>[ + '编号'=>$deviceID, + '宠物照片'=>$sample['pet_img'], + //'昵称'=>$json['header']['宠物名'], + '昵称'=>$sample['pet_name'], + '养育人'=>$sample['name'], + '测试日期'=>date('Y-m-d',$sample['create_time']), + '物种'=>$package['species'],//1狗2猫 + '个性标签'=>$this->get_speciality($sample,$json,$package), + '证书'=>$package['cert'], + '是繁育版'=>!empty($package['is_breed']), + //'证书'=>'健康证书', + //防止疾病被过滤之后 + '遗传疾病'=>$this->get_focus_disease($blocks['遗传疾病'],1), + '健康风险'=>$this->get_focus_disease($blocks['健康风险'],2), + '可升级'=>!empty($package['package_up']) && $package['package_up'] != $package['id'], + ], + ]; + //套餐不允许展示的版块不展示 + //$blocks = array_intersect(array_merge($package['structure'],'信息'),$blocks); + $package['structure'][] = '信息'; + //开放版块排序在前 + $blocks_open = []; + $blocks_lock = []; + foreach ($blocks as $key=>$val) { + if(in_array($key,$package['structure'])){ + $val['lock'] = false; + $val['view'] = true; + $blocks_open[$key] = $val; + continue; + } + $val = [ + 'lock'=>true, + 'view'=>!in_array($key,$package['structure_hide']) + ]; + $blocks_lock[$key] = $val; + } + $ret = array_merge($blocks_open,$blocks_lock,$ret); + return $ret; + + } + + + /** + * @param $block 版块名称 + * @param $reportJson 报告json + * @param $material 素材 + * @param $name 宠物名称 + * @param $sample 样品数据 + * @param $package 套餐数据 + * @return array + */ + public function get_block($block,$reportJson,$sample,$package,$material,$name){ + switch ($block){ + case '品系鉴定': + //血统分析-家族树 + //品系素材文字提取 + $temp = []; + if(!empty($reportJson['血统分析']['body']['品系纯度'])){ + $list = $reportJson['血统分析']['body']['品系纯度']; + array_multisort($list,SORT_DESC, SORT_NUMERIC ,$list); + foreach ($list as $key => $val){ + $temp[] = [ + '名称'=>$key, + '占比'=>$val, + '介绍'=>!empty($material['品系'][$key])?$material['品系'][$key]:'', + ]; + } + } + /* + $temp = [ + '品系鉴定'=>'', + '血统分析'=>'', + '品种分析'=>'', + '遗传特征'=>[ + '遗传特征'=>'', + '基因毛色'=>'', + '基因毛型'=>'' + ] + ];*/ + $temp = ['列表'=>$temp]; + break; + case '智力评估': + //print_r($reportJson);die; + $rate = $reportJson['遗传特征']['body']['智商指数']['body']['智商指数']; + $rate = round($rate); + //狗狗智商评分内容 + $map[1] = [ + 3=>[ + '检测结果'=>'优秀汪', + '结论'=>"{$name}是只聪明的狗狗,新指令重复15-25次后根据个体差异,会有不同程度的掌握。它对第一次指令作出的回应几率是70%,表现的优劣取决于练习时间的多寡。整体来说,有时反应慢半拍,但依然不妨碍它学习的很好。但如果训练者缺乏经验,或过于严厉或没耐心,狗狗的表现也会受到影响。", + '描述'=>"对于新的指令,在重复15-25次后可以理解新的指令,70%以上的时间服从主人的第一个命令", + ], + 4=>[ + '检测结果'=>'学霸汪', + '结论'=>"{$name}是一只智力上等的狗狗,简单指令学习5-15次便能学会。它遵守第一次指令的机率是85%,对于稍微复杂的指令只要多练习就能掌握。当主人离它们较远时,它也会有反应。即使训练人员经验稍微不足,还是有办法将这些狗调教得很优秀。", + '描述'=>"对于新的指令,在重复5-15次后可以理解新的指令,85%以上的时间服从主人的第一个命令", + ], + 5=>[ + '检测结果'=>'天才汪', + '结论'=>"恭喜您,{$name}是一只智力超群的天才狗,一般情况下听到新指令5次以内,就会理解需要完成的动作并牢牢记住。主人下达命令时,它的完成度高达95%以上,并且能够在3秒内做出反应。即使训练它们的人经验不足,它也可以学习得很好。", + '描述'=>"对于新的指令,不用下达超过5次,就能理解是什么意思,并且95%以上的时间对主人的第一个命令是服从的。", + ] + ]; + // 猫智力 + $map[2] = [ + 5=>[ + "检测结果"=>"天才喵", + "描述"=>"{$name}是猫中天才,只要稍加训练,甚至能像狗那样听话,比如把东西叼回对它们来说就是小菜一碟。" + ], + 4=> [ + "检测结果"=>"学霸喵", + "描述"=> "{$name}不仅有超高的智商,还有超强的服从性,可以和人很好的互动,稍加训练甚至可以带出门遛弯,可以通过看你做事情而去学习,比如开门,比如自己偷翻吃的。" + ], + 3=> [ + "检测结果"=>"优秀喵", + "描述"=> "{$name}聪明,性格好,拥有很强的观察力和学习能力,会粘人,但又总保持着自己的本性。" + ] + ]; + $map = $map[$sample['pet_species']]; + $temp = [ + '智力指数'=>$rate, + '智力描述'=>$map[$rate], + ]; + + break; + case '遗传疾病': + /* + $temp = [ + '关键数据结果'=>'', + '检测类目'=>'', + ]; + */ + $list = $reportJson['遗传疾病']['body']['单基因疾病']['body']; + //获取疾病列表检测是否被锁定,如被锁定,隐藏关键信息 + $diseaseList = $this->get_disease_list(1,$sample,$reportJson,$package,false,true,false); + $temp = $this->get_disease_block($sample,$list,$diseaseList,true); + break; + case '健康风险': + $list = isset($reportJson['健康风险']['body']['复杂疾病性状']['body'])?$reportJson['健康风险']['body']['复杂疾病性状']['body']:[]; + //健康风险,按照风险值排序 + $temp = []; + foreach ($list as $key => $val) { + $val['body']['风险解读'] = explode(',',$val['body']['风险解读']); + $temp[] = (int)str_replace('高于','',$val['body']['风险解读'][1]); + } + array_multisort($temp,SORT_DESC, SORT_NUMERIC ,$list); + rsort($temp); + /* + $temp = [ + '风险系数'=>'', + '风险介绍'=>[ + '致病机理'=>'', + '临床症状'=>'', + '所属类别'=>'', + ], + '养育建议'=>'', + ];*/ + //获取疾病列表检测是否被锁定,如被锁定,隐藏关键信息 + $diseaseList = $this->get_disease_list(2,$sample,$reportJson,$package,false,true,false); + $temp = $this->get_disease_block($sample,$list,$diseaseList,false); + break; + case '用药指导': + $riskDisease = $reportJson['遗传疾病']['body']['单基因疾病']['body']; + $temp = $this->drug( + isset($riskDisease['恶性高热']), + isset($riskDisease['多重药物敏感风险']) || isset($riskDisease['多重药物敏感']) + ); + $temp = ['列表'=>$temp]; + break; + case '饮食建议': + $result = [ + '蛋白质'=>'正常', + '钠'=>'正常', + '牛磺酸'=>'正常', + 'omega-3'=>'正常', + 'EPA和DHA'=>'正常', + '抗氧化剂'=>'正常', + 'L-肉碱'=>'正常', + '叶酸'=>'正常', + '维生素B'=>'正常', + '维生素C'=>'正常', + '维生素E'=>'正常', + '铁'=>'正常', + '氨基葡萄糖和硫酸软骨素'=>'正常', + '碳水化合物'=>'正常', + '水'=>'正常', + '辅酶Q10'=>'正常', + '磷'=>'正常' + ]; + //饮食指导 + //区分单基因/多基因 1单基因 2多基因 + $map = $material['单基因疾病医护建议']; + //依赖遗传病 + $diseaseList = $this->get_disease_list(1,$sample,$reportJson,$package,false,false,false); + $suggestion = []; + foreach ($diseaseList as $disease) { + if($disease['risk'] && !$disease['lock'] && isset($map[$disease['name']]["喂养建议 "])){ + $suggestion[] = $map[$disease['name']]["喂养建议 "]; + break; + } + } + $suggestion = implode('',$suggestion); + //营养代谢结果,增加随机性,并保存到sample里 + if(!empty($sample['diet_nutrition'])){ + $result = json_decode($sample['diet_nutrition']); + }else{ + $nutrition = isset($reportJson['营养代谢']['body']['营养代谢综合结果'])?$reportJson['营养代谢']['body']['营养代谢综合结果']:[]; + if(!is_null($nutrition)){ + $result = array_merge($result,$nutrition); + } + foreach ($result as $key=>$val) { + $v = 0; + switch ($val){ + case '微量': + $v = 1; + break; + case '少量': + $v = rand(2,3); + break; + case '正常': + $v = rand(4,7); + break; + case '稍高': + $v = rand(8,9); + break; + case '稍多': + $v = rand(8,9); + break; + case '多量': + $v = 10; + break; + } + $result[$key] = [ + '结果'=>$val, + '值'=>$v, + ]; + } + } + $temp = [ + '饮食结构'=>isset($reportJson['营养代谢']['body']['饮食结构'])?$reportJson['营养代谢']['body']['饮食结构']:'', + '饮食指导'=>$suggestion, + '营养代谢'=>$result, + ]; + //猫 + if($sample['pet_species'] == 2){ + unset($temp['营养代谢']); + } + break; + case '繁育建议': + //毛色 + $color = $reportJson['进阶项目研究']['body']['毛色分析']['body']['成年毛色预测']; + $type = $reportJson['进阶项目研究']['body']['毛型分析']['body']['成年毛型预测']; + //echo $color;die; + //$color = '白色或者黑色'; + $colors = str_replace([',','或者','或'],',',$color); + $colors = explode(',',$colors); + $color_out = []; + foreach ($colors as $key=>$val) { + //括号内的描述去掉 + $val = str_replace(['(','('],',',$val); + $val = explode(',',$val); + $val = $val[0]; + //还剩一种情况,用/分隔 + $val = explode('/',$val); + foreach ($val as $v) { + $color_out[] = trim($v); + } + } + $color_out = array_values(array_filter($color_out)); + //遗传病 + $material = $this->get_material($sample['pet_species'],$package['is_breed']); + //区分单基因/多基因 1单基因 2多基因 + $map = [ + //狗 + 1=>$material['单基因疾病医护建议'], + //猫 + 2=>$material['单基因疾病'], + ]; + $map = $map[$sample['pet_species']]; + //建议中的节点 + $map_key = [ + //狗 + 1=>'育种建议', + //猫 + 2=>'繁育建议', + ]; + $map_key = $map_key[$sample['pet_species']]; + //依赖遗传病 + $resultNotice = '可繁育'; + $diseaseList = $this->get_disease_list(1,$sample,$reportJson,$package,false,false,false); + $suggestion = []; + foreach ($diseaseList as $disease) { + if($disease['risk'] && !$disease['lock'] && isset($map[$disease['name']][$map_key])){ + $resultNotice = '不建议繁育'; + $suggestion[] = $map[$disease['name']][$map_key]; + break; + } + } + if(empty($suggestion)){ + //对于狗,还要检查健康风险 + if($sample['pet_species'] == 1){ + //重新获取健康风险,这里需要考虑解锁情况 + $diseaseList = $this->get_disease_list(2,$sample,$reportJson,$package,false,false,false); + //print_r($diseaseList);die; + foreach ($diseaseList as $disease) { + if($disease['risk'] && !$disease['lock']){ + //分析相对风险值,例如:相对风险值73.93, 高于99.9%犬只 + $temp = explode('高于',$disease['risk_detail']['风险解读']); + $temp = (int)$temp[1]; + if($temp>=90){ + $resultNotice = '不建议繁育'; + $suggestion[] = $disease['name'].':'.$disease['risk_detail']['检测结果'].','.$disease['risk_detail']['风险解读']; + break; + } + } + } + } + if(empty($suggestion)){ + $suggestion[] = '您的爱宠没有检测出遗传隐患,可放心繁育下一代,生出健康漂亮的宝宝。'; + } + } + $suggestion = implode('',$suggestion); + + $temp = [ + '结果'=>$resultNotice, + '建议'=>$suggestion, + '毛色'=>$color_out, + '毛型'=>$type, + '毛型类别'=>strpos($type,'直') === false?'卷':'直',//1直2卷 + ]; + //猫 + /* + if($sample['pet_species'] == 2){ + unset($temp['毛色'],$temp['毛型'],$temp['毛型类别']); + }*/ + break; + case '毛发美护': + $rate = round($reportJson['洗护建议']['body']['梳毛护理星级']); + $map = [ + //狗 + 1=>[ + "梳毛护理相关知识点"=>"星星表明你的爱犬需要梳理的频度,以保持它被毛的最佳状态。", + 1=>"每周1次:{$name}的被毛几乎不用特别梳理就可以有型,但不能保证地毯沙发上没有狗毛,定期梳理可大程度减少狗因褪毛而到处飞扬的狗毛。", + 2=>"每周2-3次:{$name}的被毛不会太难打理,定期梳理可大程度减少狗毛乱飞,同时也有助于你们的感情培养哦。", + 3=>"每天1次:{$name}的被毛褪毛较多,频繁的梳理可以尽量去除掉落的被毛并防止里层被毛缠结,另外每天梳理有助于你与它感情的培养哦。", + ], + 2=>[ + "梳毛护理相关知识点"=> "指猫咪被毛需要梳理的频率,得分越高,需要梳理的次数越多。", + "1"=> "每周1次:{$name}的被毛几乎不用特别梳理就可以有型,但不能保证地毯沙发上没有猫毛,定期梳理可大程度减少猫因褪毛而到处飞扬的猫毛。", + "2"=> "每周2-3次:{$name}的被毛不会太难打理,定期梳理可大程度减少猫毛乱飞,同时也是预防毛球症很好的方式之一。", + "3"=> "每天1次:{$name}的被毛褪毛较多,频繁的梳理可以尽量去除掉落的被毛并防止里层被毛缠结,同时也是预防毛球症很好的方式之一。另外每天梳理有助于你与它感情的培养哦。", + ] + ]; + $map = $map[$sample['pet_species']]; + //疾病 + $diseaseList = $this->get_disease_list(0,$sample,$reportJson,$package,false,false,false); + $washMap = [ + "GM2神经节苷脂沉着症"=> "{$name}需要舒适的床上用品,如空气床垫、水床、休闲椅垫、人用床垫、羊毛、睡袋、毯子、稻草或其他柔软舒适的东西。你需要经常更换床上用品的外层,并且需要定期帮它洗澡,以防它由于大小便失禁引起褥疮、尿烧伤、皮肤溃疡等其他疾病。在尾巴和肛门周围的毛发应该经常修剪。", + "多发性神经病"=> "{$name}需要舒适的床上用品,如空气床垫、水床、休闲椅垫、人用床垫、羊毛、睡袋、毯子、稻草或其他柔软舒适的东西。你需要经常更换床上用品的外层,并且需要定期帮它洗澡,以防它由于大小便失禁引起褥疮、尿烧伤、皮肤溃疡等其他疾病。在尾巴和肛门周围的毛发应该经常修剪。", + "感觉神经失调性神经病"=> "{$name}长期缺乏运动,需要给它提供足够柔软的睡垫并注意清洁,避免褥疮及皮肤疾病。", + "皮肤脆性综合征"=> "{$name}需要限制运动,生活环境以柔软为主,玩耍时注意力度,避免撕裂皮肤。增加剪指甲频率,防止它抓挠身体,避免受外伤。由于它的皮肤免疫力较低,应注意生活环境清洁,不要与有皮肤病的宠物接触,避免继发或加重皮肤疾病。当发现它的皮肤出现撕裂,发红,瘙痒,脱毛,化脓等异常时及时送诊。", + "球形细胞脑白质营养不良"=> "{$name}需要舒适的床上用品,如空气床垫、水床、休闲椅垫、人用床垫、羊毛、睡袋、毯子、稻草或其他柔软舒适的东西。你需要经常更换床上用品的外层,并且需要定期帮它洗澡,以防它由于大小便失禁引起褥疮、尿烧伤、皮肤溃疡等其他疾病。在尾巴和肛门周围的毛发应该经常修剪。", + "神经节苷脂病-1型"=> "{$name}需要舒适的床上用品,如空气床垫、水床、休闲椅垫、人用床垫、羊毛、睡袋、毯子、稻草或其他柔软舒适的东西。你需要经常更换床上用品的外层,并且需要定期帮它洗澡,以防它由于大小便失禁引起褥疮、尿烧伤、皮肤溃疡等其他疾病。在尾巴和肛门周围的毛发应该经常修剪。", + "退行性脊髓病"=> "{$name}需要舒适的床上用品,如空气床垫、水床、休闲椅垫、人用床垫、羊毛、睡袋、毯子、稻草或其他柔软舒适的东西。你需要经常更换床上用品的外层,并且需要定期帮它洗澡,以防它由于大小便失禁引起褥疮、尿烧伤、皮肤溃疡等其他疾病。在尾巴和肛门周围的毛发应该经常修剪。", + "岩藻糖苷贮积症"=> "{$name}需要舒适的床上用品,如空气床垫、水床、休闲椅垫、人用床垫、羊毛、睡袋、毯子、稻草或其他柔软舒适的东西。你需要经常更换床上用品的外层,并且需要定期帮它洗澡,以防它由于大小便失禁引起褥疮、尿烧伤、皮肤溃疡等其他疾病。在尾巴和肛门周围的毛发应该经常修剪。", + "鱼鳞病"=> "可使用香波冲洗皮肤,刷牙和毛发梳理等物理手段进行症状的缓解。皮肤可使用温和的抗脂溢性香波和保湿霜可用来在宠物皮肤上创造一个保护层,减少水分流失。" + ]; + //var_dump($diseaseList);die; + $washNotice = '无特别洗护要求'; + foreach ($diseaseList as $disease) { + if($disease['risk'] && !$disease['lock'] && isset($washMap[$disease['name']])){ + $washNotice = $washMap[$disease['name']]; + break; + } + } + $temp = [ + '梳毛护理星级'=>$rate, + '梳毛建议'=>$map[$rate], + '梳毛说明'=>$map["梳毛护理相关知识点"], + '洗护要求'=>$washNotice, + ]; + break; + case '性格行为': + /* + $temp = [ + '活力值'=>'', + '胆量值'=>'', + '暴躁值'=>'', + '吠叫值'=>'', + '独处值'=>'', + '排尿值'=>'', + ];*/ + //狗 + $map[1] = [ + "胆量值"=>[ + "描述"=>"指犬只对陌生事物的恐惧感及焦虑情绪,分数越高,越容易有恐惧或焦虑的情绪。", + "1"=>"{$name}是只胆大包天的狗狗,这个世界上似乎没有它害怕的事物。", + "2"=>"{$name}是只勇敢的狗狗,内心平静,是很稳重的孩子。", + "3"=>"{$name}是只勇敢的狗狗,内心平静,是很稳重的孩子。", + "4"=>"{$name}稍微有点胆小,容易焦虑,希望世界对它温柔以待。", + "5"=>"{$name}稍微有点胆小,容易焦虑,希望世界对它温柔以待。", + ], + "暴躁值"=>[ + "描述"=>"指犬只的攻击性,得分越高,越容易产生攻击行为,与战斗力无关。", + "1"=>"{$name}是只人畜无害的狗子,狗中铁憨憨。", + "2"=>"{$name}是典型的人不犯我我不犯人的狗子,不去惹毛它就不会炸毛。", + "3"=>"{$name}是典型的人不犯我我不犯人的狗子,不去惹毛它就不会炸毛。", + "4"=>"{$name}性子比较急,不要尝试去挑战它的底线,别老虎不发威就把它当HelloKitty。", + "5"=>"{$name}性子比较急,不要尝试去挑战它的底线,别老虎不发威就把它当HelloKitty。", + ], + + "吠叫值"=>[ + "描述"=>"指犬只的持续吠叫程度,分数越高,表示当犬只兴奋或受到刺激时,持续吠叫的情况越严重。", + "1"=>"{$name}可以说是最不爱说话的一类狗子了,这种不吵闹的狗子是多少人的理想型。", + "2"=>"{$name}兴奋或受到刺激的时候喜欢叫,注意观察它在说什么,它可不是随便说说而已哦。", + "3"=>"{$name}兴奋或受到刺激的时候喜欢叫,注意观察它在说什么,它可不是随便说说而已哦。", + "4"=>"{$name}天生是个话痨,有事没事就爱瞎哔哔,如果它并没有这么做,那么恭喜你,它为了融入你的生活改变了天性。", + "5"=>"{$name}天生是个话痨,有事没事就爱瞎哔哔,如果它并没有这么做,那么恭喜你,它为了融入你的生活改变了天性。", + ], + "独处值"=>[ + "描述"=>"指犬只对孤独的感知度,是否容易产生分离焦虑,分数越高,孤独的感知能力越强,独处能力越低。", + "1"=>"{$name}是只学会享受孤独的狗子,独处能力很强,但并不代表它不想和你在一起,要知道,和你在一起的时光才是它最开心的。", + "2"=>"{$name}是懂事的狗子,能够自己独处上一段时间,但是它同时也很想你,不要让它等太久。", + "3"=>"{$name}是懂事的狗子,能够自己独处上一段时间,但是它同时也很想你,不要让它等太久。", + "4"=>"{$name}觉得与你分离是世界上最难过的事,尽量多陪陪它吧,你不在的时候,它可能偷偷伤心了很久。", + "5"=>"{$name}觉得与你分离是世界上最难过的事,尽量多陪陪它吧,你不在的时候,它可能偷偷伤心了很久。", + ], + "排尿值"=>[ + "描述"=>"指犬只独自在家时乱排尿的情况,得分越高,乱排尿的可能性越大。", + "1"=>"{$name}是只讲规则的狗子,只要你事先与它确定了规则,它是不会随地尿尿的。", + "2"=>"{$name}通常不会随意尿尿,除非它忍不住或者它想通过尿尿告诉你什么。", + "3"=>"{$name}通常不会随意尿尿,除非它忍不住或者它想通过尿尿告诉你什么。", + "4"=>"{$name}在你看不到的情况下,可能会随意尿一尿,它知道这样做不太好,但是它就是想试一试。", + "5"=>"{$name}在你看不到的情况下,可能会随意尿一尿,它知道这样做不太好,但是它就是想试一试。", + ], + "活力值"=>[ + "描述"=>"指犬只的活跃度,得分越高越活泼,精力越充沛,性格更有趣喧闹,需要的运动量越大。", + "1"=>"{$name}是只喜欢安静的肥宅,请让它一只汪静静。", + "2"=>"{$name}是只动静皆宜的狗子,静如处子,动如脱兔说的就是它。", + "3"=>"{$name}是只动静皆宜的狗子,静如处子,动如脱兔说的就是它。", + "4"=>"{$name}是只喜欢蹦D的狗子,内心住着野狼DISCO本狼,请尽情陪它玩耍,释放你们的天性。", + "5"=>"{$name}是只喜欢蹦D的狗子,内心住着野狼DISCO本狼,请尽情陪它玩耍,释放你们的天性。", + ], + ]; + //猫 + $map[2] = [ + "外出频率"=> [ + "描述"=> "指猫咪的外出频率,得分越高,携带外出的可能性越高,出门受刺激的反应越低。", + "1"=> "{$name}是只害羞的猫咪,携带外出受刺激的可能性大,若没有进行专业的训练,不建议强制外出。", + "2"=> "{$name}是只可宅可外出的猫咪,值得注意的是,需要进行足够多的社会化,循序渐进的携带外出,如果外出反应大,应立即带回。", + "3"=> "{$name}是只可宅可外出的猫咪,值得注意的是,需要进行足够多的社会化,循序渐进的携带外出,如果外出反应大,应立即带回。", + "4"=> "{$name}是猫咪里的汪,是可以像狗一样外出溜达的猫咪,前期做好循序渐进的外出训练,直到在外毫无压力时便可携带外出。", + "5"=> "{$name}是猫咪里的汪,是可以像狗一样外出溜达的猫咪,前期做好循序渐进的外出训练,直到在外毫无压力时便可携带外出。" + ], + + "活力值"=> [ + "描述"=> "指猫咪的活跃度,得分越高越活泼,精力越充沛,性格更有趣喧闹,需要的运动量越大。", + "1"=> "{$name}是只喜欢安静的肥宅,请让它一只喵静静。", + "2"=> "{$name}是只动静皆宜的猫咪,静如处子,动如脱兔说的就是它。", + "3"=> "{$name}是只动静皆宜的猫咪,静如处子,动如脱兔说的就是它。", + "4"=> "{$name}是只喜欢蹦D的猫咪,内心住着野狼DISCO本狼,请尽情陪它玩耍,释放你们的天性。", + "5"=> "{$name}是只喜欢蹦D的猫咪,内心住着野狼DISCO本狼,请尽情陪它玩耍,释放你们的天性。" + ], + + "与人亲近值"=> [ + "描述"=> "指猫咪与人类的友好度,得分越高,与人的相处越轻松,越自然友爱。", + "1"=> "{$name}只喜欢它自己,内心OS:愚蠢的人类请离本喵远一点。", + "2"=> "{$name}与人类可以和谐相处,自然友爱,前提是没有受过人类的伤害。", + "3"=> "{$name}与人类可以和谐相处,自然友爱,前提是没有受过人类的伤害。", + "4"=> "{$name}是人类的好朋友,是所有猫咪中最愿意与人亲近的物种,请好好珍惜。", + "5"=> "{$name}是人类的好朋友,是所有猫咪中最愿意与人亲近的物种,请好好珍惜。" + ], + + "对陌生人的敌意"=> [ + "描述"=> "指猫咪的对陌生人的敌意,得分越高,受刺激的反应越大,越容易产生攻击行为。", + "1"=> "{$name}对陌生人很友好,如果人类没有主动攻击,基本上相安无事。", + "2"=> "{$name}对陌生人友善但警惕,受到刺激的话会产生攻击行为。", + "3"=> "{$name}对陌生人友善但警惕,受到刺激的话会产生攻击行为。", + "4"=> "{$name}对陌生人戒心很重,不要轻易让它接触陌生人,受刺激的可能性大,容易产生攻击行为。", + "5"=> "{$name}对陌生人戒心很重,不要轻易让它接触陌生人,受刺激的可能性大,容易产生攻击行为。" + ], + + "对主人的敌意"=> [ + "描述"=> "指猫咪的对主人的敌意,得分越高,服从性越低,不愿意遵守命令。", + "1"=> "{$name}很爱主人,出生自带服从性高的属性,甚至比较黏人。", + "2"=> "{$name}眼里的主人是与它平等的物种,大家相敬如宾平安无事,如果你可爱的话,它甚至有点爱你。", + "3"=> "{$name}眼里的主人是与它平等的物种,大家相敬如宾平安无事,如果你可爱的话,它甚至有点爱你。", + "4"=> "{$name}的内心住着哈士奇,自我且叛逆,可能听话的可能性很低,但也不能说它不爱你。", + "5"=> "{$name}的内心住着哈士奇,自我且叛逆,可能听话的可能性很低,但也不能说它不爱你。" + ], + + "对其它猫的敌意"=> [ + "描述"=> "指猫咪的对其它猫的敌意,得分越高,越容易产生攻击行为,与战斗力无关。", + "1"=> "{$name}对其它小伙伴很友好,是猫咪中的铁憨憨 。", + "2"=> "{$name}对其它猫友善但警惕,不会轻易接受同类,一旦接受了便会友好相处,如果被欺负也会回击。", + "3"=> "{$name}对其它猫友善但警惕,不会轻易接受同类,一旦接受了便会友好相处,如果被欺负也会回击。", + "4"=> "{$name}对同类不是很友好,如非必要,不要轻易让它们接触,相处不当会经常打架。", + "5"=> "{$name}对同类不是很友好,如非必要,不要轻易让它们接触,相处不当会经常打架。" + ], + + "对新事物的害羞程度"=> [ + "描述"=> "指猫咪对陌生事物的恐惧感及焦虑情绪,分数越高,越容易有恐惧或焦虑的情绪,害羞程度就越高。", + "1"=> "{$name}是只神经大条的猫咪,任何新事物在它眼里都很有趣。", + "2"=> "{$name}对新事物比较警惕,但只要适应一段时间便能很好的接受。", + "3"=> "{$name}对新事物比较警惕,但只要适应一段时间便能很好的接受。", + "4"=> "{$name}是只爱守旧的猫咪,比较难接受新事物,需要更多的时间和耐心让它放下戒心。", + "5"=> "{$name}是只爱守旧的猫咪,比较难接受新事物,需要更多的时间和耐心让它放下戒心。" + ], + + "对陌生人的害羞程度"=> [ + "描述"=> "指猫咪对陌生人的恐惧感及焦虑情绪,分数越高,越容易有恐惧或焦虑的情绪,害羞程度就越高。", + "1"=> "{$name}是只没皮没脸的猫咪,毫不认生,人见人爱。", + "2"=> "{$name}不排斥见陌生人但也没有那么喜欢,如果非得相处的话,请给它缓一缓的时间和空间。", + "3"=> "{$name}不排斥见陌生人但也没有那么喜欢,如果非得相处的话,请给它缓一缓的时间和空间。", + "4"=> "{$name}是只娇羞的猫咪,比较害怕见到陌生人,若非必要,不要让它们单独与陌生人相处,产生应激的机率很高。", + "5"=> "{$name}是只娇羞的猫咪,比较害怕见到陌生人,若非必要,不要让它们单独与陌生人相处,产生应激的机率很高。" + ], + + "舔毛倾向"=> [ + "描述"=> "指猫咪除自身清洁需要外,利用舔毛行为缓解压力的倾向,得分越高,感受压力越大,释放压力需求越高。", + "1"=> "{$name}除了给自己梳洗以外,偶尔也会舔舔毛来舒缓压力,是一只心理健康的猫咪。", + "2"=> "{$name}除了给自己梳洗以外,时不时用舔毛来舒缓压力,可以给它置放一些释放压力的猫抓板,防止过度舔毛引起毛球症。", + "3"=> "{$name}除了给自己梳洗以外,时不时用舔毛来舒缓压力,可以给它置放一些释放压力的猫抓板,防止过度舔毛引起毛球症。", + "4"=> "{$name}除了给自己梳洗以外,经常用舔毛来舒缓压力,主人可以多陪它玩,并放置一些释放压力的猫抓板或玩具,不要给孩子那么大的压力。", + "5"=> "{$name}除了给自己梳洗以外,经常用舔毛来舒缓压力,主人可以多陪它玩,并放置一些释放压力的猫抓板或玩具,不要给孩子那么大的压力。" + ], + ]; + $map = $map[$sample['pet_species']]; + //排序,宠物在后 + $body = $reportJson['秉性行为']['body']; + $pet_rate = $body[$name]; + $body_sorted = []; + foreach ($body as $key=>$val) { + if($key != $name){ + $body_sorted[$key] = $val; + //对于猫,直接指定数值,转换程序修改后改回来 + /* + if($sample['pet_species'] == 2){ + $body_sorted[$key] = [ + "外出指数"=> 2.44, + "活力值"=> 3.04, + "与人亲近值"=> 3.32, + "对陌生人的敌意"=> 1.36, + "对主人的敌意"=> 1.44, + "对其它猫的敌意"=> 3.12, + "对新事物害羞程度"=> 2.76, + "对陌生人害羞程度"=> 2.24, + "舔毛倾向"=> 1.76 + ]; + }*/ + } + } + $body_sorted[$name] = $pet_rate; + $temp = [ + '数值'=> $body_sorted, + '描述'=>[] + ]; + foreach ($temp['数值'] as $key=>$val) { + unset($temp['数值'][$key]['兴奋值']); + } + foreach ($map as $key=>$val) { + $_rate = round($pet_rate[$key]); + $_rate = $_rate == 0?1:$_rate; + $_rate = $_rate > 5?5:$_rate; + $temp['描述'][$key]['描述'] = $val['描述']; + $temp['描述'][$key]['检测结果'] = $val[$_rate]; + } + break; + case '可训练性': + /* + $temp = [ + '专注度'=>'', + '游戏欲'=>'', + '兴奋值'=>'', + '服从性'=>'', + '聪明值'=>'', + '逃逸值'=>'', + ];*/ + $map = [ + "专注度"=>[ + "描述"=>"指犬只在集中注意力时受外界刺激的影响程度,例如被柏油马路上的一片树叶、许多断续而短促的声音中的一个长声、被风吹起的塑料袋所吸引,或追逐飞过的小鸟及其它小动物,得分越低,表面受到外界刺激的影响程度越高,专注度越低。", + "1"=>"{$name}是只敏感的狗子,一点风吹草动都会影响它的专注度。", + "2"=>"{$name}也会集中注意力,但有时会被其它事物打断,如果训练的话,建议先从无干扰物开始。", + "3"=>"{$name}也会集中注意力,但有时会被其它事物打断,如果训练的话,建议先从无干扰物开始。", + "4"=>"{$name}天生专注度极高,它把注意力放在你身上时,其它事物很难打断它。", + "5"=>"{$name}天生专注度极高,它把注意力放在你身上时,其它事物很难打断它。", + ], + "游戏欲"=>[ + "描述"=>"指犬只的活跃度,玩游戏的欲望,得分越高越活跃,精力越充沛,游戏欲望越强。", + "1"=>"{$name}可能觉得玩游戏太幼稚了,它只想安静的睡一会儿。", + "2"=>"{$name}是喜欢玩游戏的狗子,你陪它玩儿的时间越多,它就越活泼。", + "3"=>"{$name}是喜欢玩游戏的狗子,你陪它玩儿的时间越多,它就越活泼。", + "4"=>"{$name}是个不折不扣的活力狗,爱玩更爱你陪它玩,你有多少精力它都会奉陪到底。", + "5"=>"{$name}是个不折不扣的活力狗,爱玩更爱你陪它玩,你有多少精力它都会奉陪到底。", + ], + "兴奋值"=>[ + "描述"=>"指犬只受到刺激后的反应,分数越高,表明受到刺激或引起兴奋的反应越强烈,例如散步,开车,门铃响,客人到访,主人在一段时间后回家,犬只的兴奋情况。", + "1"=>"{$name}是只佛系汪,似乎很少事情能让它感兴趣。", + "2"=>"{$name}受到刺激的时候会兴奋起来,它的兴奋程度取决于刺激它的点有多大。", + "3"=>"{$name}受到刺激的时候会兴奋起来,它的兴奋程度取决于刺激它的点有多大。", + "4"=>"{$name}是个人来疯,兴奋点太低,随随便便就激动起来。", + "5"=>"{$name}是个人来疯,兴奋点太低,随随便便就激动起来。", + ], + "服从性"=>[ + "描述"=>"得分高的犬只,表示对主人更关心,愿意遵守命令,反应积极,快速学习,服从性高。", + "1"=>"{$name}有自己的想法,不要指望它顺着你,它的行动指南就是它的心情。", + "2"=>"{$name}是孺子可教型,只要你方法得当,好好跟它说,它还是很愿意和你一起学习的。", + "3"=>"{$name}是孺子可教型,只要你方法得当,好好跟它说,它还是很愿意和你一起学习的。", + "4"=>"{$name}的心里只有你,“百依百顺”可以说是它给主人最高规格的诚意了。", + "5"=>"{$name}的心里只有你,“百依百顺”可以说是它给主人最高规格的诚意了。", + ], + "聪明值"=>[ + "描述"=>"指犬只的智商指数,得分越高,越聪明。", + "3"=>"{$name}对于新的指令,在重复15-25次后可以理解新的指令,70%以上的时间服从主人的第一个命令。", + "4"=>"{$name}对于新的指令,在重复5-15次后可以理解新的指令,85%以上的时间服从主人的第一个命令。", + "5"=>"{$name}对于新的指令,不用下达超过5次,就能理解是什么意思,并且95%以上的时间对主人的第一个命令是服从的。", + ], + "逃逸值"=>[ + "描述"=>"指犬只一有机会就逃跑,或逃离家里或主人的可能性,分数越高,可能性越大。", + "1"=>"{$name}只想和你在一起,只要你不逃走。", + "2"=>"{$name}不会轻易逃走,但经常也会因为看见更感兴趣的事物而逃离你身边,大多数情况下能唤回,这取决于你们之间的关系,出门记得栓绳哦。", + "3"=>"{$name}不会轻易逃走,但经常也会因为看见更感兴趣的事物而逃离你身边,大多数情况下能唤回,这取决于你们之间的关系,出门记得栓绳哦。", + "4"=>"{$name}它可能更向往远方,一有机会就想逃走,恭喜你,喜提一只撒手没。", + "5"=>"{$name}它可能更向往远方,一有机会就想逃走,恭喜你,喜提一只撒手没。", + ], + ]; + + $temp = [ + '数值'=> isset($reportJson['可训练性']['body'])?array_reverse($reportJson['可训练性']['body'],true):[], + '描述'=>[] + ]; + //数值的第一项是当前宠物的值 + $pet_rate = $temp['数值'][$name]; + foreach ($map as $key=>$val) { + $_rate = round($pet_rate[$key]); + $_rate = $_rate == 0?1:$_rate; + $_rate = $_rate > 5?5:$_rate; + $temp['描述'][$key]['描述'] = $val['描述']; + $temp['描述'][$key]['检测结果'] = $val[$_rate]; + } + break; + case '血型筛查': + $temp = $reportJson['B型血筛查']; + $temp['检测结果说明'] = $material['血型'][$reportJson['B型血筛查']['检测结果']]; + break; + default: + $temp=[]; + } + return $temp; + } + + // 疾病部分,对锁定的信息做隐藏及特殊处理 + protected function get_disease_block($sample,$riskDisease,$diseaseList,$addVirtualByLevel=false){ + + //按照风险内容输出,没锁定的风险项放前面 + $unlock_risk = []; + + //所有解锁项目,包括非风险项 + $unlock_all = []; + + //所有低风险项目 + $risk_low_all = []; + + //所有高风险项目 + $risk_high_all = []; + + //转化为名字对应内容 + $temp = []; + foreach ($diseaseList as $item) { + $temp[$item['name']] = $item; + if(!$item['lock']){ + $unlock_all[] = $item; + } + if($item['risk']){ + if($item['risk_level'] == 1){ + $risk_low_all[] = $item; + }else{ + $risk_high_all[] = $item; + } + + } + } + $diseaseList = $temp; + + //不同风险等级对应的锁定内容 + $lock = [ + 1=>[], + 2=>[], + ]; + + foreach ($riskDisease as $key=>$val) { + if(empty($diseaseList[$key])){ + //疾病列表里没有这一项,直接去除,否则无法做后续处理,这会造成检测结果的数量减少 + continue; + } + //锁定项目隐藏,后面会给锁定项目增加虚拟项目 + if(!$diseaseList[$key]['lock']){ + $unlock_risk[] = $diseaseList[$key]; + } + } + + //判断样品是否需要锁定一些疾病 + $is_lock = !empty($lock[1]) || !empty($lock[2]); + if(!$is_lock){ + foreach ($diseaseList as $val) { + if($val['lock']){ + $is_lock = true; + break; + } + } + } + + //如果列表中有疾病锁定了,但风险项中没有,则虚拟一些风险项,便于统一展示逻辑 + //(不考虑套餐自选疾病解锁了所有的锁定疾病的情况) + if($is_lock){ + $virtual = [ + 'lock'=>true, + 'risk'=>true, + 'risk_level'=>1, + 'name'=>'解锁后可查看细节', + ]; + //是否需要根据风险等级添加虚拟疾病 + $lock[1][] = $virtual; + $lock[1][] = $virtual; + if($addVirtualByLevel){ + $virtual['risk_level'] = 2; + $lock[2][] = $virtual; + $lock[2][] = $virtual; + } + } + //总列表 + $list = array_merge($unlock_risk,$lock[1],$lock[2]); + + //强调列表:解锁疾病数量少于10个则显示 + $list_notice = []; + if(count($unlock_all)<10){ + $custom = $this->get_disease_custom($sample); + if(!empty($custom)){ + //对于自选,展示自选,不必做解锁项目的过滤 + $list_notice = [ + 'name'=>$custom['name'], + 'list'=>$unlock_all + ]; + }else{ + $list_notice = [ + 'name'=>'遗传疾病'.count($unlock_all).'项', + 'list'=>$unlock_all + ]; + } + } + + //输出结果 + $temp = [ + '总计'=>$is_lock?'?':count($list), + '总计低风险'=>$is_lock?'?':count($risk_low_all), + '总计高风险'=>$is_lock?'?':count($risk_high_all), + '疾病总数'=>count($diseaseList), + '列表'=>$list, + '强调列表'=>$list_notice, + ]; + return $temp; + } + + // 突出特质 + protected function get_speciality($sample,$reportJson,$package){ + $map = [ + //狗 + '1'=>[ + '健康宝宝'=>['遗传病'=>[0]], + '爱因斯坦·汪'=>['智力评估'=>[5]], + '智商担当'=>['智力评估'=>[4]], + '胆大包天'=>['胆量值'=>[1]], + '铁憨憨'=>['暴躁值'=>[1]], + '安静的美狗子'=>['吠叫值'=>[1]], + '当代独立汪'=>['独处值'=>[1]], + '分离焦虑本汪'=>['独处值'=>[4,5]], + '轻度洁癖'=>['排尿值'=>[1]], + '乱尿之汪'=>['排尿值'=>[4,5]], + '蹦迪汪'=>['活力值'=>[4,5]], + '资深肥宅'=>['活力值'=>[1]], + '学习委员'=>['专注度'=>[4,5]], + '天生爱玩'=>['游戏欲'=>[4,5]], + '佛系汪'=>['兴奋值'=>[1]], + '天使宝宝'=>['服从性'=>[4,5]], + '撒手没'=>['逃逸值'=>[4,5]], + ], + //猫 + '2'=>[ + '健康宝宝'=>['遗传病'=>[0]], + '爱因斯坦·喵'=>['智力评估'=>[5]], + '智商担当'=>['智力评估'=>[4]], + '蹦迪喵'=>['活力值'=>[4,5]], + '佛系喵'=>['活力值'=>[1]], + '喵中汪'=>['外出频率'=>[4,5]], + '喵中汪 '=>['外出数值'=>[4,5]], + '黏人小妖精'=>['与人亲近值'=>[4,5]], + '满眼都是你'=>['对主人的敌意'=>[1]], + '目中无主人'=>['对主人的敌意'=>[4,5]], + '毫无畏惧'=>['对新事物的害羞程度'=>[1]], + '毫无畏惧 '=>['对新事物害羞程度'=>[1]], + ] + ]; + $pet_name = $reportJson['header']['宠物名']; + if($sample['pet_species'] == 1){ + //狗 + $value = [ + '遗传病'=>0, + '智力评估'=>$reportJson['遗传特征']['body']['智商指数']['body']['智商指数'], + '胆量值'=>$reportJson['秉性行为']['body'][$pet_name]['胆量值'], + '暴躁值'=>$reportJson['秉性行为']['body'][$pet_name]['暴躁值'], + '吠叫值'=>$reportJson['秉性行为']['body'][$pet_name]['吠叫值'], + '独处值'=>$reportJson['秉性行为']['body'][$pet_name]['独处值'], + '排尿值'=>$reportJson['秉性行为']['body'][$pet_name]['排尿值'], + '活力值'=>$reportJson['秉性行为']['body'][$pet_name]['活力值'], + '专注度'=>$reportJson['可训练性']['body'][$pet_name]['专注度'], + '游戏欲'=>$reportJson['可训练性']['body'][$pet_name]['游戏欲'], + '兴奋值'=>$reportJson['可训练性']['body'][$pet_name]['兴奋值'], + '服从性'=>$reportJson['可训练性']['body'][$pet_name]['服从性'], + '逃逸值'=>$reportJson['可训练性']['body'][$pet_name]['逃逸值'], + ]; + }else{ + //猫 + $value = [ + '遗传病'=>0, + '智力评估'=>$reportJson['遗传特征']['body']['智商指数']['body']['智商指数'], + '外出频率'=>$reportJson['秉性行为']['body'][$pet_name]['外出频率'], + //'外出数值'=>$reportJson['秉性行为']['body'][$pet_name]['外出数值'], + '与人亲近值'=>$reportJson['秉性行为']['body'][$pet_name]['与人亲近值'], + '对主人的敌意'=>$reportJson['秉性行为']['body'][$pet_name]['对主人的敌意'], + '对新事物的害羞程度'=>$reportJson['秉性行为']['body'][$pet_name]['对新事物的害羞程度'], + //'对新事物害羞程度'=>$reportJson['秉性行为']['body'][$pet_name]['对新事物害羞程度'], + //'胆量值'=>$reportJson['秉性行为']['body'][$pet_name]['胆量值'], + //'暴躁值'=>$reportJson['秉性行为']['body'][$pet_name]['暴躁值'], + //'吠叫值'=>$reportJson['秉性行为']['body'][$pet_name]['吠叫值'], + //'独处值'=>$reportJson['秉性行为']['body'][$pet_name]['独处值'], + //'排尿值'=>$reportJson['秉性行为']['body'][$pet_name]['排尿值'], + '活力值'=>$reportJson['秉性行为']['body'][$pet_name]['活力值'], + '专注度'=>$reportJson['可训练性']['body'][$pet_name]['专注度'], + '游戏欲'=>$reportJson['可训练性']['body'][$pet_name]['游戏欲'], + '兴奋值'=>$reportJson['可训练性']['body'][$pet_name]['兴奋值'], + '服从性'=>$reportJson['可训练性']['body'][$pet_name]['服从性'], + '逃逸值'=>$reportJson['可训练性']['body'][$pet_name]['逃逸值'], + ]; + } + + //是否全部疾病解锁且没有遗传病 + $diseaseList = $this->get_disease_list(0,$sample,$reportJson,$package,false,false,true); + foreach ($diseaseList as $item) { + if($item['lock'] || $item['risk']){ + $value['遗传病'] = 1; + break; + } + } + //提取特质 + $ret = []; + foreach ($map[$sample['pet_species']] as $name => $cond) { + + //数据名称 + $value_key = array_keys($cond)[0]; + if(!isset($value[$value_key])){ + continue; + } + $value_rate = round($value[$value_key]); + if(in_array($value_rate,$cond[$value_key])){ + $ret[] = $name; + } + } + + //特质少于3个,做补充 + $more = ['可爱多','独一无二','美食家']; + for($i=count($ret);$i<3;$i++){ + $ret[] = array_shift($more); + } + + return $ret; + } + + //重点关注的疾病,$gene_type = 1 遗传风险,2健康疾病 + protected function get_focus_disease($block_disease,$gene_type){ + //不必做以上过滤 + if($gene_type==2){ + //重点关注里只展示中高风险的疾病,注意锁定了不要过滤 + foreach ($block_disease['列表'] as $key=>&$val) { + if($val['risk_level'] < 2 && !$val['lock']){ + unset($block_disease['列表'][$key]); + } + /*由前端修改 + if($gene_type == 2){ + $tmp = explode(', ',$val['risk_detail']['风险解读']); + $val['risk_detail']['风险解读'] = $tmp[0]; + }*/ + } + //解锁状态,重新统计数量 + if($block_disease['总计']!='?'){ + $block_disease['总计'] = count($block_disease['列表']); + } + } + + //信息里面的遗传疾病,锁定不超过2个,因这部分根据不同风险等级添加了2个虚拟疾病 + $disease_lock_count = 0; + foreach ($block_disease['列表'] as $key=>$val) { + if($val['lock']){ + $disease_lock_count++; + } + if($disease_lock_count>2){ + unset($block_disease['列表'][$key]); + } + } + + return $block_disease; + } + + // 用药指导-内容太多,独立出来 + protected function drug($has_mh,$has_mdr1){ + return [ + [ + 'name'=>'恶性高热', + '携带'=>$has_mh?'是':'否', + 'get'=>$has_mh, + 'tag'=>'MH', + 'limit'=>$has_mh?'1项限制':'以下药物可遵医嘱使用', + 'data'=>[ + [ + 'name'=>'所有', + 'tag'=>'ALL', + 'data'=>[ + [ + 'name'=>'禁用药物', + 'tag'=>'jinyongyaowu', + 'data'=>[ + [ + 'name'=>'氟烷', + 'tag'=>'', + ], + [ + 'name'=>'七氟醚', + 'tag'=>'', + ], + [ + 'name'=>'地氟醚', + 'tag'=>'', + ], + [ + 'name'=>'异氟醚', + 'tag'=>'', + ], + [ + 'name'=>'安氟醚', + 'tag'=>'', + ], + [ + 'name'=>'琥珀胆碱', + 'tag'=>'', + ], + [ + 'name'=>'十烃季铵', + 'tag'=>'', + ], + ] + ] + ] + ] + ] + ], + [ + 'name'=>'MDR1', + '携带'=>$has_mdr1?'是':'否', + 'get'=>$has_mdr1, + 'limit'=>$has_mdr1?'4项限制':'以下药物可遵医嘱使用', + 'tag'=>'MDR1', + 'data'=>[ + [ + 'name'=>'抗寄生虫药', + 'tag'=>'ANTIPARASITIC', + 'data'=>[ + [ + 'name'=>'禁用药物', + 'tag'=>'jinyongyaowu', + 'data'=>[ + [ + 'name'=>'Alstomec', + 'tag'=>'伊维菌素', + ], + + [ + 'name'=>'Animec', + 'tag'=>'伊维菌素', + ], + + [ + 'name'=>'Bimectin', + 'tag'=>'伊维菌素', + ], + + [ + 'name'=>'Ivomec', + 'tag'=>'伊维菌素', + ], + + [ + 'name'=>'Panomec', + 'tag'=>'伊维菌素', + ], + + [ + 'name'=>'Qualimintic', + 'tag'=>'伊维菌素', + ], + + [ + 'name'=>'Vibamec', + 'tag'=>'伊维菌素', + ], + + [ + 'name'=>'Xeno 450', + 'tag'=>'伊维菌素', + ], + + [ + 'name'=>'Xeno 450/Xeno 450-mini', + 'tag'=>'伊维菌素', + ], + + [ + 'name'=>'Dectomax', + 'tag'=>'伊维菌素', + ], + + [ + 'name'=>'Miteguard', + 'tag'=>'伊维菌素', + ], + + [ + 'name'=>'Abamectin', + 'tag'=>'伊维菌素', + ], + + [ + 'name'=>'Profender', + 'tag'=>'伊维菌素', + ] + ], + ], + [ + 'name'=>'有潜在高风险药物', + 'tag'=>'qianzaifengxian', + 'data'=>[ + [ + 'name'=>'Milbemax', + 'tag'=>'米尔倍霉素', + ], + + [ + 'name'=>'Program plus', + 'tag'=>'米尔倍霉素', + ], + + [ + 'name'=>'Advocate', + 'tag'=>'莫昔克丁', + ], + + [ + 'name'=>'Stronghold', + 'tag'=>'塞拉菌素', + ] + ], + ], + [ + 'name'=>'密切关注副作用的药物', + 'tag'=>'miqieguanzhu', + 'data'=>[ + [ + 'name'=>'Metronidazole', + 'tag'=>'甲硝唑', + ], + + [ + 'name'=>'Stomorgyl', + 'tag'=>'甲硝唑', + ], + + [ + 'name'=>'Flagyl', + 'tag'=>'甲硝唑', + ], + + [ + 'name'=>'Metrolyl', + 'tag'=>'甲硝唑', + ] + ], + ], + [ + 'name'=>'部分犬只存在副作用的药物', + 'tag'=>'xianliangshiyong', + 'data'=>[ + [ + 'name'=>'Bob Martin Dog Wormer', + 'tag'=>'硝硫氰醚', + ], + + [ + 'name'=>'Lopatol', + 'tag'=>'硝硫氰醚', + ], + + [ + 'name'=>'Troscan', + 'tag'=>'硝硫氰醚', + ] + ], + ], + ] + ], + [ + 'name'=>'止泻药', + 'tag'=>'ANTIDIARRHEAL', + 'data'=>[ + [ + 'name'=>'禁用药物', + 'tag'=>'jinyongyaowu', + 'data'=>[ + [ + 'name'=>'Diareze', + 'tag'=>'洛哌丁胺', + ], + + [ + 'name'=>'Imodium', + 'tag'=>'洛哌丁胺', + ], + + [ + 'name'=>'Norimode', + 'tag'=>'洛哌丁胺', + ] + ], + ], + ], + ], + + [ + 'name'=>'止吐药', + 'tag'=>'ANTIEMETIC', + 'data'=>[ + [ + 'name'=>'禁用药物', + 'tag'=>'jinyongyaowu', + 'data'=>[ + [ + 'name'=>'Imodium', + 'tag'=>'甲氧氯普安', + ], + + [ + 'name'=>'Maxolon', + 'tag'=>'甲氧氯普安', + ], + + [ + 'name'=>'Metoclopramide', + 'tag'=>'甲氧氯普安', + ] + ], + ], + ], + ], + + [ + 'name'=>'镇静/镇痛药', + 'tag'=>'PRE-ANESTHETIC/ANELGESIC', + 'data'=>[ + [ + 'name'=>'密切关注副作用的药物', + 'tag'=>'miqieguanzhu', + 'data'=>[ + [ + 'name'=>'ACP', + 'tag'=>'乙酰丙嗪', + ], + + [ + 'name'=>'Alvegesic', + 'tag'=>'布托啡诺', + ], + + [ + 'name'=>'Dolorex', + 'tag'=>'布托啡诺', + ], + + [ + 'name'=>'Torbugesic', + 'tag'=>'布托啡诺', + ], + + [ + 'name'=>'Torbutrol', + 'tag'=>'布托啡诺', + ], + [ + 'name'=>'Torphasol', + 'tag'=>'布托啡诺', + ], + [ + 'name'=>'吗啡', + 'tag'=>'吗啡', + ], + [ + 'name'=>'Duramorph', + 'tag'=>'吗啡', + ], + [ + 'name'=>'Oramorph', + 'tag'=>'吗啡', + ], + [ + 'name'=>'Subutex', + 'tag'=>'丁丙诺啡', + ], + [ + 'name'=>'芬太尼', + 'tag'=>'芬太尼', + ], + [ + 'name'=>'Durogesic', + 'tag'=>'芬太尼', + ], + [ + 'name'=>'Fentora', + 'tag'=>'芬太尼', + ], + [ + 'name'=>'Sublimaze', + 'tag'=>'芬太尼', + ] + + ], + ], + + ], + ], + + [ + 'name'=>'抗癫痫药', + 'tag'=>'ANTIEPILEPTIC', + 'data'=>[ + [ + 'name'=>'密切关注副作用的药物', + 'tag'=>'miqieguanzhu', + 'data'=>[ + [ + 'name'=>'Diphenylhydantoin', + 'tag'=>'苯妥英钠', + ], + + [ + 'name'=>'Epanutin', + 'tag'=>'苯妥英钠', + ], + + [ + 'name'=>'Pentran', + 'tag'=>'苯妥英钠', + ] + ], + ], + ], + ], + + [ + 'name'=>'溃疡愈合药', + 'tag'=>'ANTIULCER', + 'data'=>[ + [ + 'name'=>'有潜在高风险药物的药物', + 'tag'=>'qianzaifengxian', + 'data'=>[ + [ + 'name'=>'多潘立酮', + 'tag'=>'多潘立酮', + ], + + [ + 'name'=>'多潘立酮', + 'tag'=>'多潘立酮', + ] + ] + ], + [ + 'name'=>'密切关注副作用的药物', + 'tag'=>'miqieguanzhu', + 'data'=>[ + [ + 'name'=>'西咪替丁', + 'tag'=>'西咪替丁', + ], + + [ + 'name'=>'Zitac', + 'tag'=>'西咪替丁', + ], + + [ + 'name'=>'Dyspamet', + 'tag'=>'西咪替丁', + ], + [ + 'name'=>'Tagamet', + 'tag'=>'西咪替丁', + ], + + [ + 'name'=>'雷尼替丁', + 'tag'=>'雷尼替丁', + ], + + [ + 'name'=>'Zantac', + 'tag'=>'雷尼替丁', + ], + + [ + 'name'=>'Zofran', + 'tag'=>'恩丹西酮', + ] + + ] + ], + ], + ], + + [ + 'name'=>'类固醇药', + 'tag'=>'STEROID', + 'data'=>[ + [ + 'name'=>'密切关注副作用的药物', + 'tag'=>'miqieguanzhu', + 'data'=>[ + [ + 'name'=>'Oestradiol benzoate', + 'tag'=>'雌二醇', + ], + + [ + 'name'=>'Mesalin', + 'tag'=>'雌二醇', + ] + ], + ], + ], + ], + + [ + 'name'=>'抗原虫药', + 'tag'=>'ANTIPROTOZOAL', + 'data'=>[ + [ + 'name'=>'部分犬只存在副作用的药物', + 'tag'=>'xianliangshiyong', + 'data'=>[ + [ + 'name'=>'Milteforan', + 'tag'=>'米替福新', + ] + ], + ], + ], + ], + + [ + 'name'=>'免疫调节剂', + 'tag'=>'IMMUNOMODULATOR', + 'data'=>[ + [ + 'name'=>'部分犬只存在副作用的药物', + 'tag'=>'xianliangshiyong', + 'data'=>[ + [ + 'name'=>'Ergamisol', + 'tag'=>'左旋咪唑', + ] + ], + ], + ], + ], + + [ + 'name'=>'免疫抑制剂', + 'tag'=>'IMMUNOSUPPRESSIVE', + 'data'=>[ + [ + 'name'=>'密切关注副作用的药物', + 'tag'=>'miqieguanzhu', + 'data'=>[ + [ + 'name'=>'Atopica', + 'tag'=>'环孢素', + ], + [ + 'name'=>'Optimmune', + 'tag'=>'环孢素', + ], + [ + 'name'=>'Neoral', + 'tag'=>'环孢素', + ], + [ + 'name'=>'Sandimmun', + 'tag'=>'环孢素', + ], + [ + 'name'=>'Aurizon', + 'tag'=>'地塞米松', + ], + [ + 'name'=>'Dexadreson', + 'tag'=>'地塞米松', + ], + [ + 'name'=>'Dexafort', + 'tag'=>'地塞米松', + ], + [ + 'name'=>'Rapidexon', + 'tag'=>'地塞米松', + ], + [ + 'name'=>'Voren', + 'tag'=>'地塞米松', + ], + [ + 'name'=>'Maxidex', + 'tag'=>'地塞米松', + ], + [ + 'name'=>'Maxitrol', + 'tag'=>'地塞米松', + ] + + ], + ], + ], + ], + + [ + 'name'=>'心血管药', + 'tag'=>'CARDIAC', + 'data'=>[ + [ + 'name'=>'密切关注副作用的药物', + 'tag'=>'miqieguanzhu', + 'data'=>[ + [ + 'name'=>'地高辛', + 'tag'=>'地高辛', + ], + [ + 'name'=>'Lanoxin', + 'tag'=>'地高辛', + ], + [ + 'name'=>'LanoxinPG', + 'tag'=>'地高辛', + ], + [ + 'name'=>'Digitoxin', + 'tag'=>'洋地黄毒苷', + ], + [ + 'name'=>'Kinidin Durules', + 'tag'=>'奎尼丁', + ], + [ + 'name'=>'硫酸奎尼丁', + 'tag'=>'奎尼丁', + ], + [ + 'name'=>'Hypercard', + 'tag'=>'地尔硫䓬', + ], + [ + 'name'=>'Dilcardia SR', + 'tag'=>'地尔硫䓬', + ], + [ + 'name'=>'维拉帕米', + 'tag'=>'维拉帕米', + ], + [ + 'name'=>'Cordilox', + 'tag'=>'维拉帕米', + ], + [ + 'name'=>'Securon', + 'tag'=>'维拉帕米', + ] + + ], + ], + ], + ], + + [ + 'name'=>'抗生素', + 'tag'=>'ANTIBACTERIAL', + 'data'=>[ + [ + 'name'=>'有潜在高风险药物', + 'tag'=>'qianzaifengxian', + 'data'=>[ + [ + 'name'=>'红霉素', + 'tag'=>'红霉素', + ], + [ + 'name'=>'Eyrthrocin', + 'tag'=>'红霉素', + ], + [ + 'name'=>'Erythroped', + 'tag'=>'红霉素', + ], + [ + 'name'=>'Stomorgyl', + 'tag'=>'螺旋霉素', + ], + [ + 'name'=>'拜有利', + 'tag'=>'恩诺沙星', + ], + [ + 'name'=>'Enrocare', + 'tag'=>'恩诺沙星', + ], + [ + 'name'=>'Enrotab', + 'tag'=>'恩诺沙星', + ], + [ + 'name'=>'Enrox', + 'tag'=>'恩诺沙星', + ], + [ + 'name'=>'Enroxil', + 'tag'=>'恩诺沙星', + ], + [ + 'name'=>'Floxabactin', + 'tag'=>'恩诺沙星', + ], + [ + 'name'=>'Floxibac', + 'tag'=>'恩诺沙星', + ], + [ + 'name'=>'Powerflox', + 'tag'=>'恩诺沙星', + ], + [ + 'name'=>'Xeden', + 'tag'=>'恩诺沙星', + ] + + ], + ], + + [ + 'name'=>'密切关注副作用的药物', + 'tag'=>'miqieguanzhu', + 'data'=>[ + [ + 'name'=>'Doxyseptin 300', + 'tag'=>'多西环素', + ], + [ + 'name'=>'Ornicure', + 'tag'=>'多西环素', + ], + [ + 'name'=>'Pulmodox', + 'tag'=>'多西环素', + ], + [ + 'name'=>'Ronaxan', + 'tag'=>'多西环素', + ], + [ + 'name'=>'Vibramycin', + 'tag'=>'多西环素', + ], + [ + 'name'=>'Vibravenos', + 'tag'=>'多西环素', + ], + [ + 'name'=>'Raxar', + 'tag'=>'格帕沙星', + ], + [ + 'name'=>'Zagam', + 'tag'=>'司氟沙星', + ], + [ + 'name'=>'利福平', + 'tag'=>'利福平', + ], + [ + 'name'=>'Rifadin', + 'tag'=>'利福平', + ], + [ + 'name'=>'Rimactane', + 'tag'=>'利福平', + ], + + ], + ], + ], + ], + [ + 'name'=>'抗真菌药', + 'tag'=>'ANTIFUNGAL', + 'data'=>[ + [ + 'name'=>'密切关注副作用的药物', + 'tag'=>'miqieguanzhu', + 'data'=>[ + [ + 'name'=>'Nizoral', + 'tag'=>'酮康唑', + ], + [ + 'name'=>'Itrafungol', + 'tag'=>'伊曲康唑', + ], + [ + 'name'=>'Sporanox', + 'tag'=>'伊曲康唑', + ], + ], + ], + ], + ], + + [ + 'name'=>'抗肿瘤药', + 'tag'=>'ANTINEOPLASTIC', + 'data'=>[ + [ + 'name'=>'密切关注副作用的药物', + 'tag'=>'miqieguanzhu', + 'data'=>[ + [ + 'name'=>'长春碱', + 'tag'=>'长春碱', + ], + [ + 'name'=>'Velbe', + 'tag'=>'长春碱', + ], + [ + 'name'=>'长春新碱', + 'tag'=>'长春新碱', + ], + [ + 'name'=>'Oncovin', + 'tag'=>'长春新碱', + ], + [ + 'name'=>'多柔比星', + 'tag'=>'多柔比星', + ], + [ + 'name'=>'Taxol', + 'tag'=>'紫杉醇', + ], + [ + 'name'=>'放线菌素', + 'tag'=>'放线菌素', + ], + [ + 'name'=>'Cosmegen', + 'tag'=>'放线菌素', + ], + [ + 'name'=>'Lyovac', + 'tag'=>'放线菌素', + ], + [ + 'name'=>'Novantrone', + 'tag'=>'米托蒽醌', + ], + [ + 'name'=>'Etopophos ', + 'tag'=>'依托泊甙', + ], + [ + 'name'=>'Toposar', + 'tag'=>'依托泊甙', + ] + ], + ], + ], + ], + + + ] + ], + ]; + } + +} diff --git a/models/Report_model2.php b/models/Report_model2.php new file mode 100644 index 0000000..69154fc --- /dev/null +++ b/models/Report_model2.php @@ -0,0 +1,2052 @@ +'uahpet/database/犬/JSON/', + //猫 + 2=>'uahpet/database/猫/JSON/', + ]; + + /** + * __construct function. + * + * @access public + * @return void + */ + public function __construct() { + + parent::__construct(); + //$this->load->database(); + + } + + //报告路径 + public function report_file_path($deviceID,$petSpecies=1){ + $path = $petSpecies == 1?self::DIR_REPORT_DATA:self::DIR_REPORT_DATA_CAT; + return APPPATH.$path.($deviceID).'.json'; + } + + //报告路径 + public function get_report_json($deviceID,$petSpecies=1){ + //报告文件 + $file = $this->report_file_path($deviceID,$petSpecies); + if(!file_exists($file)){ + return []; + } + $reportJson = file_get_contents($file); + return json_decode($reportJson,true); + } + + + //报告是否生成 + public function is_report_ready($deviceID){ + return file_exists( + $this->report_file_path($deviceID) + ); + } + + //获取家族树 + public function family_tree_img($deviceID){ + $file = Report_model::DIR_REPORT_FAMILY_TREE.strtoupper($deviceID).'.jpg'; + if(file_exists(APPPATH.$file)){ + return base_url('views/'.$file); + } + $file = Report_model::DIR_REPORT_DATA.strtoupper($deviceID).'.jpg'; + if(file_exists(APPPATH.$file)){ + return base_url('views/'.$file); + } + return false; + } + + //报告统计 + public function get_report_count() { + + $files = scandir(APPPATH.self::DIR_REPORT_DATA); + $count = 0; + foreach($files as $file){ + if($file === '.' || $file === '..'){ + continue; + } + if(substr($file,-5) === '.json'){ + $count++; + } + } + return $count; + + } + + //素材 + public function get_material($petSpecies=1){ + if(!is_null($this->_material)){ + return $this->_material; + } + //根据报告内容,解析建议文字 + $materialFileName = [ + //狗 + 1=>[ + //'交互式报告素材', + //'猫类单基因疾病', + '犬类单基因疾病'=>'单基因疾病', + '犬类单基因疾病医护建议'=>'单基因疾病医护建议', + '犬类复杂疾病'=>'多基因疾病', + '犬类品系'=>'品系', + ], + //猫 + 2=>[ + //'交互式报告素材', + //'猫类单基因疾病', + '猫类单基因遗传病'=>'单基因疾病', + '猫类单基因疾病医护建议'=>'单基因疾病医护建议', + '猫类复杂疾病'=>'多基因疾病', + '猫品系'=>'品系', + ], + ]; + //报告素材 + $material = []; + foreach ($materialFileName[$petSpecies] as $name=>$uni_name) { + if(PHP_OS == 'WINNT'){ + $name = iconv('UTF-8','GB2312',$name); + } + //猫没有多基因疾病与医护建议 + if(in_array($name,['猫类单基因疾病医护建议','猫类复杂疾病'])){ + $material[$uni_name] = []; + continue; + } + $_content = file_get_contents(APPPATH.self::DIR_MATERIAL[$petSpecies].$name.'.json'); + $material[$uni_name] = json_decode($_content,true); + } + //猫的品系资料转换 + if($petSpecies == 2){ + foreach ($material['品系'] as $key=>$val) { + $material['品系'][$key]['犬种特点'] = $val['猫种特点']; + } + } + //print_r($material);die; + $this->_material = $material; + return $material; + } + + //获取疾病解锁信息 + public function get_disease_unlock($sample=[],$package=[]){ + if(!is_null($this->_disease_unlock)){ + return $this->_disease_unlock; + } + //解锁疾病 + $unlockDisease = []; + if(!empty($package['disease'])){ + $package['disease'] = explode(',',$package['disease']); + $this->load->model('disease_model'); + $unlockDisease = $this->disease_model->get($package['disease'],'base.id',true,'base.name'); + $unlockDisease = array_column($unlockDisease,'name'); + foreach ($unlockDisease as &$item) { + $item = trim($item); + } + } + + //如果样品选择了某个套餐,就直接解锁 + $custom = $this->get_disease_custom($sample); + + + if(!empty($custom['disease_name'])){ + $unlockDisease = array_merge($unlockDisease,$custom['disease_name']); + } + $this->_disease_unlock = $unlockDisease; + return $unlockDisease; + } + + //获取疾病自选信息 + public function get_disease_custom($sample=[]){ + if(!is_null($this->_disease_custom)){ + return $this->_disease_custom; + } + $unlockDisease = []; + if(!empty($sample['package_custom'])){ + $unlockDisease = json_decode($sample['package_custom'],true); + } + $this->_disease_custom = $unlockDisease; + return $this->_disease_custom; + } + + /** + * 获取疾病列表带锁定信息 + * @param $gene_type int 基因类型 1单基因 2多基因 + * @param $sample array 样品资料,需要用它获取选择的疾病 + * @param $report_json array 报告数据文件,用它获取是否已得病 + * @param $package array 套餐数据,获取锁定套餐 + * @param $need_category int 是否需要分类 + * @param $need_detail int 是否需要明细 + * @param $hidden_locked bool 锁定时,是否隐藏明细 + * @return mixed + */ + public function get_disease_list($gene_type=0,$sample=[],$report_json=[],$package=[],$need_category=0,$need_detail=0,$hidden_locked=true){ + $material = $this->get_material($sample['pet_species']); + //区分单基因/多基因 1单基因 2多基因,便于检测不出来时区分显示风险描述 + foreach ($material['单基因疾病'] as $key=>$val) { + $material['单基因疾病'][$key]['gene_type'] = 1; + } + foreach ($material['多基因疾病'] as $key=>$val) { + $material['多基因疾病'][$key]['gene_type'] = 1; + } + if(empty($gene_type)){ + $list = array_merge($material['单基因疾病'],$material['多基因疾病']); + }elseif($gene_type=='1'){ + $list = array_merge($material['单基因疾病']); + }else{ + $list = array_merge($material['多基因疾病']); + } + + + //分类对应 + $map = [ + '代谢类疾病'=>'代谢免疫', + '代谢类遗传病'=>'代谢免疫', + '代谢类遗传疾病'=>'代谢免疫', + '代谢性遗传病'=>'代谢免疫', + '耳科疾病'=>'五官皮肤', + '骨骼肌肉类疾病'=>'内科', + '骨骼肌肉系统遗传病'=>'内科', + '骨骼肌肉遗传病'=>'内科', + '骨骼类遗传病'=>'内科', + '骨骼类肿瘤疾病'=>'内科', + '骨骼系统遗传病'=>'内科', + '关节类疾病'=>'内科', + '肌肉类遗传病'=>'内科', + '肌肉系统类遗传病'=>'内科', + '肌肉系统遗传病'=>'内科', + '肌肉遗传病'=>'内科', + '泌尿生殖系统遗传疾病'=>'内科', + '泌尿系统疾病'=>'内科', + '泌尿系统类遗传疾病'=>'内科', + '泌尿系统遗传病'=>'内科', + '免疫缺陷遗传病'=>'代谢免疫', + '免疫系统遗传病'=>'代谢免疫', + '内分泌系统遗传病'=>'内科', + '皮肤类疾病'=>'五官皮肤', + '皮肤类遗传病'=>'五官皮肤', + '皮肤类肿瘤疾病'=>'五官皮肤', + '皮肤肿瘤疾病'=>'五官皮肤', + '其他遗传疾病'=>'内科', + '神经类遗传病'=>'神经系统', + '神经系统疾病'=>'神经系统', + '神经系统遗传病'=>'神经系统', + '神经系统遗传疾病'=>'神经系统', + '睡眠病'=>'神经系统', + '糖类代谢类遗传疾病'=>'代谢免疫', + '消化系统疾病'=>'内科', + '消化系统遗传病'=>'内科', + '心血管系统疾病'=>'血液心脏', + '心血管系统遗传病'=>'血液心脏', + '血液类遗传病'=>'血液心脏', + '血液类遗传疾病'=>'血液心脏', + '血液淋巴系统疾病'=>'血液心脏', + '血液系统遗传病'=>'血液心脏', + '血液遗传病'=>'血液心脏', + '血液遗传疾病'=>'血液心脏', + '眼科遗传病'=>'五官皮肤', + '药物代谢类遗传疾病'=>'代谢免疫', + '遗传性眼病'=>'五官皮肤', + '骨骼肌肉类遗传病'=>'内科', + ]; + + //锁定疾病,里面已经考虑了套餐选择项 + $unlockDisease = $this->get_disease_unlock($sample,$package); +// var_dump(array_keys($list)); +// var_dump($unlockDisease);die; + + + //是否存在风险 + $riskDisease = $report_json['遗传疾病']['body']['单基因疾病']['body']; + if(isset($report_json['健康风险']['body']['复杂疾病性状']['body'])){ + $riskDisease = array_merge($riskDisease,$report_json['健康风险']['body']['复杂疾病性状']['body']); + } + + $out = []; + foreach ($list as $name=>$val) { + $name = trim($name); + $tmp = [ + //是否锁定 + 'lock'=>!in_array($name,$unlockDisease), + 'name'=>$name, + 'gene_type'=>$val['gene_type'], + 'risk'=>false, + 'risk_detail'=>false, + ]; + //详情 + if($need_detail){ + $tmp['detail'] = $val; + } + + //风险项,没有锁定时才展示 + if((!$hidden_locked || !$tmp['lock']) && isset($riskDisease[$name])){ + $tmp['risk'] = true; + + //区分猫狗,猫没有放body + if($sample['pet_species'] == 2) { + $tmp['risk_detail'] = $riskDisease[$name]; + if($tmp['risk_detail']["检测结果"] == "纯合突变" OR $tmp['risk_detail']["遗传模式"] == "显性遗传"){ + $tmp['risk_level'] = 2; + }else{ + $tmp['risk_level'] = 1; + } + }else{ + $tmp['risk_detail'] = $riskDisease[$name]['body']; + //风险等级 + switch ($tmp['risk_detail']['检测结果']) { + case '患病': + case '中等风险': + case '高风险': + case '有极高的发病风险'://风险解读 + $tmp['risk_level'] = 2; + break; + case '携带致病突变': + case '普通风险': + case '低风险': + case '低发病风险'://风险解读 + $tmp['risk_level'] = 1; + break; + } + } + } + + //是否分类 + if(!empty($need_category)){ + if(empty($map[$val['所属类别']])){ + continue; + } + $out[$map[$val['所属类别']]][] = $tmp; + }else{ + $out[] = $tmp; + } + } + + return $out; + } + + //拼装报告结构 + public function get_result($deviceID,$ignoreStep=false){ + //样品及套餐信息 + $this->load->model('sample_model'); + $this->load->model('package_model'); + $sample = $this->sample_model->get($deviceID,'device_id'); + if(!$sample){ + return []; + } + //if($deviceID == 'AGZHYW6'){print_r($sample);die();} + //样品未完成是否返回 + if(!$ignoreStep && $sample['step']!=Sample_model::STEP_COMPLETE){ + return []; + } + //资料来源:json + $json = $this->get_report_json($deviceID,$sample['pet_species']); + if(empty($json)){ + return []; + } + //补充图片,物种 + if(empty($sample['pet_img'])){ + $sample['pet_img'] = base_url().'uploads/default/common.jpg'; + } + //套餐设置成1,上线后删除 + //$sample['package_id'] = 1; + $package = $this->package_model->get($sample['package_id']); + if(!$package){ + return []; + } + $package['structure'] = explode(',',$package['structure']); + $package['cert'] = array_filter(explode(',',$package['cert'])); + //素材对应 + $material = $this->get_material($sample['pet_species']); + //模块对应 + /* + $main = [ + '爱宠大揭秘'=>[], + '健康大调查'=>[], + '养育大宝典'=>[], + '基因全解锁'=>[], + ]; + */ + $block_list = [ + '品系鉴定', + '智力评估', + '性格行为', + '遗传疾病', + '健康风险', + '用药指导', + '繁育建议', + '饮食建议', + '毛发美护', + '可训练性', + ]; + + $blocks = []; + foreach ($block_list as $val) { + $blocks[$val] = $this->get_block($val,$json,$sample,$package,$material,$json['header']['宠物名']); + } + + //营养结果固化 + if(empty($sample['diet_nutrition']) && !empty($blocks['饮食建议']['营养代谢'])){ + $this->sample_model->update([ + 'diet_nutrition'=>json_encode($blocks['饮食建议']['营养代谢'],JSON_UNESCAPED_UNICODE) + ],[ + 'id'=>$sample['id'] + ]); + } + + //绑定套餐信息:版块、证书;疾病、升级目标不处理 + $ret = [ + '信息'=>[ + '编号'=>$deviceID, + '宠物照片'=>$sample['pet_img'], + '昵称'=>$json['header']['宠物名'], + '养育人'=>$sample['name'], + '测试日期'=>date('Y-m-d',$sample['create_time']), + '物种'=>$package['species'],//1狗2猫 + '个性标签'=>$this->get_speciality($sample,$json,$package), + '证书'=>$package['cert'], + //'证书'=>'健康证书', + //防止疾病被过滤之后 + '遗传疾病'=>$this->get_focus_disease($blocks['遗传疾病'],1), + '健康风险'=>$this->get_focus_disease($blocks['健康风险'],2), + '可升级'=>!empty($package['package_up']) && $package['package_up'] != $package['id'], + ], + ]; + //套餐不允许展示的版块不展示 + //$blocks = array_intersect(array_merge($package['structure'],'信息'),$blocks); + $package['structure'][] = '信息'; + $lock_block = []; + foreach ($blocks as $key=>$val) { + if(in_array($key,$package['structure'])){ + }else{ + //未解锁的调整次序,隐藏内容 + $lock_block[$key] = ['lock'=>true]; + unset($blocks[$key]); + } + } + $ret = array_merge($blocks,$lock_block,$ret); + return $ret; + + } + + + /** + * @param $block 版块名称 + * @param $reportJson 报告json + * @param $material 素材 + * @param $name 宠物名称 + * @param $sample 样品数据 + * @param $package 套餐数据 + * @return array + */ + public function get_block($block,$reportJson,$sample,$package,$material,$name){ + switch ($block){ + case '品系鉴定': + //血统分析-家族树 + //品系素材文字提取 + $temp = []; + if(!empty($reportJson['血统分析']['body']['品系纯度'])){ + $list = $reportJson['血统分析']['body']['品系纯度']; + array_multisort($list,SORT_DESC, SORT_NUMERIC ,$list); + foreach ($list as $key => $val){ + $temp[] = [ + '名称'=>$key, + '占比'=>$val, + '介绍'=>!empty($material['品系'][$key])?$material['品系'][$key]:'', + ]; + } + } + /* + $temp = [ + '品系鉴定'=>'', + '血统分析'=>'', + '品种分析'=>'', + '遗传特征'=>[ + '遗传特征'=>'', + '基因毛色'=>'', + '基因毛型'=>'' + ] + ];*/ + break; + case '智力评估': + //print_r($reportJson);die; + $rate = $reportJson['遗传特征']['body']['智商指数']['body']['智商指数']; + $rate = round($rate); + //狗狗智商评分内容 + $map[1] = [ + 3=>[ + '检测结果'=>'优秀汪', + '结论'=>"{$name}是只聪明的狗狗,新指令重复15-25次后根据个体差异,会有不同程度的掌握。它对第一次指令作出的回应几率是70%,表现的优劣取决于练习时间的多寡。整体来说,有时反应慢半拍,但依然不妨碍它学习的很好。但如果训练者缺乏经验,或过于严厉或没耐心,狗狗的表现也会受到影响。", + '描述'=>"对于新的指令,在重复15-25次后可以理解新的指令,70%以上的时间服从主人的第一个命令", + ], + 4=>[ + '检测结果'=>'学霸汪', + '结论'=>"{$name}是一只智力上等的狗狗,简单指令学习5-15次便能学会。它遵守第一次指令的机率是85%,对于稍微复杂的指令只要多练习就能掌握。当主人离它们较远时,它也会有反应。即使训练人员经验稍微不足,还是有办法将这些狗调教得很优秀。", + '描述'=>"对于新的指令,在重复5-15次后可以理解新的指令,85%以上的时间服从主人的第一个命令", + ], + 5=>[ + '检测结果'=>'天才汪', + '结论'=>"恭喜您,{$name}是一只智力超群的天才狗,一般情况下听到新指令5次以内,就会理解需要完成的动作并牢牢记住。主人下达命令时,它的完成度高达95%以上,并且能够在3秒内做出反应。即使训练它们的人经验不足,它也可以学习得很好。", + '描述'=>"对于新的指令,不用下达超过5次,就能理解是什么意思,并且95%以上的时间对主人的第一个命令是服从的。", + ] + ]; + // 猫智力 + $map[2] = [ + 5=>[ + "检测结果"=>"天才喵", + "描述"=>"{$name}是猫中天才,只要稍加训练,甚至能像狗那样听话,比如把东西叼回对它们来说就是小菜一碟。" + ], + 4=> [ + "检测结果"=>"学霸喵", + "描述"=> "{$name}不仅有超高的智商,还有超强的服从性,可以和人很好的互动,稍加训练甚至可以带出门遛弯,可以通过看你做事情而去学习,比如开门,比如自己偷翻吃的。" + ], + 3=> [ + "检测结果"=>"优秀喵", + "描述"=> "{$name}聪明,性格好,拥有很强的观察力和学习能力,会粘人,但又总保持着自己的本性。" + ] + ]; + $map = $map[$sample['pet_species']]; + $temp = [ + '智力指数'=>$rate, + '智力描述'=>$map[$rate], + ]; + + break; + case '遗传疾病': + /* + $temp = [ + '关键数据结果'=>'', + '检测类目'=>'', + ]; + */ + $list = $reportJson['遗传疾病']['body']['单基因疾病']['body']; + //获取疾病列表检测是否被锁定,如被锁定,隐藏关键信息 + $diseaseList = $this->get_disease_list(1,$sample,$reportJson,$package,false,true,false); + $temp = $this->get_disease_block($sample,$list,$diseaseList,true); + break; + case '健康风险': + + $list = $reportJson['健康风险']['body']['复杂疾病性状']['body']; + //健康风险,按照风险值排序 + $temp = []; + foreach ($list as $key => $val) { + $val['body']['风险解读'] = explode(',',$val['body']['风险解读']); + $temp[] = (int)str_replace('高于','',$val['body']['风险解读'][1]); + } + array_multisort($temp,SORT_DESC, SORT_NUMERIC ,$list); + rsort($temp); + /* + $temp = [ + '风险系数'=>'', + '风险介绍'=>[ + '致病机理'=>'', + '临床症状'=>'', + '所属类别'=>'', + ], + '养育建议'=>'', + ];*/ + //获取疾病列表检测是否被锁定,如被锁定,隐藏关键信息 + $diseaseList = $this->get_disease_list(2,$sample,$reportJson,$package,false,true,false); + $temp = $this->get_disease_block($sample,$list,$diseaseList,false); + break; + case '用药指导': + $riskDisease = $reportJson['遗传疾病']['body']['单基因疾病']['body']; + return $this->drug( + isset($riskDisease['恶性高热']), + isset($riskDisease['多重药物敏感风险']) + ); + break; + case '饮食建议': + $result = [ + '蛋白质'=>'正常', + '钠'=>'正常', + '牛磺酸'=>'正常', + 'omega-3'=>'正常', + 'EPA和DHA'=>'正常', + '抗氧化剂'=>'正常', + 'L-肉碱'=>'正常', + '叶酸'=>'正常', + '维生素B'=>'正常', + '维生素C'=>'正常', + '维生素E'=>'正常', + '铁'=>'正常', + '氨基葡萄糖和硫酸软骨素'=>'正常', + '碳水化合物'=>'正常', + '水'=>'正常', + '辅酶Q10'=>'正常', + '磷'=>'正常' + ]; + //饮食指导 + //区分单基因/多基因 1单基因 2多基因 + $map = $material['单基因疾病医护建议']; + //依赖遗传病 + $diseaseList = $this->get_disease_list(1,$sample,$reportJson,$package,false,false,false); + $suggestion = []; + foreach ($diseaseList as $disease) { + if($disease['risk'] && !$disease['lock'] && isset($map[$disease['name']]["喂养建议 "])){ + $suggestion[] = $map[$disease['name']]["喂养建议 "]; + break; + } + } + $suggestion = implode('',$suggestion); + //营养代谢结果,增加随机性,并保存到sample里 + if(!empty($sample['diet_nutrition'])){ + $result = json_decode($sample['diet_nutrition']); + }else{ + $nutrition = $reportJson['营养代谢']['body']['营养代谢综合结果']; + if(!is_null($nutrition)){ + $result = array_merge($result,$nutrition); + } + foreach ($result as $key=>$val) { + $v = 0; + switch ($val){ + case '微量': + $v = 1; + break; + case '少量': + $v = rand(2,3); + break; + case '正常': + $v = rand(4,7); + break; + case '稍多': + $v = rand(8,9); + break; + case '多量': + $v = 10; + break; + } + $result[$key] = [ + '结果'=>$val, + '值'=>$v, + ]; + } + } + $temp = [ + '饮食结构'=>$reportJson['营养代谢']['body']['饮食结构'], + '饮食指导'=>$suggestion, + '营养代谢'=>$result, + ]; + //猫 + if($sample['pet_species'] == 2){ + unset($temp['营养代谢']); + } + break; + case '繁育建议': + //毛色 + $color = $reportJson['进阶项目研究']['body']['毛色分析']['body']['成年毛色预测']; + $type = $reportJson['进阶项目研究']['body']['毛型分析']['body']['成年毛型预测']; + //echo $color;die; + //$color = '白色或者黑色'; + $colors = str_replace([',','或者','或'],',',$color); + $colors = explode(',',$colors); + $color_out = []; + foreach ($colors as $key=>$val) { + //括号内的描述去掉 + $val = str_replace(['(','('],',',$val); + $val = explode(',',$val); + $val = $val[0]; + //还剩一种情况,用/分隔 + $val = explode('/',$val); + foreach ($val as $v) { + $color_out[] = trim($v); + } + } + $color_out = array_values(array_filter($color_out)); + //遗传病 + $material = $this->get_material(); + //区分单基因/多基因 1单基因 2多基因 + $map = [ + //狗 + 1=>$material['单基因疾病医护建议'], + //猫 + 2=>$material['单基因疾病'], + ]; + $map = $map[$sample['pet_species']]; + //建议中的节点 + $map_key = [ + //狗 + 1=>'育种建议', + //猫 + 2=>'繁育建议', + ]; + $map_key = $map_key[$sample['pet_species']]; + + //依赖遗传病 + $resultNotice = '可繁育'; + $diseaseList = $this->get_disease_list(1,$sample,$reportJson,$package,false,false,false); + $suggestion = []; + foreach ($diseaseList as $disease) { + if($disease['risk'] && !$disease['lock'] && isset($map[$disease['name']][$map_key])){ + $resultNotice = '不建议繁育'; + $suggestion[] = $map[$disease['name']][$map_key]; + break; + } + } + $suggestion = implode('',$suggestion); + if(empty($suggestion)){ + $suggestion = '您的爱宠没有检测出遗传隐患,可放心繁育下一代,生出健康漂亮的宝宝。'; + } + + $temp = [ + '结果'=>$resultNotice, + '建议'=>$suggestion, + '毛色'=>$color_out, + '毛型'=>$type, + '毛型类别'=>strpos($type,'直') === false?'卷':'直',//1直2卷 + ]; + //猫 + /* + if($sample['pet_species'] == 2){ + unset($temp['毛色'],$temp['毛型'],$temp['毛型类别']); + }*/ + break; + case '毛发美护': + $rate = round($reportJson['洗护建议']['body']['梳毛护理星级']); + $map = [ + //狗 + 1=>[ + "梳毛护理相关知识点"=>"星星表明你的爱犬需要梳理的频度,以保持它被毛的最佳状态。", + 1=>"每周1次:{$name}的被毛几乎不用特别梳理就可以有型,但不能保证地毯沙发上没有狗毛,定期梳理可大程度减少狗因褪毛而到处飞扬的狗毛。", + 2=>"每周2-3次:{$name}的被毛不会太难打理,定期梳理可大程度减少狗毛乱飞,同时也有助于你们的感情培养哦。", + 3=>"每天1次:{$name}的被毛褪毛较多,频繁的梳理可以尽量去除掉落的被毛并防止里层被毛缠结,另外每天梳理有助于你与它感情的培养哦。", + ], + 2=>[ + "梳毛护理相关知识点"=> "指猫咪被毛需要梳理的频率,得分越高,需要梳理的次数越多。", + "1"=> "每周1次:{$name}的被毛几乎不用特别梳理就可以有型,但不能保证地毯沙发上没有猫毛,定期梳理可大程度减少猫因褪毛而到处飞扬的猫毛。", + "2"=> "每周2-3次:{$name}的被毛不会太难打理,定期梳理可大程度减少猫毛乱飞,同时也是预防毛球症很好的方式之一。", + "3"=> "每天1次:{$name}的被毛褪毛较多,频繁的梳理可以尽量去除掉落的被毛并防止里层被毛缠结,同时也是预防毛球症很好的方式之一。另外每天梳理有助于你与它感情的培养哦。", + ] + ]; + $map = $map[$sample['pet_species']]; + //疾病 + $diseaseList = $this->get_disease_list(0,$sample,$reportJson,$package,false,false,false); + $washMap = [ + "GM2神经节苷脂沉着症"=> "{$name}需要舒适的床上用品,如空气床垫、水床、休闲椅垫、人用床垫、羊毛、睡袋、毯子、稻草或其他柔软舒适的东西。你需要经常更换床上用品的外层,并且需要定期帮它洗澡,以防它由于大小便失禁引起褥疮、尿烧伤、皮肤溃疡等其他疾病。在尾巴和肛门周围的毛发应该经常修剪。", + "多发性神经病"=> "{$name}需要舒适的床上用品,如空气床垫、水床、休闲椅垫、人用床垫、羊毛、睡袋、毯子、稻草或其他柔软舒适的东西。你需要经常更换床上用品的外层,并且需要定期帮它洗澡,以防它由于大小便失禁引起褥疮、尿烧伤、皮肤溃疡等其他疾病。在尾巴和肛门周围的毛发应该经常修剪。", + "感觉神经失调性神经病"=> "{$name}长期缺乏运动,需要给它提供足够柔软的睡垫并注意清洁,避免褥疮及皮肤疾病。", + "皮肤脆性综合征"=> "{$name}需要限制运动,生活环境以柔软为主,玩耍时注意力度,避免撕裂皮肤。增加剪指甲频率,防止它抓挠身体,避免受外伤。由于它的皮肤免疫力较低,应注意生活环境清洁,不要与有皮肤病的宠物接触,避免继发或加重皮肤疾病。当发现它的皮肤出现撕裂,发红,瘙痒,脱毛,化脓等异常时及时送诊。", + "球形细胞脑白质营养不良"=> "{$name}需要舒适的床上用品,如空气床垫、水床、休闲椅垫、人用床垫、羊毛、睡袋、毯子、稻草或其他柔软舒适的东西。你需要经常更换床上用品的外层,并且需要定期帮它洗澡,以防它由于大小便失禁引起褥疮、尿烧伤、皮肤溃疡等其他疾病。在尾巴和肛门周围的毛发应该经常修剪。", + "神经节苷脂病-1型"=> "{$name}需要舒适的床上用品,如空气床垫、水床、休闲椅垫、人用床垫、羊毛、睡袋、毯子、稻草或其他柔软舒适的东西。你需要经常更换床上用品的外层,并且需要定期帮它洗澡,以防它由于大小便失禁引起褥疮、尿烧伤、皮肤溃疡等其他疾病。在尾巴和肛门周围的毛发应该经常修剪。", + "退行性脊髓病"=> "{$name}需要舒适的床上用品,如空气床垫、水床、休闲椅垫、人用床垫、羊毛、睡袋、毯子、稻草或其他柔软舒适的东西。你需要经常更换床上用品的外层,并且需要定期帮它洗澡,以防它由于大小便失禁引起褥疮、尿烧伤、皮肤溃疡等其他疾病。在尾巴和肛门周围的毛发应该经常修剪。", + "岩藻糖苷贮积症"=> "{$name}需要舒适的床上用品,如空气床垫、水床、休闲椅垫、人用床垫、羊毛、睡袋、毯子、稻草或其他柔软舒适的东西。你需要经常更换床上用品的外层,并且需要定期帮它洗澡,以防它由于大小便失禁引起褥疮、尿烧伤、皮肤溃疡等其他疾病。在尾巴和肛门周围的毛发应该经常修剪。", + "鱼鳞病"=> "可使用香波冲洗皮肤,刷牙和毛发梳理等物理手段进行症状的缓解。皮肤可使用温和的抗脂溢性香波和保湿霜可用来在宠物皮肤上创造一个保护层,减少水分流失。" + ]; + //var_dump($diseaseList);die; + $washNotice = '无特别洗护要求'; + foreach ($diseaseList as $disease) { + if($disease['risk'] && !$disease['lock'] && isset($washMap[$disease['name']])){ + $washNotice = $washMap[$disease['name']]; + break; + } + } + $temp = [ + '梳毛护理星级'=>$rate, + '梳毛建议'=>$map[$rate], + '梳毛说明'=>$map["梳毛护理相关知识点"], + '洗护要求'=>$washNotice, + ]; + break; + case '性格行为': + /* + $temp = [ + '活力值'=>'', + '胆量值'=>'', + '暴躁值'=>'', + '吠叫值'=>'', + '独处值'=>'', + '排尿值'=>'', + ];*/ + //狗 + $map[1] = [ + "胆量值"=>[ + "描述"=>"指犬只对陌生事物的恐惧感及焦虑情绪,分数越高,越容易有恐惧或焦虑的情绪。", + "1"=>"{$name}是只胆大包天的狗狗,这个世界上似乎没有它害怕的事物。", + "2"=>"{$name}是只勇敢的狗狗,内心平静,是很稳重的孩子。", + "3"=>"{$name}是只勇敢的狗狗,内心平静,是很稳重的孩子。", + "4"=>"{$name}稍微有点胆小,容易焦虑,希望世界对它温柔以待。", + "5"=>"{$name}稍微有点胆小,容易焦虑,希望世界对它温柔以待。", + ], + "暴躁值"=>[ + "描述"=>"指犬只的攻击性,得分越高,越容易产生攻击行为,与战斗力无关。", + "1"=>"{$name}是只人畜无害的狗子,狗中铁憨憨。", + "2"=>"{$name}是典型的人不犯我我不犯人的狗子,不去惹毛它就不会炸毛。", + "3"=>"{$name}是典型的人不犯我我不犯人的狗子,不去惹毛它就不会炸毛。", + "4"=>"{$name}性子比较急,不要尝试去挑战它的底线,别老虎不发威就把它当HelloKitty。", + "5"=>"{$name}性子比较急,不要尝试去挑战它的底线,别老虎不发威就把它当HelloKitty。", + ], + + "吠叫值"=>[ + "描述"=>"指犬只的持续吠叫程度,分数越高,表示当犬只兴奋或受到刺激时,持续吠叫的情况越严重。", + "1"=>"{$name}可以说是最不爱说话的一类狗子了,这种不吵闹的狗子是多少人的理想型。", + "2"=>"{$name}兴奋或受到刺激的时候喜欢叫,注意观察它在说什么,它可不是随便说说而已哦。", + "3"=>"{$name}兴奋或受到刺激的时候喜欢叫,注意观察它在说什么,它可不是随便说说而已哦。", + "4"=>"{$name}天生是个话痨,有事没事就爱瞎哔哔,如果它并没有这么做,那么恭喜你,它为了融入你的生活改变了天性。", + "5"=>"{$name}天生是个话痨,有事没事就爱瞎哔哔,如果它并没有这么做,那么恭喜你,它为了融入你的生活改变了天性。", + ], + "独处值"=>[ + "描述"=>"指犬只对孤独的感知度,是否容易产生分离焦虑,分数越高,孤独的感知能力越强,独处能力越低。", + "1"=>"{$name}是只学会享受孤独的狗子,独处能力很强,但并不代表它不想和你在一起,要知道,和你在一起的时光才是它最开心的。", + "2"=>"{$name}是懂事的狗子,能够自己独处上一段时间,但是它同时也很想你,不要让它等太久。", + "3"=>"{$name}是懂事的狗子,能够自己独处上一段时间,但是它同时也很想你,不要让它等太久。", + "4"=>"{$name}觉得与你分离是世界上最难过的事,尽量多陪陪它吧,你不在的时候,它可能偷偷伤心了很久。", + "5"=>"{$name}觉得与你分离是世界上最难过的事,尽量多陪陪它吧,你不在的时候,它可能偷偷伤心了很久。", + ], + "排尿值"=>[ + "描述"=>"指犬只独自在家时乱排尿的情况,得分越高,乱排尿的可能性越大。", + "1"=>"{$name}是只讲规则的狗子,只要你事先与它确定了规则,它是不会随地尿尿的。", + "2"=>"{$name}通常不会随意尿尿,除非它忍不住或者它想通过尿尿告诉你什么。", + "3"=>"{$name}通常不会随意尿尿,除非它忍不住或者它想通过尿尿告诉你什么。", + "4"=>"{$name}在你看不到的情况下,可能会随意尿一尿,它知道这样做不太好,但是它就是想试一试。", + "5"=>"{$name}在你看不到的情况下,可能会随意尿一尿,它知道这样做不太好,但是它就是想试一试。", + ], + "活力值"=>[ + "描述"=>"指犬只的活跃度,得分越高越活泼,精力越充沛,性格更有趣喧闹,需要的运动量越大。", + "1"=>"{$name}是只喜欢安静的肥宅,请让它一只汪静静。", + "2"=>"{$name}是只动静皆宜的狗子,静如处子,动如脱兔说的就是它。", + "3"=>"{$name}是只动静皆宜的狗子,静如处子,动如脱兔说的就是它。", + "4"=>"{$name}是只喜欢蹦D的狗子,内心住着野狼DISCO本狼,请尽情陪它玩耍,释放你们的天性。", + "5"=>"{$name}是只喜欢蹦D的狗子,内心住着野狼DISCO本狼,请尽情陪它玩耍,释放你们的天性。", + ], + ]; + //猫 + $map[2] = [ + "外出指数"=> [ + "描述"=> "指猫咪的外出频率,得分越高,携带外出的可能性越高,出门受刺激的反应越低。", + "1"=> "{$name}是只害羞的猫咪,携带外出受刺激的可能性大,若没有进行专业的训练,不建议强制外出。", + "2"=> "{$name}是只可宅可外出的猫咪,值得注意的是,需要进行足够多的社会化,循序渐进的携带外出,如果外出反应大,应立即带回。", + "3"=> "{$name}是只可宅可外出的猫咪,值得注意的是,需要进行足够多的社会化,循序渐进的携带外出,如果外出反应大,应立即带回。", + "4"=> "{$name}是猫咪里的汪,是可以像狗一样外出溜达的猫咪,前期做好循序渐进的外出训练,直到在外毫无压力时便可携带外出。", + "5"=> "{$name}是猫咪里的汪,是可以像狗一样外出溜达的猫咪,前期做好循序渐进的外出训练,直到在外毫无压力时便可携带外出。" + ], + + "活力值"=> [ + "描述"=> "指猫咪的活跃度,得分越高越活泼,精力越充沛,性格更有趣喧闹,需要的运动量越大。", + "1"=> "{$name}是只喜欢安静的肥宅,请让它一只喵静静。", + "2"=> "{$name}是只动静皆宜的猫咪,静如处子,动如脱兔说的就是它。", + "3"=> "{$name}是只动静皆宜的猫咪,静如处子,动如脱兔说的就是它。", + "4"=> "{$name}是只喜欢蹦D的猫咪,内心住着野狼DISCO本狼,请尽情陪它玩耍,释放你们的天性。", + "5"=> "{$name}是只喜欢蹦D的猫咪,内心住着野狼DISCO本狼,请尽情陪它玩耍,释放你们的天性。" + ], + + "与人亲近值"=> [ + "描述"=> "指猫咪与人类的友好度,得分越高,与人的相处越轻松,越自然友爱。", + "1"=> "{$name}只喜欢它自己,内心OS:愚蠢的人类请离本喵远一点。", + "2"=> "{$name}与人类可以和谐相处,自然友爱,前提是没有受过人类的伤害。", + "3"=> "{$name}与人类可以和谐相处,自然友爱,前提是没有受过人类的伤害。", + "4"=> "{$name}是人类的好朋友,是所有猫咪中最愿意与人亲近的物种,请好好珍惜。", + "5"=> "{$name}是人类的好朋友,是所有猫咪中最愿意与人亲近的物种,请好好珍惜。" + ], + + "对陌生人的敌意"=> [ + "描述"=> "指猫咪的对陌生人的敌意,得分越高,受刺激的反应越大,越容易产生攻击行为。", + "1"=> "{$name}对陌生人很友好,如果人类没有主动攻击,基本上相安无事。", + "2"=> "{$name}对陌生人友善但警惕,受到刺激的话会产生攻击行为。", + "3"=> "{$name}对陌生人友善但警惕,受到刺激的话会产生攻击行为。", + "4"=> "{$name}对陌生人戒心很重,不要轻易让它接触陌生人,受刺激的可能性大,容易产生攻击行为。", + "5"=> "{$name}对陌生人戒心很重,不要轻易让它接触陌生人,受刺激的可能性大,容易产生攻击行为。" + ], + + "对主人的敌意"=> [ + "描述"=> "指猫咪的对主人的敌意,得分越高,服从性越低,不愿意遵守命令。", + "1"=> "{$name}很爱主人,出生自带服从性高的属性,甚至比较黏人。", + "2"=> "{$name}眼里的主人是与它平等的物种,大家相敬如宾平安无事,如果你可爱的话,它甚至有点爱你。", + "3"=> "{$name}眼里的主人是与它平等的物种,大家相敬如宾平安无事,如果你可爱的话,它甚至有点爱你。", + "4"=> "{$name}的内心住着哈士奇,自我且叛逆,可能听话的可能性很低,但也不能说它不爱你。", + "5"=> "{$name}的内心住着哈士奇,自我且叛逆,可能听话的可能性很低,但也不能说它不爱你。" + ], + + "对其它猫的敌意"=> [ + "描述"=> "指猫咪的对其它猫的敌意,得分越高,越容易产生攻击行为,与战斗力无关。", + "1"=> "{$name}对其它小伙伴很友好,是猫咪中的铁憨憨 。", + "2"=> "{$name}对其它猫友善但警惕,不会轻易接受同类,一旦接受了便会友好相处,如果被欺负也会回击。", + "3"=> "{$name}对其它猫友善但警惕,不会轻易接受同类,一旦接受了便会友好相处,如果被欺负也会回击。", + "4"=> "{$name}对同类不是很友好,如非必要,不要轻易让它们接触,相处不当会经常打架。", + "5"=> "{$name}对同类不是很友好,如非必要,不要轻易让它们接触,相处不当会经常打架。" + ], + + "对新事物的害羞程度 "=> [ + "描述"=> "指猫咪对陌生事物的恐惧感及焦虑情绪,分数越高,越容易有恐惧或焦虑的情绪,害羞程度就越高。", + "1"=> "{$name}是只神经大条的猫咪,任何新事物在它眼里都很有趣。", + "2"=> "{$name}对新事物比较警惕,但只要适应一段时间便能很好的接受。", + "3"=> "{$name}对新事物比较警惕,但只要适应一段时间便能很好的接受。", + "4"=> "{$name}是只爱守旧的猫咪,比较难接受新事物,需要更多的时间和耐心让它放下戒心。", + "5"=> "{$name}是只爱守旧的猫咪,比较难接受新事物,需要更多的时间和耐心让它放下戒心。" + ], + + "对陌生人的害羞程度 "=> [ + "描述"=> "指猫咪对陌生人的恐惧感及焦虑情绪,分数越高,越容易有恐惧或焦虑的情绪,害羞程度就越高。", + "1"=> "{$name}是只没皮没脸的猫咪,毫不认生,人见人爱。", + "2"=> "{$name}不排斥见陌生人但也没有那么喜欢,如果非得相处的话,请给它缓一缓的时间和空间。", + "3"=> "{$name}不排斥见陌生人但也没有那么喜欢,如果非得相处的话,请给它缓一缓的时间和空间。", + "4"=> "{$name}是只娇羞的猫咪,比较害怕见到陌生人,若非必要,不要让它们单独与陌生人相处,产生应激的机率很高。", + "5"=> "{$name}是只娇羞的猫咪,比较害怕见到陌生人,若非必要,不要让它们单独与陌生人相处,产生应激的机率很高。" + ], + + "舔毛倾向"=> [ + "描述"=> "指猫咪除自身清洁需要外,利用舔毛行为缓解压力的倾向,得分越高,感受压力越大,释放压力需求越高。", + "1"=> "{$name}除了给自己梳洗以外,偶尔也会舔舔毛来舒缓压力,是一只心理健康的猫咪。", + "2"=> "{$name}除了给自己梳洗以外,时不时用舔毛来舒缓压力,可以给它置放一些释放压力的猫抓板,防止过度舔毛引起毛球症。", + "3"=> "{$name}除了给自己梳洗以外,时不时用舔毛来舒缓压力,可以给它置放一些释放压力的猫抓板,防止过度舔毛引起毛球症。", + "4"=> "{$name}除了给自己梳洗以外,经常用舔毛来舒缓压力,主人可以多陪它玩,并放置一些释放压力的猫抓板或玩具,不要给孩子那么大的压力。", + "5"=> "{$name}除了给自己梳洗以外,经常用舔毛来舒缓压力,主人可以多陪它玩,并放置一些释放压力的猫抓板或玩具,不要给孩子那么大的压力。" + ], + ]; + $map = $map[$sample['pet_species']]; + //排序,宠物在后 + $body = $reportJson['秉性行为']['body']; + $pet_rate = $body[$name]; + $body_sorted = []; + foreach ($body as $key=>$val) { + if($key != $name){ + $body_sorted[$key] = $val; + } + } + $body_sorted[$name] = $pet_rate; + $temp = [ + '数值'=> $body_sorted, + '描述'=>[] + ]; + foreach ($temp['数值'] as $key=>$val) { + unset($temp['数值'][$key]['兴奋值']); + } + foreach ($map as $key=>$val) { + $_rate = round($pet_rate[$key]); + $_rate = $_rate == 0?1:$_rate; + $_rate = $_rate > 5?5:$_rate; + $temp['描述'][$key]['描述'] = $val['描述']; + $temp['描述'][$key]['检测结果'] = $val[$_rate]; + } + break; + case '可训练性': + /* + $temp = [ + '专注度'=>'', + '游戏欲'=>'', + '兴奋值'=>'', + '服从性'=>'', + '聪明值'=>'', + '逃逸值'=>'', + ];*/ + $map = [ + "专注度"=>[ + "描述"=>"指犬只在集中注意力时受外界刺激的影响程度,例如被柏油马路上的一片树叶、许多断续而短促的声音中的一个长声、被风吹起的塑料袋所吸引,或追逐飞过的小鸟及其它小动物,得分越低,表面受到外界刺激的影响程度越高,专注度越低。", + "1"=>"{$name}是只敏感的狗子,一点风吹草动都会影响它的专注度。", + "2"=>"{$name}也会集中注意力,但有时会被其它事物打断,如果训练的话,建议先从无干扰物开始。", + "3"=>"{$name}也会集中注意力,但有时会被其它事物打断,如果训练的话,建议先从无干扰物开始。", + "4"=>"{$name}天生专注度极高,它把注意力放在你身上时,其它事物很难打断它。", + "5"=>"{$name}天生专注度极高,它把注意力放在你身上时,其它事物很难打断它。", + ], + "游戏欲"=>[ + "描述"=>"指犬只的活跃度,玩游戏的欲望,得分越高越活跃,精力越充沛,游戏欲望越强。", + "1"=>"{$name}可能觉得玩游戏太幼稚了,它只想安静的睡一会儿。", + "2"=>"{$name}是喜欢玩游戏的狗子,你陪它玩儿的时间越多,它就越活泼。", + "3"=>"{$name}是喜欢玩游戏的狗子,你陪它玩儿的时间越多,它就越活泼。", + "4"=>"{$name}是个不折不扣的活力狗,爱玩更爱你陪它玩,你有多少精力它都会奉陪到底。", + "5"=>"{$name}是个不折不扣的活力狗,爱玩更爱你陪它玩,你有多少精力它都会奉陪到底。", + ], + "兴奋值"=>[ + "描述"=>"指犬只受到刺激后的反应,分数越高,表明受到刺激或引起兴奋的反应越强烈,例如散步,开车,门铃响,客人到访,主人在一段时间后回家,犬只的兴奋情况。", + "1"=>"{$name}是只佛系汪,似乎很少事情能让它感兴趣。", + "2"=>"{$name}受到刺激的时候会兴奋起来,它的兴奋程度取决于刺激它的点有多大。", + "3"=>"{$name}受到刺激的时候会兴奋起来,它的兴奋程度取决于刺激它的点有多大。", + "4"=>"{$name}是个人来疯,兴奋点太低,随随便便就激动起来。", + "5"=>"{$name}是个人来疯,兴奋点太低,随随便便就激动起来。", + ], + "服从性"=>[ + "描述"=>"得分高的犬只,表示对主人更关心,愿意遵守命令,反应积极,快速学习,服从性高。", + "1"=>"{$name}有自己的想法,不要指望它顺着你,它的行动指南就是它的心情。", + "2"=>"{$name}是孺子可教型,只要你方法得当,好好跟它说,它还是很愿意和你一起学习的。", + "3"=>"{$name}是孺子可教型,只要你方法得当,好好跟它说,它还是很愿意和你一起学习的。", + "4"=>"{$name}的心里只有你,“百依百顺”可以说是它给主人最高规格的诚意了。", + "5"=>"{$name}的心里只有你,“百依百顺”可以说是它给主人最高规格的诚意了。", + ], + "聪明值"=>[ + "描述"=>"指犬只的智商指数,得分越高,越聪明。", + "3"=>"{$name}对于新的指令,在重复15-25次后可以理解新的指令,70%以上的时间服从主人的第一个命令。", + "4"=>"{$name}对于新的指令,在重复5-15次后可以理解新的指令,85%以上的时间服从主人的第一个命令。", + "5"=>"{$name}对于新的指令,不用下达超过5次,就能理解是什么意思,并且95%以上的时间对主人的第一个命令是服从的。", + ], + "逃逸值"=>[ + "描述"=>"指犬只一有机会就逃跑,或逃离家里或主人的可能性,分数越高,可能性越大。", + "1"=>"{$name}只想和你在一起,只要你不逃走。", + "2"=>"{$name}不会轻易逃走,但经常也会因为看见更感兴趣的事物而逃离你身边,大多数情况下能唤回,这取决于你们之间的关系,出门记得栓绳哦。", + "3"=>"{$name}不会轻易逃走,但经常也会因为看见更感兴趣的事物而逃离你身边,大多数情况下能唤回,这取决于你们之间的关系,出门记得栓绳哦。", + "4"=>"{$name}它可能更向往远方,一有机会就想逃走,恭喜你,喜提一只撒手没。", + "5"=>"{$name}它可能更向往远方,一有机会就想逃走,恭喜你,喜提一只撒手没。", + ], + ]; + $temp = [ + '数值'=> array_reverse($reportJson['可训练性']['body']), + '描述'=>[] + ]; + //数值的第一项是当前宠物的值 + $pet_rate = $temp['数值'][$name]; + foreach ($map as $key=>$val) { + $_rate = round($pet_rate[$key]); + $_rate = $_rate == 0?1:$_rate; + $_rate = $_rate > 5?5:$_rate; + $temp['描述'][$key]['描述'] = $val['描述']; + $temp['描述'][$key]['检测结果'] = $val[$_rate]; + } + break; + default: + $temp=[]; + } + return $temp; + } + + // 疾病部分,对锁定的信息做隐藏及特殊处理 + protected function get_disease_block($sample,$riskDisease,$diseaseList,$addVirtualByLevel=false){ + + //按照风险内容输出,没锁定的风险项放前面 + $unlock_risk = []; + + //所有解锁项目,包括非风险项 + $unlock_all = []; + + //所有低风险项目 + $risk_low_all = []; + + //所有高风险项目 + $risk_high_all = []; + + //转化为名字对应内容 + $temp = []; + foreach ($diseaseList as $item) { + $temp[$item['name']] = $item; + if(!$item['lock']){ + $unlock_all[] = $item; + } + if($item['risk']){ + if($item['risk_level'] == 1){ + $risk_low_all[] = $item; + }else{ + $risk_high_all[] = $item; + } + + } + } + $diseaseList = $temp; + + //不同风险等级对应的锁定内容 + $lock = [ + 1=>[], + 2=>[], + ]; + + foreach ($riskDisease as $key=>$val) { + if(empty($diseaseList[$key])){ + //疾病列表里没有这一项,直接去除,否则无法做后续处理,这会造成检测结果的数量减少 + continue; + } + //锁定项目隐藏,后面会给锁定项目增加虚拟项目 + if(!$diseaseList[$key]['lock']){ + $unlock_risk[] = $diseaseList[$key]; + } + } + + //判断样品是否需要锁定一些疾病 + $is_lock = !empty($lock[1]) || !empty($lock[2]); + if(!$is_lock){ + foreach ($diseaseList as $val) { + if($val['lock']){ + $is_lock = true; + break; + } + } + } + + //如果列表中有疾病锁定了,但风险项中没有,则虚拟一些风险项,便于统一展示逻辑 + //(不考虑套餐自选疾病解锁了所有的锁定疾病的情况) + if($is_lock){ + $virtual = [ + 'lock'=>true, + 'risk'=>true, + 'risk_level'=>1, + 'name'=>'解锁后可查看细节', + ]; + //是否需要根据风险等级添加虚拟疾病 + $lock[1][] = $virtual; + $lock[1][] = $virtual; + if($addVirtualByLevel){ + $virtual['risk_level'] = 2; + $lock[2][] = $virtual; + $lock[2][] = $virtual; + } + } + //总列表 + $list = array_merge($unlock_risk,$lock[1],$lock[2]); + + //强调列表:解锁疾病数量少于10个则显示 + $list_notice = []; + if(count($unlock_all)<10){ + $custom = $this->get_disease_custom($sample); + if(!empty($custom)){ + //对于自选,展示自选,不必做解锁项目的过滤 + $list_notice = [ + 'name'=>$custom['name'], + 'list'=>$unlock_all + ]; + }else{ + $list_notice = [ + 'name'=>'遗传疾病'.count($unlock_all).'项', + 'list'=>$unlock_all + ]; + } + } + + //输出结果 + $temp = [ + '总计'=>$is_lock?'?':count($list), + '总计低风险'=>$is_lock?'?':count($risk_low_all), + '总计高风险'=>$is_lock?'?':count($risk_high_all), + '疾病总数'=>count($diseaseList), + '列表'=>$list, + '强调列表'=>$list_notice, + ]; + return $temp; + } + + // 突出特质 + protected function get_speciality($sample,$reportJson,$package){ + $map = [ + //狗 + '1'=>[ + '健康宝宝'=>['遗传病'=>[0]], + '爱因斯坦·汪'=>['智力评估'=>[5]], + '智商担当'=>['智力评估'=>[4]], + '胆大包天'=>['胆量值'=>[1]], + '铁憨憨'=>['暴躁值'=>[1]], + '安静的美狗子'=>['吠叫值'=>[1]], + '当代独立汪'=>['独处值'=>[1]], + '分离焦虑本汪'=>['独处值'=>[4,5]], + '轻度洁癖'=>['排尿值'=>[1]], + '乱尿之汪'=>['排尿值'=>[4,5]], + '蹦迪汪'=>['活力值'=>[4,5]], + '资深肥宅'=>['活力值'=>[1]], + '学习委员'=>['专注度'=>[4,5]], + '天生爱玩'=>['游戏欲'=>[4,5]], + '佛系汪'=>['兴奋值'=>[1]], + '天使宝宝'=>['服从性'=>[4,5]], + '撒手没'=>['逃逸值'=>[4,5]], + ], + //猫 + '2'=>[ + '健康宝宝'=>['遗传病'=>[0]], + '爱因斯坦·喵'=>['智力评估'=>[5]], + '智商担当'=>['智力评估'=>[4]], + '蹦迪喵'=>['活力值'=>[4,5]], + '佛系喵'=>['活力值'=>[1]], + '喵中汪'=>['外出频率'=>[4,5]], + '黏人小妖精'=>['与人亲近值'=>[4,5]], + '满眼都是你'=>['对主人的敌意'=>[1]], + '目中无主人'=>['对主人的敌意'=>[4,5]], + '毫无畏惧'=>['对新事物的害羞程度'=>[1]], + ] + ]; + $pet_name = $reportJson['header']['宠物名']; + $value = [ + '遗传病'=>0, + '智力评估'=>$reportJson['遗传特征']['body']['智商指数']['body']['智商指数'], + '外出频率'=>$reportJson['秉性行为']['body'][$pet_name]['外出频率'], + '与人亲近值'=>$reportJson['秉性行为']['body'][$pet_name]['与人亲近值'], + '对主人的敌意'=>$reportJson['秉性行为']['body'][$pet_name]['对主人的敌意'], + '对新事物的害羞程度'=>$reportJson['秉性行为']['body'][$pet_name]['对新事物的害羞程度'], + '胆量值'=>$reportJson['秉性行为']['body'][$pet_name]['胆量值'], + '暴躁值'=>$reportJson['秉性行为']['body'][$pet_name]['暴躁值'], + '吠叫值'=>$reportJson['秉性行为']['body'][$pet_name]['吠叫值'], + '独处值'=>$reportJson['秉性行为']['body'][$pet_name]['独处值'], + '排尿值'=>$reportJson['秉性行为']['body'][$pet_name]['排尿值'], + '活力值'=>$reportJson['秉性行为']['body'][$pet_name]['活力值'], + '专注度'=>$reportJson['可训练性']['body'][$pet_name]['专注度'], + '游戏欲'=>$reportJson['可训练性']['body'][$pet_name]['游戏欲'], + '兴奋值'=>$reportJson['可训练性']['body'][$pet_name]['兴奋值'], + '服从性'=>$reportJson['可训练性']['body'][$pet_name]['服从性'], + '逃逸值'=>$reportJson['可训练性']['body'][$pet_name]['逃逸值'], + ]; + //是否全部疾病解锁且没有遗传病 + $diseaseList = $this->get_disease_list(0,$sample,$reportJson,$package,false,false,true); + foreach ($diseaseList as $item) { + if($item['lock'] || $item['risk']){ + $value['遗传病'] = 1; + break; + } + } + //提取特质 + $ret = []; + foreach ($map[$package['species']] as $name => $cond) { + + //数据名称 + $value_key = array_keys($cond)[0]; + if(!isset($value[$value_key])){ + continue; + } + $value_rate = round($value[$value_key]); + if(in_array($value_rate,$cond[$value_key])){ + $ret[] = $name; + } + } + + //特质少于3个,做补充 + $more = ['可爱多','独一无二','美食家']; + for($i=count($ret);$i<3;$i++){ + $ret[] = array_shift($more); + } + + return $ret; + } + + //重点关注的疾病,$gene_type = 1 遗传风险,2健康疾病 + protected function get_focus_disease($block_disease,$gene_type){ + //不必做以上过滤 + if($gene_type==2){ + //重点关注里只展示中高风险的疾病,注意锁定了不要过滤 + foreach ($block_disease['列表'] as $key=>&$val) { + if($val['risk_level'] < 2 && !$val['lock']){ + unset($block_disease['列表'][$key]); + } + /*由前端修改 + if($gene_type == 2){ + $tmp = explode(', ',$val['risk_detail']['风险解读']); + $val['risk_detail']['风险解读'] = $tmp[0]; + }*/ + } + //解锁状态,重新统计数量 + if($block_disease['总计']!='?'){ + $block_disease['总计'] = count($block_disease['列表']); + } + } + + //信息里面的遗传疾病,锁定不超过2个,因这部分根据不同风险等级添加了2个虚拟疾病 + $disease_lock_count = 0; + foreach ($block_disease['列表'] as $key=>$val) { + if($val['lock']){ + $disease_lock_count++; + } + if($disease_lock_count>2){ + unset($block_disease['列表'][$key]); + } + } + + return $block_disease; + } + + // 用药指导-内容太多,独立出来 + protected function drug($has_mh,$has_mdr1){ + return [ + [ + 'name'=>'恶性高热', + '携带'=>$has_mh?'是':'否', + 'get'=>$has_mh, + 'tag'=>'MH', + 'limit'=>$has_mh?'1项限制':'以下药物可遵医嘱使用', + 'data'=>[ + [ + 'name'=>'所有', + 'tag'=>'ALL', + 'data'=>[ + [ + 'name'=>'禁用药物', + 'tag'=>'jinyongyaowu', + 'data'=>[ + [ + 'name'=>'氟烷', + 'tag'=>'', + ], + [ + 'name'=>'七氟醚', + 'tag'=>'', + ], + [ + 'name'=>'地氟醚', + 'tag'=>'', + ], + [ + 'name'=>'异氟醚', + 'tag'=>'', + ], + [ + 'name'=>'安氟醚', + 'tag'=>'', + ], + [ + 'name'=>'琥珀胆碱', + 'tag'=>'', + ], + [ + 'name'=>'十烃季铵', + 'tag'=>'', + ], + ] + ] + ] + ] + ] + ], + [ + 'name'=>'MDR1', + '携带'=>$has_mdr1?'是':'否', + 'get'=>$has_mdr1, + 'limit'=>$has_mdr1?'4项限制':'以下药物可遵医嘱使用', + 'tag'=>'MDR1', + 'data'=>[ + [ + 'name'=>'抗寄生虫药', + 'tag'=>'ANTIPARASITIC', + 'data'=>[ + [ + 'name'=>'禁用药物', + 'tag'=>'jinyongyaowu', + 'data'=>[ + [ + 'name'=>'Alstomec', + 'tag'=>'伊维菌素', + ], + + [ + 'name'=>'Animec', + 'tag'=>'伊维菌素', + ], + + [ + 'name'=>'Bimectin', + 'tag'=>'伊维菌素', + ], + + [ + 'name'=>'Ivomec', + 'tag'=>'伊维菌素', + ], + + [ + 'name'=>'Panomec', + 'tag'=>'伊维菌素', + ], + + [ + 'name'=>'Qualimintic', + 'tag'=>'伊维菌素', + ], + + [ + 'name'=>'Vibamec', + 'tag'=>'伊维菌素', + ], + + [ + 'name'=>'Xeno 450', + 'tag'=>'伊维菌素', + ], + + [ + 'name'=>'Xeno 450/Xeno 450-mini', + 'tag'=>'伊维菌素', + ], + + [ + 'name'=>'Dectomax', + 'tag'=>'伊维菌素', + ], + + [ + 'name'=>'Miteguard', + 'tag'=>'伊维菌素', + ], + + [ + 'name'=>'Abamectin', + 'tag'=>'伊维菌素', + ], + + [ + 'name'=>'Profender', + 'tag'=>'伊维菌素', + ] + ], + ], + [ + 'name'=>'有潜在高风险药物', + 'tag'=>'qianzaifengxian', + 'data'=>[ + [ + 'name'=>'Milbemax', + 'tag'=>'米尔倍霉素', + ], + + [ + 'name'=>'Program plus', + 'tag'=>'米尔倍霉素', + ], + + [ + 'name'=>'Advocate', + 'tag'=>'莫昔克丁', + ], + + [ + 'name'=>'Stronghold', + 'tag'=>'塞拉菌素', + ] + ], + ], + [ + 'name'=>'密切关注副作用的药物', + 'tag'=>'miqieguanzhu', + 'data'=>[ + [ + 'name'=>'Metronidazole', + 'tag'=>'甲硝唑', + ], + + [ + 'name'=>'Stomorgyl', + 'tag'=>'甲硝唑', + ], + + [ + 'name'=>'Flagyl', + 'tag'=>'甲硝唑', + ], + + [ + 'name'=>'Metrolyl', + 'tag'=>'甲硝唑', + ] + ], + ], + [ + 'name'=>'部分犬只存在副作用的药物', + 'tag'=>'xianliangshiyong', + 'data'=>[ + [ + 'name'=>'Bob Martin Dog Wormer', + 'tag'=>'硝硫氰醚', + ], + + [ + 'name'=>'Lopatol', + 'tag'=>'硝硫氰醚', + ], + + [ + 'name'=>'Troscan', + 'tag'=>'硝硫氰醚', + ] + ], + ], + ] + ], + [ + 'name'=>'止泻药', + 'tag'=>'ANTIDIARRHEAL', + 'data'=>[ + [ + 'name'=>'禁用药物', + 'tag'=>'jinyongyaowu', + 'data'=>[ + [ + 'name'=>'Diareze', + 'tag'=>'洛哌丁胺', + ], + + [ + 'name'=>'Imodium', + 'tag'=>'洛哌丁胺', + ], + + [ + 'name'=>'Norimode', + 'tag'=>'洛哌丁胺', + ] + ], + ], + ], + ], + + [ + 'name'=>'止吐药', + 'tag'=>'ANTIEMETIC', + 'data'=>[ + [ + 'name'=>'禁用药物', + 'tag'=>'jinyongyaowu', + 'data'=>[ + [ + 'name'=>'Imodium', + 'tag'=>'甲氧氯普安', + ], + + [ + 'name'=>'Maxolon', + 'tag'=>'甲氧氯普安', + ], + + [ + 'name'=>'Metoclopramide', + 'tag'=>'甲氧氯普安', + ] + ], + ], + ], + ], + + [ + 'name'=>'镇静/镇痛药', + 'tag'=>'PRE-ANESTHETIC/ANELGESIC', + 'data'=>[ + [ + 'name'=>'密切关注副作用的药物', + 'tag'=>'miqieguanzhu', + 'data'=>[ + [ + 'name'=>'ACP', + 'tag'=>'乙酰丙嗪', + ], + + [ + 'name'=>'Alvegesic', + 'tag'=>'布托啡诺', + ], + + [ + 'name'=>'Dolorex', + 'tag'=>'布托啡诺', + ], + + [ + 'name'=>'Torbugesic', + 'tag'=>'布托啡诺', + ], + + [ + 'name'=>'Torbutrol', + 'tag'=>'布托啡诺', + ], + [ + 'name'=>'Torphasol', + 'tag'=>'布托啡诺', + ], + [ + 'name'=>'吗啡', + 'tag'=>'吗啡', + ], + [ + 'name'=>'Duramorph', + 'tag'=>'吗啡', + ], + [ + 'name'=>'Oramorph', + 'tag'=>'吗啡', + ], + [ + 'name'=>'Subutex', + 'tag'=>'丁丙诺啡', + ], + [ + 'name'=>'芬太尼', + 'tag'=>'芬太尼', + ], + [ + 'name'=>'Durogesic', + 'tag'=>'芬太尼', + ], + [ + 'name'=>'Fentora', + 'tag'=>'芬太尼', + ], + [ + 'name'=>'Sublimaze', + 'tag'=>'芬太尼', + ] + + ], + ], + + ], + ], + + [ + 'name'=>'抗癫痫药', + 'tag'=>'ANTIEPILEPTIC', + 'data'=>[ + [ + 'name'=>'密切关注副作用的药物', + 'tag'=>'miqieguanzhu', + 'data'=>[ + [ + 'name'=>'Diphenylhydantoin', + 'tag'=>'苯妥英钠', + ], + + [ + 'name'=>'Epanutin', + 'tag'=>'苯妥英钠', + ], + + [ + 'name'=>'Pentran', + 'tag'=>'苯妥英钠', + ] + ], + ], + ], + ], + + [ + 'name'=>'溃疡愈合药', + 'tag'=>'ANTIULCER', + 'data'=>[ + [ + 'name'=>'有潜在高风险药物的药物', + 'tag'=>'qianzaifengxian', + 'data'=>[ + [ + 'name'=>'多潘立酮', + 'tag'=>'多潘立酮', + ], + + [ + 'name'=>'多潘立酮', + 'tag'=>'多潘立酮', + ] + ] + ], + [ + 'name'=>'密切关注副作用的药物', + 'tag'=>'miqieguanzhu', + 'data'=>[ + [ + 'name'=>'西咪替丁', + 'tag'=>'西咪替丁', + ], + + [ + 'name'=>'Zitac', + 'tag'=>'西咪替丁', + ], + + [ + 'name'=>'Dyspamet', + 'tag'=>'西咪替丁', + ], + [ + 'name'=>'Tagamet', + 'tag'=>'西咪替丁', + ], + + [ + 'name'=>'雷尼替丁', + 'tag'=>'雷尼替丁', + ], + + [ + 'name'=>'Zantac', + 'tag'=>'雷尼替丁', + ], + + [ + 'name'=>'Zofran', + 'tag'=>'恩丹西酮', + ] + + ] + ], + ], + ], + + [ + 'name'=>'类固醇药', + 'tag'=>'STEROID', + 'data'=>[ + [ + 'name'=>'密切关注副作用的药物', + 'tag'=>'miqieguanzhu', + 'data'=>[ + [ + 'name'=>'Oestradiol benzoate', + 'tag'=>'雌二醇', + ], + + [ + 'name'=>'Mesalin', + 'tag'=>'雌二醇', + ] + ], + ], + ], + ], + + [ + 'name'=>'抗原虫药', + 'tag'=>'ANTIPROTOZOAL', + 'data'=>[ + [ + 'name'=>'部分犬只存在副作用的药物', + 'tag'=>'xianliangshiyong', + 'data'=>[ + [ + 'name'=>'Milteforan', + 'tag'=>'米替福新', + ] + ], + ], + ], + ], + + [ + 'name'=>'免疫调节剂', + 'tag'=>'IMMUNOMODULATOR', + 'data'=>[ + [ + 'name'=>'部分犬只存在副作用的药物', + 'tag'=>'xianliangshiyong', + 'data'=>[ + [ + 'name'=>'Ergamisol', + 'tag'=>'左旋咪唑', + ] + ], + ], + ], + ], + + [ + 'name'=>'免疫抑制剂', + 'tag'=>'IMMUNOSUPPRESSIVE', + 'data'=>[ + [ + 'name'=>'密切关注副作用的药物', + 'tag'=>'miqieguanzhu', + 'data'=>[ + [ + 'name'=>'Atopica', + 'tag'=>'环孢素', + ], + [ + 'name'=>'Optimmune', + 'tag'=>'环孢素', + ], + [ + 'name'=>'Neoral', + 'tag'=>'环孢素', + ], + [ + 'name'=>'Sandimmun', + 'tag'=>'环孢素', + ], + [ + 'name'=>'Aurizon', + 'tag'=>'地塞米松', + ], + [ + 'name'=>'Dexadreson', + 'tag'=>'地塞米松', + ], + [ + 'name'=>'Dexafort', + 'tag'=>'地塞米松', + ], + [ + 'name'=>'Rapidexon', + 'tag'=>'地塞米松', + ], + [ + 'name'=>'Voren', + 'tag'=>'地塞米松', + ], + [ + 'name'=>'Maxidex', + 'tag'=>'地塞米松', + ], + [ + 'name'=>'Maxitrol', + 'tag'=>'地塞米松', + ] + + ], + ], + ], + ], + + [ + 'name'=>'心血管药', + 'tag'=>'CARDIAC', + 'data'=>[ + [ + 'name'=>'密切关注副作用的药物', + 'tag'=>'miqieguanzhu', + 'data'=>[ + [ + 'name'=>'地高辛', + 'tag'=>'地高辛', + ], + [ + 'name'=>'Lanoxin', + 'tag'=>'地高辛', + ], + [ + 'name'=>'LanoxinPG', + 'tag'=>'地高辛', + ], + [ + 'name'=>'Digitoxin', + 'tag'=>'洋地黄毒苷', + ], + [ + 'name'=>'Kinidin Durules', + 'tag'=>'奎尼丁', + ], + [ + 'name'=>'硫酸奎尼丁', + 'tag'=>'奎尼丁', + ], + [ + 'name'=>'Hypercard', + 'tag'=>'地尔硫䓬', + ], + [ + 'name'=>'Dilcardia SR', + 'tag'=>'地尔硫䓬', + ], + [ + 'name'=>'维拉帕米', + 'tag'=>'维拉帕米', + ], + [ + 'name'=>'Cordilox', + 'tag'=>'维拉帕米', + ], + [ + 'name'=>'Securon', + 'tag'=>'维拉帕米', + ] + + ], + ], + ], + ], + + [ + 'name'=>'抗生素', + 'tag'=>'ANTIBACTERIAL', + 'data'=>[ + [ + 'name'=>'有潜在高风险药物', + 'tag'=>'qianzaifengxian', + 'data'=>[ + [ + 'name'=>'红霉素', + 'tag'=>'红霉素', + ], + [ + 'name'=>'Eyrthrocin', + 'tag'=>'红霉素', + ], + [ + 'name'=>'Erythroped', + 'tag'=>'红霉素', + ], + [ + 'name'=>'Stomorgyl', + 'tag'=>'螺旋霉素', + ], + [ + 'name'=>'拜有利', + 'tag'=>'恩诺沙星', + ], + [ + 'name'=>'Enrocare', + 'tag'=>'恩诺沙星', + ], + [ + 'name'=>'Enrotab', + 'tag'=>'恩诺沙星', + ], + [ + 'name'=>'Enrox', + 'tag'=>'恩诺沙星', + ], + [ + 'name'=>'Enroxil', + 'tag'=>'恩诺沙星', + ], + [ + 'name'=>'Floxabactin', + 'tag'=>'恩诺沙星', + ], + [ + 'name'=>'Floxibac', + 'tag'=>'恩诺沙星', + ], + [ + 'name'=>'Powerflox', + 'tag'=>'恩诺沙星', + ], + [ + 'name'=>'Xeden', + 'tag'=>'恩诺沙星', + ] + + ], + ], + + [ + 'name'=>'密切关注副作用的药物', + 'tag'=>'miqieguanzhu', + 'data'=>[ + [ + 'name'=>'Doxyseptin 300', + 'tag'=>'多西环素', + ], + [ + 'name'=>'Ornicure', + 'tag'=>'多西环素', + ], + [ + 'name'=>'Pulmodox', + 'tag'=>'多西环素', + ], + [ + 'name'=>'Ronaxan', + 'tag'=>'多西环素', + ], + [ + 'name'=>'Vibramycin', + 'tag'=>'多西环素', + ], + [ + 'name'=>'Vibravenos', + 'tag'=>'多西环素', + ], + [ + 'name'=>'Raxar', + 'tag'=>'格帕沙星', + ], + [ + 'name'=>'Zagam', + 'tag'=>'司氟沙星', + ], + [ + 'name'=>'利福平', + 'tag'=>'利福平', + ], + [ + 'name'=>'Rifadin', + 'tag'=>'利福平', + ], + [ + 'name'=>'Rimactane', + 'tag'=>'利福平', + ], + + ], + ], + ], + ], + [ + 'name'=>'抗真菌药', + 'tag'=>'ANTIFUNGAL', + 'data'=>[ + [ + 'name'=>'密切关注副作用的药物', + 'tag'=>'miqieguanzhu', + 'data'=>[ + [ + 'name'=>'Nizoral', + 'tag'=>'酮康唑', + ], + [ + 'name'=>'Itrafungol', + 'tag'=>'伊曲康唑', + ], + [ + 'name'=>'Sporanox', + 'tag'=>'伊曲康唑', + ], + ], + ], + ], + ], + + [ + 'name'=>'抗肿瘤药', + 'tag'=>'ANTINEOPLASTIC', + 'data'=>[ + [ + 'name'=>'密切关注副作用的药物', + 'tag'=>'miqieguanzhu', + 'data'=>[ + [ + 'name'=>'长春碱', + 'tag'=>'长春碱', + ], + [ + 'name'=>'Velbe', + 'tag'=>'长春碱', + ], + [ + 'name'=>'长春新碱', + 'tag'=>'长春新碱', + ], + [ + 'name'=>'Oncovin', + 'tag'=>'长春新碱', + ], + [ + 'name'=>'多柔比星', + 'tag'=>'多柔比星', + ], + [ + 'name'=>'Taxol', + 'tag'=>'紫杉醇', + ], + [ + 'name'=>'放线菌素', + 'tag'=>'放线菌素', + ], + [ + 'name'=>'Cosmegen', + 'tag'=>'放线菌素', + ], + [ + 'name'=>'Lyovac', + 'tag'=>'放线菌素', + ], + [ + 'name'=>'Novantrone', + 'tag'=>'米托蒽醌', + ], + [ + 'name'=>'Etopophos ', + 'tag'=>'依托泊甙', + ], + [ + 'name'=>'Toposar', + 'tag'=>'依托泊甙', + ] + ], + ], + ], + ], + + + ] + ], + ]; + } + +} diff --git a/models/Role_model.php b/models/Role_model.php new file mode 100644 index 0000000..80777f0 --- /dev/null +++ b/models/Role_model.php @@ -0,0 +1,147 @@ +load->database(); + } + + + /*********************** + * 角色模型部分 + ************************/ + + /** + * 获取所有角色列表 + */ + function getRoleList() + { + $sql = "SELECT + r.* + FROM + sys_role r + ORDER BY + r.listorder"; + $query = $this->db->query($sql); + return [ + "items" => $query->result_array(), + "total" => count($query->result_array()) + ]; + } + + /** + * 获取所有菜单并加入对应的权限id + */ + function getAllMenus() + { + $sql = "SELECT + p.id perm_id, + m.* + FROM + sys_menu m, + sys_perm p + WHERE + p.perm_type = 'menu' + AND p.r_id = m.id + ORDER BY + m.listorder"; + $query = $this->db->query($sql); + return $query->result_array(); + } + + /** + * 获取所有角色列表 带perm_id + */ + function getAllRoles() + { + $sql = "SELECT + r.*, p.id perm_id + FROM + sys_role r, + sys_perm p + WHERE + r.id = p.r_id + AND p.perm_type = 'role' + ORDER BY + r.listorder"; + $query = $this->db->query($sql); + return [ + "items" => $query->result_array(), + "total" => count($query->result_array()) + ]; + } + + function getRoleMenu($RoleId) + { + $sql = "SELECT + p.id perm_id, + m.* + FROM + sys_menu m, + sys_perm p, + sys_role_perm rp + WHERE + rp.perm_id = p.id + AND p.perm_type = 'menu' + AND p.r_id = m.id + AND rp.role_id = ". $RoleId ." + ORDER BY + m.listorder"; + $query = $this->db->query($sql); + return $query->result_array(); + } + + /** + * 获取角色拥有的角色权限 + * @param $RoleId + * @return mixed + */ + function getRoleRole($RoleId) + { + $sql = "SELECT + p.id perm_id, + r.* + FROM + sys_role r, + sys_perm p, + sys_role_perm rp + WHERE + rp.perm_id = p.id + AND p.perm_type = 'role' + AND p.r_id = r.id + AND rp.role_id =". $RoleId . " + ORDER BY + r.listorder"; + $query = $this->db->query($sql); + return $query->result_array(); + } + + + /** + * 根据 角色ID 获取该角色所拥有的权限 + * [ + * ['role_id'=> 1, 'perm_id'=>1] + * ... + * ] + */ + function getRolePerm($RoleId) + { + $sql = "SELECT + role_id, perm_id + FROM + sys_role_perm + WHERE + role_id =" . $RoleId; + $query = $this->db->query($sql); + return $query->result_array(); + } + + /*********************** + * 角色模型部分结束 + ***********************/ +} \ No newline at end of file diff --git a/models/Sample_model.php b/models/Sample_model.php new file mode 100644 index 0000000..e94b790 --- /dev/null +++ b/models/Sample_model.php @@ -0,0 +1,183 @@ +'series_number as sn', + 'on'=>'base.series_id = sn.id', + 'type'=>'left' + ] + ]; + protected $keyword_field = ['device_id','base.tel','base.name','base.pet_name']; + protected $list_field = 'base.*,sn.device_id'; + + const STEP_BIND = 100; + const STEP_SENT = 200; + const STEP_RECEIVE = 300; + const STEP_DNA = 400; + const STEP_DNA_EXTRACTED = 500; + const STEP_UNQUALIFIED = 600; + const STEP_ANALYSIS = 700; + const STEP_COMPLETE = 800; + //作废,这种状态的样本对客户隐藏 + const STEP_DISCARD = 900; + + //后台的状态 + public $step_back = [// + self::STEP_BIND=>'待回寄样本', + self::STEP_SENT=>'已回寄', + self::STEP_RECEIVE=>'样本已收到', + self::STEP_DNA=>'DNA提取中', + self::STEP_DNA_EXTRACTED=>'文库分析中', + self::STEP_UNQUALIFIED=>'样本不合格', + self::STEP_ANALYSIS=>'基因测序中', + self::STEP_COMPLETE=>'报告已完成', + self::STEP_DISCARD=>'作废', + ]; + + public $step = [ + self::STEP_BIND=>'待回寄样本', + self::STEP_SENT=>'待回寄样本', + self::STEP_RECEIVE=>'样本已收到', + self::STEP_DNA=>'DNA提取中', + self::STEP_DNA_EXTRACTED=>'文库分析中', + self::STEP_UNQUALIFIED=>'样本不合格', + self::STEP_ANALYSIS=>'基因测序中', + self::STEP_COMPLETE=>'报告已完成', + ]; + + public $step_summary = [ + self::STEP_BIND=>'样品回寄', + self::STEP_SENT=>'样品回寄', + self::STEP_RECEIVE=>'实验室已收到样本', + self::STEP_DNA=>'正在提取DNA', + self::STEP_DNA_EXTRACTED=>'文库分析中', + self::STEP_UNQUALIFIED=>'实验室提取DNA失败', + self::STEP_ANALYSIS=>'基因测序中', + self::STEP_COMPLETE=>'报告已完成', + ]; + + //获取用户的总数 + public function getUserTotal($user_id) + { + $this->db->select('count(*) as count'); + $this->db->from($this->table); + $this->db->where('user_id', $user_id); + $this->db->where('step !=', Sample_model::STEP_DISCARD); + $list = $this->db->get()->row_array(); + return $list['count']; + } + + + //获取种猫种狗 + public function getBreeding($user_id,$exclude_ids,$pet_species,$pet_sex,$limit) + { + $this->db->select('base.*,sn.device_id'); + $this->db->from('sample as base'); + $this->db->where('is_breeding', 1); + $this->db->where('user_id', $user_id); + if(!empty($pet_sex)){ + $this->db->where('base.pet_sex', $pet_sex); + } + if(!empty($pet_species)){ + $this->db->where('base.pet_species', $pet_species); + } + if(!empty($exclude_ids)){ + $this->db->where_not_in('base.id', $exclude_ids); + } + $this->db->order_by('base.id','desc'); + $this->db->limit($limit); + //$this->db->where('step <', self::STEP_SENT); + $this->db->join('series_number as sn', 'base.series_id = sn.id','left'); + $list = $this->db->get()->result_array(); + if($list){ + foreach ($list as &$item) { + $this->format($item); + } + } + return $list; + } + + //根据id获取样本 + public function getByUserIds($ids=[]) + { + $this->db->select('base.*,sn.device_id'); + $this->db->from('sample as base'); + $this->db->join('series_number as sn', 'base.series_id = sn.id','left'); + $this->db->where_in('base.id', $ids); + return $this->db->get()->result_array(); + } + + //获取用户未回寄的样品 + public function getNotSentByUserId($user_id) + { + $this->db->select('*'); + $this->db->from('sample'); + $this->db->where('user_id', $user_id); + $this->db->where('step <', self::STEP_SENT); + return $this->db->get()->result_array(); + } + + //修改样品状态 + public function updateStatus($id,$step) + { + + } + + public function get($id=false, $field='base.id', $is_list=false, $select=null) + { + $list = parent::get($id, $field, $is_list, $select); + if(!$list){ + return $list; + } + if($is_list){ + foreach ($list as &$item) { + $this->format($item); + } + }else{ + $this->format($list); + } + return $list; + } + + //样品处理 + public function format(&$entity){ + $this->load->library('uploads'); + $entity['step_desc'] = $this->step[$entity['step']]; + $entity['pet_img'] = empty($entity['pet_img'])?'':base_url().Uploads::DIR.'/'.$entity['pet_img']; + } + + //批量发送完成通知 + public function complete($ids=[]){ + //发送微信通知 + $this->load->model('weixin_message_model'); + $this->load->model('customer_model'); + $this->load->model('series_number_model'); + $this->load->model('package_model'); + foreach ($ids as $id) { + $sample = $this->sample_model->get($id); + $conf = $this->config->item('allowed_cors_origins'); + $user = $this->customer_model->get($sample['user_id']); + $series = $this->series_number_model->get($sample['series_id']); + try{ + //如果没关注,会抛出错误,忽略 + $this->weixin_message_model->send( + $user['openid'], + Weixin_message_model::TEMPLATE_RESULT, + base_url().'weixin/?url='.urlencode($conf['report'].'/'.$series['device_id']), + [ + 'first'=>'您的爱宠检测报告已生成,请点击查看结果', + 'keyword1'=>$series['device_id'], + 'keyword2'=>date('Y-m-d'), + 'remark'=>'', + ] + ); + }catch (Exception $e){ + } + } + } + +} + diff --git a/models/Sample_processing_model.php b/models/Sample_processing_model.php new file mode 100644 index 0000000..9c4f56c --- /dev/null +++ b/models/Sample_processing_model.php @@ -0,0 +1,6 @@ +'sample as s', + 'on'=>'base.id = s.series_id', + 'type'=>'left' + ] + ]; + protected $keyword_field = ['device_id']; + protected $list_field = 'base.*,s.id as sample_id,s.create_time as time_bind'; + protected $has_update_time = false; + protected $where_field_map = [ + 'sample_id'=>'s.id' + ]; + protected $null_field = ['s.id']; + protected $unique_field = 'device_id'; + + function aaaaadd($entity) + { + $this->db->select('*'); + $this->db->from('package as p'); + $this->db->where('device_id',$entity['device_id']); + $result = $this->db->get()->row_array(); + if($result){ + return $entity['device_id'].'已存在'; + } + return $this->db->insert($entity); + } +} diff --git a/models/Sf_express_model.php b/models/Sf_express_model.php new file mode 100644 index 0000000..07719de --- /dev/null +++ b/models/Sf_express_model.php @@ -0,0 +1,235 @@ +config->item('sf-express');//echo($xmlContent);die; + //请求报文拼接顾客编码MD5加密再base64加密 + $verifyCode = base64_encode(md5($xmlContent . $conf['checkword'],TRUE)); + //$verifyCode = base64_encode(substr(md5($xmlContent . $conf['checkword']), 8, 16)); + //发送参数 + $post_data = array( + 'xml' => $xmlContent, + 'verifyCode' => $verifyCode + ); + + $resultCont = $this->send_post('http://bsp-oisp.sf-express.com/bsp-oisp/sfexpressService', $post_data); + //提示重复下单或不存在的顾客编码请修改txt文件内对应参数 + $xml = simplexml_load_string($resultCont); + if(isset($xml->ERROR)){ + $attr = $xml->ERROR->attributes(); + return [false,(string)$xml->ERROR,(int)$attr->code]; + } + return [true,$xml->Body]; + } + + /** + * 发送post请求 + * @param string $url 请求地址 + * @param array $post_data post键值对数据 + * @return string + */ + function send_post($url, $post_data) { + + $postdata = http_build_query($post_data); + $options = array( + 'http' => array( + 'method' => 'POST', + 'header' => 'Content-type:application/x-www-form-urlencoded;charset=utf-8', + 'content' => $postdata, + 'timeout' => 15 * 60 // 超时时间(单位:s) + ) + ); + $context = stream_context_create($options); + return file_get_contents($url, false, $context); + } + + + //寄送样品并获取运单号 + public function shipSample($address=[]) + { + $conf = $this->config->item('sf-express'); + /* + $xml_str = ' + + + + + + + '; + */ + /* + $xml_str = ' + + + + + + + '; + */ + $d_province = $address['d_province']; + $d_city = $address['d_city']; + $d_county = $address['d_county']; + $d_company = $address['d_company']; + $d_contact = $address['d_contact']; + $d_tel = $address['d_tel']; + $d_address = $address['d_address']; + /* + $xml_str = ' + + + + + + + + + + + "; + $xml = simplexml_load_string($xml_str); + $xml->Head = $conf['clientCode']; + //属性 + $order_attr = $xml->Body->Order->attributes(); + $order_attr->orderid=$address['trade_id']; + $order_attr->j_province=$address['province']; + $order_attr->j_city=$address['city']; + $order_attr->j_county=$address['district']; + $order_attr->j_contact=$address['name']; + $order_attr->j_tel=$address['tel']; + $order_attr->j_address=$address['address']; + //月结卡号:测试卡号7551234567 + $order_attr->custid=$conf['custid']; + $ret = $this->request($xml->asXML()); + if(!$ret[0]){ + log_message('error', $ret[1]); + return [false,$ret[1]]; + } + $attr = $ret[1]->OrderResponse->attributes(); + $row_base = [ + 'user_id'=>$address['user_id'], + 'mail_no'=>(string)$attr->mailno,// + 'partner_code'=>$address['trade_id'],// + 'trade_id'=>$address['trade_id'], + "sender_id"=> $address['user_id'], + "sender_name"=> $address['name'], + "sender_mobile"=> $address['tel'], + "sender_prov"=> $address['province'], + "sender_city"=> $address['city'], + "sender_county"=> $address['district'], + "sender_address"=> $address['address'], + "express"=> '2', + ]; + + $this->add($row_base); + return [true,$row_base['mail_no']]; + } + + + //测试寄送样品并获取运单号 + public function test($address) + { + $row_base = [ + 'user_id'=>$address['user_id'], + 'mail_no'=>'1',// + 'partner_code'=>$address['trade_id'],// + 'trade_id'=>$address['trade_id'], + "sender_id"=> $address['user_id'], + "sender_name"=> $address['name'], + "sender_mobile"=> $address['tel'], + "sender_prov"=> $address['province'], + "sender_city"=> $address['city'], + "sender_county"=> $address['district'], + "sender_address"=> $address['address'], + ]; + $id = $this->add($row_base); + + var_dump($id);die; + } +} diff --git a/models/Sf_express_model.php.20240424 b/models/Sf_express_model.php.20240424 new file mode 100644 index 0000000..fdedc0d --- /dev/null +++ b/models/Sf_express_model.php.20240424 @@ -0,0 +1,212 @@ +config->item('sf-express');//echo($xmlContent);die; + //请求报文拼接顾客编码MD5加密再base64加密 + $verifyCode = base64_encode(md5($xmlContent . $conf['checkword'],TRUE)); + //$verifyCode = base64_encode(substr(md5($xmlContent . $conf['checkword']), 8, 16)); + //发送参数 + $post_data = array( + 'xml' => $xmlContent, + 'verifyCode' => $verifyCode + ); + + $resultCont = $this->send_post('http://bsp-oisp.sf-express.com/bsp-oisp/sfexpressService', $post_data); + //提示重复下单或不存在的顾客编码请修改txt文件内对应参数 + $xml = simplexml_load_string($resultCont); + if(isset($xml->ERROR)){ + $attr = $xml->ERROR->attributes(); + return [false,(string)$xml->ERROR,(int)$attr->code]; + } + return [true,$xml->Body]; + } + + /** + * 发送post请求 + * @param string $url 请求地址 + * @param array $post_data post键值对数据 + * @return string + */ + function send_post($url, $post_data) { + + $postdata = http_build_query($post_data); + $options = array( + 'http' => array( + 'method' => 'POST', + 'header' => 'Content-type:application/x-www-form-urlencoded;charset=utf-8', + 'content' => $postdata, + 'timeout' => 15 * 60 // 超时时间(单位:s) + ) + ); + $context = stream_context_create($options); + return file_get_contents($url, false, $context); + } + + + //寄送样品并获取运单号 + public function shipSample($address=[]) + { + $conf = $this->config->item('sf-express'); + /* + $xml_str = ' + + + + + + + '; + */ + /* + $xml_str = ' + + + + + + + '; + */ + $xml_str = ' + + + + + + + '; + $xml = simplexml_load_string($xml_str); + $xml->Head = $conf['clientCode']; + //属性 + $order_attr = $xml->Body->Order->attributes(); + $order_attr->orderid=$address['trade_id']; + $order_attr->j_province=$address['province']; + $order_attr->j_city=$address['city']; + $order_attr->j_county=$address['district']; + $order_attr->j_contact=$address['name']; + $order_attr->j_tel=$address['tel']; + $order_attr->j_address=$address['address']; + //月结卡号:测试卡号7551234567 + $order_attr->custid=$conf['custid']; + $ret = $this->request($xml->asXML()); + if(!$ret[0]){ + log_message('error', $ret[1]); + return [false,$ret[1]]; + } + $attr = $ret[1]->OrderResponse->attributes(); + $row_base = [ + 'user_id'=>$address['user_id'], + 'mail_no'=>(string)$attr->mailno,// + 'partner_code'=>$address['trade_id'],// + 'trade_id'=>$address['trade_id'], + "sender_id"=> $address['user_id'], + "sender_name"=> $address['name'], + "sender_mobile"=> $address['tel'], + "sender_prov"=> $address['province'], + "sender_city"=> $address['city'], + "sender_county"=> $address['district'], + "sender_address"=> $address['address'], + "express"=> '2', + ]; + + $this->add($row_base); + return [true,$row_base['mail_no']]; + } + + + //测试寄送样品并获取运单号 + public function test($address) + { + $row_base = [ + 'user_id'=>$address['user_id'], + 'mail_no'=>'1',// + 'partner_code'=>$address['trade_id'],// + 'trade_id'=>$address['trade_id'], + "sender_id"=> $address['user_id'], + "sender_name"=> $address['name'], + "sender_mobile"=> $address['tel'], + "sender_prov"=> $address['province'], + "sender_city"=> $address['city'], + "sender_county"=> $address['district'], + "sender_address"=> $address['address'], + ]; + $id = $this->add($row_base); + + var_dump($id);die; + } +} diff --git a/models/Sf_express_model.php.20250905 b/models/Sf_express_model.php.20250905 new file mode 100644 index 0000000..b0df4d9 --- /dev/null +++ b/models/Sf_express_model.php.20250905 @@ -0,0 +1,235 @@ +config->item('sf-express');//echo($xmlContent);die; + //请求报文拼接顾客编码MD5加密再base64加密 + $verifyCode = base64_encode(md5($xmlContent . $conf['checkword'],TRUE)); + //$verifyCode = base64_encode(substr(md5($xmlContent . $conf['checkword']), 8, 16)); + //发送参数 + $post_data = array( + 'xml' => $xmlContent, + 'verifyCode' => $verifyCode + ); + + $resultCont = $this->send_post('http://bsp-oisp.sf-express.com/bsp-oisp/sfexpressService', $post_data); + //提示重复下单或不存在的顾客编码请修改txt文件内对应参数 + $xml = simplexml_load_string($resultCont); + if(isset($xml->ERROR)){ + $attr = $xml->ERROR->attributes(); + return [false,(string)$xml->ERROR,(int)$attr->code]; + } + return [true,$xml->Body]; + } + + /** + * 发送post请求 + * @param string $url 请求地址 + * @param array $post_data post键值对数据 + * @return string + */ + function send_post($url, $post_data) { + + $postdata = http_build_query($post_data); + $options = array( + 'http' => array( + 'method' => 'POST', + 'header' => 'Content-type:application/x-www-form-urlencoded;charset=utf-8', + 'content' => $postdata, + 'timeout' => 15 * 60 // 超时时间(单位:s) + ) + ); + $context = stream_context_create($options); + return file_get_contents($url, false, $context); + } + + + //寄送样品并获取运单号 + public function shipSample($address=[]) + { + $conf = $this->config->item('sf-express'); + /* + $xml_str = ' + + + + + + + '; + */ + /* + $xml_str = ' + + + + + + + '; + */ + $d_province = $address['d_province']; + $d_city = $address['d_city']; + $d_county = $address['d_county']; + $d_company = $address['d_company']; + $d_contact = $address['d_contact']; + $d_tel = $address['d_tel']; + $d_address = $address['d_address']; + /* + $xml_str = ' + + + + + + + + + + + "; + $xml = simplexml_load_string($xml_str); + $xml->Head = $conf['clientCode']; + //属性 + $order_attr = $xml->Body->Order->attributes(); + $order_attr->orderid=$address['trade_id']; + $order_attr->j_province=$address['province']; + $order_attr->j_city=$address['city']; + $order_attr->j_county=$address['district']; + $order_attr->j_contact=$address['name']; + $order_attr->j_tel=$address['tel']; + $order_attr->j_address=$address['address']; + //月结卡号:测试卡号7551234567 + $order_attr->custid=$conf['custid']; + $ret = $this->request($xml->asXML()); + if(!$ret[0]){ + log_message('error', $ret[1]); + return [false,$ret[1]]; + } + $attr = $ret[1]->OrderResponse->attributes(); + $row_base = [ + 'user_id'=>$address['user_id'], + 'mail_no'=>(string)$attr->mailno,// + 'partner_code'=>$address['trade_id'],// + 'trade_id'=>$address['trade_id'], + "sender_id"=> $address['user_id'], + "sender_name"=> $address['name'], + "sender_mobile"=> $address['tel'], + "sender_prov"=> $address['province'], + "sender_city"=> $address['city'], + "sender_county"=> $address['district'], + "sender_address"=> $address['address'], + "express"=> '2', + ]; + + $this->add($row_base); + return [true,$row_base['mail_no']]; + } + + + //测试寄送样品并获取运单号 + public function test($address) + { + $row_base = [ + 'user_id'=>$address['user_id'], + 'mail_no'=>'1',// + 'partner_code'=>$address['trade_id'],// + 'trade_id'=>$address['trade_id'], + "sender_id"=> $address['user_id'], + "sender_name"=> $address['name'], + "sender_mobile"=> $address['tel'], + "sender_prov"=> $address['province'], + "sender_city"=> $address['city'], + "sender_county"=> $address['district'], + "sender_address"=> $address['address'], + ]; + $id = $this->add($row_base); + + var_dump($id);die; + } +} diff --git a/models/Ship_order_model.php b/models/Ship_order_model.php new file mode 100644 index 0000000..e1d0929 --- /dev/null +++ b/models/Ship_order_model.php @@ -0,0 +1,6 @@ +load->database(); + } + + /** + * 登陆校验用户名密码 + * @param $username + * @param $passwd + */ + function validate($username, $passwd) + { + $sql = "SELECT + * + FROM + sys_user + WHERE + username = '" . $username . "' + AND password = '" . $passwd . "'"; + + $query = $this->db->query($sql); + if (($query->row_array()) == null) { + $result = array( + 'success' => FALSE, + 'userinfo' => null + ); + } else { + $result = array( + 'success' => TRUE, + 'userinfo' => $query->row_array() + ); + } + return $result; + } + + /** + * 根据 $user_id 获取上次登录角色id + * @param $Id + */ + function getLastLoginRole($Id) + { + $sql = "SELECT + role_id + FROM + sys_user_token + WHERE + user_id =" . $Id . " + ORDER BY + create_time DESC + limit 1"; + + $query = $this->db->query($sql); + $RolesArr = $query->result_array(); + + if (empty($RolesArr)) { + return [ + "code" => "50020", + "message" => "用户首次登录,没有最后一次登录信息" + ]; + } else { + foreach ($RolesArr as $k => $v) { + $sqlx = "SELECT + DISTINCT dept_id + FROM + `sys_user_role` + WHERE + user_id =" . $Id . " and role_id=" . $v['role_id']; + $queryx = $this->db->query($sqlx); + if (empty($queryx->result_array())) { + return [ + "code" => "50018", + "message" => "用户机构信息不完整, 无法登录, 请联系管理员" + ]; + } + } + return [ + "code" => "20000", + "role_id" => $RolesArr[0]['role_id'] + ]; + } + } + + /** + * 根据 $user_id 获取一个角色作为当前选择默认角色 + * 只在用户初次登录时使用 + * @param $Id + */ + function getCurrentRole($Id) + { + $sql = "SELECT + DISTINCT role_id + FROM + sys_user_role + WHERE + user_id =" . $Id; + + $query = $this->db->query($sql); + if (empty($query->result_array())) { + return [ + "code" => "50018", + "message" => "用户未分配角色, 无法登录, 请联系管理员" + ]; + } + $RolesArr = $query->result_array(); + + foreach ($RolesArr as $k => $v) { + $sqlx = "SELECT + DISTINCT dept_id + FROM + `sys_user_role` + WHERE + user_id =" . $Id . " and role_id=" . $v['role_id']; + $queryx = $this->db->query($sqlx); + if (empty($queryx->result_array())) { + return [ + "code" => "50018", + "message" => "用户机构信息不完整, 无法登录, 请联系管理员" + ]; + } + } + + return [ + "code" => "20000", + "role_id" => $RolesArr[0]['role_id'], + "message" => "成功获取第一个角色" + ]; + } + + /** + * @param $RoleId + * @param $UserId + * @return bool + * 判断该用户角色是否已分配机构部门 + */ + function roleHasDept($RoleId, $UserId) + { + $sql = "SELECT + DISTINCT dept_id + FROM + `sys_user_role` + WHERE + user_id =" . $UserId . " and role_id=" . $RoleId; + $query = $this->db->query($sql); + if (empty($query->result_array())) { + return FALSE; + } else { + return TRUE; + } + } + + /** + * 根据$token拉取用户信息 + * @param $Token + */ + function getUserInfo($Token) + { + $sql = "SELECT + u.id, + u.username, + u.tel, + u.email, + u.avatar, + u.sex, + u.last_login_ip, + u.last_login_time, + u.status + FROM + sys_user_token ut, + sys_user u + WHERE + ut.token = '" . $Token . "' + AND u.id = ut.user_id"; + + $query = $this->db->query($sql); + if (($query->row_array()) == null) { + $result = array( + 'success' => FALSE, + 'userinfo' => null + ); + } else { + $result = array( + 'success' => TRUE, + 'userinfo' => $query->row_array() + ); + } + return $result; + } + + /** + * 根据$token拉取用户角色信息 + * @param $Token + */ + function getUserRolesByToken($Token) + { + $sql = "SELECT + DISTINCT r.id,r.name + FROM + sys_user_token ut, + sys_user_role ur, + sys_role r + WHERE + ut.token = '" . $Token . "' + AND ur.user_id = ut.user_id + AND r.id = ur.role_id + and r.status=1"; + + $query = $this->db->query($sql); + return $query->result_array(); + } + + /** + * 根据$token拉取用户当前选择角色id + * @param $Token + */ + function getCurrentRoleByToken($Token) + { + $sql = "SELECT + ut.role_id + FROM + sys_user_token ut + WHERE + ut.token = '" . $Token . "'"; + $query = $this->db->query($sql); + return $query->row_array()['role_id']; + } + + /** + * 根据$token拉取用户当前选择部门 + * @param $Token + */ + function getCurrentDeptByToken($Token) + { + $sql = "SELECT + ut.user_id, + ut.role_id + FROM + sys_user_token ut + WHERE + ut.token = '" . $Token . "'"; + $query = $this->db->query($sql); + $arr = $query->result_array(); + + $sqlx = "SELECT DISTINCT + d.id, + d.pid, + d.name label + FROM + sys_user_role ur, + sys_dept d + WHERE + ur.user_id =" . $arr[0]['user_id'] . " + AND ur.role_id =" . $arr[0]['role_id'] . " + AND ur.dept_id = d.id"; + + $queryx = $this->db->query($sqlx); + return $queryx->result_array(); + } + + /** + * 获取所有用户列表 + */ + function getUserList($deptIdStr, $filters, $sort, $page, $pageSize) + { + + // 默认排序 + $orderStr = ''; + if ($sort['prop'] && $sort['order']) { + $orderStr = " ORDER BY " . $sort['prop'] . " " . ($sort['order'] === 'ascending' ? 'asc' : 'desc'); + } + + $filterStr = ''; + $j = 0; + foreach ($filters as $k => $v) { + if ($v['value'] !== '' && !is_null($v['value'])) { + if ($j) { + $filterStr = $filterStr . " and "; + } + + if ($v['prop'] === 'username') { + $filterStr .= $v['prop'] . " like '%" . $v['value'] . "%' "; + } + if ($v['prop'] === 'status') { + $filterStr .= $v['prop'] . "=" . $v['value']; + } + + $j++; + } + } + + if ($filterStr) { + $filterStr = " and " . $filterStr; + } + + //TODO: 将超级管理员隐藏 sys_user u where id != 1 and id IN ( + $sql = "SELECT + * + FROM + sys_user where id IN ( + SELECT DISTINCT + user_id + FROM + sys_user_role ur + WHERE + dept_id IN (" . $deptIdStr . ") + ) " + . $filterStr + . $orderStr . " limit " . ($page - 1) * $pageSize . "," . $pageSize; + + $query = $this->db->query($sql); + return $query->result_array(); + } + + function getUserListCnt($deptIdStr, $filters) + { + $filterStr = ''; + $j = 0; + foreach ($filters as $k => $v) { + if ($v['value'] !== '' && !is_null($v['value'])) { + if ($j) { + $filterStr = $filterStr . " and "; + } + + if ($v['prop'] === 'username') { + $filterStr .= $v['prop'] . " like '%" . $v['value'] . "%' "; + } + if ($v['prop'] === 'status') { + $filterStr .= $v['prop'] . "=" . $v['value']; + } + + $j++; + } + } + + if ($filterStr) { + $filterStr = " and " . $filterStr; + } + // TODO: 将超级管理员隐藏 sys_user u where id != 1 and id IN ( + $sql = "SELECT + count(u.id) cnt + FROM + sys_user u where id IN ( + SELECT DISTINCT + user_id + FROM + sys_user_role ur + WHERE + dept_id IN (" . $deptIdStr . ") + ) " + . $filterStr; + + $query = $this->db->query($sql); + if (empty($query->result_array())) { + return 0; + } else { + $result = $query->result_array(); + return $result[0]['cnt']; + } + } + + /** + * 获取所有角色列表 参考 permission.php 权限库,因为需要左关联组合,所以只能重新写模型 + * 并且根据$token 获取对应Token用户角色所拥有的角色类权限选项 + * 当用户含有未拥有的角色类权限时 设置 isDisabled 禁用选择 + * 新增编辑时使用 + * + */ + function getRoleOptions($Token) + { + $sql = "SELECT + r.id, + r.name, + r.remark, + r.status, + IF ( + t.name IS NULL, + 'true', + 'false' + ) isDisabled, + r.listorder + FROM + sys_role r + LEFT JOIN ( + SELECT + r.id, + r.name, + r.remark, + r.status + FROM + sys_user_token ut, + sys_role_perm rp, + sys_perm p, + sys_role r + WHERE + ut.token = '" . $Token . "' + AND ut.role_id = rp.role_id + AND rp.perm_id = p.id + AND p.perm_type = 'role' + AND p.r_id = r.id + AND r.status = 1 + ) t ON r.id = t.id + ORDER BY r.listorder"; + $query = $this->db->query($sql); + $RoleArr = $query->result_array(); + + // string to boolean + foreach ($RoleArr as $k => $v) { + $v['isDisabled'] === 'true' ? ($RoleArr[$k]['isDisabled'] = true) : ($RoleArr[$k]['isDisabled'] = false); + } + return $RoleArr; + } + + /** + * 根据 用户ID 获取该用户被分配的角色 + * + */ + function getUserRoles($Id) + { + $sql = "SELECT + DISTINCT r.id, + r.name, + r.remark, + r.status + FROM + sys_user_role ur, + sys_role r + WHERE + ur.role_id = r.id + AND ur.user_id =" . $Id; + + $query = $this->db->query($sql); + return $query->result_array(); + } + + function getUserRolesDept($user_id, $role_id) + { + $sql = "SELECT + * + FROM + sys_user_role ur + WHERE + ur.role_id =" . $role_id . " + AND ur.user_id =" . $user_id; + + $query = $this->db->query($sql); + return $query->result_array(); + } + + /** + * 根据 用户ID 获取该用户所拥有的角色 + * [ + * ['user_id'=> 1, 'role_id'=>1] + * ... + * ] + */ + function getRolesByUserId($Id) + { + $sql = "SELECT + ur.user_id,ur.role_id,ur.dept_id + FROM + sys_user_role ur + WHERE ur.user_id=" . $Id; + + $query = $this->db->query($sql); + return $query->result_array(); + } + + /* + * 微信登录认证 + */ + function getUserInfoByTel($Tel) + { + $sql = "SELECT + u.* + FROM + sys_user u + WHERE u.tel='" . $Tel . "'"; + $query = $this->db->query($sql); + return $query->result_array(); + } + + /*********************** + * 用户模型部分结束 + ***********************/ +} \ No newline at end of file diff --git a/models/Variety_model.php b/models/Variety_model.php new file mode 100644 index 0000000..b2a7995 --- /dev/null +++ b/models/Variety_model.php @@ -0,0 +1,14 @@ +config->item('weixin_uah'); + $config = [ + 'app_id' => $conf['AppId'], + 'secret' => $conf['AppSecert'], + 'token' => $conf['Token'], + 'aes_key' => $conf['EncodingAESKey'], + 'response_type' => 'array', + ]; + $app = new OfficialAccount($config); + $app->notice->send([ + 'touser' => $toUser, + 'template_id' => $template_id, + 'url' => $url, + 'data' => $msg + ]); + } + +} diff --git a/models/Zto_model.php b/models/Zto_model.php new file mode 100644 index 0000000..4fc3320 --- /dev/null +++ b/models/Zto_model.php @@ -0,0 +1,474 @@ +config->item('zto'); + // ZopProperties类的构造方法接收两个参数,分别是companyid和key,都需要注册中通开放平台后到个人中心查看 + $properties = new ZopProperties($conf['id'], $conf['key']); + $client = new ZopClient($properties); + $request = new ZopRequest(); + $request->setUrl($conf['host'].$path); + if(isset($params['company_id'])){ + $params['company_id'] = $conf['id']; + } + foreach ($params as $key=>$val) { + $request->addParam($key,$val); + } + $ret = $client->execute($request); + return json_decode($ret,true); + } + + //寄送样品并获取运单号 + public function shipSample($address=[]) + { + $data = [ + 'orderGroup'=>[ + "partnerCode"=> $address['trade_id'],//合作商订单号,为调用方生成,可以传订单号、主键、UUID等 + "type"=> 1,//订单类型 1 普通订单(线上),2线下联系订单 默认1 + "tradeId"=> $address['trade_id'],//交易号,由合作商平台产生。 + "mailNo"=> "",//运单号(有则提供,线下联系订单必须提供) + "sender"=> [ + "id"=> strval($address['user_id']), + "name"=> $address['name'], + "company"=> "", + "mobile"=> $address['tel'], + "phone"=> "", + "prov"=> $address['province'], + "city"=> $address['city'], + "county"=> $address['district'], + "address"=> $address['address'], + "zipcode"=> "" + ], + "receiver"=> [ + "id"=> "1", + "name"=> "有哈科技收样组", + "company"=> " ", + "mobile"=> "17321358370", + "phone"=> "", + "prov"=> "上海市", + "city"=> "上海市", + "county"=> "嘉定区", + "address"=> "兴贤路1180号5栋208室", + "zipcode"=> "" + ], + "items"=> [ + [ + "id"=> "1", + "name"=> "唾液样本", + "category"=> "电子产品", + "material"=> "玻璃", + "size"=> "12,11,23", + "weight"=> "1", + "unitprice"=> "80", + "quantity"=> "1", + "remark"=> "" + ] + ], + "starttime"=> date('Y-m-d'), + "endtime"=> date('Y-m-d'), + "weight"=> 1, + "size"=> "12,23,11", + "quantity"=> 1, + "price"=> 80, + "freight"=> 10, + "premium"=> 0, + "packCharges"=> 0, + "otherCharges"=> 0, + "orderSum"=> 0, + "collectMoneytype"=> "CNY", + "collectSum"=> 1, + "remark"=> "玻璃制品,请轻拿轻放" + ] + ]; + //echo json_encode($data);die; + //散客预约订单 + $ret = $this->request('OpenOrderCreate',$data); + /* + * 返回示例 + * { + "result": { + "esGroup": null, + "markGroup": null, + "orderCode": "200308000008003103" + }, + "message": "操作成功", + "status": true, + "statusCode": "0" + } + */ + //print_r($ret); + if($ret['statusCode'] == '0' && isset($ret['result']['orderCode'])){ + $row_base = [ + 'user_id'=>$address['user_id'],// 中通订单号 + 'order_code'=>$ret['result']['orderCode'],// 中通订单号 + 'partner_code'=>$address['trade_id'],// 中通订单号 + 'trade_id'=>$address['trade_id'],// 中通订单号 + "sender_id"=> $address['user_id'], + "sender_name"=> $address['name'], + //"sender_company"=> "", + "sender_mobile"=> $address['tel'], + //"sender_phone"=> "", + "sender_prov"=> $address['province'], + "sender_city"=> $address['city'], + "sender_county"=> $address['district'], + "sender_address"=> $address['address'], + //"sender_zipcode"=> "" + ]; + $row_ext = []; + /* + //查询订单 + $ret_search = $this->commonOrderSearchbycode($ret['orderCode'],$address['user_id']); + //存订单 + $order = $ret['result']; + if($ret_search['result']){ + $detail = $ret_search['data']['order_list']; + if(!empty($detail[0])){ + $detail = $detail[0]; + $row_ext = [ + 'type'=>$order['type'],// 订单类型 + 'tradeid'=>$order['tradeid'],// 交易号 + 'mailno'=>$order['mailno'],// 运单号 + 'detail'=>json_encode($detail),// 原始数据 + ]; + } + } + //todo:订阅快递信息 + $this->add(array_merge($row_base,$row_ext)); + */ + $id = $this->add($row_base); + return [true,'上门取货后获取']; + }else{ + log_message('error', $ret['message']); + } + return [false,$ret['message']]; + } + + //预约寄件-订单明细查询 + public function commonOrderSearchbycode($orderCode=[],$sendId,$partnerId='') + { + if(!is_array($orderCode)){ + $orderCode = [$orderCode]; + } + $params = [ + "company_id"=>'', + "msg_type"=>'SEARCHBYCODE', + "data"=>[ + "orderCode"=>$orderCode,//预约寄件下单后,获取的orderCode + "sendId"=>$sendId,//发件人在合作商平台中的ID号 + #"partnerId"=>"",//合作商单号,非必填 + ] + ]; + $ret = $this->request('commonOrderSearchbycode',$params); + echo(json_encode($ret));die; + $ret = '{ + "result": true, + "reason": "", + "data": { + "pageIndex": 1, + "pageSize": 10, + "count": 100, + "order_list": [ + { + "orderCode": "130520142013234", + "type": "", + "tradeid": "2701843", + "mailno": "1000000000016", + "sender": { + "id": "130520142010", + "name": "李琳", + "company": "新南电子商务有限公司", + "mobile": "13912345678", + "phone": "021-87654321", + "area": "上海市", + "city": "上海市", + "county": "青浦区", + "address": "华新镇华志路123号", + "zipcode": "610012" + }, + "receiver": { + "id": "130520142097", + "name": "杨逸嘉", + "company": "逸嘉实业有限公司", + "mobile": "13687654321", + "phone": "010-22226789", + "area": "四川省", + "city": "成都市", + "county": "武侯区", + "address": "育德路497号", + "zipcode": "610012" + }, + "starttime": "2013-05-2012: 00: 00", + "endtime": "2013-05-2015: 00: 00", + "weight": 753, + "size": "12, 23, 11", + "quantity": 2, + "price": 12650, + "freight": 1000, + "premium": 50, + "pack_charges": 100, + "other_charges": 0, + "order_sum": 0, + "collect_moneytype": "CNY", + "collect_sum": 1200, + "remark": "请勿摔货", + "create_date": "2014-12-1212: 12: 12" + }, + { + "orderCode": "130520142013234", + "type": "", + "tradeid": "2701843", + "mailno": "1000000000016", + "sender": { + "id": "130520142010", + "name": "李琳", + "company": "新南电子商务有限公司", + "mobile": "13912345678", + "phone": "021-87654321", + "area": "上海市", + "city": "上海市", + "county": "青浦区", + "address": "华新镇华志路123号", + "zipcode": "610012" + }, + "receiver": { + "id": "130520142097", + "name": "杨逸嘉", + "company": "逸嘉实业有限公司", + "mobile": "13687654321", + "phone": "010-22226789", + "area": "四川省", + "city": "成都市", + "county": "武侯区", + "address": "育德路497号", + "zipcode": "610012" + }, + "items": [ + { + "id": "1234567", + "name": "迷你风扇", + "category": "电子产品", + "material": "金属", + "size": "12, 11, 23", + "weight": "0.752", + "unitprice": "79", + "quantity": "1", + "remark": "黑色大号" + }, + { + "name": "USB3.0集线器", + "quantity": "1", + "remark": "" + } + ], + "starttime": "2013-05-2012: 00: 00", + "endtime": "2013-05-2015: 00: 00", + "weight": 753, + "size": "12, 23,11", + "quantity": 2, + "price": 12650, + "freight": 1000, + "premium": 50, + "pack_charges": 100, + "other_charges": 0, + "order_sum": 0, + "collect_moneytype": "CNY", + "collect_sum": 1200, + "remark": "请勿摔货", + "create_date": "2014-12-1212: 12: 12" + } + ] + } + } + '; + $ret = json_decode($ret,true); + + } + + //获取快件轨迹信息 + public function traceInterfaceNewTraces($order_id) + { + $conf = $this->config->item('zto'); + $data = [ + "company_id"=> $conf['id'], + "msg_type"=> 'NEW_TRACES', + "data"=> [$order_id], + ]; + return $this->request('traceInterfaceNewTraces',$data); + $tmp = '{ + "data": [ + { + "traces": [ + { + "desc": "[上海市] [上海]的张伟丰已收件 电话:17740809169", + "dispOrRecMan": "张伟丰", + "dispOrRecManCode": "", + "dispOrRecManPhone": "17740809169", + "isCenter": "T", + "preOrNextCity": "", + "preOrNextProv": "", + "preOrNextSite": "", + "preOrNextSiteCode": "", + "preOrNextSitePhone": "", + "remark": "", + "scanCity": "上海市", + "scanDate": "2017-07-26 17:30:14", + "scanProv": "上海", + "scanSite": "上海", + "scanSiteCode": "02100", + "scanSitePhone": "95311", + "scanType": "收件", + "signMan": "" + }, + { + "desc": "[金华市] 快件到达 [义乌]", + "dispOrRecMan": "", + "dispOrRecManCode": "", + "dispOrRecManPhone": "", + "isCenter": "F", + "preOrNextCity": "", + "preOrNextProv": "", + "preOrNextSite": "", + "preOrNextSiteCode": "", + "preOrNextSitePhone": "", + "remark": "", + "scanCity": "金华市", + "scanDate": "2017-05-18 16:55:01", + "scanProv": "浙江", + "scanSite": "义乌", + "scanSiteCode": "57950", + "scanSitePhone": "0579-89936000", + "scanType": "到件", + "signMan": "" + }, + { + "desc": "[上海市] 快件已到达[上海],业务员张伟丰正在第1次派件 电话:17740809169 + 请保持电话畅通、耐心等待", + "dispOrRecMan": "张伟丰", + "dispOrRecManCode": "", + "dispOrRecManPhone": "17740809169", + "isCenter": "T", + "preOrNextCity": "", + "preOrNextProv": "", + "preOrNextSite": "", + "preOrNextSiteCode": "", + "preOrNextSitePhone": "", + "remark": "", + "scanCity": "上海市", + "scanDate": "2017-07-26 17:33:27", + "scanProv": "上海", + "scanSite": "上海", + "scanSiteCode": "02100", + "scanSitePhone": "95311", + "scanType": "派件", + "signMan": "" + }, + { + "desc": "[上海市] [上海总部财务]的派件已退件签收 感谢使用中通快递,期待再次为您 + 服务!", + "dispOrRecMan": "", + "dispOrRecManCode": "", + "dispOrRecManPhone": "", + "isCenter": "F", + "preOrNextCity": "", + "preOrNextProv": "", + "preOrNextSite": "", + "preOrNextSiteCode": "", + "preOrNextSitePhone": "", + "remark": "", + "scanCity": "上海市", + "scanDate": "2017-03-03 13:11:23", + "scanProv": "上海", + "scanSite": "上海总部财务", + "scanSiteCode": "00088", + "scanSitePhone": "", + "scanType": "退件签收", + "signMan": "本人" + } + ], + "billCode": "680000000000" + } + ], + "msg": "", + "status": true +}'; + return json_decode($tmp,true); + } + + + //总对总订单,用不上 + public function plateOrder($sample=[],$address=[]) + { + $data = [ + "systemParameter"=> [ + "serviceCode"=> "StoreDeliverGoods" + ], + "orderInfo"=> [ + "bagSize"=> "20,10,30", + "partnerCode"=> "3608036589234", + "companyCode"=> "GP1551922487", + "customerId"=> "zto001", + "hallCode"=> "S2044", + "billCode"=> null, + "pickUpCode"=> null, + "startTime"=> null, + "endTime"=> null, + "siteCode"=> "", + "weight"=> 1.23, + "freight"=> 0, + "orderSum"=> 230.12, + "otherCharges"=> 0, + "packCharges"=> 0, + "premium"=> 0, + "price"=> 0, + "quantity"=> "1", + "returnAddress"=> "江苏省苏州市姑苏区绿地大道320号金茂大厦负一楼203仓库", + "remark"=> "", + "receiver"=> [ + "address"=> "外街道00号", + "city"=> "苏州市", + "company"=> "中通快递", + "county"=> "朝阳区", + "id"=> "", + "mobile"=> "13262709999", + "name"=> "黄某", + "phone"=> "", + "prov"=> "江苏省", + "zipCode"=> "" + ], + "sender"=> [ + "address"=> "华志路1685号", + "city"=> "蚌埠市", + "company"=> "中通快递股份有限公司", + "county"=> "怀远县", + "id"=> "15097756", + "mobile"=> "15216800000", + "name"=> "测试", + "phone"=> "", + "prov"=> "安徽省", + "zipCode"=> "" + ] + ] + ]; + $ret = $this->request('plateOrder',$data); + return $ret; + } +} diff --git a/models/Zto_model_bak.php b/models/Zto_model_bak.php new file mode 100644 index 0000000..21335b2 --- /dev/null +++ b/models/Zto_model_bak.php @@ -0,0 +1,290 @@ +config->item('zto'); + // ZopProperties类的构造方法接收两个参数,分别是companyid和key,都需要注册中通开放平台后到个人中心查看 + $properties = new ZopProperties($conf['id'], $conf['key']); + $client = new ZopClient($properties); + $request = new ZopRequest(); + $request->setUrl($conf['host'].$path); + //$request->setData(json_encode($data)); + $request->addParam('orderGroup',$data); + //$request->addParam('orderGroup','{"partnerCode":"130520142013234","type":1,"tradeId":"2701843","mailNo":"1000000000016","sender":{"id":"130520142010","name":"李琳","company":"新南电子商务有限公司","mobile":"13912345678","phone":"021-87654321","prov":"上海市","city":"上海市","county":"青浦区","address":"华新镇华志路123号","zipcode":"610012"},"receiver":{"id":"130520142097","name":"杨逸嘉","company":"逸嘉实业有限公司","mobile":"13687654321","phone":"010-22226789","prov":"四川省","city":"成都市","county":"武侯区","address":"育德路497号","zipcode":"610012"},"items":[{"id":"1234567","name":"迷你风扇","category":"电子产品","material":"金属","size":"12,11,23","weight":"1","unitprice":"79","quantity":"1","remark":"黑色大号"},{"name":"USB3.0集线器","quantity":"1","remark":""}],"starttime":"2013-05-20 12:00:00","endtime":"2013-05-20 15:00:00","weight":753,"size":"12,23,11","quantity":2,"price":12650,"freight":1000,"premium":50,"packCharges":100,"otherCharges":0,"orderSum":0,"collectMoneytype":"CNY","collectSum":1200,"remark":"请勿摔货"}'); + + $ret = $client->execute($request); + return json_decode($ret,true); + } + + //总对总订单,无用 + public function plateOrder($sample=[],$address=[]) + { + $data = [ + "systemParameter"=> [ + "serviceCode"=> "StoreDeliverGoods" + ], + "orderInfo"=> [ + "bagSize"=> "20,10,30", + "partnerCode"=> "3608036589234", + "companyCode"=> "GP1551922487", + "customerId"=> "zto001", + "hallCode"=> "S2044", + "billCode"=> null, + "pickUpCode"=> null, + "startTime"=> null, + "endTime"=> null, + "siteCode"=> "", + "weight"=> 1.23, + "freight"=> 0, + "orderSum"=> 230.12, + "otherCharges"=> 0, + "packCharges"=> 0, + "premium"=> 0, + "price"=> 0, + "quantity"=> "1", + "returnAddress"=> "江苏省苏州市姑苏区绿地大道320号金茂大厦负一楼203仓库", + "remark"=> "", + "receiver"=> [ + "address"=> "外街道00号", + "city"=> "苏州市", + "company"=> "中通快递", + "county"=> "朝阳区", + "id"=> "", + "mobile"=> "13262709999", + "name"=> "黄某", + "phone"=> "", + "prov"=> "江苏省", + "zipCode"=> "" + ], + "sender"=> [ + "address"=> "华志路1685号", + "city"=> "蚌埠市", + "company"=> "中通快递股份有限公司", + "county"=> "怀远县", + "id"=> "15097756", + "mobile"=> "15216800000", + "name"=> "测试", + "phone"=> "", + "prov"=> "安徽省", + "zipCode"=> "" + ] + ] + ]; + $ret = $this->request('plateOrder',$data); + return $ret; + } + + //散客预约订单 + public function OpenOrderCreate($sample=[],$address=[]) + { + $data = [ + 'orderGroup'=>[ + "partnerCode"=> $sample['device_id'],//合作商订单号,为调用方生成,可以传订单号、主键、UUID等 + "type"=> 2,//订单类型 1 普通订单(线上),2线下联系订单 默认1 + "tradeId"=> $sample['device_id'],//交易号,由合作商平台产生。 + "mailNo"=> "",//运单号(有则提供,线下联系订单必须提供) + "sender"=> [ + "id"=> $address['tel'], + "name"=> $address['name'], + "company"=> "", + "mobile"=> $address['tel'], + "phone"=> "", + "prov"=> $address['province'], + "city"=> $address['city'], + "county"=> $address['district'], + "address"=> $address['address'], + "zipcode"=> "" + ], + "receiver"=> [ + "id"=> "", + "name"=> "杨逸嘉", + "company"=> "逸嘉实业有限公司", + "mobile"=> "13687654321", + "phone"=> "010-22226789", + "prov"=> "四川省", + "city"=> "成都市", + "county"=> "武侯区", + "address"=> "育德路497号", + "zipcode"=> "610012" + ], + "items"=> [ + [ + "id"=> "1234567", + "name"=> "唾液样本", + "category"=> "电子产品", + "material"=> "金属", + "size"=> "12,11,23", + "weight"=> "1", + "unitprice"=> "79", + "quantity"=> "1", + "remark"=> "黑色大号" + ] + ], + "starttime"=> "2013-05-20 12=>00=>00", + "endtime"=> "2013-05-20 15=>00=>00", + "weight"=> 100, + "size"=> "12,23,11", + "quantity"=> 1, + "price"=> 50, + "freight"=> 1000, + "premium"=> 50, + "packCharges"=> 100, + "otherCharges"=> 0, + "orderSum"=> 0, + "collectMoneytype"=> "CNY", + "collectSum"=> 1200, + "remark"=> "" + ] + ]; + $ret = $this->request('OpenOrderCreate',$data); + /* + * Array + ( + [message] => 服务暂不可用 + [result] => + [status] => + [statusCode] => S203 + ) + */ + if($ret['status']){ + //存订单 + $order = $ret['result']; + $row = [ + /* + 'partner_code'=>$order['partnerCode'],//合作商订单号 + 'bill_code'=>$order['billCode'],// 运单号 + 'up_data'=>$order['upData'],// 状态:0-新增 1-更新 + 'mark'=>$order['mark'],// 三段码| 大头笔 + 'site_name'=>$order['siteName'],// 集包地 + 'site_code'=>$order['siteCode'],// 签约网点 + */ + 'order_code'=>$order['orderCode'],// 中通订单号 + ]; + //订阅快递信息 + $this->add($row); + return [true,'']; + } + log_message('error', $ret['message']); + return [false,$ret['message']]; + } + + + //散客预约订单,测试 + public function test() + { + $data = [ + //'orderGroup'=>[ + "partnerCode"=> 'test20200210',//合作商订单号,为调用方生成,可以传订单号、主键、UUID等 + "type"=> 1,//订单类型 1 普通订单(线上),2线下联系订单 默认1 + "tradeId"=> 'test20200210',//交易号,由合作商平台产生。 + //"mailNo"=> "",//运单号(有则提供,线下联系订单必须提供) + "sender"=> [ + "id"=> '1', + "name"=> '罗线上', + "company"=> "", + "mobile"=> '15815725225', + "phone"=> "", + "prov"=> '广东省', + "city"=> '深圳市', + "county"=> '宝安区', + "address"=> '创业立交附近新湖路一号', + "zipcode"=> "" + ], + "receiver"=> [ + //"id"=> "", + "name"=> "杨逸嘉", + "company"=> "中兴通讯有限公司", + "mobile"=> "13687654321", + "phone"=> "010-22226789", + "prov"=> "四川省", + "city"=> "成都市", + "county"=> "武侯区", + "address"=> "育德路497号", + "zipcode"=> "610012" + ], + "items"=> [ + [ + "id"=> "1234567", + "name"=> "唾液样本", + "category"=> "电子产品", + "material"=> "金属", + "size"=> "12,11,23", + "weight"=> "1", + "unitprice"=> "79", + "quantity"=> "1", + "remark"=> "黑色大号" + ] + ], + "starttime"=> "2020-02-20 12:00:00", + "endtime"=> "2020-02-30 15:00:00", + "weight"=> 100, + "size"=> "12,23,11", + "quantity"=> 1, + "price"=> 50, + "freight"=> 1000, + "premium"=> 50, + "packCharges"=> 100, + "otherCharges"=> 0, + "orderSum"=> 0, + "collectMoneytype"=> "CNY", + "collectSum"=> 1200, + "remark"=> "" + //] + ]; + + $data = [ + "partnerCode"=> 'test20200210',//合作商订单号,为调用方生成,可以传订单号、主键、UUID等 + "sender"=> [ + "id"=> '1', + "name"=> '罗线上', + "mobile"=> '15815725225', + "prov"=> '广东省', + "city"=> '深圳市', + "county"=> '宝安区', + "address"=> '创业立交附近新湖路一号', + ], + "receiver"=> [ + "name"=> "杨逸嘉", + "mobile"=> "13687654321", + "prov"=> "四川省", + "city"=> "成都市", + "county"=> "武侯区", + "address"=> "育德路497号", + ] + ]; + $ret = $this->request('OpenOrderCreate',$data); + print_r($ret);die; + } + + public function subscribeData($sample='',$address='') + { + } + + //获取快件轨迹信息 + public function traceInterfaceNewTraces($order_id) + { + $conf = $this->config->item('zto'); + $data = [ + "company_id"=> $conf['id'], + "msg_type"=> 'NEW_TRACES', + "data"=> json_encode([$order_id]), + ]; + return $this->request('traceInterfaceNewTraces',$data); + } +} diff --git a/models/Zto_model_bak2.php b/models/Zto_model_bak2.php new file mode 100644 index 0000000..f460bdf --- /dev/null +++ b/models/Zto_model_bak2.php @@ -0,0 +1,9 @@ +'皮肤', + '皮肤肿瘤疾病'=>'皮肤', +]; diff --git a/models/index.html b/models/index.html new file mode 100644 index 0000000..b702fbc --- /dev/null +++ b/models/index.html @@ -0,0 +1,11 @@ + + + + 403 Forbidden + + + +

Directory access is forbidden.

+ + + diff --git a/third_party/index.html b/third_party/index.html new file mode 100644 index 0000000..b702fbc --- /dev/null +++ b/third_party/index.html @@ -0,0 +1,11 @@ + + + + 403 Forbidden + + + +

Directory access is forbidden.

+ + + diff --git a/uahpet/cert_template/health.png b/uahpet/cert_template/health.png new file mode 100644 index 0000000..3715349 Binary files /dev/null and b/uahpet/cert_template/health.png differ diff --git a/uahpet/database b/uahpet/database new file mode 160000 index 0000000..34458eb --- /dev/null +++ b/uahpet/database @@ -0,0 +1 @@ +Subproject commit 34458eb0a2796444b7f2182d07580bda449b3bd8 diff --git a/uahpet/font/SourceHanSansCN-Bold.otf b/uahpet/font/SourceHanSansCN-Bold.otf new file mode 100644 index 0000000..4b3429a Binary files /dev/null and b/uahpet/font/SourceHanSansCN-Bold.otf differ diff --git a/uahpet/font/SourceHanSansCN-Regular.otf b/uahpet/font/SourceHanSansCN-Regular.otf new file mode 100644 index 0000000..886f82f Binary files /dev/null and b/uahpet/font/SourceHanSansCN-Regular.otf differ diff --git a/uahpet/report-data b/uahpet/report-data new file mode 160000 index 0000000..5c5cca7 --- /dev/null +++ b/uahpet/report-data @@ -0,0 +1 @@ +Subproject commit 5c5cca73bdd87e1d8cc0ee205e74082086d30192 diff --git a/uahpet/report-data_bak b/uahpet/report-data_bak new file mode 160000 index 0000000..5536c1b --- /dev/null +++ b/uahpet/report-data_bak @@ -0,0 +1 @@ +Subproject commit 5536c1b27d589f002400ef449aca9a654f1f7bad diff --git a/views/errors/cli/error_404.php b/views/errors/cli/error_404.php new file mode 100644 index 0000000..6984b61 --- /dev/null +++ b/views/errors/cli/error_404.php @@ -0,0 +1,8 @@ + + +An uncaught Exception was encountered + +Type: +Message: +Filename: getFile(), "\n"; ?> +Line Number: getLine(); ?> + + + +Backtrace: +getTrace() as $error): ?> + + File: + Line: + Function: + + + + diff --git a/views/errors/cli/error_general.php b/views/errors/cli/error_general.php new file mode 100644 index 0000000..6984b61 --- /dev/null +++ b/views/errors/cli/error_general.php @@ -0,0 +1,8 @@ + + +A PHP Error was encountered + +Severity: +Message: +Filename: +Line Number: + + + +Backtrace: + + + File: + Line: + Function: + + + + diff --git a/views/errors/cli/index.html b/views/errors/cli/index.html new file mode 100644 index 0000000..b702fbc --- /dev/null +++ b/views/errors/cli/index.html @@ -0,0 +1,11 @@ + + + + 403 Forbidden + + + +

Directory access is forbidden.

+ + + diff --git a/views/errors/html/error_404.php b/views/errors/html/error_404.php new file mode 100644 index 0000000..756ea9d --- /dev/null +++ b/views/errors/html/error_404.php @@ -0,0 +1,64 @@ + + + + +404 Page Not Found + + + +
+

+ +
+ + \ No newline at end of file diff --git a/views/errors/html/error_db.php b/views/errors/html/error_db.php new file mode 100644 index 0000000..f5a43f6 --- /dev/null +++ b/views/errors/html/error_db.php @@ -0,0 +1,64 @@ + + + + +Database Error + + + +
+

+ +
+ + \ No newline at end of file diff --git a/views/errors/html/error_exception.php b/views/errors/html/error_exception.php new file mode 100644 index 0000000..8784886 --- /dev/null +++ b/views/errors/html/error_exception.php @@ -0,0 +1,32 @@ + + +
+ +

An uncaught Exception was encountered

+ +

Type:

+

Message:

+

Filename: getFile(); ?>

+

Line Number: getLine(); ?>

+ + + +

Backtrace:

+ getTrace() as $error): ?> + + + +

+ File:
+ Line:
+ Function: +

+ + + + + + +
\ No newline at end of file diff --git a/views/errors/html/error_general.php b/views/errors/html/error_general.php new file mode 100644 index 0000000..fc3b2eb --- /dev/null +++ b/views/errors/html/error_general.php @@ -0,0 +1,64 @@ + + + + +Error + + + +
+

+ +
+ + \ No newline at end of file diff --git a/views/errors/html/error_php.php b/views/errors/html/error_php.php new file mode 100644 index 0000000..b146f9c --- /dev/null +++ b/views/errors/html/error_php.php @@ -0,0 +1,33 @@ + + +
+ +

A PHP Error was encountered

+ +

Severity:

+

Message:

+

Filename:

+

Line Number:

+ + + +

Backtrace:

+ + + + +

+ File:
+ Line:
+ Function: +

+ + + + + + + +
\ No newline at end of file diff --git a/views/errors/html/index.html b/views/errors/html/index.html new file mode 100644 index 0000000..b702fbc --- /dev/null +++ b/views/errors/html/index.html @@ -0,0 +1,11 @@ + + + + 403 Forbidden + + + +

Directory access is forbidden.

+ + + diff --git a/views/errors/index.html b/views/errors/index.html new file mode 100644 index 0000000..b702fbc --- /dev/null +++ b/views/errors/index.html @@ -0,0 +1,11 @@ + + + + 403 Forbidden + + + +

Directory access is forbidden.

+ + + diff --git a/views/index.html b/views/index.html new file mode 100644 index 0000000..b702fbc --- /dev/null +++ b/views/index.html @@ -0,0 +1,11 @@ + + + + 403 Forbidden + + + +

Directory access is forbidden.

+ + + diff --git a/views/rest_server.php b/views/rest_server.php new file mode 100644 index 0000000..5212e6d --- /dev/null +++ b/views/rest_server.php @@ -0,0 +1,222 @@ + + + + + + + REST Server Tests + + + + + +
+

REST Server Tests

+ +
+ +

Home

+ +

+ See the article + + http://net.tutsplus.com/tutorials/php/working-with-restful-services-in-codeigniter-2/ + +

+ +

+ The master project repository is + + https://github.com/chriskacerguis/codeigniter-restserver + +

+ +

+ Click on the links to check whether the REST server is working. +

+ +
    +
  1. Users - defaulting to JSON
  2. +
  3. Users - get it in CSV
  4. +
  5. User #1 - defaulting to JSON (users/id/1)
  6. +
  7. User #1 - defaulting to JSON (users/1)
  8. +
  9. User #1 - get it in XML (users/id/1.xml)
  10. +
  11. User #1 - get it in XML (users/id/1/format/xml)
  12. +
  13. User #1 - get it in XML (users/id/1?format=xml)
  14. +
  15. User #1 - get it in XML (users/1.xml)
  16. +
  17. Users - get it in JSON (AJAX request)
  18. +
  19. Users - get it in HTML (users.html)
  20. +
  21. Users - get it in HTML (users/format/html)
  22. +
  23. Users - get it in HTML (users?format=html)
  24. +
+ +
+ + +
+ + + + + + + diff --git a/views/welcome_message.php b/views/welcome_message.php new file mode 100644 index 0000000..e030389 --- /dev/null +++ b/views/welcome_message.php @@ -0,0 +1 @@ +欢迎访问