框架发布

框架发布

最新版本发布信息
提问交流

提问交流

使用问题咨询
经验分享

经验分享

开发经验交流分享
功能建议

功能建议

官方开发功能建议
BUG反馈

BUG反馈

使用BUG反馈
模块&插件&数据包

模块&插件&数据包

模块插件数据包分享

双通道加密的最安全聊天软件im免费使用

huakai 发表了文章 • 0 个评论 • 14 次浏览 • 4 天前 • 来自相关话题

双通道加密的最安全聊天软件im免费使用






目前系统率先推出了ios版本,可以去appstore搜索“online app”下载注册安装使用
 

android版本近期开放发布release



系统支持点对点音视频/文字聊天/转账/阅后即焚/aa收款/定时发送/超时回复/
普通红包/口令红包



系统支持百人大群 多人音视频/口令红包/迷底红包/翻牌红包/拼手气红包/普通红包等



系统支持消息实时焚毁,服务器不保留任何数据
 

点对点聊天支持加密模式下的聊天 消息在本地以及服务器不做任何存储 聊完即焚




支持聊天密码加密模式 输入指定密码才可以进入消息聊天界面

支持用户之间转账  支持到账提醒



支持用户储蓄卡/信用卡充值以及提现



系统功能全备 欢迎各界朋友使用



合作v: onlinesam



 

免费im 免费聊天软件 im im加密聊天 加密聊天软件 加密聊天系统 im聊天  查看全部
双通道加密的最安全聊天软件im免费使用






目前系统率先推出了ios版本,可以去appstore搜索“online app”下载注册安装使用
 

android版本近期开放发布release



系统支持点对点音视频/文字聊天/转账/阅后即焚/aa收款/定时发送/超时回复/
普通红包/口令红包



系统支持百人大群 多人音视频/口令红包/迷底红包/翻牌红包/拼手气红包/普通红包等



系统支持消息实时焚毁,服务器不保留任何数据
 

点对点聊天支持加密模式下的聊天 消息在本地以及服务器不做任何存储 聊完即焚




支持聊天密码加密模式 输入指定密码才可以进入消息聊天界面

支持用户之间转账  支持到账提醒



支持用户储蓄卡/信用卡充值以及提现



系统功能全备 欢迎各界朋友使用



合作v: onlinesam



 

免费im 免费聊天软件 im im加密聊天 加密聊天软件 加密聊天系统 im聊天 

本地文件同步海豚附件方法

yangweijie 发表了文章 • 0 个评论 • 55 次浏览 • 2020-06-04 16:12 • 来自相关话题

use app\admin\model\Attachment;


public function local_upload($dir = ''){
if($dir){
if(!is_dir($dir)){
$this->error('路径不存在');
}
set_time_limit(0);
ini_set('memory_limit', '3072M');
$reload = url();
if($this->request->isPost()){
$ids = input('ids/a', []);
if($ids){
foreach ($ids as $key => $path) {
$md5 = md5_file($path);
$exist = Attachment::where('md5', $md5)->find();
if($exist){
if(is_file($exist['path'])){
;
}else{
copy($path, $exist['path']);
}
}else{
$target_dir = 'uploads/files/'.date('Ymd');
if(!is_dir($target_dir)){
mkdir($target_dir);
}
$finfo = finfo_open(FILEINFO_MIME_TYPE);
$mime = finfo_file($finfo, $path);
$target = $target_dir . DIRECTORY_SEPARATOR.md5((string) microtime(true)).'.'.pathinfo($path, PATHINFO_EXTENSION);
copy($path, $target);
$file_name = pathinfo($path, PATHINFO_BASENAME);
$file_info = [
'uid' => session('user_auth.uid'),
'name' => $file_name,
'mime' => $mime,
'path' => str_replace('\\', '/', $target),
'ext' => pathinfo($file_name, PATHINFO_EXTENSION),
'size' => filesize($path),
'md5' => md5_file($path),
'sha1' => sha1_file($path),
'thumb' => '',
'module' => 'admin',
'width' => '',
'height' => '',
];
Attachment::create($file_info);
}
}
$this->success('同步成功');
}else{
$this->error('请至少选择一个文件');
}
}
$current_dir = getcwd();
chdir($dir);
$data_list = [];
$files = glob('*.*');
chdir($current_dir);
if($files){
foreach ($files as $key => $file) {
$file = $dir.DIRECTORY_SEPARATOR.$file;
$type = is_dir(realpath($file))?'dir':'file';
if($type == 'file'){
$md5 = md5_file($file);
$exist = Attachment::where('md5', $md5)->find();
}else{
$md5 = '';
$exist = [];
}
$data_list[] = [
'index' => $key,
'md5' => $md5,
'path' => realpath($file),
'type' => is_dir(realpath($file))?'dir':'file',
'size' => filesize($file),
'status' => $exist? is_file($exist['path'])?'已同步'.$exist['id'] :'待恢复'.$exist['id']: '未同步',
];
}
}
$parent_dir = dirname($dir, 1);
$parent_dir = url('local_upload', ['dir'=>$parent_dir]);
$js = <<<JS
<script>
function browser(index){
\$path = \$.trim(\$('#builder-table table tbody tr').eq(index).find('td:eq(1) div').text());
location.href = '{$reload}'.replace('.html', '?dir='+\$path);
}
</script>
JS;
return ZBuilder::make('table')
->setTableName(true)
->addTopButton('upload', ['title'=>'同步', 'href'=>url('local_upload', ['dir'=>$dir]), 'class'=>'btn btn-default ajax-post'])
->addColumns([
// ['index', 'index', 'hidden'],
['path', 'path'],
['md5', 'md5'],
['size', 'size'],
['status', '状态'],
['right_button', '操作'],
])
->setPrimaryKey('path')
->setPageTips("当前路径为:{$dir}, <a href='{$parent_dir}'>返回上一级</a> <a href='{$reload}'>重新浏览</a>")
->addRightButton('sub_dir', [
'icon' => 'fa fa-fw fa-inbox',
'title' => '浏览子目录',
'href' => 'javascript:browser(__index__)',
])
->setExtraJs($js)
->replaceRightButton(['type'=>'file'], '', ['sub_dir'])
->setRowList($data_list)
->fetch(); // 渲染模板
}else{
return ZBuilder::make('form')
->setPageTips('请填写要同步的本地目录')
->addFormItems([
['text','dir', '待匹配的目录', '绝对路径格式'],
])
->method('get')
->isAjax(false)
->fetch();
}
}上面是attachment 模型里加的获取器
 
