Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
L
loveisland
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
刘小敏
loveisland
Commits
7425af1c
Commit
7425af1c
authored
Jun 11, 2026
by
刘小敏
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
上传文件设置公共读权限;obs插件状态开;
parent
bf77467c
Hide whitespace changes
Inline
Side-by-side
Showing
6 changed files
with
354 additions
and
45 deletions
+354
-45
Index.php
addons/hwobs/controller/Index.php
+5
-1
info.ini
addons/hwobs/info.ini
+1
-1
addons.php
application/extra/addons.php
+56
-33
upload.php
application/extra/upload.php
+2
-2
spark.js
public/assets/addons/hwobs/js/spark.js
+0
-0
addons.js
public/assets/js/addons.js
+290
-8
No files found.
addons/hwobs/controller/Index.php
View file @
7425af1c
...
...
@@ -70,6 +70,7 @@ class Index extends Controller
$ret
=
$obs
->
initiateMultipartUpload
([
'Bucket'
=>
$config
[
'bucket'
],
'Key'
=>
$key
,
'ACL'
=>
'public-read'
,
// 设置公共读权限
]);
}
catch
(
\Exception
$e
)
{
$this
->
error
(
"上传失败"
);
...
...
@@ -84,12 +85,14 @@ class Index extends Controller
'Bucket'
=>
$config
[
'bucket'
],
'Key'
=>
$key
,
'FormParams'
=>
[
'acl'
=>
'public-read'
// 设置公共读权限
]
]);
$params
[
'key'
]
=
$key
;
$params
[
'AccessKeyId'
]
=
$config
[
'accessKey'
];
$params
[
'policy'
]
=
$signature
[
'Policy'
];
$params
[
'signature'
]
=
$signature
[
'Signature'
];
$params
[
'acl'
]
=
'public-read'
;
// 传递 ACL 参数给前端
}
$params
[
'headers'
]
=
$headers
;
$params
[
'date'
]
=
$date
;
...
...
@@ -237,7 +240,8 @@ class Index extends Controller
$ret
=
$obs
->
putObject
([
'Bucket'
=>
$config
[
'bucket'
],
'Key'
=>
ltrim
(
$attachment
->
url
,
'/'
),
'SourceFile'
=>
$filePath
'SourceFile'
=>
$filePath
,
'ACL'
=>
'public-read'
,
// 设置公共读权限
]);
//成功不做任何操作
}
catch
(
\Exception
$e
)
{
...
...
addons/hwobs/info.ini
View file @
7425af1c
...
...
@@ -4,7 +4,7 @@ intro = 使用华为OBS作为默认云储存
author
=
FastAdmin
website
=
version = 1.2.10
state
=
0
state
=
1
url
=
/addons/hwobs
license
=
regular
licenseto
=
114257
application/extra/addons.php
View file @
7425af1c
<?php
return
[
'autoload'
=>
false
,
'hooks'
=>
[
'epay_config_init'
=>
[
'epay'
,
],
'addon_action_begin'
=>
[
'epay'
,
],
'action_begin'
=>
[
'epay'
,
],
'upgrade'
=>
[
'shopro'
,
'simditor'
,
],
'app_init'
=>
[
'shopro'
,
],
'config_init'
=>
[
'shopro'
,
'simditor'
,
],
],
'route'
=>
[
'/example$'
=>
'example/index/index'
,
'/example/d/[:name]'
=>
'example/demo/index'
,
'/example/d1/[:name]'
=>
'example/demo/demo1'
,
'/example/d2/[:name]'
=>
'example/demo/demo2'
,
],
'priority'
=>
[],
'domain'
=>
''
,
];
return
array
(
'autoload'
=>
false
,
'hooks'
=>
array
(
'epay_config_init'
=>
array
(
0
=>
'epay'
,
),
'addon_action_begin'
=>
array
(
0
=>
'epay'
,
),
'action_begin'
=>
array
(
0
=>
'epay'
,
),
'module_init'
=>
array
(
0
=>
'hwobs'
,
),
'upload_config_init'
=>
array
(
0
=>
'hwobs'
,
),
'upload_delete'
=>
array
(
0
=>
'hwobs'
,
),
'app_init'
=>
array
(
0
=>
'hwobs'
,
1
=>
'shopro'
,
),
'upgrade'
=>
array
(
0
=>
'shopro'
,
1
=>
'simditor'
,
),
'config_init'
=>
array
(
0
=>
'shopro'
,
1
=>
'simditor'
,
),
),
'route'
=>
array
(
'/example$'
=>
'example/index/index'
,
'/example/d/[:name]'
=>
'example/demo/index'
,
'/example/d1/[:name]'
=>
'example/demo/demo1'
,
'/example/d2/[:name]'
=>
'example/demo/demo2'
,
),
'priority'
=>
array
(
),
'domain'
=>
''
,
);
application/extra/upload.php
View file @
7425af1c
...
...
@@ -7,9 +7,9 @@ return [
*/
'uploadurl'
=>
'ajax/upload'
,
/**
* CDN地址
* CDN地址
(华为云OBS域名)
*/
'cdnurl'
=>
''
,
'cdnurl'
=>
'
https://beevera.obs.cn-east-3.myhuaweicloud.com
'
,
/**
* 文件保存格式
*/
...
...
addons/hwobs/asset
s/js/spark.js
→
public/assets/addons/hwob
s/js/spark.js
View file @
7425af1c
File moved
public/assets/js/addons.js
View file @
7425af1c
...
...
@@ -34,6 +34,294 @@ define([], function () {
});
});
if
(
typeof
Config
.
upload
.
storage
!==
'undefined'
&&
Config
.
upload
.
storage
===
'hwobs'
)
{
require
([
'upload'
],
function
(
Upload
)
{
//获取文件MD5值
var
getFileMd5
=
function
(
file
,
cb
)
{
//如果savekey中未检测到md5,则无需获取文件md5,直接返回upload的uuid
if
(
!
Config
.
upload
.
savekey
.
match
(
/
\{(
file
)?
md5
\}
/
))
{
cb
&&
cb
(
file
.
upload
.
uuid
);
return
;
}
require
([
'../addons/hwobs/js/spark'
],
function
(
SparkMD5
)
{
var
blobSlice
=
File
.
prototype
.
slice
||
File
.
prototype
.
mozSlice
||
File
.
prototype
.
webkitSlice
,
chunkSize
=
10
*
1024
*
1024
,
chunks
=
Math
.
ceil
(
file
.
size
/
chunkSize
),
currentChunk
=
0
,
spark
=
new
SparkMD5
.
ArrayBuffer
(),
fileReader
=
new
FileReader
();
fileReader
.
onload
=
function
(
e
)
{
spark
.
append
(
e
.
target
.
result
);
currentChunk
++
;
if
(
currentChunk
<
chunks
)
{
loadNext
();
}
else
{
cb
&&
cb
(
spark
.
end
());
}
};
fileReader
.
onerror
=
function
()
{
console
.
warn
(
'文件读取错误'
);
};
function
loadNext
()
{
var
start
=
currentChunk
*
chunkSize
,
end
=
((
start
+
chunkSize
)
>=
file
.
size
)
?
file
.
size
:
start
+
chunkSize
;
fileReader
.
readAsArrayBuffer
(
blobSlice
.
call
(
file
,
start
,
end
));
}
loadNext
();
});
};
var
_onInit
=
Upload
.
events
.
onInit
;
//初始化中完成判断
Upload
.
events
.
onInit
=
function
()
{
_onInit
.
apply
(
this
,
Array
.
prototype
.
slice
.
apply
(
arguments
));
//如果上传接口不是hwobs,则不处理
if
(
this
.
options
.
url
!==
Config
.
upload
.
uploadurl
)
{
return
;
}
$
.
extend
(
this
.
options
,
{
//关闭自动处理队列功能
autoQueue
:
false
,
params
:
function
(
files
,
xhr
,
chunk
)
{
var
params
=
$
.
extend
({},
Config
.
upload
.
multipart
);
if
(
chunk
)
{
return
$
.
extend
({},
params
,
{
filesize
:
chunk
.
file
.
size
,
filename
:
chunk
.
file
.
name
,
chunkid
:
chunk
.
file
.
upload
.
uuid
,
chunkindex
:
chunk
.
index
,
chunkcount
:
chunk
.
file
.
upload
.
totalChunkCount
,
chunkfilesize
:
chunk
.
dataBlock
.
data
.
size
,
chunksize
:
this
.
options
.
chunkSize
,
width
:
chunk
.
file
.
width
||
0
,
height
:
chunk
.
file
.
height
||
0
,
type
:
chunk
.
file
.
type
,
uploadId
:
chunk
.
file
.
uploadId
,
key
:
chunk
.
file
.
key
,
});
}
return
params
;
},
chunkSuccess
:
function
(
chunk
,
file
,
response
)
{
var
etag
=
chunk
.
xhr
.
getResponseHeader
(
"ETag"
).
replace
(
/
(
^"
)
|
(
"$
)
/g
,
''
);
file
.
etags
=
file
.
etags
?
file
.
etags
:
[];
file
.
etags
[
chunk
.
index
]
=
etag
;
},
chunksUploaded
:
function
(
file
,
done
)
{
var
that
=
this
;
Fast
.
api
.
ajax
({
url
:
"/addons/hwobs/index/upload"
,
data
:
{
action
:
'merge'
,
filesize
:
file
.
size
,
filename
:
file
.
name
,
chunkid
:
file
.
upload
.
uuid
,
chunkcount
:
file
.
upload
.
totalChunkCount
,
md5
:
file
.
md5
,
key
:
file
.
key
,
uploadId
:
file
.
uploadId
,
etags
:
file
.
etags
,
category
:
file
.
category
||
''
,
hwobstoken
:
Config
.
upload
.
multipart
.
hwobstoken
,
},
},
function
(
data
,
ret
)
{
done
(
JSON
.
stringify
(
ret
));
return
false
;
},
function
(
data
,
ret
)
{
file
.
accepted
=
false
;
that
.
_errorProcessing
([
file
],
ret
.
msg
);
return
false
;
});
},
});
var
_success
=
this
.
options
.
success
;
//先移除已有的事件
this
.
off
(
"success"
,
_success
).
on
(
"success"
,
function
(
file
,
response
)
{
var
ret
=
{
code
:
0
,
msg
:
response
};
try
{
if
(
response
)
{
ret
=
typeof
response
===
'string'
?
JSON
.
parse
(
response
)
:
response
;
}
if
(
file
.
xhr
.
status
===
200
||
file
.
xhr
.
status
===
204
)
{
if
(
Config
.
upload
.
uploadmode
===
'client'
)
{
ret
=
{
code
:
1
,
data
:
{
url
:
'/'
+
file
.
key
}};
}
if
(
ret
.
code
==
1
)
{
var
url
=
ret
.
data
.
url
||
''
;
Fast
.
api
.
ajax
({
url
:
"/addons/hwobs/index/notify"
,
data
:
{
name
:
file
.
name
,
url
:
url
,
md5
:
file
.
md5
,
size
:
file
.
size
,
width
:
file
.
width
||
0
,
height
:
file
.
height
||
0
,
type
:
file
.
type
,
category
:
file
.
category
||
''
,
hwobstoken
:
Config
.
upload
.
multipart
.
hwobstoken
}
},
function
()
{
return
false
;
},
function
()
{
return
false
;
});
}
else
{
console
.
error
(
ret
);
}
}
else
{
console
.
error
(
file
.
xhr
);
}
}
catch
(
e
)
{
console
.
error
(
e
);
}
_success
.
call
(
this
,
file
,
ret
);
});
this
.
on
(
"addedfile"
,
function
(
file
)
{
var
that
=
this
;
setTimeout
(
function
()
{
if
(
file
.
status
===
'error'
)
{
return
;
}
getFileMd5
(
file
,
function
(
md5
)
{
var
chunk
=
that
.
options
.
chunking
&&
file
.
size
>
that
.
options
.
chunkSize
?
1
:
0
;
var
params
=
$
(
that
.
element
).
data
(
"params"
)
||
{};
var
category
=
typeof
params
.
category
!==
'undefined'
?
params
.
category
:
(
$
(
that
.
element
).
data
(
"category"
)
||
''
);
category
=
typeof
category
===
'function'
?
category
.
call
(
that
,
file
)
:
category
;
Fast
.
api
.
ajax
({
url
:
"/addons/hwobs/index/params"
,
data
:
{
method
:
'POST'
,
category
:
category
,
md5
:
md5
,
name
:
file
.
name
,
type
:
file
.
type
,
size
:
file
.
size
,
chunk
:
chunk
,
chunksize
:
that
.
options
.
chunkSize
,
hwobstoken
:
Config
.
upload
.
multipart
.
hwobstoken
},
},
function
(
data
)
{
file
.
md5
=
md5
;
file
.
id
=
data
.
id
;
file
.
key
=
data
.
key
;
file
.
date
=
data
.
date
;
file
.
uploadId
=
data
.
uploadId
;
file
.
policy
=
data
.
policy
;
file
.
signature
=
data
.
signature
;
file
.
partsAuthorization
=
data
.
partsAuthorization
;
file
.
headers
=
data
.
headers
;
delete
data
.
headers
;
file
.
params
=
data
;
file
.
category
=
category
;
if
(
file
.
status
!=
'error'
)
{
//开始上传
that
.
enqueueFile
(
file
);
}
else
{
that
.
removeFile
(
file
);
}
return
false
;
},
function
()
{
that
.
removeFile
(
file
);
});
});
},
0
);
});
if
(
Config
.
upload
.
uploadmode
===
'client'
)
{
var
_method
=
this
.
options
.
method
;
var
_url
=
this
.
options
.
url
;
this
.
options
.
method
=
function
(
files
)
{
if
(
files
[
0
].
upload
.
chunked
)
{
var
chunk
=
null
;
files
[
0
].
upload
.
chunks
.
forEach
(
function
(
item
)
{
if
(
item
.
status
===
'uploading'
)
{
chunk
=
item
;
}
});
if
(
!
chunk
)
{
return
"POST"
;
}
else
{
return
"PUT"
;
}
}
else
{
return
"POST"
;
}
return
_method
;
};
this
.
options
.
url
=
function
(
files
)
{
if
(
files
[
0
].
upload
.
chunked
)
{
var
chunk
=
null
;
files
[
0
].
upload
.
chunks
.
forEach
(
function
(
item
)
{
if
(
item
.
status
===
'uploading'
)
{
chunk
=
item
;
}
});
var
index
=
chunk
.
dataBlock
.
chunkIndex
;
this
.
options
.
headers
=
{
"Authorization"
:
files
[
0
][
'partsAuthorization'
][
index
],
"x-amz-date"
:
files
[
0
][
'date'
]};
if
(
!
chunk
)
{
return
Config
.
upload
.
uploadurl
+
"/"
+
files
[
0
].
key
+
"?uploadId="
+
files
[
0
].
uploadId
;
}
else
{
return
Config
.
upload
.
uploadurl
+
"/"
+
files
[
0
].
key
+
"?partNumber="
+
(
index
+
1
)
+
"&uploadId="
+
files
[
0
].
uploadId
;
}
}
return
_url
;
};
this
.
options
.
params
=
function
(
files
,
xhr
,
chunk
)
{
var
params
=
Config
.
upload
.
multipart
;
delete
params
.
category
;
if
(
chunk
)
{
return
$
.
extend
({},
params
,
{
filesize
:
chunk
.
file
.
size
,
filename
:
chunk
.
file
.
name
,
chunkid
:
chunk
.
file
.
upload
.
uuid
,
chunkindex
:
chunk
.
index
,
chunkcount
:
chunk
.
file
.
upload
.
totalChunkCount
,
chunkfilesize
:
chunk
.
dataBlock
.
data
.
size
,
width
:
chunk
.
file
.
width
||
0
,
height
:
chunk
.
file
.
height
||
0
,
type
:
chunk
.
file
.
type
,
});
}
else
{
var
retParams
=
$
.
extend
({},
params
,
files
[
0
].
params
||
{});
delete
retParams
.
hwobstoken
;
delete
retParams
.
date
;
delete
retParams
.
md5
;
// 确保 acl 参数存在
if
(
!
retParams
.
acl
)
{
retParams
.
acl
=
'public-read'
;
}
if
(
Config
.
upload
.
uploadmode
!==
'client'
)
{
params
.
category
=
files
[
0
].
category
||
''
;
}
return
retParams
;
}
};
this
.
on
(
"sending"
,
function
(
file
,
xhr
,
formData
)
{
var
that
=
this
;
var
_send
=
xhr
.
send
;
//确保 acl 参数存在
if
(
!
formData
.
get
(
'acl'
))
{
formData
.
append
(
'acl'
,
'public-read'
);
}
//仅允许部分字段
var
allowFields
=
[
'partNumber'
,
'uploadId'
,
'key'
,
'AccessKeyId'
,
'policy'
,
'signature'
,
'file'
,
'acl'
];
formData
.
forEach
(
function
(
value
,
key
)
{
if
(
allowFields
.
indexOf
(
key
)
<
0
)
{
formData
.
delete
(
key
);
}
});
if
(
file
.
upload
.
chunked
)
{
xhr
.
send
=
function
()
{
if
(
file
.
upload
.
chunked
)
{
var
chunk
=
null
;
file
.
upload
.
chunks
.
forEach
(
function
(
item
)
{
if
(
item
.
status
==
'uploading'
)
{
chunk
=
item
;
}
});
_send
.
call
(
xhr
,
chunk
.
dataBlock
.
data
);
}
};
}
});
}
};
});
}
if
(
Config
.
modulename
==
'admin'
&&
Config
.
controllername
==
'index'
&&
Config
.
actionname
==
'index'
)
{
require
.
config
({
paths
:
{
...
...
@@ -50,9 +338,6 @@ if (Config.modulename == 'admin' && Config.controllername == 'index' && Config.a
'ElementPlus'
:
{
deps
:
[
'css!../addons/shopro/libs/element-plus/index.css'
]
},
'ElementPlusIconsVue'
:
{
deps
:
[
'ElementPlusIconsVue3'
]
}
},
});
require
([
'vue3'
,
'ElementPlusIconsVue3'
],
function
(
Vue3
,
ElementPlusIconsVue3
)
{
...
...
@@ -78,11 +363,8 @@ if (Config.modulename == 'admin' && Config.controllername == 'index' && Config.a
const
app
=
createApp
({})
app
.
use
(
ElementPlus
)
if
(
ElementPlusIconsVue
&&
typeof
ElementPlusIconsVue
===
'object'
)
{
for
(
const
[
key
,
component
]
of
Object
.
entries
(
ElementPlusIconsVue
))
{
app
.
component
(
key
,
component
)
}
for
(
const
[
key
,
component
]
of
Object
.
entries
(
ElementPlusIconsVue
))
{
app
.
component
(
key
,
component
)
}
app
.
component
(
'sa-chat'
,
SaChat
)
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment