1.8.0
This commit is contained in:
@@ -41,6 +41,9 @@ class dianping implements api
|
||||
if($url){
|
||||
$visitid = getSubstr($url, 'visitId=', '&');
|
||||
if($visitid){
|
||||
$url = 'https://kf.dianping.com/api/portal/message/init?visitId='.$visitid.'&accessToken=undefined';
|
||||
$post = '{"type":"Init","parameters":{"isPreview":true,"build":null}}';
|
||||
get_curl($url, $post);
|
||||
cache('dianping_visitid', $visitid, 86400);
|
||||
return $visitid;
|
||||
}
|
||||
|
||||
@@ -1,87 +0,0 @@
|
||||
<?php
|
||||
/**
|
||||
* uniCloud文件快传
|
||||
*/
|
||||
|
||||
namespace plugin\utility\unicloud;
|
||||
|
||||
use app\Plugin;
|
||||
use think\facade\Db;
|
||||
use plugin\utility\unicloud\UnicloudClient;
|
||||
use Exception;
|
||||
|
||||
class App extends Plugin
|
||||
{
|
||||
|
||||
private $unicloud;
|
||||
|
||||
public function index()
|
||||
{
|
||||
return $this->view();
|
||||
}
|
||||
|
||||
public function preUpload(){
|
||||
if(!input('?post.filename'))exit('{"code":-1,"msg":"请选择文件"}');
|
||||
|
||||
try{
|
||||
$this->getSession();
|
||||
} catch (Exception $e) {
|
||||
return ['code'=>-1, 'msg'=>'获取AccessToken失败:' . $e->getMessage()];
|
||||
}
|
||||
|
||||
try{
|
||||
$result = $this->unicloud->pre_upload_file(input('post.filename'));
|
||||
$fileurl = 'https://'.$result['cdnDomain'].'/'.$result['ossPath'];
|
||||
session('unicloud_filename', input('post.filename'));
|
||||
session('unicloud_fileurl', $fileurl);
|
||||
return json(['code'=>0, 'data'=>$result]);
|
||||
} catch (Exception $e) {
|
||||
return json(['code'=>-1, 'msg'=>'准备文件上传失败:' . $e->getMessage()]);
|
||||
}
|
||||
}
|
||||
|
||||
public function completeUpload(){
|
||||
if(!input('?post.id'))exit('{"code":-1,"msg":"no id"}');
|
||||
|
||||
try{
|
||||
$this->getSession();
|
||||
} catch (Exception $e) {
|
||||
return ['code'=>-1, 'msg'=>'获取AccessToken失败:' . $e->getMessage()];
|
||||
}
|
||||
|
||||
try{
|
||||
$result = $this->unicloud->complete_upload_file(input('post.id'));
|
||||
|
||||
Db::name('uploadlog')->insert([
|
||||
'uid' => request()->islogin ? request()->user['id'] : 0,
|
||||
'type' => 'file',
|
||||
'source' => 'unicloud',
|
||||
'filename' => session('unicloud_filename'),
|
||||
'fileurl' => session('unicloud_fileurl'),
|
||||
'ip' => $this->clientip,
|
||||
'addtime' => date("Y-m-d H:i:s")
|
||||
]);
|
||||
session('unicloud_filename', null);
|
||||
session('unicloud_fileurl', null);
|
||||
|
||||
return json(['code'=>0, 'data'=>$result]);
|
||||
} catch (Exception $e) {
|
||||
return json(['code'=>-1, 'msg'=>'完成文件上传失败:' . $e->getMessage()]);
|
||||
}
|
||||
}
|
||||
|
||||
private function getSession(){
|
||||
include dirname(__FILE__).'/config.php';
|
||||
$this->unicloud = new UnicloudClient($spaceId, $clientSecret);
|
||||
if(session('access_token') && session('access_token_expire') && session('access_token_expire')>time()){
|
||||
$access_token = session('access_token');
|
||||
$this->unicloud->set_access_token($access_token);
|
||||
}else{
|
||||
$access_token = $this->unicloud->get_access_token();
|
||||
session('access_token', $access_token);
|
||||
session('access_token_expire', time()+600);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,144 +0,0 @@
|
||||
<?php
|
||||
// uniCloud云存储客户端
|
||||
|
||||
namespace plugin\utility\unicloud;
|
||||
|
||||
use Exception;
|
||||
|
||||
class UnicloudClient {
|
||||
private $spaceId;
|
||||
private $clientSecret;
|
||||
private $endpoint = "https://api.bspapp.com";
|
||||
private $accessToken = null;
|
||||
|
||||
function __construct($spaceId, $clientSecret){
|
||||
$this->spaceId = $spaceId;
|
||||
$this->clientSecret = $clientSecret;
|
||||
}
|
||||
|
||||
public function set_access_token($accessToken){
|
||||
$this->accessToken = $accessToken;
|
||||
}
|
||||
|
||||
// 获取AccessToken
|
||||
public function get_access_token(){
|
||||
if(!empty($this->accessToken)) return $this->accessToken;
|
||||
$param = [
|
||||
'method' => 'serverless.auth.user.anonymousAuthorize',
|
||||
'params' => '{}',
|
||||
'spaceId' => $this->spaceId,
|
||||
'timestamp' => $this->msec_time()
|
||||
];
|
||||
$sign = $this->get_sign($param);
|
||||
$payload = json_encode($param);
|
||||
$header = [
|
||||
'x-serverless-sign: '.$sign
|
||||
];
|
||||
$result = $this->curl_post($payload, $header);
|
||||
$this->accessToken = $result['accessToken'];
|
||||
return $this->accessToken;
|
||||
}
|
||||
|
||||
// 获取文件上传信息
|
||||
public function pre_upload_file($filename){
|
||||
$method = 'serverless.file.resource.generateProximalSign';
|
||||
$params = [
|
||||
'env' => 'public',
|
||||
'filename' => $filename
|
||||
];
|
||||
$result = $this->send_request($method, $params);
|
||||
return $result;
|
||||
}
|
||||
|
||||
// 完成文件上传
|
||||
public function complete_upload_file($id){
|
||||
$method = 'serverless.file.resource.report';
|
||||
$params = [
|
||||
'id' => $id
|
||||
];
|
||||
$this->send_request($method, $params);
|
||||
return true;
|
||||
}
|
||||
|
||||
// 删除文件(不支持阿里云)
|
||||
public function delete_file($id){
|
||||
$method = 'serverless.file.resource.delete';
|
||||
$params = [
|
||||
'id' => $id
|
||||
];
|
||||
$this->send_request($method, $params);
|
||||
return true;
|
||||
}
|
||||
|
||||
private function send_request($method, $params){
|
||||
$access_token = $this->get_access_token();
|
||||
$postparam = [
|
||||
'method' => $method,
|
||||
'params' => json_encode($params),
|
||||
'spaceId' => $this->spaceId,
|
||||
'timestamp' => $this->msec_time(),
|
||||
'token' => $access_token
|
||||
];
|
||||
$sign = $this->get_sign($postparam);
|
||||
$payload = json_encode($postparam);
|
||||
$header = [
|
||||
'x-basement-token: '.$access_token,
|
||||
'x-serverless-sign: '.$sign
|
||||
];
|
||||
$result = $this->curl_post($payload, $header);
|
||||
return $result;
|
||||
}
|
||||
|
||||
private function get_sign($param){
|
||||
$signPars = "";
|
||||
ksort($param);
|
||||
foreach ($param as $k => $v) {
|
||||
if ($v != '') {
|
||||
$signPars .= $k . '=' . $v . '&';
|
||||
}
|
||||
}
|
||||
$signPars = substr($signPars, 0, -1);
|
||||
$sign = hash_hmac('md5', $signPars, $this->clientSecret);
|
||||
return $sign;
|
||||
}
|
||||
|
||||
private function msec_time() {
|
||||
list($msec, $sec) = explode(' ', microtime());
|
||||
$msectime = (float)sprintf('%.0f', (floatval($msec) + floatval($sec)) * 1000);
|
||||
return $msectime;
|
||||
}
|
||||
|
||||
private function curl_post($payload, $header){
|
||||
$url = $this->endpoint.'/client';
|
||||
$httpheader[] = "accept: */*";
|
||||
$httpheader[] = "accept-encoding: gzip,deflate,sdch";
|
||||
$httpheader[] = "accept-language: zh-CN,zh;q=0.8";
|
||||
$httpheader[] = "cache-control: no-cache";
|
||||
$httpheader[] = "content-type: application/json";
|
||||
$httpheader[] = "pragma: no-cache";
|
||||
$httpheader[] = "connection: close";
|
||||
$httpheader = array_merge($httpheader, $header);
|
||||
$ch=curl_init($url);
|
||||
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
|
||||
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false);
|
||||
curl_setopt($ch, CURLOPT_HTTPHEADER, $httpheader);
|
||||
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
|
||||
curl_setopt($ch, CURLOPT_TIMEOUT, 10);
|
||||
curl_setopt($ch, CURLOPT_POST, 1);
|
||||
curl_setopt($ch, CURLOPT_POSTFIELDS, $payload);
|
||||
curl_setopt($ch, CURLOPT_USERAGENT,'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/86.0.4240.198 Safari/537.36');
|
||||
$json=curl_exec($ch);
|
||||
$httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
|
||||
curl_close($ch);
|
||||
if($httpCode==200){
|
||||
$arr=json_decode($json,true);
|
||||
if($arr['success'] == true){
|
||||
return $arr['data'];
|
||||
}else{
|
||||
throw new Exception($arr['error']['message'] ? $arr['error']['message'] : '未知错误');
|
||||
}
|
||||
}else{
|
||||
throw new Exception('curl error! httpcode='.$httpCode);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,5 +0,0 @@
|
||||
<?php
|
||||
|
||||
$spaceId = '10b3891b-be67-4103-a60f-9da1d057470c';
|
||||
|
||||
$clientSecret = '6H2YuHYH4Cju+/5K8YIJjA==';
|
||||
@@ -1,312 +0,0 @@
|
||||
{extend name="common/plugin_layout" /}
|
||||
{block name="title"}{$plugin.title} - {:config_get('title')}{/block}
|
||||
{block name="main"}
|
||||
<style>
|
||||
.btn-block {
|
||||
white-space:normal;
|
||||
}
|
||||
.btn-active {background-color: #1c2b46;color: #fff;}
|
||||
</style>
|
||||
<div class="container-xl" id="app">
|
||||
<div class="col-sm-12 col-md-10 col-xl-9 center-block">
|
||||
<div class="card card-preview">
|
||||
<div class="card-inner mt-3">
|
||||
<div class="nya-title nk-ibx-action-item progress-rating">
|
||||
<span class="nk-menu-text font-weight-bold">uniCloud文件快传</span>
|
||||
</div>
|
||||
<div class="progress progress-lg mt-1 mb-1">
|
||||
<div class="progress-bar progress-bar-striped progress-bar-animated" v-bind:style="{ width: progress + '%' }">{{progress}}%</div>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<div class="text-center pt-5 pb-5 btn btn-lg btn-block btn-outline-light mb-4 d-block" id="fileInput">
|
||||
<div class="preview-icon-wrap"><em class="ni ni-upload"></em></div><span>点击选择文件/Ctrl+V粘贴/拖拽到此处</span>
|
||||
<input type="file" id="file" style="opacity: 0;position: absolute;cursor: pointer;width: 100%;height: 100%;left: 0;top: 0;" @change="selectFile">
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
<div class="btn-group">
|
||||
<button v-for="v in set.output_types.items" class="btn btn-outline-dark btn-sm"
|
||||
:class="{'btn-active':set.output_types.current===v.key}"
|
||||
@click="set.output_types.current=v.key"
|
||||
>
|
||||
{{v.title}}
|
||||
</button>
|
||||
</div>
|
||||
<div class="form-control-wrap">
|
||||
<textarea class="form-control" id="output" v-model="result" rows="8" placeholder="这里显示上传的结果"></textarea>
|
||||
</div>
|
||||
<div class="text-center"><button class="btn btn-sm btn-outline-light" @click="copy"><em class="icon ni ni-copy"></em>点此复制</button> <button class="btn btn-sm btn-outline-light" @click="reset"><em class="icon ni ni-reload"></em>清空</button></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="card card-preview">
|
||||
<div class="card-inner">
|
||||
<h6><em class="icon ni ni-info"></em> 工具说明</h6>
|
||||
<div class="accordion-inner">
|
||||
<p>uniCloud文件快传底层使用阿里云OSS存储,支持任何格式的文件,也可以当图床使用。</p>
|
||||
<p>一次只能上传1个文件,文件大小限制100M。一经上传,将无法删除,本站也不会保存。</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{/block}
|
||||
{block name="script"}
|
||||
<script src="{$cdn_cdnjs}vue/2.6.14/vue.min.js"></script>
|
||||
<script>
|
||||
new Vue({
|
||||
el: '#app',
|
||||
data: {
|
||||
set: {
|
||||
output_types: {
|
||||
current: 'URL',
|
||||
items: [
|
||||
{
|
||||
title: 'URL',
|
||||
key: 'URL',
|
||||
template: '#url#',
|
||||
},
|
||||
{
|
||||
title: 'HTML',
|
||||
key: 'HTML',
|
||||
template: '<a href="#url#" target="_blank">#name#</a>',
|
||||
},
|
||||
{
|
||||
title: 'BBCode',
|
||||
key: 'BBCode',
|
||||
template: '[url=#url#]#name#[/url]',
|
||||
},
|
||||
{
|
||||
title: 'Markdown',
|
||||
key: 'Markdown',
|
||||
template: '[#name#](#url#)',
|
||||
},
|
||||
]
|
||||
},
|
||||
output: [],
|
||||
},
|
||||
progress: 0,
|
||||
urls: {},
|
||||
result: '',
|
||||
},
|
||||
mounted() {
|
||||
var that=this;
|
||||
document.addEventListener('paste', function(e) {
|
||||
var items = ((e.clipboardData || window.clipboardData).items) || [];
|
||||
var file = null;
|
||||
|
||||
if (items && items.length) {
|
||||
for (var i = 0; i < items.length; i++) {
|
||||
if (items[i].type.indexOf('text/') === -1) {
|
||||
file = items[i].getAsFile();
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!file) {
|
||||
return;
|
||||
}
|
||||
that.pasteFile(file)
|
||||
|
||||
});
|
||||
},
|
||||
watch: {
|
||||
'set.output'(newVal) {
|
||||
let list = {}
|
||||
for (item of this.set.output_types.items) {
|
||||
let arr = []
|
||||
for (const v of newVal) {
|
||||
arr.push(item.template.replaceAll('#url#', v.url).replaceAll('#name#', v.name))
|
||||
}
|
||||
list[item.key] = arr;
|
||||
}
|
||||
this.urls = list
|
||||
},
|
||||
'urls'(newVal) {
|
||||
this.result = newVal[this.set.output_types.current].join('\n')
|
||||
},
|
||||
'set.output_types.current'(newVal) {
|
||||
this.result = this.urls[newVal] ? this.urls[newVal].join('\n') : '';
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
async preUpload(filename){
|
||||
var that = this;
|
||||
return new Promise((resolve, reject) => {
|
||||
$.ajax({
|
||||
type : "POST",
|
||||
url : "/api/{$plugin.alias}/preUpload",
|
||||
data : {filename: filename},
|
||||
dataType : 'json',
|
||||
success : function(data) {
|
||||
if(data.code == 0){
|
||||
resolve(data.data);
|
||||
}else{
|
||||
reject(data.msg);
|
||||
}
|
||||
},
|
||||
error : function(){
|
||||
reject('准备文件上传失败:接口错误');
|
||||
}
|
||||
});
|
||||
})
|
||||
},
|
||||
async completeUpload(id){
|
||||
var that = this;
|
||||
return new Promise((resolve, reject) => {
|
||||
$.ajax({
|
||||
type : "POST",
|
||||
url : "/api/{$plugin.alias}/completeUpload",
|
||||
data : {id: id},
|
||||
dataType : 'json',
|
||||
success : function(data) {
|
||||
if(data.code == 0){
|
||||
resolve(data.data);
|
||||
}else{
|
||||
reject(data.msg);
|
||||
}
|
||||
},
|
||||
error : function(){
|
||||
reject('完成文件上传失败:接口错误');
|
||||
}
|
||||
});
|
||||
})
|
||||
},
|
||||
async uploadFile(url, postdata, file){
|
||||
var that = this;
|
||||
return new Promise((resolve, reject) => {
|
||||
var data = new FormData();
|
||||
for(key in postdata){
|
||||
data.append(key, postdata[key]);
|
||||
}
|
||||
data.append('file', file);
|
||||
$.ajax({
|
||||
type : "POST",
|
||||
url : url,
|
||||
data : data,
|
||||
processData: false,
|
||||
contentType: false,
|
||||
dataType : 'html',
|
||||
success : function(data) {
|
||||
resolve();
|
||||
},
|
||||
error : function(){
|
||||
reject('文件上传失败!');
|
||||
},
|
||||
xhr: function() {
|
||||
var xhr = new XMLHttpRequest();
|
||||
xhr.upload.addEventListener('progress', function (e) {
|
||||
//console.log(e);
|
||||
progressRate = Math.round(e.loaded / e.total * 100);
|
||||
that.progress = progressRate;
|
||||
})
|
||||
return xhr;
|
||||
}
|
||||
});
|
||||
})
|
||||
},
|
||||
async selectFile(e) {
|
||||
var total = e.target.files.length;
|
||||
if(total == 0) return;
|
||||
var file = e.target.files[0];
|
||||
if(file.size > 104857600){
|
||||
layer.alert('文件大小限制100M');return;
|
||||
}
|
||||
this.progress = 0;
|
||||
|
||||
var url,postdata,fileid,fileurl;
|
||||
|
||||
var loading = layer.msg('正在准备文件上传', {icon: 16,shade: 0.3,time: 0});
|
||||
await this.preUpload(file.name).then(data => {
|
||||
fileid = data.id;
|
||||
postdata = {'Cache-Control':'max-age=2592000', 'Content-Disposition':'attachment', 'OSSAccessKeyId':data.accessKeyId, 'Signature':data.signature, 'host':data.host, 'id':data.id, 'key':data.ossPath, 'policy':data.policy, 'success_action_status':'200'};
|
||||
url = 'https://' + data.host + '/';
|
||||
fileurl = 'https://' + data.cdnDomain + '/' + data.ossPath;
|
||||
}, error => {
|
||||
layer.close(loading);
|
||||
layer.alert(error, {icon: 2});
|
||||
$("#file").val('');
|
||||
throw Error();
|
||||
});
|
||||
|
||||
loading = layer.msg('正在上传文件,请稍候...', {icon: 16,shade: 0.3,time: 0});
|
||||
await this.uploadFile(url, postdata, file).then(() => {
|
||||
}, error => {
|
||||
layer.close(loading);
|
||||
layer.alert(error, {icon: 2});
|
||||
$("#file").val('');
|
||||
throw Error();
|
||||
});
|
||||
|
||||
loading = layer.msg('上传成功,正在保存', {icon: 16,shade: 0.3,time: 0});
|
||||
await this.completeUpload(fileid).then(data => {
|
||||
layer.close(loading);
|
||||
}, error => {
|
||||
layer.close(loading);
|
||||
layer.alert(error, {icon: 2});
|
||||
$("#file").val('');
|
||||
throw Error();
|
||||
});
|
||||
|
||||
var res = { url: fileurl, name: file.name };
|
||||
this.set.output.push(res)
|
||||
},
|
||||
async pasteFile(file) {
|
||||
if(file.size > 104857600){
|
||||
layer.alert('文件大小限制100M');return;
|
||||
}
|
||||
this.progress = 0;
|
||||
|
||||
var url,postdata,fileid,fileurl;
|
||||
|
||||
var loading = layer.msg('正在准备文件上传', {icon: 16,shade: 0.3,time: 0});
|
||||
await this.preUpload(file.name).then(data => {
|
||||
fileid = data.id;
|
||||
postdata = {'Cache-Control':'max-age=2592000', 'Content-Disposition':'attachment', 'OSSAccessKeyId':data.accessKeyId, 'Signature':data.signature, 'host':data.host, 'id':data.id, 'key':data.ossPath, 'policy':data.policy, 'success_action_status':'200'};
|
||||
url = 'https://' + data.host + '/';
|
||||
fileurl = 'https://' + data.cdnDomain + '/' + data.ossPath;
|
||||
}, error => {
|
||||
layer.close(loading);
|
||||
layer.alert(error, {icon: 2});
|
||||
$("#file").val('');
|
||||
throw Error();
|
||||
});
|
||||
|
||||
loading = layer.msg('正在上传文件,请稍候...', {icon: 16,shade: 0.3,time: 0});
|
||||
await this.uploadFile(url, postdata, file).then(() => {
|
||||
}, error => {
|
||||
layer.close(loading);
|
||||
layer.alert(error, {icon: 2});
|
||||
$("#file").val('');
|
||||
throw Error();
|
||||
});
|
||||
|
||||
loading = layer.msg('上传成功,正在保存', {icon: 16,shade: 0.3,time: 0});
|
||||
await this.completeUpload(fileid).then(data => {
|
||||
layer.close(loading);
|
||||
}, error => {
|
||||
layer.close(loading);
|
||||
layer.alert(error, {icon: 2});
|
||||
$("#file").val('');
|
||||
throw Error();
|
||||
});
|
||||
|
||||
var res = { url: fileurl, name: file.name };
|
||||
this.set.output.push(res)
|
||||
},
|
||||
copy(){
|
||||
if(!this.result) return;
|
||||
$("#output").select();
|
||||
document.execCommand("Copy");
|
||||
layer.msg('复制成功', {icon:1, time:600})
|
||||
},
|
||||
reset(){
|
||||
this.set.output = [];
|
||||
this.progress = 0;
|
||||
}
|
||||
},
|
||||
})
|
||||
</script>
|
||||
{/block}
|
||||
Reference in New Issue
Block a user