然后自己加个节点 使用就好,
  查看全部
use app\admin\model\Attachment;


public function local_upload($dir = ''){
if($dir){
if(!is_dir($dir)){
$this->error('路径不存在');
}
set_time_limit(0);
ini_set('memory_limit', '3072M');
$reload = url();
if($this->request->isPost()){
$ids = input('ids/a', []);
if($ids){
foreach ($ids as $key => $path) {
$md5 = md5_file($path);
$exist = Attachment::where('md5', $md5)->find();
if($exist){
if(is_file($exist['path'])){
;
}else{
copy($path, $exist['path']);
}
}else{
$target_dir = 'uploads/files/'.date('Ymd');
if(!is_dir($target_dir)){
mkdir($target_dir);
}
$finfo = finfo_open(FILEINFO_MIME_TYPE);
$mime = finfo_file($finfo, $path);
$target = $target_dir . DIRECTORY_SEPARATOR.md5((string) microtime(true)).'.'.pathinfo($path, PATHINFO_EXTENSION);
copy($path, $target);
$file_name = pathinfo($path, PATHINFO_BASENAME);
$file_info = [
'uid' => session('user_auth.uid'),
'name' => $file_name,
'mime' => $mime,
'path' => str_replace('\\', '/', $target),
'ext' => pathinfo($file_name, PATHINFO_EXTENSION),
'size' => filesize($path),
'md5' => md5_file($path),
'sha1' => sha1_file($path),
'thumb' => '',
'module' => 'admin',
'width' => '',
'height' => '',
];
Attachment::create($file_info);
}
}
$this->success('同步成功');
}else{
$this->error('请至少选择一个文件');
}
}
$current_dir = getcwd();
chdir($dir);
$data_list = [];
$files = glob('*.*');
chdir($current_dir);
if($files){
foreach ($files as $key => $file) {
$file = $dir.DIRECTORY_SEPARATOR.$file;
$type = is_dir(realpath($file))?'dir':'file';
if($type == 'file'){
$md5 = md5_file($file);
$exist = Attachment::where('md5', $md5)->find();
}else{
$md5 = '';
$exist = [];
}
$data_list[] = [
'index' => $key,
'md5' => $md5,
'path' => realpath($file),
'type' => is_dir(realpath($file))?'dir':'file',
'size' => filesize($file),
'status' => $exist? is_file($exist['path'])?'已同步'.$exist['id'] :'待恢复'.$exist['id']: '未同步',
];
}
}
$parent_dir = dirname($dir, 1);
$parent_dir = url('local_upload', ['dir'=>$parent_dir]);
$js = <<<JS
<script>
function browser(index){
\$path = \$.trim(\$('#builder-table table tbody tr').eq(index).find('td:eq(1) div').text());
location.href = '{$reload}'.replace('.html', '?dir='+\$path);
}
</script>
JS;
return ZBuilder::make('table')
->setTableName(true)
->addTopButton('upload', ['title'=>'同步', 'href'=>url('local_upload', ['dir'=>$dir]), 'class'=>'btn btn-default ajax-post'])
->addColumns([
// ['index', 'index', 'hidden'],
['path', 'path'],
['md5', 'md5'],
['size', 'size'],
['status', '状态'],
['right_button', '操作'],
])
->setPrimaryKey('path')
->setPageTips("当前路径为:{$dir}, <a href='{$parent_dir}'>返回上一级</a> <a href='{$reload}'>重新浏览</a>")
->addRightButton('sub_dir', [
'icon' => 'fa fa-fw fa-inbox',
'title' => '浏览子目录',
'href' => 'javascript:browser(__index__)',
])
->setExtraJs($js)
->replaceRightButton(['type'=>'file'], '', ['sub_dir'])
->setRowList($data_list)
->fetch(); // 渲染模板
}else{
return ZBuilder::make('form')
->setPageTips('请填写要同步的本地目录')
->addFormItems([
['text','dir', '待匹配的目录', '绝对路径格式'],
])
->method('get')
->isAjax(false)
->fetch();
}
}
上面是attachment 模型里加的获取器
 
然后自己加个节点 使用就好,
 

请问数据库取出的列怎么对应到复选框中?

回复

zzyu220 发起了问题 • 1 人关注 • 0 个回复 • 101 次浏览 • 2020-05-18 11:14 • 来自相关话题

寻找有时间做外包的兄弟

回复

chuangsjh 发起了问题 • 1 人关注 • 0 个回复 • 271 次浏览 • 2020-03-07 21:57 • 来自相关话题

调用第三方物流公司API即时查询物流信息

fire70 发表了文章 • 0 个评论 • 268 次浏览 • 2019-10-14 18:21 • 来自相关话题

主要是利用快递鸟提供的物流服务,通过对接快递鸟的API,调用即时查询接口,获取物流信息。
这里采用java语言,调用快递鸟的接口为例。步骤如下:
1.首先,得去快递鸟的官方网站注册一个账号并进行实名认证,获得一个用户ID跟API key ,主要是作为个人唯一标识方便调用接口
快递鸟api接口申请地址:快递鸟官网

可以看到即时查询接口每天的调用服务次数是3000次

