@aggbond/my-file-preview-mobile 1.0.2 → 1.0.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
|
@@ -0,0 +1,607 @@
|
|
|
1
|
+
/*!
|
|
2
|
+
* ReadFilePopupMobile Component v1.0.3
|
|
3
|
+
* GitHub: https://github.com/aGG-Bond/ReadFilePopupMobile#readme
|
|
4
|
+
* (c) 2025 aGG-Bond
|
|
5
|
+
* @license MIT
|
|
6
|
+
*/
|
|
7
|
+
import Popup from "@aggbond/my-popup";
|
|
8
|
+
const myPopup = new Popup();
|
|
9
|
+
class FilePreview {
|
|
10
|
+
Configns;
|
|
11
|
+
constructor(options) {
|
|
12
|
+
this.Configns = Object.assign(
|
|
13
|
+
{
|
|
14
|
+
basePath: "/assets/pdfs/",
|
|
15
|
+
// 文件基础路径
|
|
16
|
+
modalId: "filePreviewModal",
|
|
17
|
+
// 模态框ID
|
|
18
|
+
contentId: "filePreviewContent",
|
|
19
|
+
// 内容容器ID
|
|
20
|
+
closeBtnId: "filePreviewCloseBtn",
|
|
21
|
+
// 关闭按钮ID
|
|
22
|
+
fileTypes: {
|
|
23
|
+
// 支持的文件类型
|
|
24
|
+
pdf: "application/pdf",
|
|
25
|
+
txt: "text/plain",
|
|
26
|
+
html: "text/html",
|
|
27
|
+
"1": "richTextFile",
|
|
28
|
+
// 富文本
|
|
29
|
+
"2": "choosePdfFile",
|
|
30
|
+
// pdf
|
|
31
|
+
"3": "quotePdfFile"
|
|
32
|
+
// 引用文本
|
|
33
|
+
// 可以扩展更多类型
|
|
34
|
+
},
|
|
35
|
+
fileKeyNameConfign: {
|
|
36
|
+
// 配置文件键值key 免于不同格式的数据转换 isConfignFileKeyName 为true,则fielKeyNameConfign为required;
|
|
37
|
+
fileTitle: "name",
|
|
38
|
+
//标题
|
|
39
|
+
fileType: "doc_type",
|
|
40
|
+
// 文件类型 1 富文本 2 pdf 3 引用文本,引用文本通常有多份
|
|
41
|
+
filePdfUrl: "pdf_url",
|
|
42
|
+
// pdf地址 绝对路径
|
|
43
|
+
fileRichContent: "content_text",
|
|
44
|
+
// 富文本内容
|
|
45
|
+
fileArr: "com_terms"
|
|
46
|
+
// 可以扩展更多类型
|
|
47
|
+
},
|
|
48
|
+
isConfignFileKeyName: false,
|
|
49
|
+
// 是否需要转换文件key 默认为false
|
|
50
|
+
isDrawFileList: false,
|
|
51
|
+
// 是否需要绘制阅读文件列表
|
|
52
|
+
listObj: {
|
|
53
|
+
listId: "",
|
|
54
|
+
// 列表容器ID require
|
|
55
|
+
fileList: [
|
|
56
|
+
// 文件列表 require
|
|
57
|
+
{
|
|
58
|
+
name: "默认标题",
|
|
59
|
+
//标题
|
|
60
|
+
file_type: 3,
|
|
61
|
+
// 文件类型 1 富文本 2 pdf 3 引用文本,引用文本通常有多份
|
|
62
|
+
pdf_url: "",
|
|
63
|
+
// pdf地址 绝对路径
|
|
64
|
+
content_text: "",
|
|
65
|
+
// 富文本内容
|
|
66
|
+
com_terms: [
|
|
67
|
+
// 多份文件
|
|
68
|
+
{
|
|
69
|
+
name: "默认标题",
|
|
70
|
+
//标题
|
|
71
|
+
pdf_url: "clause_pdf: https://showFile.com/address.pdf",
|
|
72
|
+
// pdf地址
|
|
73
|
+
content_text: "disclaimer<p><strong>默认文件</strong></p>"
|
|
74
|
+
// 富文本内容
|
|
75
|
+
}
|
|
76
|
+
],
|
|
77
|
+
styleStr: {
|
|
78
|
+
color: "red",
|
|
79
|
+
"font-weight": "bold"
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
],
|
|
83
|
+
fileStyle: {
|
|
84
|
+
color: "red",
|
|
85
|
+
"font-weight": "bold"
|
|
86
|
+
},
|
|
87
|
+
// 文件样式span
|
|
88
|
+
isCheckButton: false,
|
|
89
|
+
// 列表是否需要复选框
|
|
90
|
+
isCoerceReadPopup: true,
|
|
91
|
+
// 是否强制阅读弹窗
|
|
92
|
+
checkCallBack: (isChecked) => {
|
|
93
|
+
console.log("复选框状态改变:", isChecked);
|
|
94
|
+
},
|
|
95
|
+
// 复选框回调函数
|
|
96
|
+
listText: "更多详情请阅读",
|
|
97
|
+
checkButtonID: "ReadFileCheckBox"
|
|
98
|
+
},
|
|
99
|
+
// 强制阅读弹窗参数
|
|
100
|
+
coerceReadList: {
|
|
101
|
+
titleText: "请阅读并同意以下文件",
|
|
102
|
+
fileList: [
|
|
103
|
+
// 文件列表 require
|
|
104
|
+
{
|
|
105
|
+
name: "默认标题",
|
|
106
|
+
//标题
|
|
107
|
+
file_type: 3,
|
|
108
|
+
// 文件类型 1 富文本 2 pdf 3 引用文本,引用文本通常有多份
|
|
109
|
+
pdf_url: "",
|
|
110
|
+
// pdf地址 绝对路径
|
|
111
|
+
content_text: "",
|
|
112
|
+
// 富文本内容
|
|
113
|
+
com_terms: [
|
|
114
|
+
// 多份文件
|
|
115
|
+
{
|
|
116
|
+
name: "默认标题",
|
|
117
|
+
//标题
|
|
118
|
+
pdf_url: "clause_pdf: https://showFile.com/address.pdf",
|
|
119
|
+
// pdf地址
|
|
120
|
+
content_text: "disclaimer<p><strong>默认文件</strong></p>"
|
|
121
|
+
// 富文本内容
|
|
122
|
+
}
|
|
123
|
+
],
|
|
124
|
+
styleStr: {
|
|
125
|
+
color: "red",
|
|
126
|
+
"font-weight": "bold"
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
],
|
|
130
|
+
fileStyle: {
|
|
131
|
+
color: "red",
|
|
132
|
+
"font-weight": "bold"
|
|
133
|
+
},
|
|
134
|
+
btnArr: ["确认已阅读并同意", "拒绝"],
|
|
135
|
+
btnStyle: [{ color: "red" }, { color: "gray" }],
|
|
136
|
+
btnBoxStyle: {},
|
|
137
|
+
showProgressInButton: false,
|
|
138
|
+
coerceCallBack: [
|
|
139
|
+
(control, buttonIndex) => {
|
|
140
|
+
console.log("btn[0]强制阅读弹窗结果:", control, buttonIndex);
|
|
141
|
+
},
|
|
142
|
+
(control, buttonIndex) => {
|
|
143
|
+
console.log("btn[1]强制阅读弹窗结果:", control, buttonIndex);
|
|
144
|
+
}
|
|
145
|
+
]
|
|
146
|
+
},
|
|
147
|
+
isBindFileClick: false
|
|
148
|
+
// 是否需要绑定文件点击事件
|
|
149
|
+
},
|
|
150
|
+
options
|
|
151
|
+
);
|
|
152
|
+
this.initModal();
|
|
153
|
+
}
|
|
154
|
+
// 初始化
|
|
155
|
+
initModal() {
|
|
156
|
+
const {
|
|
157
|
+
isDrawFileList,
|
|
158
|
+
listObj,
|
|
159
|
+
isBindFileClick,
|
|
160
|
+
isConfignFileKeyName,
|
|
161
|
+
coerceReadList
|
|
162
|
+
} = this.Configns;
|
|
163
|
+
if (isConfignFileKeyName && listObj.fileList && listObj.fileList.length > 0) {
|
|
164
|
+
this.Configns.listObj.fileList = this.dataChange(listObj.fileList);
|
|
165
|
+
}
|
|
166
|
+
if (coerceReadList.fileList && coerceReadList.fileList.length > 0) {
|
|
167
|
+
this.Configns.coerceReadList.fileList = this.dataChange(
|
|
168
|
+
coerceReadList.fileList
|
|
169
|
+
);
|
|
170
|
+
}
|
|
171
|
+
isDrawFileList && this.drawReadFileList(listObj);
|
|
172
|
+
isBindFileClick && this.bindFileClick(listObj.listId, void 0);
|
|
173
|
+
}
|
|
174
|
+
// 数据转换
|
|
175
|
+
dataChange(data) {
|
|
176
|
+
if (!this.Configns.fileKeyNameConfign)
|
|
177
|
+
throw new Error("请传入文件keyNameConfign");
|
|
178
|
+
const { fileTitle, filePdfUrl, fileRichContent, fileArr, fileType } = this.Configns.fileKeyNameConfign;
|
|
179
|
+
if (!fileTitle || !filePdfUrl || !fileRichContent || !fileArr)
|
|
180
|
+
throw new Error("请传入文件keyNameConfign的参数");
|
|
181
|
+
data.forEach((item) => {
|
|
182
|
+
item.name = item[fileTitle];
|
|
183
|
+
item.file_type = item[fileType];
|
|
184
|
+
item.pdf_url = item[filePdfUrl];
|
|
185
|
+
item.content_text = item[fileRichContent];
|
|
186
|
+
item.com_terms = item[fileArr];
|
|
187
|
+
});
|
|
188
|
+
return data;
|
|
189
|
+
}
|
|
190
|
+
//渲染阅读文件列表
|
|
191
|
+
drawReadFileList(listObj) {
|
|
192
|
+
const {
|
|
193
|
+
listId: ID,
|
|
194
|
+
fileList,
|
|
195
|
+
isCheckButton,
|
|
196
|
+
isCoerceReadPopup,
|
|
197
|
+
checkCallBack,
|
|
198
|
+
listText,
|
|
199
|
+
checkButtonID,
|
|
200
|
+
fileStyle
|
|
201
|
+
} = listObj;
|
|
202
|
+
if (!ID) throw new Error("请传入需要添加的dom ID");
|
|
203
|
+
if (fileList.length < 1) throw new Error("请传入需要渲染的文件数据");
|
|
204
|
+
let html = `${isCheckButton ? `<input type="checkbox" id="${checkButtonID}" />` : ""}${listText}`;
|
|
205
|
+
for (let i = 0, len = fileList.length; i < len; i++) {
|
|
206
|
+
const { name, pdf_url, file_type, styleStr } = fileList[i];
|
|
207
|
+
const type = file_type || this.judgeFileType({ type: "", file: fileList[i], index: i });
|
|
208
|
+
html += `<span class="pdfsee item-contract" data-pdf="${file_type == 2 ? pdf_url : ""}" data-title="${name}" data-index="${i}" data-type="${type}" style="${this.objToStr(
|
|
209
|
+
styleStr ? styleStr : fileStyle || {}
|
|
210
|
+
)}">${name}</span>`;
|
|
211
|
+
}
|
|
212
|
+
const element = document.querySelector(ID);
|
|
213
|
+
if (!element) throw new Error("未找到元素" + ID);
|
|
214
|
+
element.insertAdjacentHTML("beforeend", html);
|
|
215
|
+
if (isCheckButton && checkButtonID) {
|
|
216
|
+
const inputBox = document.getElementById(checkButtonID);
|
|
217
|
+
if (inputBox) {
|
|
218
|
+
inputBox.addEventListener("click", (e) => {
|
|
219
|
+
const target = e.target;
|
|
220
|
+
const isChecked = target.checked;
|
|
221
|
+
checkCallBack && checkCallBack(isChecked);
|
|
222
|
+
isChecked && isCoerceReadPopup && this.openCoerceReadPopup();
|
|
223
|
+
});
|
|
224
|
+
}
|
|
225
|
+
}
|
|
226
|
+
}
|
|
227
|
+
// 对象转换为字符串
|
|
228
|
+
objToStr(obj) {
|
|
229
|
+
return Object.entries(obj).reduce(
|
|
230
|
+
(str, [key, value]) => `${str}${key}:${value};`,
|
|
231
|
+
""
|
|
232
|
+
);
|
|
233
|
+
}
|
|
234
|
+
// 判断文件格式
|
|
235
|
+
judgeFileType(params) {
|
|
236
|
+
const { type, file, index, fromChooseList = false, isCoerce = false } = params;
|
|
237
|
+
if (!file) throw new Error("未找到对应文件信息 file is not defined");
|
|
238
|
+
let html;
|
|
239
|
+
switch (type) {
|
|
240
|
+
case "1":
|
|
241
|
+
case 1:
|
|
242
|
+
html = this.richTextFile({ file, fromChooseList, isCoerce });
|
|
243
|
+
break;
|
|
244
|
+
case "2":
|
|
245
|
+
case 2:
|
|
246
|
+
html = this.quotePdfFile({ file, fromChooseList, isCoerce });
|
|
247
|
+
break;
|
|
248
|
+
case "3":
|
|
249
|
+
case 3:
|
|
250
|
+
html = this.choosePdfFile({ file, index, fromChooseList, isCoerce });
|
|
251
|
+
break;
|
|
252
|
+
default:
|
|
253
|
+
const { com_terms, content_text, pdf_url } = file;
|
|
254
|
+
if (com_terms && com_terms.length > 0) {
|
|
255
|
+
return 3;
|
|
256
|
+
} else if (content_text) {
|
|
257
|
+
return 1;
|
|
258
|
+
} else if (pdf_url) {
|
|
259
|
+
return 2;
|
|
260
|
+
}
|
|
261
|
+
break;
|
|
262
|
+
}
|
|
263
|
+
if (isCoerce) return html;
|
|
264
|
+
}
|
|
265
|
+
// 富文本文件
|
|
266
|
+
richTextFile(params) {
|
|
267
|
+
const { file: filebox, fromChooseList = false, isCoerce = false } = params;
|
|
268
|
+
const { name: title, content_text: text } = filebox;
|
|
269
|
+
const popupInstance = fromChooseList ? new Popup() : myPopup;
|
|
270
|
+
if (isCoerce) return text;
|
|
271
|
+
popupInstance.showBottomPopup({
|
|
272
|
+
title,
|
|
273
|
+
content: text,
|
|
274
|
+
contentStyle: {},
|
|
275
|
+
titleStyle: {
|
|
276
|
+
fontWeight: "bold"
|
|
277
|
+
},
|
|
278
|
+
// btns: ['确定'],
|
|
279
|
+
callbacks: [function() {
|
|
280
|
+
console.log("richTextFile callbacks");
|
|
281
|
+
}]
|
|
282
|
+
});
|
|
283
|
+
}
|
|
284
|
+
// 多分pdf选择
|
|
285
|
+
choosePdfFile(params) {
|
|
286
|
+
const { file: filebox, index: _index, fromChooseList = false, isCoerce = false } = params;
|
|
287
|
+
console.log("filebox", filebox);
|
|
288
|
+
const { com_terms: fileArr = [], name: title } = filebox;
|
|
289
|
+
const popupInstance = fromChooseList ? new Popup() : myPopup;
|
|
290
|
+
let html = "<dl class='ChoosePdfFileList' style='margin:0;padding:0;'>";
|
|
291
|
+
for (let i = 0; i < fileArr.length; i++) {
|
|
292
|
+
const { pdf_url, name, file_type } = fileArr[i];
|
|
293
|
+
const type = file_type || this.judgeFileType({ type: "", file: fileArr[i], index: i });
|
|
294
|
+
html += `<dd class="cl" data-pdf="${pdf_url}" data-title="${name}" data-index="${i}" style="margin:0">
|
|
295
|
+
<span class="pdfsee item-contract" data-pdf="${pdf_url}" data-title="${name}" data-index="${i}" data-type="${type}">${name}</span>
|
|
296
|
+
</dd>`;
|
|
297
|
+
}
|
|
298
|
+
html += "</dl>";
|
|
299
|
+
if (isCoerce) return html;
|
|
300
|
+
popupInstance.showBottomPopup({
|
|
301
|
+
title,
|
|
302
|
+
content: html,
|
|
303
|
+
contentStyle: {},
|
|
304
|
+
titleStyle: {
|
|
305
|
+
fontWeight: "bold"
|
|
306
|
+
},
|
|
307
|
+
// btns: ['确定'],
|
|
308
|
+
callbacks: [function() {
|
|
309
|
+
console.log("choosePDffile callbacks");
|
|
310
|
+
}]
|
|
311
|
+
});
|
|
312
|
+
this.bindFileClick(".ChoosePdfFileList", fileArr);
|
|
313
|
+
}
|
|
314
|
+
// 引用条款 pdf文件
|
|
315
|
+
quotePdfFile(params) {
|
|
316
|
+
const { file: filebox, fromChooseList = false, isControl = false, isCoerce = false } = params;
|
|
317
|
+
const { pdf_url: url, name: title, divType = "iframe" } = filebox;
|
|
318
|
+
const popupInstance = fromChooseList ? new Popup() : myPopup;
|
|
319
|
+
const modifiedUrl = isControl ? url : `${url}#toolbar=0&navpanes=0&scrollbar=0`;
|
|
320
|
+
const iframeHtml = `<iframe src="${modifiedUrl}" width="100%" height="800" style="border:none;"></iframe>`;
|
|
321
|
+
const objectHtml = `<object data="${modifiedUrl}" type="application/pdf" width="100%" height="800">
|
|
322
|
+
<p>您的浏览器不支持PDF查看。请<a href="${modifiedUrl}">下载文件</a>。</p></object>`;
|
|
323
|
+
const embedHtml = `<embed src="${modifiedUrl}" type="application/pdf" width="100%" height="800" />`;
|
|
324
|
+
const html = divType === "iframe" ? iframeHtml : divType === "object" ? objectHtml : embedHtml;
|
|
325
|
+
if (isCoerce) return html;
|
|
326
|
+
popupInstance.showBottomPopup({
|
|
327
|
+
title,
|
|
328
|
+
content: html,
|
|
329
|
+
contentStyle: {
|
|
330
|
+
// maxHeight: '100vh',
|
|
331
|
+
// overflow: 'hidden auto'
|
|
332
|
+
padding: "0"
|
|
333
|
+
},
|
|
334
|
+
contentBoxStyle: {
|
|
335
|
+
maxHeight: "100vh"
|
|
336
|
+
},
|
|
337
|
+
titleStyle: {
|
|
338
|
+
fontWeight: "bold"
|
|
339
|
+
},
|
|
340
|
+
callbacks: [function() {
|
|
341
|
+
console.log("quotePdfFile callback");
|
|
342
|
+
}]
|
|
343
|
+
});
|
|
344
|
+
return;
|
|
345
|
+
}
|
|
346
|
+
// 绑定文件点击事件
|
|
347
|
+
bindFileClick(containerSelector, fileArr) {
|
|
348
|
+
const container = document.querySelector(containerSelector);
|
|
349
|
+
if (!container) throw new Error("容器未找到:" + containerSelector);
|
|
350
|
+
container.addEventListener("click", (event) => {
|
|
351
|
+
const target = event.target;
|
|
352
|
+
if (target.tagName.toLowerCase() === "span") {
|
|
353
|
+
const dataset = target.dataset;
|
|
354
|
+
const type = dataset.type;
|
|
355
|
+
const index = dataset.index ? parseInt(dataset.index) : void 0;
|
|
356
|
+
if (index !== void 0) {
|
|
357
|
+
const file = fileArr?.[index] || this.Configns?.listObj?.fileList?.[index];
|
|
358
|
+
console.log("read", index, type, file);
|
|
359
|
+
if (type !== void 0 && file) {
|
|
360
|
+
this.judgeFileType({ type, file, index, fromChooseList: !!fileArr });
|
|
361
|
+
}
|
|
362
|
+
}
|
|
363
|
+
}
|
|
364
|
+
});
|
|
365
|
+
}
|
|
366
|
+
// 渲染强制阅读文件内容
|
|
367
|
+
openCoerceReadPopup() {
|
|
368
|
+
const {
|
|
369
|
+
fileList,
|
|
370
|
+
btnArr = ["同意并继续"],
|
|
371
|
+
btnStyle,
|
|
372
|
+
btnBoxStyle,
|
|
373
|
+
coerceCallBack,
|
|
374
|
+
titleText,
|
|
375
|
+
showProgressInButton
|
|
376
|
+
} = this.Configns.coerceReadList;
|
|
377
|
+
if (fileList.length === 0) throw new Error("fileList不能为空");
|
|
378
|
+
let currentIndex = 0;
|
|
379
|
+
let customButtonTitles = null;
|
|
380
|
+
let visitedIndices = [0];
|
|
381
|
+
const showNextFile = (_btnTitleArr) => {
|
|
382
|
+
if (currentIndex >= fileList.length) return;
|
|
383
|
+
const file = fileList[currentIndex];
|
|
384
|
+
const isLastFile = currentIndex === fileList.length - 1;
|
|
385
|
+
if (!file.file_type) {
|
|
386
|
+
file.file_type = this.judgeFileType({
|
|
387
|
+
type: "",
|
|
388
|
+
file,
|
|
389
|
+
isCoerce: true
|
|
390
|
+
});
|
|
391
|
+
}
|
|
392
|
+
const fileContent = this.judgeFileType({
|
|
393
|
+
type: file.file_type,
|
|
394
|
+
file,
|
|
395
|
+
isCoerce: true
|
|
396
|
+
});
|
|
397
|
+
const control = {
|
|
398
|
+
next: () => {
|
|
399
|
+
customButtonTitles = null;
|
|
400
|
+
currentIndex++;
|
|
401
|
+
if (!visitedIndices.includes(currentIndex)) {
|
|
402
|
+
visitedIndices.push(currentIndex);
|
|
403
|
+
}
|
|
404
|
+
showNextFile();
|
|
405
|
+
},
|
|
406
|
+
prev: () => {
|
|
407
|
+
customButtonTitles = null;
|
|
408
|
+
if (currentIndex > 0) {
|
|
409
|
+
currentIndex--;
|
|
410
|
+
showNextFile();
|
|
411
|
+
}
|
|
412
|
+
},
|
|
413
|
+
close: () => {
|
|
414
|
+
myPopup.close();
|
|
415
|
+
},
|
|
416
|
+
getCurrentIndex: () => currentIndex,
|
|
417
|
+
// 获取当前索引
|
|
418
|
+
getFileList: () => [...fileList],
|
|
419
|
+
// 返回副本防止外部修改
|
|
420
|
+
isLastFile: () => isLastFile,
|
|
421
|
+
// 是否为最后一份文件
|
|
422
|
+
setButtonTitles: (titles) => {
|
|
423
|
+
if (Array.isArray(titles)) {
|
|
424
|
+
customButtonTitles = titles;
|
|
425
|
+
}
|
|
426
|
+
},
|
|
427
|
+
// 获取已访问的文件索引列表
|
|
428
|
+
getVisitedIndices: () => [...visitedIndices],
|
|
429
|
+
// 跳转到指定文件索引
|
|
430
|
+
goTo: (index) => {
|
|
431
|
+
if (index >= 0 && index < fileList.length) {
|
|
432
|
+
customButtonTitles = null;
|
|
433
|
+
currentIndex = index;
|
|
434
|
+
if (!visitedIndices.includes(currentIndex)) {
|
|
435
|
+
visitedIndices.push(currentIndex);
|
|
436
|
+
}
|
|
437
|
+
showNextFile();
|
|
438
|
+
}
|
|
439
|
+
},
|
|
440
|
+
// 控制复选框选中状态
|
|
441
|
+
setCheckboxChecked: (isChecked) => {
|
|
442
|
+
const checkboxId = this.Configns.listObj?.checkButtonID;
|
|
443
|
+
if (checkboxId) {
|
|
444
|
+
const checkbox = document.getElementById(checkboxId);
|
|
445
|
+
if (checkbox) {
|
|
446
|
+
checkbox.checked = isChecked;
|
|
447
|
+
const event = new Event("change");
|
|
448
|
+
checkbox.dispatchEvent(event);
|
|
449
|
+
}
|
|
450
|
+
}
|
|
451
|
+
},
|
|
452
|
+
// 获取复选框当前状态
|
|
453
|
+
isCheckboxChecked: () => {
|
|
454
|
+
const checkboxId = this.Configns.listObj?.checkButtonID;
|
|
455
|
+
if (checkboxId) {
|
|
456
|
+
const checkbox = document.getElementById(checkboxId);
|
|
457
|
+
return checkbox ? checkbox.checked : false;
|
|
458
|
+
}
|
|
459
|
+
return false;
|
|
460
|
+
}
|
|
461
|
+
};
|
|
462
|
+
const callbacks = [];
|
|
463
|
+
if (btnArr && btnArr.length > 0) {
|
|
464
|
+
for (let i = 0; i < btnArr.length; i++) {
|
|
465
|
+
callbacks.push(
|
|
466
|
+
/* @__PURE__ */ ((buttonIndex) => {
|
|
467
|
+
return () => {
|
|
468
|
+
if (typeof coerceCallBack === "function") {
|
|
469
|
+
return coerceCallBack(control, buttonIndex);
|
|
470
|
+
} else if (Array.isArray(coerceCallBack) && typeof coerceCallBack[buttonIndex] === "function") {
|
|
471
|
+
return coerceCallBack[buttonIndex](control);
|
|
472
|
+
}
|
|
473
|
+
};
|
|
474
|
+
})(i)
|
|
475
|
+
);
|
|
476
|
+
}
|
|
477
|
+
}
|
|
478
|
+
let finalButtons = customButtonTitles || btnArr;
|
|
479
|
+
if (showProgressInButton !== false && !customButtonTitles && btnArr && btnArr.length > 0) {
|
|
480
|
+
const currentDisplayIndex = currentIndex + 1;
|
|
481
|
+
const totalLength = fileList.length;
|
|
482
|
+
finalButtons = [...btnArr];
|
|
483
|
+
if (typeof showProgressInButton === "number") {
|
|
484
|
+
const buttonIndex = showProgressInButton;
|
|
485
|
+
if (buttonIndex >= 0 && buttonIndex < finalButtons.length) {
|
|
486
|
+
finalButtons[buttonIndex] = `${btnArr[buttonIndex]}(${currentDisplayIndex}/${totalLength})`;
|
|
487
|
+
}
|
|
488
|
+
} else if (showProgressInButton === true) {
|
|
489
|
+
finalButtons[0] = `${btnArr[0]}(${currentDisplayIndex}/${totalLength})`;
|
|
490
|
+
}
|
|
491
|
+
}
|
|
492
|
+
console.log("showNextFile", btnArr, finalButtons);
|
|
493
|
+
const popupConfig = {
|
|
494
|
+
title: file.name || `${titleText || "文件"} (${currentIndex + 1}/${fileList.length})`,
|
|
495
|
+
content: fileContent,
|
|
496
|
+
btnBoxStyle: btnBoxStyle || {
|
|
497
|
+
display: "flex",
|
|
498
|
+
justifyContent: "space-around",
|
|
499
|
+
alignItems: "center",
|
|
500
|
+
padding: "0 2.4vw"
|
|
501
|
+
},
|
|
502
|
+
btns: finalButtons,
|
|
503
|
+
btnStyle: btnStyle || [
|
|
504
|
+
{
|
|
505
|
+
display: "inline-block",
|
|
506
|
+
width: "91vw",
|
|
507
|
+
height: "10.667vw",
|
|
508
|
+
color: "#fff",
|
|
509
|
+
backgroundColor: "#29AEEF",
|
|
510
|
+
borderRadius: "8.533vw",
|
|
511
|
+
textAlign: "center",
|
|
512
|
+
lineHeight: "10.667vw",
|
|
513
|
+
cursor: "pointer",
|
|
514
|
+
margin: "5.33vw auto"
|
|
515
|
+
},
|
|
516
|
+
{
|
|
517
|
+
display: "inline-block",
|
|
518
|
+
width: "91vw",
|
|
519
|
+
height: "10.667vw",
|
|
520
|
+
color: "#fff",
|
|
521
|
+
backgroundColor: "#29AEEF",
|
|
522
|
+
borderRadius: "8.533vw",
|
|
523
|
+
textAlign: "center",
|
|
524
|
+
lineHeight: "10.667vw",
|
|
525
|
+
cursor: "pointer",
|
|
526
|
+
margin: "5.33vw auto"
|
|
527
|
+
}
|
|
528
|
+
],
|
|
529
|
+
callbacks
|
|
530
|
+
};
|
|
531
|
+
control.setCheckboxChecked(false);
|
|
532
|
+
myPopup.showBottomPopup(popupConfig);
|
|
533
|
+
if (file.file_type === 3 && file.com_terms) {
|
|
534
|
+
this.bindFileClick(".ChoosePdfFileList", file.com_terms);
|
|
535
|
+
}
|
|
536
|
+
};
|
|
537
|
+
showNextFile();
|
|
538
|
+
}
|
|
539
|
+
// 加载文件内容
|
|
540
|
+
loadFile(filePath) {
|
|
541
|
+
const fileExtension = filePath.split(".").pop()?.toLowerCase();
|
|
542
|
+
if (!fileExtension) {
|
|
543
|
+
console.error("无法识别文件类型:", filePath);
|
|
544
|
+
return;
|
|
545
|
+
}
|
|
546
|
+
const contentType = this.Configns.fileTypes[fileExtension];
|
|
547
|
+
if (!contentType) {
|
|
548
|
+
console.error("不支持的文件类型:", fileExtension);
|
|
549
|
+
return;
|
|
550
|
+
}
|
|
551
|
+
const fileName = filePath.split("/").pop() || "文件";
|
|
552
|
+
if (contentType === "application/pdf") {
|
|
553
|
+
myPopup.showBottomPopup({
|
|
554
|
+
title: fileName,
|
|
555
|
+
content: `<iframe src="${filePath}" width="100%" height="600px" style="border:none;"></iframe>`,
|
|
556
|
+
contentStyle: {},
|
|
557
|
+
titleStyle: {
|
|
558
|
+
fontWeight: "bold"
|
|
559
|
+
},
|
|
560
|
+
// btns: ['确定'],
|
|
561
|
+
callbacks: [function() {
|
|
562
|
+
console.log("loadFile callback");
|
|
563
|
+
}]
|
|
564
|
+
});
|
|
565
|
+
} else {
|
|
566
|
+
fetch(filePath).then((response) => {
|
|
567
|
+
if (!response.ok) {
|
|
568
|
+
throw new Error(`HTTP error! status: ${response.status}`);
|
|
569
|
+
}
|
|
570
|
+
return response.text();
|
|
571
|
+
}).then((data) => {
|
|
572
|
+
let content;
|
|
573
|
+
if (fileExtension === "html" || fileExtension === "htm") {
|
|
574
|
+
content = `<div style="max-height: 70vh; overflow-y: auto;">${data}</div>`;
|
|
575
|
+
} else {
|
|
576
|
+
content = `<pre style="white-space: pre-wrap; word-wrap: break-word; max-height: 70vh; overflow-y: auto;">${data}</pre>`;
|
|
577
|
+
}
|
|
578
|
+
myPopup.showBottomPopup({
|
|
579
|
+
title: fileName,
|
|
580
|
+
content,
|
|
581
|
+
contentStyle: {
|
|
582
|
+
maxHeight: "70vh",
|
|
583
|
+
overflow: "auto"
|
|
584
|
+
},
|
|
585
|
+
titleStyle: {
|
|
586
|
+
fontWeight: "bold"
|
|
587
|
+
},
|
|
588
|
+
callbacks: [function() {
|
|
589
|
+
console.log("文件内容弹窗关闭");
|
|
590
|
+
}]
|
|
591
|
+
});
|
|
592
|
+
}).catch((error) => {
|
|
593
|
+
console.error("文件加载失败:", error);
|
|
594
|
+
myPopup.showBottomPopup({
|
|
595
|
+
title: "文件加载失败",
|
|
596
|
+
content: `<p style="color: red;">无法加载文件: ${filePath}</p><p>错误详情: ${error.message}</p>`,
|
|
597
|
+
callbacks: [function() {
|
|
598
|
+
console.log("错误提示弹窗关闭");
|
|
599
|
+
}]
|
|
600
|
+
});
|
|
601
|
+
});
|
|
602
|
+
}
|
|
603
|
+
}
|
|
604
|
+
}
|
|
605
|
+
export {
|
|
606
|
+
FilePreview as default
|
|
607
|
+
};
|
|
@@ -1,8 +1,7 @@
|
|
|
1
1
|
/*!
|
|
2
|
-
*
|
|
2
|
+
* ReadFilePopupMobile Component v1.0.3
|
|
3
3
|
* GitHub: https://github.com/aGG-Bond/ReadFilePopupMobile#readme
|
|
4
4
|
* (c) 2025 aGG-Bond
|
|
5
5
|
* @license MIT
|
|
6
6
|
*/
|
|
7
|
-
import
|
|
8
|
-
/* @__PURE__ */(e=>()=>"function"==typeof l?l(m,e):Array.isArray(l)&&"function"==typeof l[e]?l[e](m):void 0)(e));let C=a||i;if(!1!==r&&!a&&i&&i.length>0){const t=c+1,o=e.length;if(C=[...i],"number"==typeof r){const e=r;e>=0&&e<C.length&&(C[e]=`${i[e]}(${t}/${o})`)}else!0===r&&(C[0]=`${i[0]}(${t}/${o})`)}const w={title:p.name||`${s||"文件"} (${c+1}/${e.length})`,content:g,btnBoxStyle:n||{display:"flex",justifyContent:"space-around",alignItems:"center",padding:"0 2.4vw"},btns:C,btnStyle:o||[{display:"inline-block",width:"91vw",height:"10.667vw",color:"#fff",backgroundColor:"#29AEEF",borderRadius:"8.533vw",textAlign:"center",lineHeight:"10.667vw",cursor:"pointer",margin:"5.33vw auto"},{display:"inline-block",width:"91vw",height:"10.667vw",color:"#fff",backgroundColor:"#29AEEF",borderRadius:"8.533vw",textAlign:"center",lineHeight:"10.667vw",cursor:"pointer",margin:"5.33vw auto"}],callbacks:y};m.setCheckboxChecked(!1),t.showBottomPopup(w),3===p.file_type&&p.com_terms&&this.bindFileClick(".ChoosePdfFileList",p.com_terms)};f()}loadFile(e){const i=e.split(".").pop()?.toLowerCase();if(!i)return;const o=this.Configns.fileTypes[i];if(!o)return;const n=e.split("/").pop()||"文件";"application/pdf"===o?t.showBottomPopup({title:n,content:`<iframe src="${e}" width="100%" height="600px" style="border:none;"></iframe>`,contentStyle:{},titleStyle:{fontWeight:"bold"},callbacks:[function(){}]}):fetch(e).then(e=>{if(!e.ok)throw new Error(`HTTP error! status: ${e.status}`);return e.text()}).then(e=>{let o;o="html"===i||"htm"===i?`<div style="max-height: 70vh; overflow-y: auto;">${e}</div>`:`<pre style="white-space: pre-wrap; word-wrap: break-word; max-height: 70vh; overflow-y: auto;">${e}</pre>`,t.showBottomPopup({title:n,content:o,contentStyle:{maxHeight:"70vh",overflow:"auto"},titleStyle:{fontWeight:"bold"},callbacks:[function(){}]})}).catch(i=>{t.showBottomPopup({title:"文件加载失败",content:`<p style="color: red;">无法加载文件: ${e}</p><p>错误详情: ${i.message}</p>`,callbacks:[function(){}]})})}}export{i as default};
|
|
7
|
+
import Popup from"@aggbond/my-popup";const myPopup=new Popup;class FilePreview{Configns;constructor(e){this.Configns=Object.assign({basePath:"/assets/pdfs/",modalId:"filePreviewModal",contentId:"filePreviewContent",closeBtnId:"filePreviewCloseBtn",fileTypes:{pdf:"application/pdf",txt:"text/plain",html:"text/html",1:"richTextFile",2:"choosePdfFile",3:"quotePdfFile"},fileKeyNameConfign:{fileTitle:"name",fileType:"doc_type",filePdfUrl:"pdf_url",fileRichContent:"content_text",fileArr:"com_terms"},isConfignFileKeyName:!1,isDrawFileList:!1,listObj:{listId:"",fileList:[{name:"默认标题",file_type:3,pdf_url:"",content_text:"",com_terms:[{name:"默认标题",pdf_url:"clause_pdf: https://showFile.com/address.pdf",content_text:"disclaimer<p><strong>默认文件</strong></p>"}],styleStr:{color:"red","font-weight":"bold"}}],fileStyle:{color:"red","font-weight":"bold"},isCheckButton:!1,isCoerceReadPopup:!0,checkCallBack:e=>{},listText:"更多详情请阅读",checkButtonID:"ReadFileCheckBox"},coerceReadList:{titleText:"请阅读并同意以下文件",fileList:[{name:"默认标题",file_type:3,pdf_url:"",content_text:"",com_terms:[{name:"默认标题",pdf_url:"clause_pdf: https://showFile.com/address.pdf",content_text:"disclaimer<p><strong>默认文件</strong></p>"}],styleStr:{color:"red","font-weight":"bold"}}],fileStyle:{color:"red","font-weight":"bold"},btnArr:["确认已阅读并同意","拒绝"],btnStyle:[{color:"red"},{color:"gray"}],btnBoxStyle:{},showProgressInButton:!1,coerceCallBack:[(e,t)=>{},(e,t)=>{}]},isBindFileClick:!1},e),this.initModal()}initModal(){const{isDrawFileList:e,listObj:t,isBindFileClick:i,isConfignFileKeyName:o,coerceReadList:n}=this.Configns;o&&t.fileList&&t.fileList.length>0&&(this.Configns.listObj.fileList=this.dataChange(t.fileList)),n.fileList&&n.fileList.length>0&&(this.Configns.coerceReadList.fileList=this.dataChange(n.fileList)),e&&this.drawReadFileList(t),i&&this.bindFileClick(t.listId,void 0)}dataChange(e){if(!this.Configns.fileKeyNameConfign)throw new Error("请传入文件keyNameConfign");const{fileTitle:t,filePdfUrl:i,fileRichContent:o,fileArr:n,fileType:l}=this.Configns.fileKeyNameConfign;if(!(t&&i&&o&&n))throw new Error("请传入文件keyNameConfign的参数");return e.forEach(e=>{e.name=e[t],e.file_type=e[l],e.pdf_url=e[i],e.content_text=e[o],e.com_terms=e[n]}),e}drawReadFileList(e){const{listId:t,fileList:i,isCheckButton:o,isCoerceReadPopup:n,checkCallBack:l,listText:s,checkButtonID:r,fileStyle:c}=e;if(!t)throw new Error("请传入需要添加的dom ID");if(i.length<1)throw new Error("请传入需要渲染的文件数据");let a=`${o?`<input type="checkbox" id="${r}" />`:""}${s}`;for(let e=0,t=i.length;e<t;e++){const{name:t,pdf_url:o,file_type:n,styleStr:l}=i[e];a+=`<span class="pdfsee item-contract" data-pdf="${2==n?o:""}" data-title="${t}" data-index="${e}" data-type="${n||this.judgeFileType({type:"",file:i[e],index:e})}" style="${this.objToStr(l||(c||{}))}">${t}</span>`}const d=document.querySelector(t);if(!d)throw new Error("未找到元素"+t);if(d.insertAdjacentHTML("beforeend",a),o&&r){const e=document.getElementById(r);e&&e.addEventListener("click",e=>{const t=e.target.checked;l&&l(t),t&&n&&this.openCoerceReadPopup()})}}objToStr(e){return Object.entries(e).reduce((e,[t,i])=>`${e}${t}:${i};`,"")}judgeFileType(e){const{type:t,file:i,index:o,fromChooseList:n=!1,isCoerce:l=!1}=e;if(!i)throw new Error("未找到对应文件信息 file is not defined");let s;switch(t){case"1":case 1:s=this.richTextFile({file:i,fromChooseList:n,isCoerce:l});break;case"2":case 2:s=this.quotePdfFile({file:i,fromChooseList:n,isCoerce:l});break;case"3":case 3:s=this.choosePdfFile({file:i,index:o,fromChooseList:n,isCoerce:l});break;default:const{com_terms:e,content_text:t,pdf_url:r}=i;if(e&&e.length>0)return 3;if(t)return 1;if(r)return 2}if(l)return s}richTextFile(e){const{file:t,fromChooseList:i=!1,isCoerce:o=!1}=e,{name:n,content_text:l}=t,s=i?new Popup:myPopup;if(o)return l;s.showBottomPopup({title:n,content:l,contentStyle:{},titleStyle:{fontWeight:"bold"},callbacks:[function(){}]})}choosePdfFile(e){const{file:t,index:i,fromChooseList:o=!1,isCoerce:n=!1}=e,{com_terms:l=[],name:s}=t,r=o?new Popup:myPopup;let c="<dl class='ChoosePdfFileList' style='margin:0;padding:0;'>";for(let e=0;e<l.length;e++){const{pdf_url:t,name:i,file_type:o}=l[e];c+=`<dd class="cl" data-pdf="${t}" data-title="${i}" data-index="${e}" style="margin:0">\n <span class="pdfsee item-contract" data-pdf="${t}" data-title="${i}" data-index="${e}" data-type="${o||this.judgeFileType({type:"",file:l[e],index:e})}">${i}</span>\n </dd>`}if(c+="</dl>",n)return c;r.showBottomPopup({title:s,content:c,contentStyle:{},titleStyle:{fontWeight:"bold"},callbacks:[function(){}]}),this.bindFileClick(".ChoosePdfFileList",l)}quotePdfFile(e){const{file:t,fromChooseList:i=!1,isControl:o=!1,isCoerce:n=!1}=e,{pdf_url:l,name:s,divType:r="iframe"}=t,c=i?new Popup:myPopup,a=o?l:`${l}#toolbar=0&navpanes=0&scrollbar=0`,d="iframe"===r?`<iframe src="${a}" width="100%" height="800" style="border:none;"></iframe>`:"object"===r?`<object data="${a}" type="application/pdf" width="100%" height="800">\n <p>您的浏览器不支持PDF查看。请<a href="${a}">下载文件</a>。</p></object>`:`<embed src="${a}" type="application/pdf" width="100%" height="800" />`;if(n)return d;c.showBottomPopup({title:s,content:d,contentStyle:{padding:"0"},contentBoxStyle:{maxHeight:"100vh"},titleStyle:{fontWeight:"bold"},callbacks:[function(){}]})}bindFileClick(e,t){const i=document.querySelector(e);if(!i)throw new Error("容器未找到:"+e);i.addEventListener("click",e=>{const i=e.target;if("span"===i.tagName.toLowerCase()){const e=i.dataset,o=e.type,n=e.index?parseInt(e.index):void 0;if(void 0!==n){const e=t?.[n]||this.Configns?.listObj?.fileList?.[n];void 0!==o&&e&&this.judgeFileType({type:o,file:e,index:n,fromChooseList:!!t})}}})}openCoerceReadPopup(){const{fileList:e,btnArr:t=["同意并继续"],btnStyle:i,btnBoxStyle:o,coerceCallBack:n,titleText:l,showProgressInButton:s}=this.Configns.coerceReadList;if(0===e.length)throw new Error("fileList不能为空");let r=0,c=null,a=[0];const d=f=>{if(r>=e.length)return;const p=e[r],h=r===e.length-1;p.file_type||(p.file_type=this.judgeFileType({type:"",file:p,isCoerce:!0}));const u=this.judgeFileType({type:p.file_type,file:p,isCoerce:!0}),m={next:()=>{c=null,r++,a.includes(r)||a.push(r),d()},prev:()=>{c=null,r>0&&(r--,d())},close:()=>{myPopup.close()},getCurrentIndex:()=>r,getFileList:()=>[...e],isLastFile:()=>h,setButtonTitles:e=>{Array.isArray(e)&&(c=e)},getVisitedIndices:()=>[...a],goTo:t=>{t>=0&&t<e.length&&(c=null,r=t,a.includes(r)||a.push(r),d())},setCheckboxChecked:e=>{const t=this.Configns.listObj?.checkButtonID;if(t){const i=document.getElementById(t);if(i){i.checked=e;const t=new Event("change");i.dispatchEvent(t)}}},isCheckboxChecked:()=>{const e=this.Configns.listObj?.checkButtonID;if(e){const t=document.getElementById(e);return!!t&&t.checked}return!1}},y=[];if(t&&t.length>0)for(let e=0;e<t.length;e++)y.push((e=>()=>"function"==typeof n?n(m,e):Array.isArray(n)&&"function"==typeof n[e]?n[e](m):void 0)(e));let g=c||t;if(!1!==s&&!c&&t&&t.length>0){const i=r+1,o=e.length;if(g=[...t],"number"==typeof s){const e=s;e>=0&&e<g.length&&(g[e]=`${t[e]}(${i}/${o})`)}else!0===s&&(g[0]=`${t[0]}(${i}/${o})`)}const C={title:p.name||`${l||"文件"} (${r+1}/${e.length})`,content:u,btnBoxStyle:o||{display:"flex",justifyContent:"space-around",alignItems:"center",padding:"0 2.4vw"},btns:g,btnStyle:i||[{display:"inline-block",width:"91vw",height:"10.667vw",color:"#fff",backgroundColor:"#29AEEF",borderRadius:"8.533vw",textAlign:"center",lineHeight:"10.667vw",cursor:"pointer",margin:"5.33vw auto"},{display:"inline-block",width:"91vw",height:"10.667vw",color:"#fff",backgroundColor:"#29AEEF",borderRadius:"8.533vw",textAlign:"center",lineHeight:"10.667vw",cursor:"pointer",margin:"5.33vw auto"}],callbacks:y};m.setCheckboxChecked(!1),myPopup.showBottomPopup(C),3===p.file_type&&p.com_terms&&this.bindFileClick(".ChoosePdfFileList",p.com_terms)};d()}loadFile(e){const t=e.split(".").pop()?.toLowerCase();if(!t)return;const i=this.Configns.fileTypes[t];if(!i)return;const o=e.split("/").pop()||"文件";"application/pdf"===i?myPopup.showBottomPopup({title:o,content:`<iframe src="${e}" width="100%" height="600px" style="border:none;"></iframe>`,contentStyle:{},titleStyle:{fontWeight:"bold"},callbacks:[function(){}]}):fetch(e).then(e=>{if(!e.ok)throw new Error(`HTTP error! status: ${e.status}`);return e.text()}).then(e=>{let i;i="html"===t||"htm"===t?`<div style="max-height: 70vh; overflow-y: auto;">${e}</div>`:`<pre style="white-space: pre-wrap; word-wrap: break-word; max-height: 70vh; overflow-y: auto;">${e}</pre>`,myPopup.showBottomPopup({title:o,content:i,contentStyle:{maxHeight:"70vh",overflow:"auto"},titleStyle:{fontWeight:"bold"},callbacks:[function(){}]})}).catch(t=>{myPopup.showBottomPopup({title:"文件加载失败",content:`<p style="color: red;">无法加载文件: ${e}</p><p>错误详情: ${t.message}</p>`,callbacks:[function(){}]})})}}export{FilePreview as default};
|