|
|
@@ -65,12 +65,13 @@
|
|
|
<p style="color: #666; margin-bottom: 12px; font-size: 0.95em;">每次仅保留一个附件;新上传会替换当前附件。</p>
|
|
|
|
|
|
<div class="attachment-upload-grid">
|
|
|
- <button type="button" class="btn btn-primary" onclick="document.getElementById('inpCameraPhoto').click()">拍照</button>
|
|
|
- <button type="button" class="btn btn-primary" onclick="document.getElementById('inpCameraVideo').click()">拍视频</button>
|
|
|
- <button type="button" class="btn btn-info" onclick="document.getElementById('inpGalleryImage').click()">相册图片</button>
|
|
|
- <button type="button" class="btn btn-info" onclick="document.getElementById('inpGalleryVideo').click()">相册视频</button>
|
|
|
- <button type="button" class="btn btn-warning" onclick="document.getElementById('inpAnyFile').click()">选择文件</button>
|
|
|
+ <button type="button" class="btn btn-primary" id="btnCameraPhoto">拍照</button>
|
|
|
+ <button type="button" class="btn btn-primary" id="btnCameraVideo">拍视频</button>
|
|
|
+ <button type="button" class="btn btn-info" id="btnGalleryImage">相册图片</button>
|
|
|
+ <button type="button" class="btn btn-info" id="btnGalleryVideo">相册视频</button>
|
|
|
+ <button type="button" class="btn btn-warning" id="btnAnyFile">选择文件</button>
|
|
|
</div>
|
|
|
+ <p id="uniappHint" style="display:none;color:#666;font-size:0.9em;margin-bottom:12px;">当前为 UniApp WebView,已使用原生拍照/录像/相册与上传通道。</p>
|
|
|
|
|
|
<input type="file" id="inpCameraPhoto" accept="image/*" capture="environment" style="display:none" />
|
|
|
<input type="file" id="inpCameraVideo" accept="video/*" capture="environment" style="display:none" />
|
|
|
@@ -89,6 +90,7 @@
|
|
|
{% endblock %}
|
|
|
|
|
|
{% block scripts %}
|
|
|
+<script src="{{ url_for('main.serve_templates_js', filename='im-sdk.js') }}"></script>
|
|
|
<script>
|
|
|
(function () {
|
|
|
let currentUrl = '';
|
|
|
@@ -97,6 +99,17 @@
|
|
|
const previewWrap = document.getElementById('previewWrap');
|
|
|
const previewActions = document.getElementById('previewActions');
|
|
|
const urlBox = document.getElementById('urlBox');
|
|
|
+ const uniappHint = document.getElementById('uniappHint');
|
|
|
+
|
|
|
+ function useUniNative() {
|
|
|
+ return window.imSDK && typeof imSDK.isUniAppIm === 'function' && imSDK.isUniAppIm();
|
|
|
+ }
|
|
|
+
|
|
|
+ function refreshUniHint() {
|
|
|
+ if (uniappHint && useUniNative()) uniappHint.style.display = 'block';
|
|
|
+ }
|
|
|
+ refreshUniHint();
|
|
|
+ setTimeout(refreshUniHint, 400);
|
|
|
|
|
|
function isImageName(name) {
|
|
|
return /\.(png|jpe?g|gif|bmp|webp|heic|heif)$/i.test(name || '');
|
|
|
@@ -112,6 +125,59 @@
|
|
|
});
|
|
|
}
|
|
|
|
|
|
+ function parseNativeUploadResponse(res) {
|
|
|
+ if (res == null) return null;
|
|
|
+ if (typeof res === 'string') {
|
|
|
+ try { return JSON.parse(res); } catch (e) { return null; }
|
|
|
+ }
|
|
|
+ if (typeof res.data === 'string') {
|
|
|
+ try { return JSON.parse(res.data); } catch (e) { return null; }
|
|
|
+ }
|
|
|
+ if (res.data && typeof res.data === 'object') return res.data;
|
|
|
+ return res;
|
|
|
+ }
|
|
|
+
|
|
|
+ function nativeTempPath(res) {
|
|
|
+ if (!res) return '';
|
|
|
+ if (res.tempFilePaths && res.tempFilePaths.length) return res.tempFilePaths[0];
|
|
|
+ if (res.tempFilePath) return res.tempFilePath;
|
|
|
+ if (res.apFilePath) return res.apFilePath;
|
|
|
+ return '';
|
|
|
+ }
|
|
|
+
|
|
|
+ function uploadNativePath(filePath) {
|
|
|
+ if (!filePath) {
|
|
|
+ showMessage('未获取到本地文件路径', 'error');
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ var uploadUrl = window.location.origin + '/api/attachment_test/upload';
|
|
|
+ var timeoutId = setTimeout(function () {
|
|
|
+ showLoading(false);
|
|
|
+ showMessage('上传超时,请检查 App 是否实现 uploadFile 与 Cookie', 'error');
|
|
|
+ }, 120000);
|
|
|
+ showLoading(true);
|
|
|
+ imSDK.uploadFile({
|
|
|
+ url: uploadUrl,
|
|
|
+ filePath: filePath,
|
|
|
+ name: 'file',
|
|
|
+ success: function (res) {
|
|
|
+ clearTimeout(timeoutId);
|
|
|
+ showLoading(false);
|
|
|
+ var data = parseNativeUploadResponse(res);
|
|
|
+ if (data && data.success) {
|
|
|
+ showMessage(data.message || '上传成功');
|
|
|
+ renderPreview({
|
|
|
+ has_file: true,
|
|
|
+ filename: data.filename,
|
|
|
+ url: data.url
|
|
|
+ });
|
|
|
+ } else {
|
|
|
+ showMessage((data && data.message) || '上传失败', 'error');
|
|
|
+ }
|
|
|
+ }
|
|
|
+ });
|
|
|
+ }
|
|
|
+
|
|
|
function renderPreview(data) {
|
|
|
currentUrl = data.url || '';
|
|
|
currentFilename = data.filename || '';
|
|
|
@@ -200,6 +266,73 @@
|
|
|
}
|
|
|
['inpCameraPhoto', 'inpCameraVideo', 'inpGalleryImage', 'inpGalleryVideo', 'inpAnyFile'].forEach(wireInput);
|
|
|
|
|
|
+ function triggerFileInput(id) {
|
|
|
+ var el = document.getElementById(id);
|
|
|
+ if (el) el.click();
|
|
|
+ }
|
|
|
+
|
|
|
+ document.getElementById('btnCameraPhoto').addEventListener('click', function () {
|
|
|
+ if (useUniNative()) {
|
|
|
+ imSDK.chooseImage({
|
|
|
+ count: 1,
|
|
|
+ sourceType: ['camera'],
|
|
|
+ success: function (res) { uploadNativePath(nativeTempPath(res)); }
|
|
|
+ });
|
|
|
+ } else {
|
|
|
+ triggerFileInput('inpCameraPhoto');
|
|
|
+ }
|
|
|
+ });
|
|
|
+ document.getElementById('btnCameraVideo').addEventListener('click', function () {
|
|
|
+ if (useUniNative()) {
|
|
|
+ imSDK.chooseVideo({
|
|
|
+ sourceType: ['camera'],
|
|
|
+ maxDuration: 120,
|
|
|
+ camera: 'back',
|
|
|
+ success: function (res) { uploadNativePath(nativeTempPath(res)); }
|
|
|
+ });
|
|
|
+ } else {
|
|
|
+ triggerFileInput('inpCameraVideo');
|
|
|
+ }
|
|
|
+ });
|
|
|
+ document.getElementById('btnGalleryImage').addEventListener('click', function () {
|
|
|
+ if (useUniNative()) {
|
|
|
+ imSDK.chooseImage({
|
|
|
+ count: 1,
|
|
|
+ sourceType: ['album'],
|
|
|
+ success: function (res) { uploadNativePath(nativeTempPath(res)); }
|
|
|
+ });
|
|
|
+ } else {
|
|
|
+ triggerFileInput('inpGalleryImage');
|
|
|
+ }
|
|
|
+ });
|
|
|
+ document.getElementById('btnGalleryVideo').addEventListener('click', function () {
|
|
|
+ if (useUniNative()) {
|
|
|
+ imSDK.chooseVideo({
|
|
|
+ sourceType: ['album'],
|
|
|
+ maxDuration: 120,
|
|
|
+ camera: 'back',
|
|
|
+ success: function (res) { uploadNativePath(nativeTempPath(res)); }
|
|
|
+ });
|
|
|
+ } else {
|
|
|
+ triggerFileInput('inpGalleryVideo');
|
|
|
+ }
|
|
|
+ });
|
|
|
+ document.getElementById('btnAnyFile').addEventListener('click', function () {
|
|
|
+ if (useUniNative()) {
|
|
|
+ imSDK.chooseFile({
|
|
|
+ count: 1,
|
|
|
+ extension: [],
|
|
|
+ success: function (res) {
|
|
|
+ var path = nativeTempPath(res);
|
|
|
+ if (!path && res.tempFiles && res.tempFiles[0]) path = res.tempFiles[0].path;
|
|
|
+ uploadNativePath(path);
|
|
|
+ }
|
|
|
+ });
|
|
|
+ } else {
|
|
|
+ triggerFileInput('inpAnyFile');
|
|
|
+ }
|
|
|
+ });
|
|
|
+
|
|
|
document.getElementById('btnShare').addEventListener('click', async function () {
|
|
|
if (!currentUrl) {
|
|
|
showMessage('没有可分享的链接', 'error');
|