2.接下来介绍API接口参数:
API参数  
一、接口描述/说明
(1)查询接口支持按照运单号查询(单个查询)。
(2)接口需要指定快递单号的快递公司编码,格式不对或则编码错误都会返失败的信息。
(3)返回的物流跟踪信息按照发生的时间升序排列。
(4)接口指令1002。
(5)接口支持的消息接收方式为HTTP POST
给出一个示例:
请求示例 JSON
[size=14][code]没有物流轨迹的
{
"EBusinessID": "1109259",
"Traces": [],
"OrderCode": "",
"ShipperCode": "SF",
"LogisticCode": "118461988807",
"Success": false,
"Reason": null
}
有物流轨迹的
{
"EBusinessID": "1109259",
"OrderCode": "",
"ShipperCode": "SF",
"LogisticCode": "118461988807",
"Success": true,
"State": 3,
"Reason": null,
"Traces": [
{
"AcceptTime": "2014/06/25 08:05:37",
"AcceptStation": "正在派件..(派件人:邓裕富,电话:18718866310)[深圳 市]",
"Remark": null
},
{
"AcceptTime": "2014/06/25 04:01:28",
"AcceptStation": "快件在 深圳集散中心 ,准备送往下一站 深圳 [深圳市]",
"Remark": null
},
{
"AcceptTime": "2014/06/25 01:41:06",
"AcceptStation": "快件在 深圳集散中心 [深圳市]",
"Remark": null
},
{
"AcceptTime": "2014/06/24 20:18:58",
"AcceptStation": "已收件[深圳市]",
"Remark": null
},
{
"AcceptTime": "2014/06/24 20:55:28",
"AcceptStation": "快件在 深圳 ,准备送往下一站 深圳集散中心 [深圳市]",
"Remark": null
},
{
"AcceptTime": "2014/06/25 10:23:03",
"AcceptStation": "派件已签收[深圳市]",
"Remark": null
},
{
"AcceptTime": "2014/06/25 10:23:03",
"AcceptStation": "签收人是:已签收[深圳市]",
"Remark": null
}
]
}[/size][/code] 查看全部
主要是利用快递鸟提供的物流服务,通过对接快递鸟的API,调用即时查询接口,获取物流信息。
这里采用java语言,调用快递鸟的接口为例。步骤如下:
1.首先,得去快递鸟的官方网站注册一个账号并进行实名认证,获得一个用户ID跟API key ,主要是作为个人唯一标识方便调用接口
快递鸟api接口申请地址:快递鸟官网

可以看到即时查询接口每天的调用服务次数是3000次

2.接下来介绍API接口参数:
API参数  
一、接口描述/说明
(1)查询接口支持按照运单号查询(单个查询)。
(2)接口需要指定快递单号的快递公司编码,格式不对或则编码错误都会返失败的信息。
(3)返回的物流跟踪信息按照发生的时间升序排列。
(4)接口指令1002。
(5)接口支持的消息接收方式为HTTP POST
给出一个示例:
请求示例 JSON
[size=14][code]没有物流轨迹的
{
"EBusinessID": "1109259",
"Traces": [],
"OrderCode": "",
"ShipperCode": "SF",
"LogisticCode": "118461988807",
"Success": false,
"Reason": null
}
有物流轨迹的
{
"EBusinessID": "1109259",
"OrderCode": "",
"ShipperCode": "SF",
"LogisticCode": "118461988807",
"Success": true,
"State": 3,
"Reason": null,
"Traces": [
{
"AcceptTime": "2014/06/25 08:05:37",
"AcceptStation": "正在派件..(派件人:邓裕富,电话:18718866310)[深圳 市]",
"Remark": null
},
{
"AcceptTime": "2014/06/25 04:01:28",
"AcceptStation": "快件在 深圳集散中心 ,准备送往下一站 深圳 [深圳市]",
"Remark": null
},
{
"AcceptTime": "2014/06/25 01:41:06",
"AcceptStation": "快件在 深圳集散中心 [深圳市]",
"Remark": null
},
{
"AcceptTime": "2014/06/24 20:18:58",
"AcceptStation": "已收件[深圳市]",
"Remark": null
},
{
"AcceptTime": "2014/06/24 20:55:28",
"AcceptStation": "快件在 深圳 ,准备送往下一站 深圳集散中心 [深圳市]",
"Remark": null
},
{
"AcceptTime": "2014/06/25 10:23:03",
"AcceptStation": "派件已签收[深圳市]",
"Remark": null
},
{
"AcceptTime": "2014/06/25 10:23:03",
"AcceptStation": "签收人是:已签收[深圳市]",
"Remark": null
}
]
}
[/size][/code]

常用快递单号物流查询接口通用API(JAVA快递鸟对接)

fire70 发表了文章 • 0 个评论 • 571 次浏览 • 2019-08-22 11:41 • 来自相关话题

快递查询接口通用API是给发货电商用来实现查询快递物流轨迹功能的,接口对接前要先到快递鸟网站申请接口秘钥和APIKEY
快递API的应用场景与用途
最常见的应用场景如下:
(1)电商网站:例如B2C、团购、B2B、批发分销站、C2C、本地生活交易等网站。
(2)管理系统:订单处理平台、订货平台、发货平台、分销系统、渠道管理系统、客户管理系统、ERP等。
快递API的用途如下:
(1)让顾客登录网站后,直接在“我的订单”页面内就能看到订单的物流状态。
(2)自动筛选出“已签收”、“疑难件”等状态的单号,减轻物流跟单人员的压力。
(3)改变订单的状态和交易流程,例如单号变为“已签收”,就能让订单变为可以确认退换货等。
(4)评估选择快递公司,根据“已签收”的运单数,可以算出销售人员的业绩,且便于应对货到付款的结算。
(5)邮件、短信提醒用户运单的最新状态,可以安抚用户,也可以利用邮件短信二次营销。
对接要求:
(1)、查询接口支持按照运单号查询(单个查询,并发不超过10个/S)。
(2)、指定的物流运单号选择相应的快递公司编码,格式不对或则编码错误都会返失败的信息。如EMS物流单号应选择快递公司编码(EMS)
(3)、返回的物流跟踪信息按照发生的时间升序排列。
(4)、接口指令1002
(5)、接口提供:快递鸟
(6)、请求地址:快递鸟
请求参数:




返回参数:




java请求示例:import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.io.UnsupportedEncodingException;
import java.net.HttpURLConnection;
import java.net.URL;
import java.net.URLEncoder;
import java.security.MessageDigest;
import java.util.HashMap;
import java.util.Map;

/**
*
* 单日超过500单查询量,建议接入物流轨迹订阅推送接口
*
*/

public class KdniaoTrackQueryAPI {

//DEMO
public static void main(String[] args) {
KdniaoTrackQueryAPI api = new KdniaoTrackQueryAPI();
try {
String result = api.getOrderTracesByJson("ANE", "210001633605");
System.out.print(result);

} catch (Exception e) {
e.printStackTrace();
}
}

//电商ID
private String EBusinessID="申请";
//电商加密私钥,注意保管,不要泄漏
private String AppKey="申请";
//请求url
/**
* Json方式 查询订单物流轨迹
* @throws Exception
*/
public String getOrderTracesByJson(String expCode, String expNo) throws Exception{
String requestData= "{'OrderCode':'','ShipperCode':'" + expCode + "','LogisticCode':'" + expNo + "'}";

Map params = new HashMap();
params.put("RequestData", urlEncoder(requestData, "UTF-8"));
params.put("EBusinessID", EBusinessID);
params.put("RequestType", "1002");
String dataSign=encrypt(requestData, AppKey, "UTF-8");
params.put("DataSign", urlEncoder(dataSign, "UTF-8"));
params.put("DataType", "2");

String result=sendPost(ReqURL, params);

//根据公司业务处理返回的信息......

return result;
}

/**
* MD5加密
* @param str 内容
* @param charset 编码方式
* @throws Exception
*/
@SuppressWarnings("unused")
private String MD5(String str, String charset) throws Exception {
MessageDigest md = MessageDigest.getInstance("MD5");
md.update(str.getBytes(charset));
byte[] result = md.digest();
StringBuffer sb = new StringBuffer(32);
for (int i = 0; i < result.length; i++) {
int val = result[i] & 0xff;
if (val <= 0xf) {
sb.append("0");
}
sb.append(Integer.toHexString(val));
}
return sb.toString().toLowerCase();
}

/**
* base64编码
* @param str 内容
* @param charset 编码方式
* @throws UnsupportedEncodingException
*/
private String base64(String str, String charset) throws UnsupportedEncodingException{
String encoded = base64Encode(str.getBytes(charset));
return encoded;
}

@SuppressWarnings("unused")
private String urlEncoder(String str, String charset) throws UnsupportedEncodingException{
String result = URLEncoder.encode(str, charset);
return result;
}

/**
* 电商Sign签名生成
* @param content 内容
* @param keyValue Appkey
* @param charset 编码方式
* @throws UnsupportedEncodingException ,Exception
* @return DataSign签名
*/
@SuppressWarnings("unused")
private String encrypt (String content, String keyValue, String charset) throws UnsupportedEncodingException, Exception
{
if (keyValue != null)
{
return base64(MD5(content + keyValue, charset), charset);
}
return base64(MD5(content, charset), charset);
}

/**
* 向指定 URL 发送POST方法的请求
* @param url 发送请求的 URL
* @param params 请求的参数集合
* @return 远程资源的响应结果
*/
@SuppressWarnings("unused")
private String sendPost(String url, Map params) {
OutputStreamWriter out = null;
BufferedReader in = null;
StringBuilder result = new StringBuilder();
try {
URL realUrl = new URL(url);
HttpURLConnection conn =(HttpURLConnection) realUrl.openConnection();
// 发送POST请求必须设置如下两行
conn.setDoOutput(true);
conn.setDoInput(true);
// POST方法
conn.setRequestMethod("POST");
// 设置通用的请求属性
conn.setRequestProperty("accept", "*/*");
conn.setRequestProperty("connection", "Keep-Alive");
conn.setRequestProperty("user-agent",
"Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1;SV1)");
conn.setRequestProperty("Content-Type", "application/x-www-form-urlencoded");
conn.connect();
// 获取URLConnection对象对应的输出流
out = new OutputStreamWriter(conn.getOutputStream(), "UTF-8");
// 发送请求参数
if (params != null) {
StringBuilder param = new StringBuilder();
for (Map.Entry entry : params.entrySet()) {
if(param.length()>0){
param.append("&");
}
param.append(entry.getKey());
param.append("=");
param.append(entry.getValue());
//System.out.println(entry.getKey()+":"+entry.getValue());
}
//System.out.println("param:"+param.toString());
out.write(param.toString());
}
// flush输出流的缓冲
out.flush();
// 定义BufferedReader输入流来读取URL的响应
in = new BufferedReader(
new InputStreamReader(conn.getInputStream(), "UTF-8"));
String line;
while ((line = in.readLine()) != null) {
result.append(line);
}
} catch (Exception e) {
e.printStackTrace();
}
//使用finally块来关闭输出流、输入流
finally{
try{
if(out!=null){
out.close();
}
if(in!=null){
in.close();
}
}
catch(IOException ex){
ex.printStackTrace();
}
}
return result.toString();
}


private static char[] base64EncodeChars = new char[] {
'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H',
'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P',
'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X',
'Y', 'Z', 'a', 'b', 'c', 'd', 'e', 'f',
'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n',
'o', 'p', 'q', 'r', 's', 't', 'u', 'v',
'w', 'x', 'y', 'z', '0', '1', '2', '3',
'4', '5', '6', '7', '8', '9', '+', '/' };

public static String base64Encode(byte[] data) {
StringBuffer sb = new StringBuffer();
int len = data.length;
int i = 0;
int b1, b2, b3;
while (i < len) {
b1 = data[i++] & 0xff;
if (i == len)
{
sb.append(base64EncodeChars[b1 >>> 2]);
sb.append(base64EncodeChars[(b1 & 0x3) << 4]);
sb.append("==");
break;
}
b2 = data[i++] & 0xff;
if (i == len)
{
sb.append(base64EncodeChars[b1 >>> 2]);
sb.append(base64EncodeChars[((b1 & 0x03) << 4) | ((b2 & 0xf0) >>> 4)]);
sb.append(base64EncodeChars[(b2 & 0x0f) << 2]);
sb.append("=");
break;
}
b3 = data[i++] & 0xff;
sb.append(base64EncodeChars[b1 >>> 2]);
sb.append(base64EncodeChars[((b1 & 0x03) << 4) | ((b2 & 0xf0) >>> 4)]);
sb.append(base64EncodeChars[((b2 & 0x0f) << 2) | ((b3 & 0xc0) >>> 6)]);
sb.append(base64EncodeChars[b3 & 0x3f]);
}
return sb.toString();
}
} 查看全部
快递查询接口通用API是给发货电商用来实现查询快递物流轨迹功能的,接口对接前要先到快递鸟网站申请接口秘钥和APIKEY
快递API的应用场景与用途
最常见的应用场景如下:
(1)电商网站:例如B2C、团购、B2B、批发分销站、C2C、本地生活交易等网站。
(2)管理系统:订单处理平台、订货平台、发货平台、分销系统、渠道管理系统、客户管理系统、ERP等。
快递API的用途如下:
(1)让顾客登录网站后,直接在“我的订单”页面内就能看到订单的物流状态。
(2)自动筛选出“已签收”、“疑难件”等状态的单号,减轻物流跟单人员的压力。
(3)改变订单的状态和交易流程,例如单号变为“已签收”,就能让订单变为可以确认退换货等。
(4)评估选择快递公司,根据“已签收”的运单数,可以算出销售人员的业绩,且便于应对货到付款的结算。
(5)邮件、短信提醒用户运单的最新状态,可以安抚用户,也可以利用邮件短信二次营销。
对接要求:
(1)、查询接口支持按照运单号查询(单个查询,并发不超过10个/S)。
(2)、指定的物流运单号选择相应的快递公司编码,格式不对或则编码错误都会返失败的信息。如EMS物流单号应选择快递公司编码(EMS)
(3)、返回的物流跟踪信息按照发生的时间升序排列。
(4)、接口指令1002
(5)、接口提供:快递鸟
(6)、请求地址:快递鸟
请求参数:
91.png

返回参数:
92.png

java请求示例:
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.io.UnsupportedEncodingException;
import java.net.HttpURLConnection;
import java.net.URL;
import java.net.URLEncoder;
import java.security.MessageDigest;
import java.util.HashMap;
import java.util.Map;

/**
*
* 单日超过500单查询量,建议接入物流轨迹订阅推送接口
*
*/

public class KdniaoTrackQueryAPI {

//DEMO
public static void main(String[] args) {
KdniaoTrackQueryAPI api = new KdniaoTrackQueryAPI();
try {
String result = api.getOrderTracesByJson("ANE", "210001633605");
System.out.print(result);

} catch (Exception e) {
e.printStackTrace();
}
}

//电商ID
private String EBusinessID="申请";
//电商加密私钥,注意保管,不要泄漏
private String AppKey="申请";
//请求url
/**
* Json方式 查询订单物流轨迹
* @throws Exception
*/
public String getOrderTracesByJson(String expCode, String expNo) throws Exception{
String requestData= "{'OrderCode':'','ShipperCode':'" + expCode + "','LogisticCode':'" + expNo + "'}";

Map params = new HashMap();
params.put("RequestData", urlEncoder(requestData, "UTF-8"));
params.put("EBusinessID", EBusinessID);
params.put("RequestType", "1002");
String dataSign=encrypt(requestData, AppKey, "UTF-8");
params.put("DataSign", urlEncoder(dataSign, "UTF-8"));
params.put("DataType", "2");

String result=sendPost(ReqURL, params);

//根据公司业务处理返回的信息......

return result;
}

/**
* MD5加密
* @param str 内容
* @param charset 编码方式
* @throws Exception
*/
@SuppressWarnings("unused")
private String MD5(String str, String charset) throws Exception {
MessageDigest md = MessageDigest.getInstance("MD5");
md.update(str.getBytes(charset));
byte[] result = md.digest();
StringBuffer sb = new StringBuffer(32);
for (int i = 0; i < result.length; i++) {
int val = result[i] & 0xff;
if (val <= 0xf) {
sb.append("0");
}
sb.append(Integer.toHexString(val));
}
return sb.toString().toLowerCase();
}

/**
* base64编码
* @param str 内容
* @param charset 编码方式
* @throws UnsupportedEncodingException
*/
private String base64(String str, String charset) throws UnsupportedEncodingException{
String encoded = base64Encode(str.getBytes(charset));
return encoded;
}

@SuppressWarnings("unused")
private String urlEncoder(String str, String charset) throws UnsupportedEncodingException{
String result = URLEncoder.encode(str, charset);
return result;
}

/**
* 电商Sign签名生成
* @param content 内容
* @param keyValue Appkey
* @param charset 编码方式
* @throws UnsupportedEncodingException ,Exception
* @return DataSign签名
*/
@SuppressWarnings("unused")
private String encrypt (String content, String keyValue, String charset) throws UnsupportedEncodingException, Exception
{
if (keyValue != null)
{
return base64(MD5(content + keyValue, charset), charset);
}
return base64(MD5(content, charset), charset);
}

/**
* 向指定 URL 发送POST方法的请求
* @param url 发送请求的 URL
* @param params 请求的参数集合
* @return 远程资源的响应结果
*/
@SuppressWarnings("unused")
private String sendPost(String url, Map params) {
OutputStreamWriter out = null;
BufferedReader in = null;
StringBuilder result = new StringBuilder();
try {
URL realUrl = new URL(url);
HttpURLConnection conn =(HttpURLConnection) realUrl.openConnection();
// 发送POST请求必须设置如下两行
conn.setDoOutput(true);
conn.setDoInput(true);
// POST方法
conn.setRequestMethod("POST");
// 设置通用的请求属性
conn.setRequestProperty("accept", "*/*");
conn.setRequestProperty("connection", "Keep-Alive");
conn.setRequestProperty("user-agent",
"Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1;SV1)");
conn.setRequestProperty("Content-Type", "application/x-www-form-urlencoded");
conn.connect();
// 获取URLConnection对象对应的输出流
out = new OutputStreamWriter(conn.getOutputStream(), "UTF-8");
// 发送请求参数
if (params != null) {
StringBuilder param = new StringBuilder();
for (Map.Entry entry : params.entrySet()) {
if(param.length()>0){
param.append("&");
}
param.append(entry.getKey());
param.append("=");
param.append(entry.getValue());
//System.out.println(entry.getKey()+":"+entry.getValue());
}
//System.out.println("param:"+param.toString());
out.write(param.toString());
}
// flush输出流的缓冲
out.flush();
// 定义BufferedReader输入流来读取URL的响应
in = new BufferedReader(
new InputStreamReader(conn.getInputStream(), "UTF-8"));
String line;
while ((line = in.readLine()) != null) {
result.append(line);
}
} catch (Exception e) {
e.printStackTrace();
}
//使用finally块来关闭输出流、输入流
finally{
try{
if(out!=null){
out.close();
}
if(in!=null){
in.close();
}
}
catch(IOException ex){
ex.printStackTrace();
}
}
return result.toString();
}


private static char[] base64EncodeChars = new char[] {
'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H',
'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P',
'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X',
'Y', 'Z', 'a', 'b', 'c', 'd', 'e', 'f',
'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n',
'o', 'p', 'q', 'r', 's', 't', 'u', 'v',
'w', 'x', 'y', 'z', '0', '1', '2', '3',
'4', '5', '6', '7', '8', '9', '+', '/' };

public static String base64Encode(byte[] data) {
StringBuffer sb = new StringBuffer();
int len = data.length;
int i = 0;
int b1, b2, b3;
while (i < len) {
b1 = data[i++] & 0xff;
if (i == len)
{
sb.append(base64EncodeChars[b1 >>> 2]);
sb.append(base64EncodeChars[(b1 & 0x3) << 4]);
sb.append("==");
break;
}
b2 = data[i++] & 0xff;
if (i == len)
{
sb.append(base64EncodeChars[b1 >>> 2]);
sb.append(base64EncodeChars[((b1 & 0x03) << 4) | ((b2 & 0xf0) >>> 4)]);
sb.append(base64EncodeChars[(b2 & 0x0f) << 2]);
sb.append("=");
break;
}
b3 = data[i++] & 0xff;
sb.append(base64EncodeChars[b1 >>> 2]);
sb.append(base64EncodeChars[((b1 & 0x03) << 4) | ((b2 & 0xf0) >>> 4)]);
sb.append(base64EncodeChars[((b2 & 0x0f) << 2) | ((b3 & 0xc0) >>> 6)]);
sb.append(base64EncodeChars[b3 & 0x3f]);
}
return sb.toString();
}
}

java免费对接快递鸟快递单号查询api接口案例

fire70 发表了文章 • 0 个评论 • 556 次浏览 • 2019-08-08 16:33 • 来自相关话题

 
快递查询API接口是使用的物流单号即可实现查询物流信息。主要应用在电商商城、ERP系统商、WMS系统商、快递柜、银行等企业。多家快递物流公司接口统一接入,建议对接接口提供商,一次性可以接入多家快递,在后期的技术维护也会省下很多工作。
目前快递查询API接口有两种实现方式,一种是主动查询,一种是订阅接口推送数据。以快递鸟接口为例(接口对接需要接口秘钥,这里用的是测试的,不能够正式使用,可以到快递鸟官网申请,是免费申请秘钥的)最后附有一个的demo,更多demo可登陆快递鸟网站查询。
一.主动查询(即时查询API)
1)接口规则
a、查询接口支持按照运单号查询(单个查询,并发不超过10个/S)。
b、指定的物流运单号选择相应的快递公司编码,格式不对或则编码错误都会返失败的信息。如圆通快递物流单号应选择圆通快递公司编码(YTO)
c、返回的物流跟踪信息按照发生的时间升序排列。
d、接口指令1002。
e、请求地址:快递鸟注册
2)系统级和应用级输入参数系统级输入参数







3)返回结果参数







4)JSON请求示例{
“OrderCode”: “”,
“ShipperCode”: “SF”,
“LogisticCode”: “118650888018”
}
// "YTO"为圆通快递公司编码,其他编码可在快递鸟官网下载
5)JSON返回示例
//没有物流轨迹的
{
“EBusinessID”: “1109259”,
"Traces":[],
“OrderCode”: “”,
“ShipperCode”: “SF”,
“LogisticCode”: “118461988807”,
“Success”: true,
“Reason”: null
}
//有物流轨迹的
{
“EBusinessID”: “1109259”,
"OrderCode":"",
“ShipperCode”: “SF”,
“LogisticCode”: “118461988807”,
“Success”: true,
"CallBack":"",
“State”: 3,
“Reason”: null,
"Traces":[
{
"AcceptTime": "2014/06/25 08:05:37",
"AcceptStation": "正在派件..(派件人:邓裕富,电话:18718866310)[深圳 市]",
"Remark": null
},
{
"AcceptTime": "2014/06/25 04:01:28",
"AcceptStation": "快件在 深圳集散中心 ,准备送往下一站 深圳 [深圳市]",
"Remark": null
},
{
"AcceptTime": "2014/06/2501:41:06",
"AcceptStation": "快件在 深圳集散中心 [深圳市]",
"Remark": null
},
{
"AcceptTime": "2014/06/24 20:18:58",
"AcceptStation": "已收件[深圳市]",
"Remark": null
},
{
"AcceptTime": "2014/06/24 20:55:28",
"AcceptStation": "快件在 深圳 ,准备送往下一站 深圳集散中心 [深圳市]",
"Remark": null
},
{
"AcceptTime": "2014/06/25 10:23:03",
"AcceptStation": "派件已签收[深圳市]",
"Remark": null
},
{
"AcceptTime": "2014/06/25 10:23:03",
"AcceptStation": "签收人是:已签收[深圳市]",
"Remark": null
}
]
 
 
  查看全部
 
快递查询API接口是使用的物流单号即可实现查询物流信息。主要应用在电商商城、ERP系统商、WMS系统商、快递柜、银行等企业。多家快递物流公司接口统一接入,建议对接接口提供商,一次性可以接入多家快递,在后期的技术维护也会省下很多工作。
目前快递查询API接口有两种实现方式,一种是主动查询,一种是订阅接口推送数据。以快递鸟接口为例(接口对接需要接口秘钥,这里用的是测试的,不能够正式使用,可以到快递鸟官网申请,是免费申请秘钥的)最后附有一个的demo,更多demo可登陆快递鸟网站查询。
一.主动查询(即时查询API)
1)接口规则
a、查询接口支持按照运单号查询(单个查询,并发不超过10个/S)。
b、指定的物流运单号选择相应的快递公司编码,格式不对或则编码错误都会返失败的信息。如圆通快递物流单号应选择圆通快递公司编码(YTO)
c、返回的物流跟踪信息按照发生的时间升序排列。
d、接口指令1002。
e、请求地址:快递鸟注册
2)系统级和应用级输入参数系统级输入参数


中1.png


3)返回结果参数

中2.png



4)JSON请求示例
{
“OrderCode”: “”,
“ShipperCode”: “SF”,
“LogisticCode”: “118650888018”
}
// "YTO"为圆通快递公司编码,其他编码可在快递鸟官网下载
5)JSON返回示例
//没有物流轨迹的
{
“EBusinessID”: “1109259”,
"Traces":[],
“OrderCode”: “”,
“ShipperCode”: “SF”,
“LogisticCode”: “118461988807”,
“Success”: true,
“Reason”: null
}
//有物流轨迹的
{
“EBusinessID”: “1109259”,
"OrderCode":"",
“ShipperCode”: “SF”,
“LogisticCode”: “118461988807”,
“Success”: true,
"CallBack":"",
“State”: 3,
“Reason”: null,
"Traces":[
{
"AcceptTime": "2014/06/25 08:05:37",
"AcceptStation": "正在派件..(派件人:邓裕富,电话:18718866310)[深圳 市]",
"Remark": null
},
{
"AcceptTime": "2014/06/25 04:01:28",
"AcceptStation": "快件在 深圳集散中心 ,准备送往下一站 深圳 [深圳市]",
"Remark": null
},
{
"AcceptTime": "2014/06/2501:41:06",
"AcceptStation": "快件在 深圳集散中心 [深圳市]",
"Remark": null
},
{
"AcceptTime": "2014/06/24 20:18:58",
"AcceptStation": "已收件[深圳市]",
"Remark": null
},
{
"AcceptTime": "2014/06/24 20:55:28",
"AcceptStation": "快件在 深圳 ,准备送往下一站 深圳集散中心 [深圳市]",
"Remark": null
},
{
"AcceptTime": "2014/06/25 10:23:03",
"AcceptStation": "派件已签收[深圳市]",
"Remark": null
},
{
"AcceptTime": "2014/06/25 10:23:03",
"AcceptStation": "签收人是:已签收[深圳市]",
"Remark": null
}
]
 

 

 

js二维码插件

回复

mx2118 发起了问题 • 2 人关注 • 0 个回复 • 371 次浏览 • 2019-04-13 17:45 • 来自相关话题

添加提示文字

cc110110 发表了文章 • 0 个评论 • 760 次浏览 • 2018-08-23 14:35 • 来自相关话题

在配置管理->系统->配置值  里面添加 tiptext:提示文本
需要修改的代码文件
common->builder->table->Builder.php 第1885行后添加case 'tiptext':
$row[$column['name'].'__'.$column['type']] = '<div class="el-tooltip" aria-describedby="el-tooltip-127" tabindex="0" style="color: rgb(64, 158, 255); text-overflow: ellipsis; overflow: hidden; white-space: nowrap;" title="'.$row[$column['name']].'" data-toggle="tooltip" >'.$row[$column['name']].'</div>';
break; 查看全部
在配置管理->系统->配置值  里面添加 tiptext:提示文本
需要修改的代码文件
common->builder->table->Builder.php 第1885行后添加
case 'tiptext':
$row[$column['name'].'__'.$column['type']] = '<div class="el-tooltip" aria-describedby="el-tooltip-127" tabindex="0" style="color: rgb(64, 158, 255); text-overflow: ellipsis; overflow: hidden; white-space: nowrap;" title="'.$row[$column['name']].'" data-toggle="tooltip" >'.$row[$column['name']].'</div>';
break;

Tp5与Ucenter用户整合

wpcost 发表了文章 • 0 个评论 • 1075 次浏览 • 2018-02-18 09:35 • 来自相关话题

Tp5中api开发中异常输出为html的问题

dragonlhp 发表了文章 • 0 个评论 • 909 次浏览 • 2018-02-05 20:06 • 来自相关话题

现在谁不开发接口的呢?但是在接口开发过程中,报错误异常后居然返回错误的信息依然是html信息!TP官方也不知道为啥不添加,说好的为接口而生,我的解决方案也很简单,把系统的异常处理类复制出来,去掉模板相关,直接以json方式输出;下面是解决方案:

1:按照TP扩展异常的方式引用这个文件
看云 /manual/thinkphp5_1/354092

2:判断一下配置文件的默认输出类型
配置文件:
    //    判断默认输出类型
    if ($app['default_return_type'] == 'json') {
        // 异常处理handle类 留空使用 \think\exception\Handle
        $app['exception_handle'] = '\\app\\common\\exception\\JsonException';
    }


    return $app;

  查看全部
现在谁不开发接口的呢?但是在接口开发过程中,报错误异常后居然返回错误的信息依然是html信息!TP官方也不知道为啥不添加,说好的为接口而生,我的解决方案也很简单,把系统的异常处理类复制出来,去掉模板相关,直接以json方式输出;下面是解决方案:

1:按照TP扩展异常的方式引用这个文件
看云 /manual/thinkphp5_1/354092

2:判断一下配置文件的默认输出类型
配置文件:
    //    判断默认输出类型
    if ($app['default_return_type'] == 'json') {
        // 异常处理handle类 留空使用 \think\exception\Handle
        $app['exception_handle'] = '\\app\\common\\exception\\JsonException';
    }


    return $app;

 

关于linkages标签 三个选项框不能对应三层结构数据的问题

chhnang 发表了文章 • 0 个评论 • 795 次浏览 • 2017-10-23 16:13 • 来自相关话题

在做省市县三个选项框时, 经常出现 直辖市: 两级结构;  省: 四级结构(市多一个市辖区)  ,导致linkages标签不能愉快的使用, 在下做了一个数据调整,供大家参考!
在做省市县三个选项框时, 经常出现 直辖市: 两级结构;  省: 四级结构(市多一个市辖区)  ,导致linkages标签不能愉快的使用, 在下做了一个数据调整,供大家参考!

text 文本框 的 input-group 类型

清风笑对人生 发表了文章 • 0 个评论 • 848 次浏览 • 2017-09-23 17:08 • 来自相关话题

修改了一下,可以支持按钮的添加
修改了一下,可以支持按钮的添加

IIS 7.下面URL Rewrite的路由配置

小兔言言 发表了文章 • 0 个评论 • 1548 次浏览 • 2017-06-28 22:17 • 来自相关话题

海豚PHP的源码Rewrite配置是针对Linux下面的Apache设置的.htaccess,但是像我使用的是Windows Server IIS 7的用户来说,需要手动设置URL Rewrite的规则,才可以使得前台通过index.php路由访问正常,具体的做法很简单,安装好Rewrite组件后,在网站根目录下新建一个web.config,然后复制以下内容,保存后,前台即可路由正常了
<?xml version="1.0" encoding="UTF-8"?>  
<configuration>  
  <system.webServer>  
    <rewrite>  
      <rules>  
        <rule name="thinkPhp" enabled="true" stopProcessing="true">  
          <match url=".*" />  
          <conditions logicalGrouping="MatchAll">  
            <add input="{REQUEST_FILENAME}" matchType="IsFile" negate="true" />  
            <add input="{REQUEST_FILENAME}" matchType="IsDirectory" negate="true" />  
          </conditions>  
          <action type="Rewrite" url="index.php/{R:0}" />  
        </rule>  
      </rules>  
    </rewrite>  
  </system.webServer>  
</configuration> 查看全部
海豚PHP的源码Rewrite配置是针对Linux下面的Apache设置的.htaccess,但是像我使用的是Windows Server IIS 7的用户来说,需要手动设置URL Rewrite的规则,才可以使得前台通过index.php路由访问正常,具体的做法很简单,安装好Rewrite组件后,在网站根目录下新建一个web.config,然后复制以下内容,保存后,前台即可路由正常了
<?xml version="1.0" encoding="UTF-8"?>  
<configuration>  
  <system.webServer>  
    <rewrite>  
      <rules>  
        <rule name="thinkPhp" enabled="true" stopProcessing="true">  
          <match url=".*" />  
          <conditions logicalGrouping="MatchAll">  
            <add input="{REQUEST_FILENAME}" matchType="IsFile" negate="true" />  
            <add input="{REQUEST_FILENAME}" matchType="IsDirectory" negate="true" />  
          </conditions>  
          <action type="Rewrite" url="index.php/{R:0}" />  
        </rule>  
      </rules>  
    </rewrite>  
  </system.webServer>  
</configuration>

表格页面的时间快捷编辑无法使用的解决方法

dolphinphp 发表了文章 • 0 个评论 • 949 次浏览 • 2017-06-09 16:51 • 来自相关话题

打开
application\admin\view\layout.html
 
大概439行左右,添加
<script src="__LIBS__/bootstrap-datetimepicker/moment.min.js"></script>




  查看全部
打开
application\admin\view\layout.html
 
大概439行左右,添加
<script src="__LIBS__/bootstrap-datetimepicker/moment.min.js"></script>

QQ截图20170609164740.png

 

关于升级到1.0.3版本后,验证码不显示的解决办法

dolphinphp 发表了文章 • 0 个评论 • 1171 次浏览 • 2017-05-10 17:50 • 来自相关话题

由于1.0.3版本关闭了后台的路由功能,所以导致验证码无法显示。
 
临时解决办法:
 
打开admin.php,将一下代码注释掉
// 关闭路由
\think\App::route(false);
由于1.0.3版本关闭了后台的路由功能,所以导致验证码无法显示。
 
临时解决办法:
 
打开admin.php,将一下代码注释掉
// 关闭路由
\think\App::route(false);

get_thumb 函数增加 返回完整域名 参数

momo 发表了文章 • 0 个评论 • 759 次浏览 • 2017-04-17 10:25 • 来自相关话题

有的时候我们希望获取图片路径的时候带上完整的域名,官方的get_thumb函数没有提供,
自己加了一个$domain参数,给需要的人

application\common.php

if (!function_exists('get_thumb')) {
/**
* 获取图片缩略图路径
* @param int $id 附件id
* @author 蔡伟明 <314013107@qq.com>
* @return string
*/
function get_thumb($id = 0,$domain=true)
{
$path = model('admin/attachment')->getThumbPath($id);
if (!$path) {
return config('public_static_path').'admin/img/none.png';
}

if($domain){
if(empty($_SERVER['HTTPS']))
$pre="http://";
else
$pre="https://";
return $pre.$_SERVER['HTTP_HOST'].PUBLIC_PATH. $path;
}
else {
return PUBLIC_PATH. $path;
}
}
} 查看全部
有的时候我们希望获取图片路径的时候带上完整的域名,官方的get_thumb函数没有提供,
自己加了一个$domain参数,给需要的人

application\common.php

if (!function_exists('get_thumb')) {
/**
* 获取图片缩略图路径
* @param int $id 附件id
* @author 蔡伟明 <314013107@qq.com>
* @return string
*/
function get_thumb($id = 0,$domain=true)
{
$path = model('admin/attachment')->getThumbPath($id);
if (!$path) {
return config('public_static_path').'admin/img/none.png';
}

if($domain){
if(empty($_SERVER['HTTPS']))
$pre="http://";
else
$pre="https://";
return $pre.$_SERVER['HTTP_HOST'].PUBLIC_PATH. $path;
}
else {
return PUBLIC_PATH. $path;
}
}
}

常见问题收集以及处理方法,错过了QQ群里的信息的可以到这里找找!

xin5288 发表了文章 • 0 个评论 • 803 次浏览 • 2017-03-04 14:23 • 来自相关话题

不管是老司机还是嫩小鸟,都会遇到一些小小小的问题,如果你有遇到小问题自己又解决了跟贴了·
 
Q:升级或者新anz安装顶部菜单点击无反映
A:强制刷新liu浏览器(CTRL+F5),再不行就清空liu浏览器缓存。
 

Q:添加了ZBuilder表格添加了->addRightButton却不显示按钮?
A:查看代码是否忘添加表头操作列。 查看全部
不管是老司机还是嫩小鸟,都会遇到一些小小小的问题,如果你有遇到小问题自己又解决了跟贴了·
 
Q:升级或者新anz安装顶部菜单点击无反映
A:强制刷新liu浏览器(CTRL+F5),再不行就清空liu浏览器缓存。
 

Q:添加了ZBuilder表格添加了->addRightButton却不显示按钮?
A:查看代码是否忘添加表头操作列。

时间格式的处理细节

mrcai 发表了文章 • 0 个评论 • 714 次浏览 • 2017-01-16 09:34 • 来自相关话题

我的数据库内的时间字段是int型,老是显示不对。经过询问技术明白了。
 
add_time int (11) 是时间字段保存的是时间戳
 
------------
保存的时候
$data['add_time'] = strtotime($data['add_time']);
 

编辑取出数据后
$info['add_time'] = date('Y-m-d H:i:s', $info['add_time']); 查看全部
我的数据库内的时间字段是int型,老是显示不对。经过询问技术明白了。
 
add_time int (11) 是时间字段保存的是时间戳
 
------------
保存的时候
$data['add_time'] = strtotime($data['add_time']);
 

编辑取出数据后
$info['add_time'] = date('Y-m-d H:i:s', $info['add_time']);