提交 a355b167823a66be2e5e1515b62cad3e73a0c1f6
0 个父辈
wps-oa插件
Signed-off-by: yongkangw <yongkangw@chinadci.com>
正在显示
33 个修改的文件
包含
3448 行增加
和
0 行删除
package.json
0 → 100644
1 | +{ | |
2 | + "name": "wps-oa", | |
3 | + "addonType": "wps", | |
4 | + "version": "1.0.0", | |
5 | + "private": true, | |
6 | + "dependencies": { | |
7 | + "axios": "^0.19.2", | |
8 | + "http-server": "^0.12.3", | |
9 | + "immutable": "^4.0.0-rc.12", | |
10 | + "react": "^16.13.1", | |
11 | + "react-dom": "^16.13.1", | |
12 | + "react-redux": "^7.2.0", | |
13 | + "react-router-dom": "^5.2.0", | |
14 | + "react-scripts": "3.4.1", | |
15 | + "redux": "^4.0.5" | |
16 | + }, | |
17 | + "scripts": { | |
18 | + "start": "set PORT=3889 && react-scripts start", | |
19 | + "build": "react-scripts build", | |
20 | + "test": "react-scripts test", | |
21 | + "eject": "react-scripts eject" | |
22 | + }, | |
23 | + "eslintConfig": { | |
24 | + "extends": "react-app", | |
25 | + "globals": { | |
26 | + "wps": "readonly" | |
27 | + } | |
28 | + }, | |
29 | + "browserslist": { | |
30 | + "production": [ | |
31 | + ">0.2%", | |
32 | + "not dead", | |
33 | + "not op_mini all" | |
34 | + ], | |
35 | + "development": [ | |
36 | + "last 1 chrome version", | |
37 | + "last 1 firefox version", | |
38 | + "last 1 safari version" | |
39 | + ] | |
40 | + }, | |
41 | + "devDependencies": { | |
42 | + "wps-jsapi": "latest" | |
43 | + } | |
44 | +} | |
\ No newline at end of file | ... | ... |
public/.debugTemp/NotifyDemoUrl
0 → 100644
1 | +http://127.0.0.1:3889/.debugTemp/systemdemo.html | |
\ No newline at end of file | ... | ... |
public/.debugTemp/project.js
0 → 100644
1 | +var projInfo = {"name":"wps-oa","type":"wps"} | |
\ No newline at end of file | ... | ... |
public/.debugTemp/systemdemo.html
0 → 100644
1 | +<!DOCTYPE html> | |
2 | +<html> | |
3 | +<meta http-equiv="X-UA-Compatible" content="IE=edge chrome=1"> | |
4 | + | |
5 | +<head> | |
6 | + <meta charset="utf-8"> | |
7 | + <meta http-equiv="X-UA-Compatible" content="IE=8"> | |
8 | + <title>业务系统模拟页面</title> | |
9 | + <script type="text/javascript" src="./wpsjsrpcsdk.js"></script> | |
10 | + <script type="text/javascript" src="./project.js"></script> | |
11 | +</head> | |
12 | + | |
13 | +<body> | |
14 | + <div class="divTitle">XXX业务系统-前端模拟页面</div> | |
15 | + <div> | |
16 | + <div class="partItem">单进程模式:</div> | |
17 | + <div class="divItem"> | |
18 | + <li><a href="#" onclick="openOfficeFile('http://我是文件的服务端地址')">打开业务系统文件</a></li> | |
19 | + </div> | |
20 | + <div class="divItem"> | |
21 | + <li><a href="#" onclick="onDivClick('getDocumentName', false)">获取wps当前打开的文件的文件名</a></li> | |
22 | + </div> | |
23 | + <div class="divItem"> | |
24 | + <li><a href="#" onclick="onDivClick('newDocument', true)">新建一个文件</a></li> | |
25 | + </div> | |
26 | + <div class="divItem">请点击wps加载项“给业务系统发通知”按钮,体验加载项主动发送消息</div> | |
27 | + <div class="divItem">消息内容:<span style="font-weight: bolder;color: red;" id="webnotifyspan"></span></div> | |
28 | + </div> | |
29 | + | |
30 | + <div id='tishi'> | |
31 | + <p style="text-align: center;">正在打开文件</p> | |
32 | + <p> | |
33 | + <progress id="openFile" value="0" max="100"> | |
34 | + <p style="text-align: center;">当前进度<span id="openfilespan" style="color:crimson;">0</span>%</p> | |
35 | + </progress> | |
36 | + </p> | |
37 | + </div> | |
38 | + | |
39 | + <div> | |
40 | + <div class="partItem">多进程模式:</div> | |
41 | + <li><a href="#" onclick="openFileInSilentMode()">新建客户端:静默打开文件</a> | |
42 | + </li> | |
43 | + <div id="rootClients"></div> | |
44 | + </div> | |
45 | + | |
46 | + <div class="divNote"> | |
47 | + <hr> | |
48 | + <p> | |
49 | + 更详细的与B/S业务系统集成的能力相关的示例,请参考: | |
50 | + <span style="font-weight: bolder;color: slateblue;"><a | |
51 | + href="https://code.aliyun.com/zouyingfeng/wps/blob/master/README.md" target="_blank"> | |
52 | + https://code.aliyun.com/zouyingfeng/wps/blob/master/README.md | |
53 | + </a></span> | |
54 | + </p> | |
55 | + <p> | |
56 | + 和我们一起构建WPS开发者社区,可以来<a href="https://zhuanlan.zhihu.com/c_1256350603921915904" | |
57 | + target="_blank">「WPS二次开发」</a>转转,留下您的评论。 | |
58 | + </p> | |
59 | + </div> | |
60 | +</body> | |
61 | +<script> | |
62 | + //实际的开发中,业务系统与wps加载项的交互代码如下: | |
63 | + var callbackFunc = function (result) { | |
64 | + if (result.status == 0) { | |
65 | + //下面这行代码用来注册从wps加载项返回的消息的接收函数 | |
66 | + WpsInvoke.RegWebNotify(projInfo.type, projInfo.name, function (messageText) { | |
67 | + var span = document.getElementById("webnotifyspan") | |
68 | + span.innerHTML = messageText | |
69 | + }) | |
70 | + alert(result.response) | |
71 | + } | |
72 | + else | |
73 | + alert(result.message) | |
74 | + } | |
75 | + | |
76 | + function openOfficeFile(param) { | |
77 | + var invokeParam = { | |
78 | + flag: "openOfficeFile", | |
79 | + filepath: param | |
80 | + } //根据需求任意定义 | |
81 | + WpsInvoke.InvokeAsHttp( | |
82 | + projInfo.type, | |
83 | + projInfo.name, //wps加载项的名字,在实际项目中写上对应的名字 | |
84 | + "openOfficeFileFromSystemDemo", //要调用的在wps加载项中的函数名 | |
85 | + JSON.stringify(invokeParam), //调用的在wps加载项中的函数要传递的数据,是一个json对象,根据业务系统需求任意定义 | |
86 | + callbackFunc) //回调函数,wps加载项中InvokeFromSystemDemo这个函数的返回值作为这个函数的参数 | |
87 | + } | |
88 | + | |
89 | + function onDivClick(param, showToFront) { | |
90 | + var invokeParam = { | |
91 | + 按需求定义: "安需求给值", | |
92 | + Index: param, | |
93 | + AppType: projInfo.type, | |
94 | + 自定义: { | |
95 | + xxx定义: "xxx值" | |
96 | + } | |
97 | + } //根据需求任意定义 | |
98 | + WpsInvoke.InvokeAsHttp( | |
99 | + projInfo.type, | |
100 | + projInfo.name, //wps加载项的名字,在实际项目中写上对应的名字 | |
101 | + "InvokeFromSystemDemo", //要调用的在wps加载项中的函数名 | |
102 | + JSON.stringify(invokeParam), //调用的在wps加载项中的函数要传递的数据,是一个json对象,根据业务系统需求任意定义 | |
103 | + callbackFunc, //回调函数,wps加载项中InvokeFromSystemDemo这个函数的返回值作为这个函数的参数 | |
104 | + showToFront) //设置wps是否显示到最前面来 | |
105 | + } | |
106 | + | |
107 | + //WebNotifyUseTimeout() | |
108 | + var clientCount = 0; | |
109 | + var dialogProgress; //打开文件进度计数 | |
110 | + var interval; //window.setInterval对象 | |
111 | + function openFileInSilentMode() { | |
112 | + var dlg = document.getElementById("tishi"); | |
113 | + dlg.style.display = 'block'; | |
114 | + dialogProgress = 0 | |
115 | + interval = setInterval(updateProgress, 100) | |
116 | + document.body.style.pointerEvents = "none" | |
117 | + | |
118 | + var houzui = ".xlsx"; | |
119 | + if (projInfo.type == "wps") | |
120 | + houzui = ".docx" | |
121 | + else if (projInfo.type == "wpp") | |
122 | + houzui = ".pptx" | |
123 | + var url = location.protocol + "//" + location.host + "/.debugTemp/" + projInfo.type + "Demo" + houzui; | |
124 | + var wpsClient = new WpsClient(projInfo.type); | |
125 | + var eleId = "clientId" + (++clientCount); | |
126 | + var WebNotifycount = 0; | |
127 | + wpsClient.onMessage = function (messageText) { | |
128 | + ++WebNotifycount; | |
129 | + var spanDiv = document.getElementById("webnotifyCount" + eleId); | |
130 | + spanDiv.innerText = "(次数:" + WebNotifycount + "):"; | |
131 | + var span = document.getElementById("webnotifyspan" + eleId); | |
132 | + span.innerHTML = messageText; | |
133 | + } | |
134 | + //先静默启动客户端,在回调函数里面实现打开大文件 | |
135 | + wpsClient.StartWpsInSilentMode(projInfo.name, function () { | |
136 | + var invokeParam = { | |
137 | + 按需求定义: "安需求给值", | |
138 | + Index: 'OpenFile', | |
139 | + AppType: projInfo.type, | |
140 | + filepath: url, //要打开的文件路径 | |
141 | + 自定义: { | |
142 | + xxx定义: "xxx值" | |
143 | + } | |
144 | + } //根据需求任意定义 | |
145 | + wpsClient.InvokeAsHttp( | |
146 | + projInfo.name, //wps加载项的名字,在实际项目中写上对应的名字 | |
147 | + "InvokeFromSystemDemo", //要调用的在wps加载项中的函数名 | |
148 | + JSON.stringify(invokeParam), //调用的在wps加载项中的函数要传递的数据,是一个json对象,根据业务系统需求任意定义 | |
149 | + openFileCallbackFunc, //回调函数,wps加载项中InvokeFromSystemDemo这个函数的返回值作为这个函数的参数 | |
150 | + false) //设置wps是否显示到最前面来 | |
151 | + }); | |
152 | + | |
153 | + //打开文件成功后的交互代码 | |
154 | + function openFileCallbackFunc(result) { | |
155 | + clearInterval(interval); | |
156 | + //console.log(JSON.stringify(result)) | |
157 | + if (result.status !== 0) { | |
158 | + setProgress(0) | |
159 | + var dlg = document.getElementById("tishi"); | |
160 | + dlg.style.display = 'none'; | |
161 | + document.body.style.pointerEvents = "auto" | |
162 | + alert(result.message) | |
163 | + return; | |
164 | + } | |
165 | + setProgress(100); | |
166 | + wpsClient.ShowToFront(projInfo.name, function () { | |
167 | + setProgress(0) | |
168 | + var dlg = document.getElementById("tishi"); | |
169 | + dlg.style.display = 'none'; | |
170 | + document.body.style.pointerEvents = "auto" | |
171 | + }); | |
172 | + | |
173 | + var rootElement = document.getElementById("rootClients"); | |
174 | + var ele = document.createElement("div"); | |
175 | + ele.className = "addonItem"; | |
176 | + ele.id = eleId; | |
177 | + ele.client = wpsClient; | |
178 | + ele.innerHTML = | |
179 | + '<div class="clientItem">客户端' + clientCount + '\n' + | |
180 | + '<div class="divItem"><li><a href="#" onclick="onClientGetFileName(' + "'" + ele.id + "'" + ',' + "'getDocumentName'" + ', false' + ')">获取wps当前打开的文件的文件名</a></li></div>\n' + | |
181 | + '<div class="divItem"><li><a href="#" onclick="onClientGetFileName(' + "'" + ele.id + "'" + ',' + "'newDocument'" + ', true' + ')">新建一个文件</a></li></div>\n' + | |
182 | + '<div class="divItem">加载项主动发送的消息内容<span id="webnotifyCount' + ele.id + '"></span><span style="font-weight: bolder;color: red;" id="webnotifyspan' + ele.id + '"></span></div>' | |
183 | + '</div>'; | |
184 | + rootElement.appendChild(ele); | |
185 | + } | |
186 | + } | |
187 | + | |
188 | + function onClientGetFileName(clientId, param, showToFront) { | |
189 | + var invokeParam = { | |
190 | + 按需求定义: "安需求给值", | |
191 | + Index: param, | |
192 | + AppType: projInfo.type, | |
193 | + 自定义: { | |
194 | + xxx定义: "xxx值" | |
195 | + } | |
196 | + } //根据需求任意定义 | |
197 | + var ele = document.getElementById(clientId); | |
198 | + ele.client.InvokeAsHttp( | |
199 | + projInfo.name, //wps加载项的名字,在实际项目中写上对应的名字 | |
200 | + "InvokeFromSystemDemo", //要调用的在wps加载项中的函数名 | |
201 | + JSON.stringify(invokeParam), //调用的在wps加载项中的函数要传递的数据,是一个json对象,根据业务系统需求任意定义 | |
202 | + clientCallbackFunc, //回调函数,wps加载项中InvokeFromSystemDemo这个函数的返回值作为这个函数的参数 | |
203 | + showToFront) //设置wps是否显示到最前面来 | |
204 | + | |
205 | + function clientCallbackFunc(result) { | |
206 | + if (result.status !== 0) | |
207 | + alert(result.message) | |
208 | + else { | |
209 | + if (result.response == "Failed to send message to WPS.") { | |
210 | + ele.client.IsClientRunning(function (status) { | |
211 | + if (status.response == "Client is running.") | |
212 | + alert("任务发送失败,WPS 正在执行其他任务,请前往WPS完成当前任务") | |
213 | + else | |
214 | + alert("WPS 客户端被关闭了!") | |
215 | + }) | |
216 | + } else { | |
217 | + alert(result.response) | |
218 | + } | |
219 | + } | |
220 | + } | |
221 | + } | |
222 | + | |
223 | + function updateProgress() { | |
224 | + setProgress(++dialogProgress); | |
225 | + } | |
226 | + function setProgress(newValue) { | |
227 | + if (newValue < 90 || newValue == 100) { | |
228 | + var progress = document.getElementById('openFile'); | |
229 | + progress.value = newValue; | |
230 | + var span = document.getElementById("openfilespan") | |
231 | + span.innerHTML = newValue; | |
232 | + } | |
233 | + } | |
234 | +</script> | |
235 | +<style> | |
236 | + .divTitle { | |
237 | + margin-top: 30px; | |
238 | + margin-bottom: 20px; | |
239 | + font-size: 40px; | |
240 | + font-weight: bolder; | |
241 | + text-align: center; | |
242 | + } | |
243 | + | |
244 | + .divItem { | |
245 | + margin: 5px; | |
246 | + } | |
247 | + | |
248 | + .divNote { | |
249 | + margin-top: 60px; | |
250 | + } | |
251 | + | |
252 | + #rootClients { | |
253 | + padding-left: 20px; | |
254 | + font-size: 15px; | |
255 | + } | |
256 | + | |
257 | + .clientItem { | |
258 | + margin: 5px; | |
259 | + } | |
260 | + | |
261 | + .partItem { | |
262 | + font-size: 20px; | |
263 | + margin: 5px; | |
264 | + padding-top: 20px; | |
265 | + } | |
266 | + | |
267 | + #tishi { | |
268 | + position: absolute; | |
269 | + left: 600px; | |
270 | + min-height: 150px; | |
271 | + border: 1px solid black; | |
272 | + padding: 10px 12px; | |
273 | + display: none; | |
274 | + background: #fff; | |
275 | + | |
276 | + } | |
277 | +</style> | |
278 | + | |
279 | +</html> | |
\ No newline at end of file | ... | ... |
public/.debugTemp/wps-remote-debug.json
0 → 100644
1 | +D:\JsProjects\wps-oa | |
\ No newline at end of file | ... | ... |
public/.debugTemp/wpsDemo.docx
0 → 100644
不能预览此文件类型
public/.debugTemp/wpsjsrpcsdk.js
0 → 100644
1 | +(function (global, factory) { | |
2 | + | |
3 | + "use strict"; | |
4 | + | |
5 | + if (typeof module === "object" && typeof module.exports === "object") { | |
6 | + module.exports = factory(global, true); | |
7 | + } else { | |
8 | + factory(global); | |
9 | + } | |
10 | + | |
11 | +})(typeof window !== "undefined" ? window : this, function (window, noGlobal) { | |
12 | + | |
13 | + "use strict"; | |
14 | + | |
15 | + var bFinished = true; | |
16 | + | |
17 | + function getHttpObj() { | |
18 | + var httpobj = null; | |
19 | + if (IEVersion() < 10) { | |
20 | + try { | |
21 | + httpobj = new XDomainRequest(); | |
22 | + } catch (e1) { | |
23 | + httpobj = new createXHR(); | |
24 | + } | |
25 | + } else { | |
26 | + httpobj = new createXHR(); | |
27 | + } | |
28 | + return httpobj; | |
29 | + } | |
30 | + //兼容IE低版本的创建xmlhttprequest对象的方法 | |
31 | + function createXHR() { | |
32 | + if (typeof XMLHttpRequest != 'undefined') { //兼容高版本浏览器 | |
33 | + return new XMLHttpRequest(); | |
34 | + } else if (typeof ActiveXObject != 'undefined') { //IE6 采用 ActiveXObject, 兼容IE6 | |
35 | + var versions = [ //由于MSXML库有3个版本,因此都要考虑 | |
36 | + 'MSXML2.XMLHttp.6.0', | |
37 | + 'MSXML2.XMLHttp.3.0', | |
38 | + 'MSXML2.XMLHttp' | |
39 | + ]; | |
40 | + | |
41 | + for (var i = 0; i < versions.length; i++) { | |
42 | + try { | |
43 | + return new ActiveXObject(versions[i]); | |
44 | + } catch (e) { | |
45 | + //跳过 | |
46 | + } | |
47 | + } | |
48 | + } else { | |
49 | + throw new Error('您的浏览器不支持XHR对象'); | |
50 | + } | |
51 | + } | |
52 | + | |
53 | + function startWps(options) { | |
54 | + if (!bFinished && !options.concurrent) { | |
55 | + if (options.callback) | |
56 | + options.callback({ | |
57 | + status: 1, | |
58 | + message: "上一次请求没有完成" | |
59 | + }); | |
60 | + return; | |
61 | + } | |
62 | + bFinished = false; | |
63 | + | |
64 | + function startWpsInnder(tryCount) { | |
65 | + if (tryCount <= 0) { | |
66 | + if (bFinished) | |
67 | + return; | |
68 | + bFinished = true; | |
69 | + if (options.callback) | |
70 | + options.callback({ | |
71 | + status: 2, | |
72 | + message: "请允许浏览器打开WPS Office" | |
73 | + }); | |
74 | + return; | |
75 | + } | |
76 | + var xmlReq = getHttpObj(); | |
77 | + //WPS客户端提供的接收参数的本地服务,HTTP服务端口为58890,HTTPS服务端口为58891 | |
78 | + //这俩配置,取一即可,不可同时启用 | |
79 | + xmlReq.open('POST', options.url); | |
80 | + xmlReq.onload = function (res) { | |
81 | + bFinished = true; | |
82 | + if (options.callback) { | |
83 | + options.callback({ | |
84 | + status: 0, | |
85 | + response: IEVersion() < 10 ? xmlReq.responseText : res.target.response | |
86 | + }); | |
87 | + } | |
88 | + } | |
89 | + xmlReq.ontimeout = xmlReq.onerror = function (res) { | |
90 | + xmlReq.bTimeout = true; | |
91 | + if (tryCount == options.tryCount && options.bPop) { //打开wps并传参 | |
92 | + window.location.href = "ksoWPSCloudSvr://start=RelayHttpServer" //是否启动wps弹框 | |
93 | + } | |
94 | + setTimeout(function () { | |
95 | + startWpsInnder(tryCount - 1) | |
96 | + }, 1000); | |
97 | + } | |
98 | + if (IEVersion() < 10) { | |
99 | + xmlReq.onreadystatechange = function () { | |
100 | + if (xmlReq.readyState != 4) | |
101 | + return; | |
102 | + if (xmlReq.bTimeout) { | |
103 | + return; | |
104 | + } | |
105 | + if (xmlReq.status === 200) | |
106 | + xmlReq.onload(); | |
107 | + else | |
108 | + xmlReq.onerror(); | |
109 | + } | |
110 | + } | |
111 | + xmlReq.timeout = options.timeout; | |
112 | + xmlReq.send(options.sendData) | |
113 | + } | |
114 | + startWpsInnder(options.tryCount); | |
115 | + return; | |
116 | + } | |
117 | + | |
118 | + var fromCharCode = String.fromCharCode; | |
119 | + // encoder stuff | |
120 | + var cb_utob = function (c) { | |
121 | + if (c.length < 2) { | |
122 | + var cc = c.charCodeAt(0); | |
123 | + return cc < 0x80 ? c : | |
124 | + cc < 0x800 ? (fromCharCode(0xc0 | (cc >>> 6)) + | |
125 | + fromCharCode(0x80 | (cc & 0x3f))) : | |
126 | + (fromCharCode(0xe0 | ((cc >>> 12) & 0x0f)) + | |
127 | + fromCharCode(0x80 | ((cc >>> 6) & 0x3f)) + | |
128 | + fromCharCode(0x80 | (cc & 0x3f))); | |
129 | + } else { | |
130 | + var cc = 0x10000 + | |
131 | + (c.charCodeAt(0) - 0xD800) * 0x400 + | |
132 | + (c.charCodeAt(1) - 0xDC00); | |
133 | + return (fromCharCode(0xf0 | ((cc >>> 18) & 0x07)) + | |
134 | + fromCharCode(0x80 | ((cc >>> 12) & 0x3f)) + | |
135 | + fromCharCode(0x80 | ((cc >>> 6) & 0x3f)) + | |
136 | + fromCharCode(0x80 | (cc & 0x3f))); | |
137 | + } | |
138 | + }; | |
139 | + var re_utob = /[\uD800-\uDBFF][\uDC00-\uDFFFF]|[^\x00-\x7F]/g; | |
140 | + var utob = function (u) { | |
141 | + return u.replace(re_utob, cb_utob); | |
142 | + }; | |
143 | + var _encode = function (u) { | |
144 | + var isUint8Array = Object.prototype.toString.call(u) === '[object Uint8Array]'; | |
145 | + if (isUint8Array) | |
146 | + return u.toString('base64') | |
147 | + else | |
148 | + return btoa(utob(String(u))); | |
149 | + } | |
150 | + | |
151 | + if (typeof window.btoa !== 'function') window.btoa = func_btoa; | |
152 | + | |
153 | + function func_btoa(input) { | |
154 | + var str = String(input); | |
155 | + var chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/='; | |
156 | + for ( | |
157 | + // initialize result and counter | |
158 | + var block, charCode, idx = 0, map = chars, output = ''; | |
159 | + // if the next str index does not exist: | |
160 | + // change the mapping table to "=" | |
161 | + // check if d has no fractional digits | |
162 | + str.charAt(idx | 0) || (map = '=', idx % 1); | |
163 | + // "8 - idx % 1 * 8" generates the sequence 2, 4, 6, 8 | |
164 | + output += map.charAt(63 & block >> 8 - idx % 1 * 8) | |
165 | + ) { | |
166 | + charCode = str.charCodeAt(idx += 3 / 4); | |
167 | + if (charCode > 0xFF) { | |
168 | + throw new InvalidCharacterError("'btoa' failed: The string to be encoded contains characters outside of the Latin1 range."); | |
169 | + } | |
170 | + block = block << 8 | charCode; | |
171 | + } | |
172 | + return output; | |
173 | + } | |
174 | + | |
175 | + var encode = function (u, urisafe) { | |
176 | + return !urisafe ? | |
177 | + _encode(u) : | |
178 | + _encode(String(u)).replace(/[+\/]/g, function (m0) { | |
179 | + return m0 == '+' ? '-' : '_'; | |
180 | + }).replace(/=/g, ''); | |
181 | + }; | |
182 | + | |
183 | + function IEVersion() { | |
184 | + var userAgent = navigator.userAgent; //取得浏览器的userAgent字符串 | |
185 | + var isIE = userAgent.indexOf("compatible") > -1 && userAgent.indexOf("MSIE") > -1; //判断是否IE<11浏览器 | |
186 | + var isEdge = userAgent.indexOf("Edge") > -1 && !isIE; //判断是否IE的Edge浏览器 | |
187 | + var isIE11 = userAgent.indexOf('Trident') > -1 && userAgent.indexOf("rv:11.0") > -1; | |
188 | + if (isIE) { | |
189 | + var reIE = new RegExp("MSIE (\\d+\\.\\d+);"); | |
190 | + reIE.test(userAgent); | |
191 | + var fIEVersion = parseFloat(RegExp["$1"]); | |
192 | + if (fIEVersion == 7) { | |
193 | + return 7; | |
194 | + } else if (fIEVersion == 8) { | |
195 | + return 8; | |
196 | + } else if (fIEVersion == 9) { | |
197 | + return 9; | |
198 | + } else if (fIEVersion == 10) { | |
199 | + return 10; | |
200 | + } else { | |
201 | + return 6; //IE版本<=7 | |
202 | + } | |
203 | + } else if (isEdge) { | |
204 | + return 20; //edge | |
205 | + } else if (isIE11) { | |
206 | + return 11; //IE11 | |
207 | + } else { | |
208 | + return 30; //不是ie浏览器 | |
209 | + } | |
210 | + } | |
211 | + | |
212 | + function WpsStart(options) { | |
213 | + var startInfo = { | |
214 | + "name": options.name, | |
215 | + "function": options.func, | |
216 | + "info": options.param.param, | |
217 | + "jsPluginsXml": options.param.jsPluginsXml | |
218 | + }; | |
219 | + var strData = JSON.stringify(startInfo); | |
220 | + if (IEVersion() < 10) { | |
221 | + try { | |
222 | + eval("strData = '" + JSON.stringify(startInfo) + "';"); | |
223 | + } catch (err) { | |
224 | + | |
225 | + } | |
226 | + } | |
227 | + | |
228 | + var baseData = encode(strData); | |
229 | + var url = options.urlBase + "/" + options.clientType + "/runParams"; | |
230 | + var data = "ksowebstartup" + options.clientType + "://" + baseData; | |
231 | + startWps({ | |
232 | + url: url, | |
233 | + sendData: data, | |
234 | + callback: options.callback, | |
235 | + tryCount: options.tryCount, | |
236 | + bPop: options.bPop, | |
237 | + timeout: 5000, | |
238 | + concurrent: false, | |
239 | + client: options.wpsclient | |
240 | + }); | |
241 | + } | |
242 | + | |
243 | + function WpsStartWrap(options) { | |
244 | + WpsStart({ | |
245 | + clientType: options.clientType, | |
246 | + name: options.name, | |
247 | + func: options.func, | |
248 | + param: options.param, | |
249 | + urlBase: options.urlBase, | |
250 | + callback: options.callback, | |
251 | + tryCount: 4, | |
252 | + bPop: true, | |
253 | + wpsclient: options.wpsclient, | |
254 | + }) | |
255 | + } | |
256 | + | |
257 | + /** | |
258 | + * 支持浏览器触发,WPS有返回值的启动 | |
259 | + * | |
260 | + * @param {*} clientType 组件类型 | |
261 | + * @param {*} name WPS加载项名称 | |
262 | + * @param {*} func WPS加载项入口方法 | |
263 | + * @param {*} param 参数:包括WPS加载项内部定义的方法,参数等 | |
264 | + * @param {*} callback 回调函数 | |
265 | + * @param {*} tryCount 重试次数 | |
266 | + * @param {*} bPop 是否弹出浏览器提示对话框 | |
267 | + */ | |
268 | + var exId = 0; | |
269 | + function WpsStartWrapExInner(options) { | |
270 | + var infocontent = options.param.param; | |
271 | + if (!options.wpsclient) { | |
272 | + infocontent = JSON.stringify(options.param.param); | |
273 | + var rspUrl = options.urlBase + "/transferEcho/runParams"; | |
274 | + var time = new Date(); | |
275 | + var cmdId = "js" + time.getTime() + "_" + exId; | |
276 | + var funcEx = "var res = " + options.func; | |
277 | + var cbCode = "var xhr = new XMLHttpRequest();xhr.open('POST', '" + rspUrl + "');xhr.send(JSON.stringify({id: '" + cmdId + "', response: res}));" //res 为func执行返回值 | |
278 | + var infoEx = infocontent + ");" + cbCode + "void(0"; | |
279 | + options.func = funcEx; | |
280 | + infocontent = infoEx; | |
281 | + } | |
282 | + var startInfo = { | |
283 | + "name": options.name, | |
284 | + "function": options.func, | |
285 | + "info": infocontent, | |
286 | + "showToFront": options.param.showToFront, | |
287 | + "jsPluginsXml": options.param.jsPluginsXml, | |
288 | + }; | |
289 | + | |
290 | + var strData = JSON.stringify(startInfo); | |
291 | + if (IEVersion() < 10) { | |
292 | + try { | |
293 | + eval("strData = '" + JSON.stringify(startInfo) + "';"); | |
294 | + } catch (err) { | |
295 | + | |
296 | + } | |
297 | + } | |
298 | + | |
299 | + var baseData = encode(strData); | |
300 | + var wrapper; | |
301 | + | |
302 | + if (!options.wpsclient) { | |
303 | + var url = options.urlBase + "/transfer/runParams"; | |
304 | + var data = "ksowebstartup" + options.clientType + "://" + baseData; | |
305 | + wrapper = { | |
306 | + id: cmdId, | |
307 | + app: options.clientType, | |
308 | + data: data | |
309 | + }; | |
310 | + } | |
311 | + else { | |
312 | + var url = options.urlBase + "/transferEx/runParams"; | |
313 | + wrapper = { | |
314 | + id: options.wpsclient.clientId, | |
315 | + app: options.clientType, | |
316 | + data: baseData, | |
317 | + mode: options.wpsclient.silentMode ? "true" : "false" | |
318 | + }; | |
319 | + } | |
320 | + wrapper = JSON.stringify(wrapper); | |
321 | + startWps({ | |
322 | + url: url, | |
323 | + sendData: wrapper, | |
324 | + callback: options.callback, | |
325 | + tryCount: options.tryCount, | |
326 | + bPop: options.bPop, | |
327 | + timeout: 0, | |
328 | + concurrent: options.concurrent, | |
329 | + client: options.wpsclient | |
330 | + }); | |
331 | + } | |
332 | + | |
333 | + var serverVersion = "wait" | |
334 | + var cloudSvrStart = true; | |
335 | + function WpsStartWrapVersionInner(options) { | |
336 | + if (serverVersion == "wait") { | |
337 | + if (cloudSvrStart == false) { | |
338 | + window.location.href = "ksoWPSCloudSvr://start=RelayHttpServer" //是否启动wps弹框 | |
339 | + } | |
340 | + startWps({ | |
341 | + url: options.urlBase + '/version', | |
342 | + data: "", | |
343 | + callback: function (res) { | |
344 | + if (res.status !== 0) { | |
345 | + options.callback(res) | |
346 | + return; | |
347 | + } | |
348 | + serverVersion = res.response; | |
349 | + cloudSvrStart = true; | |
350 | + options.tryCount = 1 | |
351 | + options.bPop = false | |
352 | + if (serverVersion === "") { | |
353 | + WpsStart(options) | |
354 | + } else if (serverVersion < "1.0.1" && options.wpsclient) { | |
355 | + if (options.callback) { | |
356 | + options.callback({ | |
357 | + status: 4, | |
358 | + message: "当前客户端不支持,请升级客户端" | |
359 | + }) | |
360 | + } | |
361 | + } else { | |
362 | + WpsStartWrapExInner(options); | |
363 | + } | |
364 | + }, | |
365 | + tryCount: 4, | |
366 | + bPop: true, | |
367 | + timeout: 5000, | |
368 | + concurrent: options.concurrent | |
369 | + }); | |
370 | + } else { | |
371 | + if (serverVersion === "") { | |
372 | + WpsStartWrap(options) | |
373 | + } else if (serverVersion < "1.0.1" && options.wpsclient) { | |
374 | + if (options.callback) { | |
375 | + options.callback({ | |
376 | + status: 4, | |
377 | + message: "当前客户端不支持,请升级客户端" | |
378 | + }) | |
379 | + } | |
380 | + } else { | |
381 | + options.tryCount = 1 | |
382 | + options.bPop = true | |
383 | + WpsStartWrapExInner(options); | |
384 | + } | |
385 | + } | |
386 | + } | |
387 | + | |
388 | + var HeartBeatCode = | |
389 | + "function getHttpObj() {\n" | |
390 | ++" var httpobj = null;\n" | |
391 | ++" if (IEVersion() < 10) {\n" | |
392 | ++" try {\n" | |
393 | ++" httpobj = new XDomainRequest();\n" | |
394 | ++" } catch (e1) {\n" | |
395 | ++" httpobj = new createXHR();\n" | |
396 | ++" }\n" | |
397 | ++" } else {\n" | |
398 | ++" httpobj = new createXHR();\n" | |
399 | ++" }\n" | |
400 | ++" return httpobj;\n" | |
401 | ++" }\n" | |
402 | ++" \n" | |
403 | ++" function createXHR() {\n" | |
404 | ++" if (typeof XMLHttpRequest != 'undefined') {\n" | |
405 | ++" return new XMLHttpRequest();\n" | |
406 | ++" } else if (typeof ActiveXObject != 'undefined') {\n" | |
407 | ++" var versions = [\n" | |
408 | ++" 'MSXML2.XMLHttp.6.0',\n" | |
409 | ++" 'MSXML2.XMLHttp.3.0',\n" | |
410 | ++" 'MSXML2.XMLHttp'\n" | |
411 | ++" ];\n" | |
412 | ++" \n" | |
413 | ++" for (var i = 0; i < versions.length; i++) {\n" | |
414 | ++" try {\n" | |
415 | ++" return new ActiveXObject(versions[i]);\n" | |
416 | ++" } catch (e) {\n" | |
417 | ++" \n" | |
418 | ++" }\n" | |
419 | ++" }\n" | |
420 | ++" } else {\n" | |
421 | ++" throw new Error('您的浏览器不支持XHR对象');\n" | |
422 | ++" }\n" | |
423 | ++" }\n" | |
424 | ++" \n" | |
425 | ++" function IEVersion() {\n" | |
426 | ++" var userAgent = navigator.userAgent; \n" | |
427 | ++" var isIE = userAgent.indexOf('compatible') > -1 && userAgent.indexOf('MSIE') > -1;\n" | |
428 | ++" var isEdge = userAgent.indexOf('Edge') > -1 && !isIE; \n" | |
429 | ++" var isIE11 = userAgent.indexOf('Trident') > -1 && userAgent.indexOf('rv:11.0') > -1;\n" | |
430 | ++" if (isIE) {\n" | |
431 | ++" var reIE = new RegExp('MSIE (\\d+\\.\\d+);');\n" | |
432 | ++" reIE.test(userAgent);\n" | |
433 | ++" var fIEVersion = parseFloat(RegExp['$1']);\n" | |
434 | ++" if (fIEVersion == 7) {\n" | |
435 | ++" return 7;\n" | |
436 | ++" } else if (fIEVersion == 8) {\n" | |
437 | ++" return 8;\n" | |
438 | ++" } else if (fIEVersion == 9) {\n" | |
439 | ++" return 9;\n" | |
440 | ++" } else if (fIEVersion == 10) {\n" | |
441 | ++" return 10;\n" | |
442 | ++" } else {\n" | |
443 | ++" return 6; \n" | |
444 | ++" }\n" | |
445 | ++" } else if (isEdge) {\n" | |
446 | ++" return 20; \n" | |
447 | ++" } else if (isIE11) {\n" | |
448 | ++" return 11; \n" | |
449 | ++" } else {\n" | |
450 | ++" return 30; \n" | |
451 | ++" }\n" | |
452 | ++" }\n" | |
453 | ++" var heartBeatStart = false;\n" | |
454 | ++" function checkLastRegTime() {\n" | |
455 | ++" var now = new Date().valueOf();\n" | |
456 | ++" var TimeGap = now - LastRegTime;\n" | |
457 | ++" if (TimeGap > 5000 && !heartBeatStart) {\n" | |
458 | ++" HeartBeat();\n" | |
459 | ++" heartBeatStart = true;\n" | |
460 | ++" }\n" | |
461 | ++" }\n" | |
462 | ++" \n" | |
463 | ++" function HeartBeat() {\n" | |
464 | ++" var heartBeatItem = function () {\n" | |
465 | ++" var xhr = getHttpObj();\n" | |
466 | ++" xhr.onload = function (e) {\n" | |
467 | ++" self.setTimeout(heartBeatItem, 5000);\n" | |
468 | ++" }\n" | |
469 | ++" xhr.onerror = function (e) {\n" | |
470 | ++" self.setTimeout(heartBeatItem, 5000);\n" | |
471 | ++" }\n" | |
472 | ++" xhr.ontimeout = function (e) {\n" | |
473 | ++" self.setTimeout(heartBeatItem, 5000);\n" | |
474 | ++" }\n" | |
475 | ++" xhr.open('POST', 'http://127.0.0.1:58890/askwebnotify', true);\n" | |
476 | ++" xhr.timeout = 2000;\n" | |
477 | ++" xhr.send(JSON.stringify(paramStr));\n" | |
478 | ++" }\n" | |
479 | ++" heartBeatItem();\n" | |
480 | ++" }\n" | |
481 | ++" \n" | |
482 | ++" var paramStr;\n" | |
483 | ++" var startCheck = false;\n" | |
484 | ++" self.addEventListener('message', function (event) {\n" | |
485 | ++" var data = event.data;\n" | |
486 | ++" paramStr = data.param\n" | |
487 | ++" paramStr.heartBeat = true\n" | |
488 | ++" LastRegTime = data.LastRegTime;\n" | |
489 | ++" if (!startCheck) {\n" | |
490 | ++" startCheck = true;\n" | |
491 | ++" self.setInterval(checkLastRegTime, 5000)\n" | |
492 | ++" }\n" | |
493 | ++" }, false);\n" | |
494 | + | |
495 | + function codeToBlob(code) { | |
496 | + var blob = new Blob([code], { type: 'text/javascript' }); // 生成js文件对象 | |
497 | + var objectURL = window.URL.createObjectURL(blob); // 生成js文件的url | |
498 | + return objectURL; | |
499 | + } | |
500 | + | |
501 | + var RegWebNotifyMap = { wps: {}, wpp: {}, et: {} } | |
502 | + var bWebNotifyUseTimeout = true | |
503 | + function WebNotifyUseTimeout(value) { | |
504 | + bWebNotifyUseTimeout = value ? true : false | |
505 | + } | |
506 | + var g_businessId = Number(Math.random().toString().substr(3, 5) + Date.parse(new Date())).toString(36); | |
507 | + var HeartBeatWorker | |
508 | + if (window.Worker) { | |
509 | + try { | |
510 | + HeartBeatWorker = new Worker(codeToBlob(HeartBeatCode)); | |
511 | + } catch (error) { | |
512 | + // | |
513 | + } | |
514 | + } | |
515 | + var g_LastRegTime; | |
516 | + /** | |
517 | + * 注册一个前端页面接收WPS传来消息的方法 | |
518 | + * @param {*} clientType wps | et | wpp | |
519 | + * @param {*} name WPS加载项的名称 | |
520 | + * @param {*} callback 回调函数 | |
521 | + */ | |
522 | + function RegWebNotify(clientType, name, callback, wpsclient) { | |
523 | + if (clientType != "wps" && clientType != "wpp" && clientType != "et") | |
524 | + return; | |
525 | + var paramStr = {} | |
526 | + if (wpsclient) { | |
527 | + if (wpsclient.notifyRegsitered == true) { | |
528 | + return | |
529 | + } | |
530 | + wpsclient.notifyRegsitered = true; | |
531 | + paramStr = { | |
532 | + clientId: wpsclient.clientId, | |
533 | + name: name, | |
534 | + type: clientType | |
535 | + } | |
536 | + if (HeartBeatWorker) | |
537 | + paramStr.businessId = g_businessId | |
538 | + } | |
539 | + else { | |
540 | + if (typeof callback != 'function') | |
541 | + return | |
542 | + if (RegWebNotifyMap[clientType][name]) { | |
543 | + RegWebNotifyMap[clientType][name] = callback; | |
544 | + return | |
545 | + } | |
546 | + var RegWebNotifyID = new Date().valueOf() + '' | |
547 | + paramStr = { | |
548 | + id: RegWebNotifyID, | |
549 | + name: name, | |
550 | + type: clientType | |
551 | + } | |
552 | + if (HeartBeatWorker) | |
553 | + paramStr.businessId = g_businessId | |
554 | + RegWebNotifyMap[clientType][name] = callback | |
555 | + } | |
556 | + | |
557 | + var askItem = function () { | |
558 | + var xhr = getHttpObj() | |
559 | + xhr.onload = function (e) { | |
560 | + if (xhr.responseText == "WPSInnerMessage_quit") { | |
561 | + RegWebNotifyMap[clientType][name] = undefined; | |
562 | + return; | |
563 | + } | |
564 | + try { | |
565 | + var resText = JSON.parse(xhr.responseText); | |
566 | + if(typeof resText == 'object'){ | |
567 | + paramStr.messageId = resText.msgId; | |
568 | + } | |
569 | + if (wpsclient) { | |
570 | + wpsclient.OnRegWebNotify(resText.data) | |
571 | + } else { | |
572 | + var func = RegWebNotifyMap[clientType][name] | |
573 | + func(resText.data) | |
574 | + } | |
575 | + } | |
576 | + catch (e) { | |
577 | + if (wpsclient) { | |
578 | + wpsclient.OnRegWebNotify(xhr.responseText) | |
579 | + } else { | |
580 | + var func = RegWebNotifyMap[clientType][name] | |
581 | + func(xhr.responseText) | |
582 | + } | |
583 | + } | |
584 | + window.setTimeout(askItem, 300) | |
585 | + } | |
586 | + xhr.onerror = function (e) { | |
587 | + if (bWebNotifyUseTimeout) | |
588 | + window.setTimeout(askItem, 1000) | |
589 | + else | |
590 | + window.setTimeout(askItem, 10000) | |
591 | + } | |
592 | + xhr.ontimeout = function (e) { | |
593 | + if (bWebNotifyUseTimeout) | |
594 | + window.setTimeout(askItem, 300) | |
595 | + else | |
596 | + window.setTimeout(askItem, 10000) | |
597 | + } | |
598 | + if (IEVersion() < 10) { | |
599 | + xhr.onreadystatechange = function () { | |
600 | + if (xhr.readyState != 4) | |
601 | + return; | |
602 | + if (xhr.bTimeout) { | |
603 | + return; | |
604 | + } | |
605 | + if (xhr.status === 200) | |
606 | + xhr.onload(); | |
607 | + else | |
608 | + xhr.onerror(); | |
609 | + } | |
610 | + } | |
611 | + xhr.open('POST', GetUrlBase() + '/askwebnotify', true) | |
612 | + if (bWebNotifyUseTimeout) | |
613 | + xhr.timeout = 2000; | |
614 | + if (HeartBeatWorker){ | |
615 | + g_LastRegTime = new Date().valueOf(); | |
616 | + var param = { | |
617 | + param : { | |
618 | + name: projInfo.name, | |
619 | + type: projInfo.type, | |
620 | + businessId: g_businessId | |
621 | + }, | |
622 | + LastRegTime: g_LastRegTime | |
623 | + } | |
624 | + HeartBeatWorker.postMessage(param) | |
625 | + } | |
626 | + xhr.send(JSON.stringify(paramStr)); | |
627 | + } | |
628 | + window.setTimeout(askItem, 2000) | |
629 | + } | |
630 | + | |
631 | + function GetUrlBase() { | |
632 | + if (location.protocol == "http:") | |
633 | + return "http://127.0.0.1:58890" | |
634 | + return "https://127.0.0.1:58891" | |
635 | + } | |
636 | + | |
637 | + function WpsStartWrapVersion(clientType, name, func, param, callback, showToFront, jsPluginsXml) { | |
638 | + var paramEx = { | |
639 | + jsPluginsXml: jsPluginsXml ? jsPluginsXml : "", | |
640 | + showToFront: typeof (showToFront) == 'boolean' ? showToFront : true, | |
641 | + param: (typeof (param) == 'object' ? param : JSON.parse(param)) | |
642 | + } | |
643 | + var options = { | |
644 | + clientType: clientType, | |
645 | + name: name, | |
646 | + func: func, | |
647 | + param: paramEx, | |
648 | + urlBase: GetUrlBase(), | |
649 | + callback: callback, | |
650 | + wpsclient: undefined, | |
651 | + concurrent: true | |
652 | + } | |
653 | + WpsStartWrapVersionInner(options); | |
654 | + } | |
655 | + | |
656 | + //从外部浏览器远程调用 WPS 加载项中的方法 | |
657 | + var WpsInvoke = { | |
658 | + InvokeAsHttp: WpsStartWrapVersion, | |
659 | + InvokeAsHttps: WpsStartWrapVersion, | |
660 | + RegWebNotify: RegWebNotify, | |
661 | + ClientType: { | |
662 | + wps: "wps", | |
663 | + et: "et", | |
664 | + wpp: "wpp" | |
665 | + }, | |
666 | + CreateXHR: getHttpObj, | |
667 | + IsClientRunning: IsClientRunning | |
668 | + } | |
669 | + | |
670 | + window.wpsclients = []; | |
671 | + /** | |
672 | + * @constructor WpsClient wps客户端 | |
673 | + * @param {string} clientType 必传参数,加载项类型,有效值为"wps","wpp","et";分别表示文字,演示,电子表格 | |
674 | + */ | |
675 | + function WpsClient(clientType) { | |
676 | + /** | |
677 | + * 设置RegWebNotify的回调函数,加载项给业务端发消息通过该函数 | |
678 | + * @memberof WpsClient | |
679 | + * @member onMessage | |
680 | + */ | |
681 | + this.onMessage; | |
682 | + | |
683 | + /** | |
684 | + * 设置加载项路径 | |
685 | + * @memberof WpsClient | |
686 | + * @member jsPluginsXml | |
687 | + */ | |
688 | + this.jsPluginsXml; | |
689 | + | |
690 | + /** | |
691 | + * 内部成员,外部无需调用 | |
692 | + */ | |
693 | + this.notifyRegsitered = false; | |
694 | + this.clientId = ""; | |
695 | + this.concurrent = false; | |
696 | + this.clientType = clientType; | |
697 | + this.firstRequest = true; | |
698 | + | |
699 | + /** | |
700 | + * 内部函数,外部无需调用 | |
701 | + * @param {*} options | |
702 | + */ | |
703 | + this.initWpsClient = function (options) { | |
704 | + options.clientType = this.clientType | |
705 | + options.wpsclient = this | |
706 | + options.concurrent = this.firstRequest ? true : this.concurrent | |
707 | + this.firstRequest = false; | |
708 | + WpsStartWrapVersionInner(options) | |
709 | + } | |
710 | + | |
711 | + /** | |
712 | + * 以http启动 | |
713 | + * @param {string} name 加载项名称 | |
714 | + * @param {string} func 要调用的加载项中的函数行 | |
715 | + * @param {string} param 在加载项中执行函数func要传递的数据 | |
716 | + * @param {function({int, string})} callback 回调函数,status = 0 表示成功,失败请查看message信息 | |
717 | + * @param {bool} showToFront 设置wps是否显示到前面来 | |
718 | + * @return {string} "Failed to send message to WPS." 发送消息失败,客户端已关闭; | |
719 | + * "WPS Addon is not response." 加载项阻塞,函数执行失败 | |
720 | + */ | |
721 | + this.InvokeAsHttp = function (name, func, param, callback, showToFront) { | |
722 | + function clientCallback(res) { | |
723 | + //this不是WpsClient | |
724 | + if (res.status !== 0 || serverVersion < "1.0.1") { | |
725 | + if (callback) callback(res); | |
726 | + return; | |
727 | + } | |
728 | + var resObject = JSON.parse(res.response); | |
729 | + if (this.client.clientId == "") { | |
730 | + this.client.clientId = resObject.clientId; | |
731 | + } | |
732 | + this.client.concurrent = true; | |
733 | + if (typeof resObject.data == "object") | |
734 | + res.response = JSON.stringify(resObject.data); | |
735 | + else | |
736 | + res.response = resObject.data; | |
737 | + if (IEVersion() < 10) | |
738 | + eval(" res.response = '" + res.response + "';"); | |
739 | + if (callback) | |
740 | + callback(res); | |
741 | + this.client.RegWebNotify(name); | |
742 | + } | |
743 | + var paramEx = { | |
744 | + jsPluginsXml: this.jsPluginsXml ? this.jsPluginsXml : "", | |
745 | + showToFront: typeof (showToFront) == 'boolean' ? showToFront : true, | |
746 | + param: (typeof (param) == 'object' ? param : JSON.parse(param)) | |
747 | + } | |
748 | + this.initWpsClient({ | |
749 | + name: name, | |
750 | + func: func, | |
751 | + param: paramEx, | |
752 | + urlBase: GetUrlBase(), | |
753 | + callback: clientCallback | |
754 | + }) | |
755 | + } | |
756 | + | |
757 | + /** | |
758 | + * 以https启动 | |
759 | + * @param {string} name 加载项名称 | |
760 | + * @param {string} func 要调用的加载项中的函数行 | |
761 | + * @param {string} param 在加载项中执行函数func要传递的数据 | |
762 | + * @param {function({int, string})} callback 回调函数,status = 0 表示成功,失败请查看message信息 | |
763 | + * @param {bool} showToFront 设置wps是否显示到前面来 | |
764 | + */ | |
765 | + this.InvokeAsHttps = function (name, func, param, callback, showToFront) { | |
766 | + var paramEx = { | |
767 | + jsPluginsXml: this.jsPluginsXml ? this.jsPluginsXml : "", | |
768 | + showToFront: typeof (showToFront) == 'boolean' ? showToFront : true, | |
769 | + param: (typeof (param) == 'object' ? param : JSON.parse(param)) | |
770 | + } | |
771 | + this.initWpsClient({ | |
772 | + name: name, | |
773 | + func: func, | |
774 | + param: paramEx, | |
775 | + urlBase: GetUrlBase(), | |
776 | + callback: callback | |
777 | + }) | |
778 | + } | |
779 | + | |
780 | + /** | |
781 | + * 内部函数,外部无需调用 | |
782 | + * @param {*} name | |
783 | + */ | |
784 | + this.RegWebNotify = function (name) { | |
785 | + RegWebNotify(this.clientType, name, null, this); | |
786 | + } | |
787 | + | |
788 | + this.OnRegWebNotify = function (message) { | |
789 | + if (this.onMessage) | |
790 | + this.onMessage(message) | |
791 | + } | |
792 | + | |
793 | + /** | |
794 | + * 以静默模式启动客户端 | |
795 | + * @param {string} name 必传参数,加载项名称 | |
796 | + * @param {function({int, string})} [callback] 回调函数,status = 0 表示成功,失败请查看message信息 | |
797 | + */ | |
798 | + this.StartWpsInSilentMode = function (name, callback) { | |
799 | + function initCallback(res) { | |
800 | + //this不是WpsClient | |
801 | + if (res.status !== 0 || serverVersion < "1.0.1") { | |
802 | + if (callback) callback(res); | |
803 | + return; | |
804 | + } | |
805 | + if (this.client.clientId == "") { | |
806 | + this.client.clientId = JSON.parse(res.response).clientId; | |
807 | + window.wpsclients[window.wpsclients.length] = { name: name, client: this.client }; | |
808 | + } | |
809 | + res.response = JSON.stringify(JSON.parse(res.response).data); | |
810 | + this.client.concurrent = true; | |
811 | + if (callback) { | |
812 | + callback(res); | |
813 | + } | |
814 | + this.client.RegWebNotify(name); | |
815 | + } | |
816 | + var paramEx = { | |
817 | + jsPluginsXml: this.jsPluginsXml, | |
818 | + showToFront: false, | |
819 | + param: { status: "InitInSilentMode" } | |
820 | + } | |
821 | + this.silentMode = true; | |
822 | + this.initWpsClient({ | |
823 | + name: name, | |
824 | + func: "", | |
825 | + param: paramEx, | |
826 | + urlBase: GetUrlBase(), | |
827 | + callback: initCallback | |
828 | + }) | |
829 | + } | |
830 | + | |
831 | + /** | |
832 | + * 显示客户端到最前面 | |
833 | + * @param {string} name 必传参数,加载项名称 | |
834 | + * @param {function({int, string})} [callback] 回调函数 | |
835 | + */ | |
836 | + this.ShowToFront = function (name, callback) { | |
837 | + if (serverVersion < "1.0.1") { | |
838 | + if (callback) { | |
839 | + callback({ | |
840 | + status: 4, | |
841 | + message: "当前客户端不支持,请升级客户端" | |
842 | + }); | |
843 | + return; | |
844 | + } | |
845 | + return; | |
846 | + } | |
847 | + if (this.clientId == "") { | |
848 | + if (callback) callback({ | |
849 | + status: 3, | |
850 | + message: "没有静默启动客户端" | |
851 | + }); | |
852 | + return; | |
853 | + } | |
854 | + var paramEx = { | |
855 | + jsPluginsXml: "", | |
856 | + showToFront: true, | |
857 | + param: { status: "ShowToFront" } | |
858 | + } | |
859 | + this.initWpsClient({ | |
860 | + name: name, | |
861 | + func: "", | |
862 | + param: paramEx, | |
863 | + urlBase: GetUrlBase(), | |
864 | + callback: callback | |
865 | + }) | |
866 | + } | |
867 | + | |
868 | + /** | |
869 | + * 关闭未显示出来的静默启动客户端 | |
870 | + * @param {string} name 必传参数,加载项名称 | |
871 | + * @param {function({int, string})} [callback] 回调函数 | |
872 | + */ | |
873 | + this.CloseSilentClient = function (name, callback) { | |
874 | + if (serverVersion < "1.0.1") { | |
875 | + if (callback) { | |
876 | + callback({ | |
877 | + status: 4, | |
878 | + message: "当前客户端不支持,请升级客户端" | |
879 | + }); | |
880 | + return; | |
881 | + } | |
882 | + return; | |
883 | + } | |
884 | + if (this.clientId == "") { | |
885 | + if (callback) callback({ | |
886 | + status: 3, | |
887 | + message: "没有静默启动客户端" | |
888 | + }); | |
889 | + return; | |
890 | + } | |
891 | + var paramEx = { | |
892 | + jsPluginsXml: "", | |
893 | + showToFront: false, | |
894 | + param: undefined | |
895 | + } | |
896 | + var func; | |
897 | + if (this.clientType == "wps") | |
898 | + func = "wps.WpsApplication().Quit" | |
899 | + else if (this.clientType == "et") | |
900 | + func = "wps.EtApplication().Quit" | |
901 | + else if (this.clientType == "wpp") | |
902 | + func = "wps.WppApplication().Quit" | |
903 | + | |
904 | + function closeSilentClient(res) { | |
905 | + if (res.status == 0) | |
906 | + this.client.clientId = "" | |
907 | + if (callback) callback(res); | |
908 | + return; | |
909 | + } | |
910 | + this.initWpsClient({ | |
911 | + name: name, | |
912 | + func: func, | |
913 | + param: paramEx, | |
914 | + urlBase: GetUrlBase(), | |
915 | + callback: closeSilentClient | |
916 | + }) | |
917 | + } | |
918 | + | |
919 | + /** | |
920 | + * 当前客户端是否在运行,使用WpsClient.IsClientRunning()进行调用 | |
921 | + * @param {function({int, string})} [callback] 回调函数,"Client is running." 客户端正在运行 | |
922 | + * "Client is not running." 客户端没有运行 | |
923 | + */ | |
924 | + this.IsClientRunning = function (callback) { | |
925 | + if (serverVersion < "1.0.1") { | |
926 | + if (callback) { | |
927 | + callback({ | |
928 | + status: 4, | |
929 | + message: "当前客户端不支持,请升级客户端" | |
930 | + }); | |
931 | + return; | |
932 | + } | |
933 | + return; | |
934 | + } | |
935 | + IsClientRunning(this.clientType, callback, this) | |
936 | + } | |
937 | + } | |
938 | + | |
939 | + function InitSdk() { | |
940 | + var url = GetUrlBase() + "/version"; | |
941 | + startWps({ | |
942 | + url: url, | |
943 | + data: "", | |
944 | + callback: function (res) { | |
945 | + if (res.status !== 0) { | |
946 | + cloudSvrStart = false; | |
947 | + return; | |
948 | + } | |
949 | + if (serverVersion == "wait") { | |
950 | + serverVersion = res.response; | |
951 | + cloudSvrStart = true; | |
952 | + } | |
953 | + }, | |
954 | + tryCount: 1, | |
955 | + bPop: false, | |
956 | + timeout: 5000 | |
957 | + }); | |
958 | + } | |
959 | + InitSdk(); | |
960 | + | |
961 | + if (typeof noGlobal === "undefined") { | |
962 | + window.WpsInvoke = WpsInvoke; | |
963 | + window.WpsClient = WpsClient; | |
964 | + window.WebNotifyUseTimeout = WebNotifyUseTimeout; | |
965 | + } | |
966 | + | |
967 | + /** | |
968 | + * 当前客户端是否在运行,使用WpsInvoke.IsClientRunning()进行调用 | |
969 | + * @param {string} clientType 加载项类型 | |
970 | + * @param {function} [callback] 回调函数,"Client is running." 客户端正在运行 | |
971 | + * "Client is not running." 客户端没有运行 | |
972 | + */ | |
973 | + function IsClientRunning(clientType, callback, wpsclient) { | |
974 | + var url = GetUrlBase() + "/isRunning"; | |
975 | + var wrapper = { | |
976 | + id: wpsclient == undefined ? undefined : wpsclient.clientId, | |
977 | + app: clientType | |
978 | + } | |
979 | + wrapper = JSON.stringify(wrapper); | |
980 | + startWps({ | |
981 | + url: url, | |
982 | + sendData: wrapper, | |
983 | + callback: callback, | |
984 | + tryCount: 1, | |
985 | + bPop: false, | |
986 | + timeout: 2000, | |
987 | + concurrent: true, | |
988 | + client: wpsclient | |
989 | + }); | |
990 | + } | |
991 | + | |
992 | + function WpsAddonGetAllConfig(callBack) { | |
993 | + var baseData; | |
994 | + startWps({ | |
995 | + url: GetUrlBase() + "/publishlist", | |
996 | + type: "GET", | |
997 | + sendData: baseData, | |
998 | + callback: callBack, | |
999 | + tryCount: 3, | |
1000 | + bPop: true, | |
1001 | + timeout: 5000, | |
1002 | + concurrent: true | |
1003 | + }); | |
1004 | + } | |
1005 | + | |
1006 | + function WpsAddonVerifyStatus(element, callBack) { | |
1007 | + var xmlReq = getHttpObj(); | |
1008 | + var offline = element.online === "false"; | |
1009 | + var url = offline ? element.url : element.url + "ribbon.xml"; | |
1010 | + xmlReq.open("POST", GetUrlBase() + "/redirect/runParams"); | |
1011 | + xmlReq.onload = function (res) { | |
1012 | + if (offline && !res.target.response.startsWith("7z")) { | |
1013 | + callBack({ status: 1, msg: "不是有效的7z格式" + url }); | |
1014 | + } else if (!offline && !res.target.response.startsWith("<customUI")) { | |
1015 | + callBack({ status: 1, msg: "不是有效的ribbon.xml, " + url }) | |
1016 | + } else { | |
1017 | + callBack({ status: 0, msg: "OK" }) | |
1018 | + } | |
1019 | + } | |
1020 | + xmlReq.onerror = function (res) { | |
1021 | + xmlReq.bTimeout = true; | |
1022 | + callBack({ status: 2, msg: "网页路径不可访问,如果是跨域问题,不影响使用" + url }) | |
1023 | + } | |
1024 | + xmlReq.ontimeout = function (res) { | |
1025 | + xmlReq.bTimeout = true; | |
1026 | + callBack({ status: 3, msg: "访问超时" + url }) | |
1027 | + } | |
1028 | + if (IEVersion() < 10) { | |
1029 | + xmlReq.onreadystatechange = function () { | |
1030 | + if (xmlReq.readyState != 4) | |
1031 | + return; | |
1032 | + if (xmlReq.bTimeout) { | |
1033 | + return; | |
1034 | + } | |
1035 | + if (xmlReq.status === 200) | |
1036 | + xmlReq.onload(); | |
1037 | + else | |
1038 | + xmlReq.onerror(); | |
1039 | + } | |
1040 | + } | |
1041 | + xmlReq.timeout = 5000; | |
1042 | + var data = { | |
1043 | + method: "get", | |
1044 | + url: url, | |
1045 | + data: "" | |
1046 | + } | |
1047 | + var sendData = FormatSendData(data) | |
1048 | + xmlReq.send(sendData); | |
1049 | + } | |
1050 | + | |
1051 | + function WpsAddonHandleEx(element, cmd, callBack) { | |
1052 | + var data = FormatData(element, cmd); | |
1053 | + startWps({ | |
1054 | + url: GetUrlBase() + "/deployaddons/runParams", | |
1055 | + type: "POST", | |
1056 | + sendData: data, | |
1057 | + callback: callBack, | |
1058 | + tryCount: 3, | |
1059 | + bPop: true, | |
1060 | + timeout: 5000, | |
1061 | + concurrent: true | |
1062 | + }); | |
1063 | + } | |
1064 | + | |
1065 | + function WpsAddonEnable(element, callBack) { | |
1066 | + WpsAddonHandleEx(element, "enable", callBack) | |
1067 | + } | |
1068 | + | |
1069 | + function WpsAddonDisable(element, callBack) { | |
1070 | + WpsAddonHandleEx(element, "disable", callBack) | |
1071 | + } | |
1072 | + | |
1073 | + function FormatData(element, cmd) { | |
1074 | + var data = { | |
1075 | + "cmd": cmd, //"enable", 启用, "disable", 禁用, "disableall", 禁用所有 | |
1076 | + "name": element.name, | |
1077 | + "url": element.url, | |
1078 | + "addonType": element.addonType, | |
1079 | + "online": element.online, | |
1080 | + "version": element.version | |
1081 | + } | |
1082 | + return FormatSendData(data); | |
1083 | + } | |
1084 | + | |
1085 | + function FormatSendData(data) { | |
1086 | + var strData = JSON.stringify(data); | |
1087 | + if (IEVersion() < 10) | |
1088 | + eval("strData = '" + JSON.stringify(strData) + "';"); | |
1089 | + return encode(strData); | |
1090 | + } | |
1091 | + //管理 WPS 加载项 | |
1092 | + var WpsAddonMgr = { | |
1093 | + getAllConfig: WpsAddonGetAllConfig, | |
1094 | + verifyStatus: WpsAddonVerifyStatus, | |
1095 | + enable: WpsAddonEnable, | |
1096 | + disable: WpsAddonDisable, | |
1097 | + } | |
1098 | + | |
1099 | + if (typeof noGlobal === "undefined") { | |
1100 | + window.WpsAddonMgr = WpsAddonMgr; | |
1101 | + } | |
1102 | + | |
1103 | + return { WpsInvoke: WpsInvoke, WpsAddonMgr: WpsAddonMgr, version: "1.0.15" }; | |
1104 | +}); | |
\ No newline at end of file | ... | ... |
public/favicon.ico
0 → 100644
不能预览此文件类型
public/images/1.svg
0 → 100644
1 | +<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><defs><style type="text/css">.skinbaseDark,.skinbaseLight,.skinthemeDark{fill-rule:evenodd;}.skinbaseDark,.skinbaseLight{opacity:0.8;}.skinbaseLight{fill:#838383;}.skinthemeDark{fill:#5789d9;}</style></defs><title>编辑文字</title><path class="skinbaseDark" d="M21,23H2a2,2,0,0,1-2-2V2A2,2,0,0,1,2,0H21a2,2,0,0,1,2,2V21A2,2,0,0,1,21,23ZM22,2a1,1,0,0,0-1-1H2A1,1,0,0,0,1,2V21a1,1,0,0,0,1,1H21a1,1,0,0,0,1-1Z"/><path class="skinbaseLight" d="M21.5,12h-3a.5.5,0,1,1,0-1h3a.5.5,0,1,1,0,1Zm-10,10a.50005.50005,0,0,1-.5-.5v-3a.5.5,0,1,1,1,0v3A.50005.50005,0,0,1,11.5,22Zm0-19a.50005.50005,0,0,1-.5-.5v-1a.5.5,0,1,1,1,0v1A.50005.50005,0,0,1,11.5,3Zm-7,9h-3a.5.5,0,1,1,0-1h3a.5.5,0,1,1,0,1Z"/><path class="skinthemeDark" d="M17.9993,18.9997H16.9367L15.27,14H7.7281L6.0617,18.9997H4.9991L8.9988,6.9993h0a2.92165,2.92165,0,0,1,2.5-2,2.75159,2.75159,0,0,1,2.5,2h0ZM12.9363,6.9993a1.2901,1.2901,0,0,0-1.4375-.9375,1.39754,1.39754,0,0,0-1.4375.9375h0L8.0613,13h6.8753L12.9362,6.9993h.0001Z"/></svg> | |
\ No newline at end of file | ... | ... |
public/images/2.svg
0 → 100644
1 | +<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><defs><style type="text/css">.skinbaseDark,.skinthemeDark{fill-rule:evenodd;}.skinbaseDark{opacity:0.8;}.skinthemeDark{fill:#5789d9;}</style></defs><title>艺术字大小</title><path class="skinbaseDark" d="M17.9993,18.9997H16.9367L15.27,14H7.7281L6.0617,18.9997H4.9991L8.9988,6.9993h0a2.92165,2.92165,0,0,1,2.5-2,2.75159,2.75159,0,0,1,2.5,2h0ZM12.9363,6.9993a1.2901,1.2901,0,0,0-1.4375-.9375,1.39754,1.39754,0,0,0-1.4375.9375h0L8.0613,13h6.8753L12.9362,6.9993h.0001Z"/><path class="skinthemeDark" d="M23,21v1a1,1,0,0,1-1,1H21a1,1,0,0,1-1-1H3a1,1,0,0,1-1,1H1a1,1,0,0,1-1-1V21a1,1,0,0,1,1-1V4A1,1,0,0,1,0,3V2A1,1,0,0,1,1,1H2A1,1,0,0,1,3,2H20a1,1,0,0,1,1-1h1a1,1,0,0,1,1,1V3a1,1,0,0,1-1,1V20A1,1,0,0,1,23,21ZM1,21.6a.4.4,0,0,0,.4.4h.2a.4.4,0,0,0,.4-.4v-.2a.4.4,0,0,0-.4-.4H1.4a.4.4,0,0,0-.4.4ZM2,2.4A.4.4,0,0,0,1.6,2H1.4a.4.4,0,0,0-.4.4v.2a.4.4,0,0,0,.4.4h.2A.4.4,0,0,0,2,2.6ZM20,3H3A1,1,0,0,1,2,4V20a1,1,0,0,1,1,1H20a1,1,0,0,1,1-1V4A1,1,0,0,1,20,3Zm2-.6a.4.4,0,0,0-.4-.4h-.2a.4.4,0,0,0-.4.4v.2a.4.4,0,0,0,.4.4h.2a.4.4,0,0,0,.4-.4ZM21.6,21h-.2a.4.4,0,0,0-.4.4v.2a.4.4,0,0,0,.4.4h.2a.4.4,0,0,0,.4-.4v-.2A.4.4,0,0,0,21.6,21Z"/></svg> | |
\ No newline at end of file | ... | ... |
public/images/3.svg
0 → 100644
1 | +<?xml version="1.0" encoding="utf-8"?> | |
2 | +<!-- Generator: Adobe Illustrator 21.0.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) --> | |
3 | +<svg version="1.1" id="图层_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px" | |
4 | + viewBox="0 0 24 24" style="enable-background:new 0 0 24 24;" xml:space="preserve"> | |
5 | +<style type="text/css"> | |
6 | + .skinbaseDark{opacity:0.8;enable-background:new ;} | |
7 | + .skinthemeDark{fill:#5789D9;} | |
8 | +</style> | |
9 | +<path class="skinbaseDark" d="M13,23h-1.4c-0.1,0-0.2,0-0.3-0.1c-0.7-0.2-0.9-0.6-1.3-0.9l-5-5H1.6C0.7,17,0,16.3,0,15.4V8.6 | |
10 | + C0,7.7,0.7,7,1.6,7H5l5-5c0.4-0.4,0.6-0.8,1.3-0.9C11.4,1,11.5,1,11.6,1H12l0,0l0,0h1c0.6,0,1,0.5,1,1v20C14,22.5,13.6,23,13,23z | |
11 | + M13,2.4C13,2.2,12.8,2,12.6,2H12c-0.5,0-0.9,0.2-1.1,0.4c0.1-0.1,0,0,0,0C10.8,2.6,7.3,6,5.3,8H1.6C1.3,8,1,8.3,1,8.6v6.8 | |
12 | + C1,15.7,1.3,16,1.6,16h3.7c2,2,5.5,5.5,5.7,5.7c0.2,0.2,0.6,0.3,1,0.3h0.6c0.2,0,0.4-0.2,0.4-0.4V2.4z M10,2C10,2,9.9,2.1,10,2 | |
13 | + C9.9,2,10,2,10,2z"/> | |
14 | +<path class="skinthemeDark" d="M18.5,20.9c-0.1,0.1-0.2,0.1-0.4,0.1c-0.3,0-0.5-0.2-0.5-0.5c0-0.2,0.1-0.4,0.3-0.5l0,0 | |
15 | + c3-1.5,5.1-4.5,5.1-8.1s-2.1-6.6-5.1-8.1l0,0c-0.2-0.1-0.3-0.3-0.3-0.5c0-0.3,0.2-0.5,0.5-0.5c0.1,0,0.3,0.1,0.4,0.2 | |
16 | + c3.3,1.6,5.5,5,5.5,8.9S21.8,19.3,18.5,20.9z M19,12c0,1.7-0.9,3.2-2.2,4.1c-0.1,0.1-0.2,0.2-0.4,0.2c-0.3,0-0.5-0.2-0.5-0.5 | |
17 | + c0-0.2,0.1-0.4,0.3-0.5v0c1.1-0.7,1.8-1.9,1.8-3.3c0-1.4-0.7-2.6-1.8-3.3v0c-0.2-0.1-0.3-0.3-0.3-0.5c0-0.3,0.2-0.5,0.5-0.5 | |
18 | + c0.2,0,0.3,0.1,0.4,0.2C18.1,8.8,19,10.3,19,12z"/> | |
19 | +</svg> | ... | ... |
public/images/newFromTemp.svg
0 → 100644
1 | +<?xml version="1.0" encoding="UTF-8"?> | |
2 | +<svg width="21px" height="20px" viewBox="0 0 21 20" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"> | |
3 | + <!-- Generator: Sketch 51.2 (57519) - http://www.bohemiancoding.com/sketch --> | |
4 | + <title>从模版新建</title> | |
5 | + <desc>Created with Sketch.</desc> | |
6 | + <defs></defs> | |
7 | + <g id="Page-1" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd"> | |
8 | + <g id="Artboard" transform="translate(-31.000000, -26.000000)"> | |
9 | + <g id="从模版新建" transform="translate(29.000000, 24.000000)"> | |
10 | + <g id="Group" stroke-width="1"> | |
11 | + <g id="新增节" transform="translate(2.000000, 2.000000)"> | |
12 | + <path d="M19.9587402,10 L18.9587402,10 L18.9587402,2 C18.9587402,1.44771525 18.511025,1 17.9587402,1 L6.0300293,1 C5.47774455,1 5.0300293,1.44771525 5.0300293,2 L5.0300293,18 C5.0300293,18.5522847 5.47774455,19 6.0300293,19 L9.95874023,19 L9.95874023,20 L6.0300293,20 C4.9254598,20 4.0300293,19.1045695 4.0300293,18 L4.0300293,2 C4.0300293,0.8954305 4.9254598,2.02906125e-16 6.0300293,0 L17.9587402,0 C19.0633097,-2.02906125e-16 19.9587402,0.8954305 19.9587402,2 L19.9587402,10 Z" id="Combined-Shape" fill="#404040" fill-rule="nonzero"></path> | |
13 | + <path d="M6,1 L4,1 C3.44771525,1 3,1.44771525 3,2 L3,18 C3,18.5522847 3.44771525,19 4,19 L6,19 L6,20 L4,20 C2.8954305,20 2,19.1045695 2,18 L2,2 C2,0.8954305 2.8954305,2.02906125e-16 4,0 L6,0 L6,1 Z" id="Combined-Shape-Copy-2" fill="#404040" fill-rule="nonzero"></path> | |
14 | + <path d="M4,1 L2,1 C1.44771525,1 1,1.44771525 1,2 L1,18 C1,18.5522847 1.44771525,19 2,19 L4,19 L4,20 L2,20 C0.8954305,20 1.03797111e-16,19.1045695 0,18 L0,2 C-1.10284431e-16,0.8954305 0.8954305,2.02906125e-16 2,0 L4,0 L4,1 Z" id="Combined-Shape-Copy-3" fill="#404040" fill-rule="nonzero"></path> | |
15 | + <path d="M17,15 L20.5,15 C20.7761424,15 21,15.2238576 21,15.5 C21,15.7761424 20.7761424,16 20.5,16 L17,16 L17,19.5 C17,19.7761424 16.7761424,20 16.5,20 C16.2238576,20 16,19.7761424 16,19.5 L16,16 L12.5,16 C12.2238576,16 12,15.7761424 12,15.5 C12,15.2238576 12.2238576,15 12.5,15 L16,15 L16,11.5 C16,11.2238576 16.2238576,11 16.5,11 C16.7761424,11 17,11.2238576 17,11.5 L17,15 Z" id="Combined-Shape" fill="#5789D9"></path> | |
16 | + </g> | |
17 | + </g> | |
18 | + <rect id="Rectangle-15" fill="#404040" x="9" y="6" width="10" height="1"></rect> | |
19 | + </g> | |
20 | + </g> | |
21 | + </g> | |
22 | +</svg> | |
\ No newline at end of file | ... | ... |
public/index.html
0 → 100644
1 | +<!DOCTYPE html> | |
2 | +<html lang="en"> | |
3 | + <head> | |
4 | + <meta charset="utf-8" /> | |
5 | + <title>WPSJS</title> | |
6 | + </head> | |
7 | + <body> | |
8 | + <noscript>You need to enable JavaScript to run this app.</noscript> | |
9 | + <div id="root"></div> | |
10 | + <!-- | |
11 | + This HTML file is a template. | |
12 | + If you open it directly in the browser, you will see an empty page. | |
13 | + | |
14 | + You can add webfonts, meta tags, or analytics to this file. | |
15 | + The build step will place the bundled scripts into the <body> tag. | |
16 | + | |
17 | + To begin the development, run `npm start` or `yarn start`. | |
18 | + To create a production bundle, use `npm run build` or `yarn build`. | |
19 | + --> | |
20 | + </body> | |
21 | +</html> | ... | ... |
public/ribbon.xml
0 → 100644
1 | +<customUI xmlns="http://schemas.microsoft.com/office/2006/01/customui" onLoad="ribbon.OnAddinLoad"> | |
2 | + <ribbon startFromScratch="false"> | |
3 | + <tabs> | |
4 | + <tab id="SystemAddin" label="系统插件" insertBeforeMso="TabHome"> | |
5 | + <group id="btnDemoGroup" label="group1"> | |
6 | + <!-- <button id="btnShowMsg" label="弹出消息框" onAction="ribbon.OnAction" getEnabled="ribbon.OnGetEnabled" getImage="ribbon.GetImage" visible="true" size="large"/> | |
7 | + <button id="btnIsEnbable" getLabel="ribbon.OnGetLabel" onAction="ribbon.OnAction" enabled="true" getImage="ribbon.GetImage" visible="true" size="large"/> | |
8 | + <button id="btnShowDialog" label="弹对话框网页" onAction="ribbon.OnAction" getEnabled="ribbon.OnGetEnabled" getImage="ribbon.GetImage" getVisible="ribbon.OnGetVisible" size="large"/> | |
9 | + <button id="btnShowTaskPane" label="弹任务窗格网页" onAction="ribbon.OnAction" getEnabled="ribbon.OnGetEnabled" getImage="ribbon.GetImage" getVisible="ribbon.OnGetVisible" size="large"/> | |
10 | + <button id="btnApiEvent" getLabel="ribbon.OnGetLabel" onAction="ribbon.OnAction" getEnabled="ribbon.OnGetEnabled" getImage="ribbon.GetImage" getVisible="ribbon.OnGetVisible" size="large"/> | |
11 | + <button id="btnWebNotify" label="给业务系统发通知" onAction="ribbon.OnAction" enabled="true" getImage="ribbon.GetImage" getVisible="ribbon.OnGetVisible" size="large"/> | |
12 | + <button id="btnOpenWebFile" label="打开远程文件" onAction="ribbon.OnAction" enabled="true" getImage="ribbon.GetImage" getVisible="ribbon.OnGetVisible" size="large"/> --> | |
13 | + <button id="btnSaveToServer" label="保存到OA" onAction="ribbon.OnAction" enabled="true" getImage="ribbon.GetImage" size="large"/> | |
14 | + <button id="btnInsertRedHeader" label="套红头" onAction="ribbon.OnAction" enabled="true" getImage="ribbon.GetImage" size="large"/> | |
15 | + </group> | |
16 | + </tab> | |
17 | + </tabs> | |
18 | + </ribbon> | |
19 | + <commands> | |
20 | + <!-- idMso支持getEnabled和onAction,不支持visible属性和事件--> | |
21 | + <!-- 文档复制和剪切控制--> | |
22 | + <!-- <command idMso="Copy" getEnabled="OnGetEnabled" /> | |
23 | + <command idMso="Cut" getEnabled="OnGetEnabled" /> --> --> | |
24 | + <!-- 文档保存和另存控制--> | |
25 | + <command idMso="FileSave" enabled="true" onAction="ribbon.OnAction"/> | |
26 | + <!-- <command idMso="SaveAll" getEnabled="OnGetEnabled" /> | |
27 | + <command idMso="FileSaveAsMenu" getEnabled="OnGetEnabled" onAction="OnAction"/> | |
28 | + <command idMso="FileSaveAs" getEnabled="OnGetEnabled" onAction="OnAction"/> | |
29 | + <command idMso="FileSaveAsPicture" getEnabled="OnGetEnabled" /> | |
30 | + <command idMso="SaveAsPicture" getEnabled="OnGetEnabled" /> | |
31 | + <command idMso="FileMenuSendMail" getEnabled="OnGetEnabled" /> | |
32 | + <!-- 输出PDF控制--> | |
33 | + <command idMso="SaveAsPDF" getEnabled="OnGetEnabled"/> | |
34 | + <command idMso="FileSaveAsPDF" getEnabled="OnGetEnabled"/> | |
35 | + <command idMso="ExportToPDF" getEnabled="OnGetEnabled"/> | |
36 | + <command idMso="FileSaveAsPdfOrXps" getEnabled="OnGetEnabled"/> | |
37 | + <!-- 输出OFD控制--> | |
38 | + <command idMso="SaveAsOfd" getEnabled="OnGetEnabled"/> | |
39 | + <command idMso="FileSaveAsOfd" getEnabled="OnGetEnabled"/> | |
40 | + <!--文档打印控制--> | |
41 | + <command idMso="FilePrint" getEnabled="OnGetEnabled"/> | |
42 | + <command idMso="FilePrintMenu" getEnabled="OnGetEnabled"/> | |
43 | + <command idMso="FilePrintPreview" getEnabled="OnGetEnabled"/> | |
44 | + <!--文档修订控制--> | |
45 | + <command idMso="ReviewTrackChangesMenu" getEnabled="OnGetEnabled"/> | |
46 | + <command idMso="ReviewRejectChangeMenu" getEnabled="OnGetEnabled"/> | |
47 | + <command idMso="ReviewAcceptChangeMenu" getEnabled="OnGetEnabled"/> | |
48 | + <!--文档新建控制--> | |
49 | + <command idMso="FileNewMenu" getEnabled="OnGetEnabled" onAction="OnAction"/> | |
50 | + <command idMso="FileNew" getEnabled="OnGetEnabled" onAction="OnAction"/> | |
51 | + <command idMso="WindowNew" getEnabled="OnGetEnabled" onAction="OnAction"/> | |
52 | + <command idMso="FileNewBlankDocument" getEnabled="OnGetEnabled" onAction="OnAction"/> | |
53 | + </commands> | |
54 | +</customUI> | |
\ No newline at end of file | ... | ... |
src/actions/common.js
0 → 100644
1 | +// -------------------------- 通用常量 | |
2 | +import {constStrEnum,EnumDocLandMode} from "./enum" | |
3 | +var wps = window.wps||window | |
4 | + | |
5 | + | |
6 | +//OA门户网站用接口,配置默认服务器接口 | |
7 | +var OA_DOOR = { | |
8 | + templateDataUrl: undefined, //正文模板列表接口 | |
9 | + templateBaseURL: undefined, //指定正文模板基础接口 | |
10 | + redHeadsPath: undefined, //默认红头模板列表获取路径 | |
11 | + getRedHeadPath: undefined, //默认获取红头文件路径 | |
12 | + bookmarkPath: undefined, //书签列表接口 | |
13 | + redHeadsPath: undefined, //默认红头模板列表获取路径 | |
14 | +} | |
15 | + | |
16 | +// -------------------------- 通用方法 --------------------------- | |
17 | +//去除字符串左边空格 | |
18 | +String.prototype.ltrim = function () { | |
19 | + return this.replace(/(^\s*)/g, ""); | |
20 | +} | |
21 | + | |
22 | +//去除字符串右边空格 | |
23 | +String.prototype.rtrim = function () { | |
24 | + return this.replace(/(\s*$)/g, ""); | |
25 | +} | |
26 | + | |
27 | +//扩展js string endwith,startwith方法 | |
28 | +String.prototype.endWith = function (str) { | |
29 | + if (str == null || str == "" || this.length == 0 || str.length > this.length) | |
30 | + return false; | |
31 | + if (this.substring(this.length - str.length) == str) | |
32 | + return true; | |
33 | + else | |
34 | + return false; | |
35 | +} | |
36 | + | |
37 | +String.prototype.startWith = function (str) { | |
38 | + if (str == null || str == "" || this.length == 0 || str.length > this.length) | |
39 | + return false; | |
40 | + if (this.substr(0, str.length) == str) | |
41 | + return true; | |
42 | + else | |
43 | + return false; | |
44 | +} | |
45 | + | |
46 | +//UTF-16转UTF-8 | |
47 | +function utf16ToUtf8(s) { | |
48 | + if (!s) { | |
49 | + return; | |
50 | + } | |
51 | + var i, code, ret = [], | |
52 | + len = s.length; | |
53 | + for (i = 0; i < len; i++) { | |
54 | + code = s.charCodeAt(i); | |
55 | + if (code > 0x0 && code <= 0x7f) { | |
56 | + //单字节 | |
57 | + //UTF-16 0000 - 007F | |
58 | + //UTF-8 0xxxxxxx | |
59 | + ret.push(s.charAt(i)); | |
60 | + } else if (code >= 0x80 && code <= 0x7ff) { | |
61 | + //双字节 | |
62 | + //UTF-16 0080 - 07FF | |
63 | + //UTF-8 110xxxxx 10xxxxxx | |
64 | + ret.push( | |
65 | + //110xxxxx | |
66 | + String.fromCharCode(0xc0 | ((code >> 6) & 0x1f)), | |
67 | + //10xxxxxx | |
68 | + String.fromCharCode(0x80 | (code & 0x3f)) | |
69 | + ); | |
70 | + } else if (code >= 0x800 && code <= 0xffff) { | |
71 | + //三字节 | |
72 | + //UTF-16 0800 - FFFF | |
73 | + //UTF-8 1110xxxx 10xxxxxx 10xxxxxx | |
74 | + ret.push( | |
75 | + //1110xxxx | |
76 | + String.fromCharCode(0xe0 | ((code >> 12) & 0xf)), | |
77 | + //10xxxxxx | |
78 | + String.fromCharCode(0x80 | ((code >> 6) & 0x3f)), | |
79 | + //10xxxxxx | |
80 | + String.fromCharCode(0x80 | (code & 0x3f)) | |
81 | + ); | |
82 | + } | |
83 | + } | |
84 | + | |
85 | + return ret.join(''); | |
86 | + | |
87 | +} | |
88 | +var Base64 = { | |
89 | + _keyStr: "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=", | |
90 | + encode: function(e) { | |
91 | + var t = ""; | |
92 | + var n, r, i, s, o, u, a; | |
93 | + var f = 0; | |
94 | + e = Base64._utf8_encode(e); | |
95 | + while (f < e.length) { | |
96 | + n = e.charCodeAt(f++); | |
97 | + r = e.charCodeAt(f++); | |
98 | + i = e.charCodeAt(f++); | |
99 | + s = n >> 2; | |
100 | + o = (n & 3) << 4 | r >> 4; | |
101 | + u = (r & 15) << 2 | i >> 6; | |
102 | + a = i & 63; | |
103 | + if (isNaN(r)) { | |
104 | + u = a = 64 | |
105 | + } else if (isNaN(i)) { | |
106 | + a = 64 | |
107 | + } | |
108 | + t = t + this._keyStr.charAt(s) + this._keyStr.charAt(o) + this._keyStr.charAt(u) + this._keyStr.charAt(a) | |
109 | + } | |
110 | + return t | |
111 | + }, | |
112 | + decode: function(e) { | |
113 | + var t = ""; | |
114 | + var n, r, i; | |
115 | + var s, o, u, a; | |
116 | + var f = 0; | |
117 | + e = e.replace(/[^A-Za-z0-9+/=]/g, ""); | |
118 | + while (f < e.length) { | |
119 | + s = this._keyStr.indexOf(e.charAt(f++)); | |
120 | + o = this._keyStr.indexOf(e.charAt(f++)); | |
121 | + u = this._keyStr.indexOf(e.charAt(f++)); | |
122 | + a = this._keyStr.indexOf(e.charAt(f++)); | |
123 | + n = s << 2 | o >> 4; | |
124 | + r = (o & 15) << 4 | u >> 2; | |
125 | + i = (u & 3) << 6 | a; | |
126 | + t = t + String.fromCharCode(n); | |
127 | + if (u != 64) { | |
128 | + t = t + String.fromCharCode(r) | |
129 | + } | |
130 | + if (a != 64) { | |
131 | + t = t + String.fromCharCode(i) | |
132 | + } | |
133 | + } | |
134 | + t = Base64._utf8_decode(t); | |
135 | + return t | |
136 | + }, | |
137 | + _utf8_encode: function(e) { | |
138 | + e = e.replace(/rn/g, "n"); | |
139 | + var t = ""; | |
140 | + for (var n = 0; n < e.length; n++) { | |
141 | + var r = e.charCodeAt(n); | |
142 | + if (r < 128) { | |
143 | + t += String.fromCharCode(r) | |
144 | + } else if (r > 127 && r < 2048) { | |
145 | + t += String.fromCharCode(r >> 6 | 192); | |
146 | + t += String.fromCharCode(r & 63 | 128) | |
147 | + } else { | |
148 | + t += String.fromCharCode(r >> 12 | 224); | |
149 | + t += String.fromCharCode(r >> 6 & 63 | 128); | |
150 | + t += String.fromCharCode(r & 63 | 128) | |
151 | + } | |
152 | + } | |
153 | + return t | |
154 | + }, | |
155 | + _utf8_decode: function(e) { | |
156 | + var t = ""; | |
157 | + var n = 0; | |
158 | + let c1,c2,c3; | |
159 | + var r = c1 = c2 = 0; | |
160 | + while (n < e.length) { | |
161 | + r = e.charCodeAt(n); | |
162 | + if (r < 128) { | |
163 | + t += String.fromCharCode(r); | |
164 | + n++ | |
165 | + } else if (r > 191 && r < 224) { | |
166 | + c2 = e.charCodeAt(n + 1); | |
167 | + t += String.fromCharCode((r & 31) << 6 | c2 & 63); | |
168 | + n += 2 | |
169 | + } else { | |
170 | + c2 = e.charCodeAt(n + 1); | |
171 | + c3 = e.charCodeAt(n + 2); | |
172 | + t += String.fromCharCode((r & 15) << 12 | (c2 & 63) << 6 | c3 & 63); | |
173 | + n += 3 | |
174 | + } | |
175 | + } | |
176 | + return t | |
177 | + } | |
178 | +} | |
179 | +//UTF-8转UTF-16 | |
180 | +function utf8ToUtf16(s) { | |
181 | + if (!s) { | |
182 | + return; | |
183 | + } | |
184 | + | |
185 | + var i, codes, bytes, ret = [], | |
186 | + len = s.length; | |
187 | + for (i = 0; i < len; i++) { | |
188 | + codes = []; | |
189 | + codes.push(s.charCodeAt(i)); | |
190 | + if (((codes[0] >> 7) & 0xff) == 0x0) { | |
191 | + //单字节 0xxxxxxx | |
192 | + ret.push(s.charAt(i)); | |
193 | + } else if (((codes[0] >> 5) & 0xff) == 0x6) { | |
194 | + //双字节 110xxxxx 10xxxxxx | |
195 | + codes.push(s.charCodeAt(++i)); | |
196 | + bytes = []; | |
197 | + bytes.push(codes[0] & 0x1f); | |
198 | + bytes.push(codes[1] & 0x3f); | |
199 | + ret.push(String.fromCharCode((bytes[0] << 6) | bytes[1])); | |
200 | + } else if (((codes[0] >> 4) & 0xff) == 0xe) { | |
201 | + //三字节 1110xxxx 10xxxxxx 10xxxxxx | |
202 | + codes.push(s.charCodeAt(++i)); | |
203 | + codes.push(s.charCodeAt(++i)); | |
204 | + bytes = []; | |
205 | + bytes.push((codes[0] << 4) | ((codes[1] >> 2) & 0xf)); | |
206 | + bytes.push(((codes[1] & 0x3) << 6) | (codes[2] & 0x3f)); | |
207 | + ret.push(String.fromCharCode((bytes[0] << 8) | bytes[1])); | |
208 | + } | |
209 | + } | |
210 | + return ret.join(''); | |
211 | + | |
212 | +} | |
213 | + | |
214 | +function currentTime() { | |
215 | + var now = new Date(); | |
216 | + | |
217 | + var year = now.getFullYear(); //年 | |
218 | + var month = now.getMonth() + 1; //月 | |
219 | + var day = now.getDate(); //日 | |
220 | + | |
221 | + var hh = now.getHours(); //时 | |
222 | + var mm = now.getMinutes(); //分 | |
223 | + | |
224 | + var clock = year + "年"; | |
225 | + | |
226 | + if (month < 10) | |
227 | + clock += "0"; | |
228 | + | |
229 | + clock += month + "月"; | |
230 | + | |
231 | + if (day < 10) | |
232 | + clock += "0"; | |
233 | + | |
234 | + clock += day + "日"; | |
235 | + | |
236 | + if (hh < 10) | |
237 | + clock += "0"; | |
238 | + | |
239 | + clock += hh + ":"; | |
240 | + if (mm < 10) clock += '0'; | |
241 | + clock += mm; | |
242 | + return (clock); | |
243 | +} | |
244 | + | |
245 | +/** | |
246 | + * 获取文件路径 | |
247 | + * @param {*} html 文件全称 | |
248 | + */ | |
249 | +function getHtmlURL(html) { | |
250 | + //弹出辅助窗格框 | |
251 | + var GetUrlPath = ()=> { | |
252 | + var e = document.location.toString(); | |
253 | + return -1 != (e = decodeURI(e)).indexOf("/") && (e = e.substring(0, e.lastIndexOf("/"))), e | |
254 | + } | |
255 | + | |
256 | + var url = GetUrlPath(); | |
257 | + | |
258 | + if (url.length != 0) { | |
259 | + url = url.concat("/" + html); | |
260 | + } else { | |
261 | + url = url.concat("./" + html); | |
262 | + } | |
263 | + return url; | |
264 | +} | |
265 | + | |
266 | +/** | |
267 | + * wps内弹出web页面 | |
268 | + * @param {*} html 文件名 | |
269 | + * @param {*} title 窗口标题 | |
270 | + * @param {*} hight 窗口高 | |
271 | + * @param {*} width 窗口宽 | |
272 | + */ | |
273 | +export function OnShowDialog(html, title, height, width, bModal) { | |
274 | + var l_ActiveDoc = wps.WpsApplication().ActiveDocument; | |
275 | + if (!l_ActiveDoc) { | |
276 | + alert("WPS当前没有可操作文档!") | |
277 | + return; | |
278 | + } | |
279 | + if (typeof bModal == "undefined" || bModal == null) { | |
280 | + bModal = true; | |
281 | + } | |
282 | + width *= window.devicePixelRatio; | |
283 | + height *= window.devicePixelRatio; | |
284 | + var url = getHtmlURL(html); | |
285 | + wps.ShowDialog(url, title, height, width, bModal); | |
286 | +} | |
287 | + | |
288 | +/** | |
289 | + * 解析返回response的参数 | |
290 | + * @param {*} resp | |
291 | + * @return {*} body | |
292 | + */ | |
293 | +function handleResultBody(resp) { | |
294 | + var result = ""; | |
295 | + if (resp.Body) { | |
296 | + // 解析返回response的参数 | |
297 | + } | |
298 | + return result; | |
299 | +} | |
300 | + | |
301 | + | |
302 | +/** | |
303 | + * 判断WPS中的文件个数是否为0,若为0则关闭WPS函数 | |
304 | + * @param {*} name | |
305 | + */ | |
306 | +function closeWpsIfNoDocument() { | |
307 | + var wpsApp = wps.WpsApplication(); | |
308 | + var docs = wpsApp.Documents; | |
309 | + if (!docs || docs.Count == 0) { | |
310 | + wps.ApiEvent.Cancel = true; | |
311 | + //根据业务可以选择是否退出进程 wpsApp.Quit(); | |
312 | + } | |
313 | +} | |
314 | + | |
315 | +export function activeTab() { | |
316 | + //启动WPS程序后,默认显示的工具栏选项卡为ribbon.xml中某一tab | |
317 | + if (wps.ribbonUI) | |
318 | + wps.ribbonUI.ActivateTab('wpsAddinTab'); | |
319 | +} | |
320 | + | |
321 | +// function showOATab() { | |
322 | +// wps.PluginStorage.setItem("ShowOATabDocActive", pCheckIfOADoc()); //根据文件是否为OA文件来显示OA菜单 | |
323 | +// wps.ribbonUI.Invalidate(); // 刷新Ribbon自定义按钮的状态 | |
324 | +// } | |
325 | + | |
326 | +function getDemoTemplatePath() { | |
327 | + var url = document.location.toString(); | |
328 | + url = decodeURI(url); | |
329 | + if (url.indexOf("/") != -1) { | |
330 | + url = url.substring(0, url.lastIndexOf("/")); | |
331 | + } | |
332 | + if (url.length !== 0) | |
333 | + url = url.concat("/template/红头文件.docx"); | |
334 | + | |
335 | + if (url.startsWith("file:///")) | |
336 | + url = url.substr("file:///".length); | |
337 | + return url; | |
338 | +} | |
339 | + | |
340 | +function getDemoSealPath() { | |
341 | + var url = document.location.toString(); | |
342 | + url = decodeURI(url); | |
343 | + if (url.indexOf("/") != -1) { | |
344 | + url = url.substring(0, url.lastIndexOf("/")); | |
345 | + } | |
346 | + if (url.length !== 0) | |
347 | + url = url.concat("/template/OA模板:公章.png"); | |
348 | + | |
349 | + if (url.startsWith("file:///")) | |
350 | + url = url.substr("file:///".length); | |
351 | + return url; | |
352 | +} | |
353 | + | |
354 | +function pGetParamName(data, attr) { | |
355 | + var start = data.indexOf(attr); | |
356 | + data = data.substring(start + attr.length); | |
357 | + return data; | |
358 | +} | |
359 | +/** | |
360 | + * 从requst中获取文件名(确保请求中有filename这个参数) | |
361 | + * @param {*} request | |
362 | + * @param {*} url | |
363 | + */ | |
364 | +function pGetFileName(request, url) { | |
365 | + var disposition = request.getResponseHeader("Content-Disposition"); | |
366 | + var filename = ""; | |
367 | + if (disposition) { | |
368 | + var matchs = pGetParamName(disposition, "filename="); | |
369 | + if (matchs) { | |
370 | + filename = decodeURIComponent(matchs); | |
371 | + } else { | |
372 | + filename = "petro" + Date.getTime(); | |
373 | + } | |
374 | + } else { | |
375 | + var filename = url.substring(url.lastIndexOf("/") + 1); | |
376 | + } | |
377 | + return filename; | |
378 | +} | |
379 | + | |
380 | +function StringToUint8Array(string) { | |
381 | + var binLen, buffer, chars, i, _i; | |
382 | + binLen = string.length; | |
383 | + buffer = new ArrayBuffer(binLen); | |
384 | + chars = new Uint8Array(buffer); | |
385 | + for (var i = 0; i < binLen; ++i) { | |
386 | + chars[i] = String.prototype.charCodeAt.call(string, i); | |
387 | + } | |
388 | + return buffer; | |
389 | +} | |
390 | +/** | |
391 | + * WPS下载文件到本地打开(业务系统可根据实际情况进行修改) | |
392 | + * @param {*} url 文件流的下载路径 | |
393 | + * @param {*} callback 下载后的回调 | |
394 | + */ | |
395 | +export function DownloadFile(url,fileName, callback) { | |
396 | + var xhr = new XMLHttpRequest(); | |
397 | + xhr.onreadystatechange = function () { | |
398 | + if (this.readyState == 4 && this.status == 200) { | |
399 | + //需要业务系统的服务端在传递文件流时,确保请求中的参数有filename | |
400 | + // var fileName = pGetFileName(xhr, url) | |
401 | + //落地打开模式下,WPS会将文件下载到本地的临时目录,在关闭后会进行清理 | |
402 | + var path = wps.Env.GetTempPath() + "/" + fileName | |
403 | + var reader = new FileReader(); | |
404 | + reader.onload = function () { | |
405 | + wps.FileSystem.writeAsBinaryString(path, reader.result); | |
406 | + callback(path); | |
407 | + }; | |
408 | + reader.readAsBinaryString(xhr.response); | |
409 | + } | |
410 | + } | |
411 | + xhr.open('GET', url); | |
412 | + xhr.responseType = 'blob'; | |
413 | + xhr.send(); | |
414 | +} | |
415 | +/** | |
416 | + * WPS上传文件到服务端(业务系统可根据实际情况进行修改,为了兼容中文,服务端约定用UTF-8编码格式) | |
417 | + * @param {*} strFileName 上传到服务端的文件名称(包含文件后缀) | |
418 | + * @param {*} strPath 上传文件的文件路径(文件在操作系统的绝对路径) | |
419 | + * @param {*} uploadPath 上传文件的服务端地址 | |
420 | + * @param {*} strFieldName 业务调用方自定义的一些内容可通过此字段传递,默认赋值'file' | |
421 | + * @param {*} OnSuccess 上传成功后的回调 | |
422 | + * @param {*} OnFail 上传失败后的回调 | |
423 | + */ | |
424 | +export function UploadFile(strFileName, strPath, uploadPath, strFieldName, params ,OnSuccess, OnFail) { | |
425 | + var xhr = new XMLHttpRequest(); | |
426 | + xhr.open('POST', uploadPath); | |
427 | + | |
428 | + var fileData = wps.FileSystem.readAsBinaryString(strPath); | |
429 | + | |
430 | + var data = new window.FakeFormData(); | |
431 | + | |
432 | + | |
433 | + if (strFieldName == "" || typeof strFieldName == "undefined"){//如果业务方没定义,默认设置为'file' | |
434 | + strFieldName = 'stream'; | |
435 | + } | |
436 | + | |
437 | + | |
438 | + | |
439 | + if(params != null && typeof params == "object"){ | |
440 | + const {nid,pid,token,tokenIdKey} = params; | |
441 | + if(nid != null){ | |
442 | + data.append("nid",nid); | |
443 | + data.append("reUploadNid",nid); | |
444 | + data.append("isReUpload",true); | |
445 | + } | |
446 | + | |
447 | + if(pid != null){ | |
448 | + data.append("pid",pid) | |
449 | + }; | |
450 | + | |
451 | + if(token != null) { | |
452 | + data.append("token",token); | |
453 | + if(tokenIdKey != null) | |
454 | + data.append(tokenIdKey,token) | |
455 | + else | |
456 | + data.append("DCI_TOKEN_ID",token); | |
457 | + } | |
458 | + | |
459 | + } | |
460 | + | |
461 | + data.append("stream", { | |
462 | + name: strFileName, //主要是考虑中文名的情况,服务端约定用utf-8来解码。 | |
463 | + type: "application/octet-stream", | |
464 | + getAsBinary: function () { | |
465 | + return fileData; | |
466 | + } | |
467 | + }); | |
468 | + | |
469 | + xhr.onreadystatechange = function () { | |
470 | + if (xhr.readyState == 4) { | |
471 | + if (xhr.status == 200) | |
472 | + OnSuccess(xhr.response) | |
473 | + else | |
474 | + OnFail(xhr.response); | |
475 | + } | |
476 | + }; | |
477 | + xhr.setRequestHeader("Cache-Control", "no-cache"); | |
478 | + xhr.setRequestHeader("X-Requested-With", "XMLHttpRequest"); | |
479 | + xhr.setRequestHeader("Accept", "*/*") | |
480 | + xhr.setRequestHeader("Access-Control-Allow-Origin", "*") | |
481 | + xhr.setRequestHeader("Access-Control-Allow-Credentials", "true") | |
482 | + // xhr.setRequestHeader("Accept-Encoding","gzip, deflate, br") | |
483 | + if (data.fake) { | |
484 | + xhr.setRequestHeader("Content-Type", "multipart/form-data; boundary=" + data.boundary); | |
485 | + var arr = StringToUint8Array(data.toString()); | |
486 | + xhr.send(arr); | |
487 | + } else { | |
488 | + xhr.send(data); | |
489 | + } | |
490 | +} | |
491 | + | |
492 | +// /** | |
493 | +// * 打开WPS后通知到业务系统,可根据需求扩展 | |
494 | +// * @param {*} p_Url 业务方接受请求的地址 | |
495 | +// */ | |
496 | +// function NotifyToServer(p_Url) { | |
497 | +// $.ajax({ | |
498 | +// url: p_Url, // URL + '/wps/wpsCanOpen', | |
499 | +// async: true, | |
500 | +// method: "post", | |
501 | +// dataType: 'json' | |
502 | +// }); | |
503 | +// } | |
504 | + | |
505 | +// /** | |
506 | +// * 更新编辑状态 | |
507 | +// * @param {*} p_Url 要传入OA端,通知业务系统,当前文档所处的编辑状态的URL地址路径 | |
508 | +// * @param {*} p_OpenUrl 当前文档从业务系统打开时的入口URL,这个URL包含业务系统开发者需要传入的ID等参数 | |
509 | +// * @param {*} docId 文档id | |
510 | +// * @param {*} state 0-正在编辑中 1-文件保存 2-文件关闭 状态可根据需要进行自定义扩展 | |
511 | +// */ | |
512 | +// function UpdateEditState(p_Url, p_OpenUrl, docId, state) { | |
513 | +// var formData = { | |
514 | +// "openUrl": p_OpenUrl, | |
515 | +// "docId": docId, | |
516 | +// "state": state | |
517 | +// }; | |
518 | +// $.ajax({ | |
519 | +// url: p_Url, //URL + '/document/stateMonitor', | |
520 | +// async: false, | |
521 | +// data: formData, | |
522 | +// method: "post", | |
523 | +// dataType: 'json', | |
524 | +// success: function (response) { | |
525 | +// if (response == "success") { | |
526 | +// console.log(response); | |
527 | +// } | |
528 | +// }, | |
529 | +// error: function (response) { | |
530 | +// console.log(response); | |
531 | +// } | |
532 | +// }); | |
533 | +// } | |
534 | + | |
535 | +// /** | |
536 | +// * 作用:判断文档关闭后,如果系统已经没有打开的文档了,则设置回初始用户名 | |
537 | +// */ | |
538 | +// function pSetWPSAppUserName() { | |
539 | +// //文档全部关闭的情况下,把WPS初始启动的用户名设置回去 | |
540 | +// if (wps.WpsApplication().Documents.Count == 1) { | |
541 | +// var l_strUserName = wps.PluginStorage.getItem(constStrEnum.WPSInitUserName); | |
542 | +// wps.WpsApplication().UserName = l_strUserName; | |
543 | +// } | |
544 | +// } | |
545 | + | |
546 | +/** | |
547 | + * 设置文档参数的属性值 | |
548 | + * @param {*} Doc | |
549 | + * @param {*} Key | |
550 | + * @param {*} Value | |
551 | + */ | |
552 | +function SetDocParamsValue(Doc, Key, Value) { | |
553 | + if (!Doc || !Key) { | |
554 | + return; | |
555 | + } | |
556 | + | |
557 | + var l_Params = wps.PluginStorage.getItem(Doc.DocID); | |
558 | + if (!l_Params) { | |
559 | + return; | |
560 | + } | |
561 | + | |
562 | + var l_objParams = JSON.parse(l_Params); | |
563 | + if (!(typeof(l_objParams) == "undefined")) { | |
564 | + l_objParams[Key] = Value; | |
565 | + } | |
566 | + | |
567 | + //把属性值整体再写回原来的文档ID中 | |
568 | + wps.PluginStorage.setItem(Doc.DocID, JSON.stringify(l_objParams)); | |
569 | +} | |
570 | + | |
571 | +export function GetDocParamsValue(Doc, Key) { | |
572 | + if (!Doc) { | |
573 | + return ""; | |
574 | + } | |
575 | + | |
576 | + var l_Params = wps.PluginStorage.getItem(Doc.DocID); | |
577 | + if (!l_Params) { | |
578 | + return ""; | |
579 | + } | |
580 | + | |
581 | + var l_objParams = JSON.parse(l_Params); | |
582 | + if (typeof(l_objParams) == "undefined") { | |
583 | + return ""; | |
584 | + } | |
585 | + | |
586 | + var l_rtnValue = l_objParams[Key]; | |
587 | + if (typeof(l_rtnValue) == "undefined" || l_rtnValue == null) { | |
588 | + return ""; | |
589 | + } | |
590 | + return l_rtnValue; | |
591 | +} | |
592 | + | |
593 | +function pIsOnlineOADoc(doc) { | |
594 | + var l_LandMode = GetDocParamsValue(doc, constStrEnum.OADocLandMode); //获取文档落地模式 | |
595 | + if (l_LandMode == "") { //用户本地打开的文档 | |
596 | + return false; | |
597 | + } | |
598 | + return l_LandMode == EnumDocLandMode.DLM_OnlineDoc; | |
599 | +} | |
600 | + | |
601 | +export function OnUploadToServerSuccess (info){ | |
602 | + if(info == undefined || info.length == 0) { | |
603 | + alert("请求处理失败!请检查是否允许跨域!") | |
604 | + } | |
605 | + if(info != null){ | |
606 | + if(typeof info === "string"){ | |
607 | + info = JSON.parse(info); | |
608 | + } | |
609 | + if(typeof info === "object"){ | |
610 | + if(info.code == 0 && info.success){ | |
611 | + alert(info.message || "上传成功!"); | |
612 | + return; | |
613 | + } | |
614 | + } | |
615 | + } | |
616 | + alert(info && info.message || info || "上传失败!"); | |
617 | +} | |
618 | + | |
619 | +export function OnUploadToServerFail (info){ | |
620 | + if(info == undefined || info.length == 0) { | |
621 | + alert("请求处理失败!请检查是否允许跨域!") | |
622 | + } | |
623 | + if( typeof info === "string"){ | |
624 | + info = JSON.parse(info); | |
625 | + } | |
626 | + alert(info && info.message || info || "上传失败!"); | |
627 | +} | |
628 | + | |
629 | + | |
630 | +function pInsertRInedHead(doc, strFile, bookmark) { | |
631 | + var bookMarks = doc.Bookmarks; | |
632 | + if (bookMarks.Item("quanwen")) { // 当前文档存在"quanwen"书签时候表示已经套过红头 | |
633 | + alert("当前文档已套过红头,请勿重复操作!"); | |
634 | + return; | |
635 | + } | |
636 | + | |
637 | + var wpsApp = wps.WpsApplication(); | |
638 | + var activeDoc = wpsApp.ActiveDocument; | |
639 | + var selection = wpsApp.ActiveWindow.Selection; | |
640 | + // 准备以非批注的模式插入红头文件(剪切/粘贴等操作会留有痕迹,故先关闭修订) | |
641 | + activeDoc.TrackRevisions = false; | |
642 | + selection.WholeStory(); //选取全文 | |
643 | + bookMarks.Add("quanwen", selection.Range) | |
644 | + selection.Cut(); | |
645 | + selection.InsertFile(strFile); | |
646 | + if (bookMarks.Exists(bookmark)) { | |
647 | + var bookmark1 = bookMarks.Item(bookmark); | |
648 | + bookmark1.Range.Select(); //获取指定书签位置 | |
649 | + var s = activeDoc.ActiveWindow.Selection; | |
650 | + s.Paste(); | |
651 | + } else { | |
652 | + alert("套红头失败,您选择的红头模板没有对应书签:" + bookmark); | |
653 | + } | |
654 | + | |
655 | + // 轮询插入书签 | |
656 | + var elements = GetDocParamsValue(doc, constStrEnum.redFileElement); | |
657 | + if (elements != "") { | |
658 | + for (var key in elements) { | |
659 | + console.log(key + "----" + elements[key]) | |
660 | + if (bookMarks.Exists(key)) { | |
661 | + // 直接插入 | |
662 | + var eleBookmark = bookMarks.Item(key); | |
663 | + eleBookmark.Range.Text = elements[key]; | |
664 | + } | |
665 | + } | |
666 | + } | |
667 | + | |
668 | + // 恢复修订模式(根据传入参数决定) | |
669 | + var l_revisionCtrl = GetDocParamsValue(activeDoc, constStrEnum.revisionCtrl); | |
670 | + activeDoc.TrackRevisions = l_revisionCtrl == "" ? false : l_revisionCtrl.bOpenRevision; | |
671 | + //取消WPS关闭时的提示信息 | |
672 | + wps.WpsApplication().DisplayAlerts = wps.Enum&&wps.Enum.wdAlertsNone||0; | |
673 | +} | |
674 | +/** | |
675 | + * 从OA-web端点击套红头 | |
676 | + * doc : 需要存在以下属性 | |
677 | + * 'insertFileUrl':'',获取红头模板接口 | |
678 | + * 'bkInsertFile':'' ,正文书签 | |
679 | + */ | |
680 | +export function InsertRedHeadDoc(doc) { //插入红头 | |
681 | + if (!doc) { | |
682 | + alert('文档不存在!'); | |
683 | + return; | |
684 | + } | |
685 | + | |
686 | + var bookmark = GetDocParamsValue(doc, constStrEnum.bkInsertFile); | |
687 | + var strFile = GetDocParamsValue(doc, constStrEnum.insertFileUrl); | |
688 | + if (strFile == "") { | |
689 | + alert("未获取到系统传入的红头模板URL路径,不能正常套红"); | |
690 | + return; | |
691 | + } | |
692 | + if (bookmark == "") { | |
693 | + alert("套红头失败,您选择的红头模板没有正文书签!"); | |
694 | + return; | |
695 | + } | |
696 | + | |
697 | + pInsertRInedHead(doc, strFile, bookmark) | |
698 | +} | ... | ... |
src/actions/dialog.js
0 → 100644
1 | +export const GETDOCNAME = "getDocName"; | |
2 | +export const CREATETASKPANE = "createTaskpane"; | |
3 | +export const NEWDOC = "newDoc"; | |
4 | +export const ADDSTRING = "addString"; | |
5 | +export const CLOSEDOC = "closeDoc"; | |
6 | +export const SETDEMOSPAN = "setDemoSpan"; | |
7 | +export const OPENWEB = "openWeb"; | |
8 | + | |
9 | +export function getDocName(data) { | |
10 | + return { type: GETDOCNAME, data } | |
11 | +} | |
12 | + | |
13 | +export function createTaskpane(data) { | |
14 | + return { type: CREATETASKPANE, data } | |
15 | +} | |
16 | + | |
17 | +export function newDoc(data) { | |
18 | + return { type: NEWDOC, data } | |
19 | +} | |
20 | + | |
21 | +export function addString(data) { | |
22 | + return { type: ADDSTRING, data } | |
23 | +} | |
24 | + | |
25 | +export function closeDoc(data) { | |
26 | + return { type: CLOSEDOC, data } | |
27 | +} | |
28 | + | |
29 | +export function setDemoSpan(data) { | |
30 | + return { type: SETDEMOSPAN, data } | |
31 | +} | |
32 | + | |
33 | +export function openWeb(data) { | |
34 | + return { type: OPENWEB, data } | |
35 | +} | |
\ No newline at end of file | ... | ... |
src/actions/enum.js
0 → 100644
1 | +/** | |
2 | + * WPS常用的API枚举值,具体参与API文档 | |
3 | + */ | |
4 | +export const WPS_Enum = { | |
5 | + wdDoNotSaveChanges: 0, | |
6 | + wdFormatPDF: 17, | |
7 | + wdFormatOpenDocumentText: 23, | |
8 | + wdFieldFormTextInput: 70, | |
9 | + wdAlertsNone: 0, | |
10 | + wdDialogFilePageSetup: 178, | |
11 | + wdDialogFilePrint: 88, | |
12 | + wdRelativeHorizontalPositionPage: 1, | |
13 | + wdGoToPage: 1, | |
14 | + wdPropertyPages: 14, | |
15 | + wdRDIComments: 1, | |
16 | + wdDialogInsertDateTime: 165, | |
17 | + msoCTPDockPositionLeft: 0, | |
18 | + msoCTPDockPositionRight: 2, | |
19 | + /** | |
20 | + * 将形状嵌入到文字中。 | |
21 | + */ | |
22 | + wdWrapInline: 7, | |
23 | + /** | |
24 | + * 将形状放在文字前面。 请参阅 wdWrapFront。 | |
25 | + */ | |
26 | + wdWrapNone: 3, | |
27 | + /** | |
28 | + * 使文字环绕形状。 行在形状的另一侧延续。 | |
29 | + */ | |
30 | + wdWrapSquare: 0, | |
31 | + /** | |
32 | + * 使文字环绕形状。 | |
33 | + */ | |
34 | + wdWrapThrough: 2, | |
35 | + /** | |
36 | + * 使文字紧密地环绕形状。 | |
37 | + */ | |
38 | + wdWrapTight: 1, | |
39 | + /** | |
40 | + * 将文字放在形状的上方和下方。 | |
41 | + */ | |
42 | + wdWrapTopBottom: 4, | |
43 | + /** | |
44 | + * 将形状放在文字后面。 | |
45 | + */ | |
46 | + wdWrapBehind: 5, | |
47 | + /** | |
48 | + * 将形状放在文字前面。 | |
49 | + */ | |
50 | + wdWrapFront: 6 | |
51 | +} | |
52 | + | |
53 | +/** | |
54 | + * WPS加载项自定义的枚举值 | |
55 | + */ | |
56 | + export const constStrEnum = { | |
57 | + AllowOADocReOpen: "AllowOADocReOpen", | |
58 | + AutoSaveToServerTime: "AutoSaveToServerTime", | |
59 | + bkInsertFile: "bkInsertFile", | |
60 | + buttonGroups: "buttonGroups", | |
61 | + CanSaveAs: "CanSaveAs", | |
62 | + copyUrl: "copyUrl", | |
63 | + DefaultUploadFieldName: "DefaultUploadFieldName", | |
64 | + disableBtns: "disableBtns", | |
65 | + insertFileUrl: "insertFileUrl", | |
66 | + IsInCurrOADocOpen: "IsInCurrOADocOpen", | |
67 | + IsInCurrOADocSaveAs: "IsInCurrOADocSaveAs", | |
68 | + isOA: "isOA", | |
69 | + notifyUrl: "notifyUrl", | |
70 | + OADocCanSaveAs: "OADocCanSaveAs", | |
71 | + OADocLandMode: "OADocLandMode", | |
72 | + OADocUserSave: "OADocUserSave", | |
73 | + openType: "openType", | |
74 | + picPath: "picPath", | |
75 | + picHeight: "picHeight", | |
76 | + picWidth: "picWidth", | |
77 | + redFileElement: "redFileElement", | |
78 | + revisionCtrl: "revisionCtrl", | |
79 | + ShowOATabDocActive: "ShowOATabDocActive", | |
80 | + SourcePath: "SourcePath", | |
81 | + /** | |
82 | + * 保存文档到业务系统服务端时,另存一份其他格式到服务端,其他格式支持:.pdf .ofd .uot .uof | |
83 | + */ | |
84 | + suffix: "suffix", | |
85 | + templateDataUrl: "templateDataUrl", | |
86 | + TempTimerID: "TempTimerID", | |
87 | + /** | |
88 | + * 文档上传到业务系统的保存地址:服务端接收文件流的地址 | |
89 | + */ | |
90 | + uploadPath: "uploadPath", | |
91 | + /** | |
92 | + * 文档上传到服务端后的名称 | |
93 | + */ | |
94 | + uploadFieldName: "uploadFieldName", | |
95 | + /** | |
96 | + * 文档上传时的名称,默认取当前活动文档的名称 | |
97 | + */ | |
98 | + uploadFileName: "uploadFileName", | |
99 | + uploadAppendPath: "uploadAppendPath", | |
100 | + /** | |
101 | + * 标志位: 1 在保存到业务系统时再保存一份suffix格式的文档, 需要和suffix参数配合使用 | |
102 | + */ | |
103 | + uploadWithAppendPath: "uploadWithAppendPath", | |
104 | + userName: "userName", | |
105 | + WPSInitUserName: "WPSInitUserName", | |
106 | + taskpaneid: "taskpaneid", | |
107 | + /** | |
108 | + * 是否弹出上传前确认和成功后的确认信息:true|弹出,false|不弹出 | |
109 | + */ | |
110 | + Save2OAShowConfirm: "Save2OAShowConfirm", | |
111 | + /** | |
112 | + * 修订状态标志位 | |
113 | + */ | |
114 | + RevisionEnableFlag: "RevisionEnableFlag" | |
115 | +} | |
116 | + | |
117 | +export const EnumOAFlag = { | |
118 | + DocFromOA: 1, | |
119 | + DocFromNoOA: 0 | |
120 | +} | |
121 | + | |
122 | +//记录是否用户点击OA文件的保存按钮 | |
123 | +export const EnumDocSaveFlag = { | |
124 | + OADocSave: 1, | |
125 | + NoneOADocSave: 0 | |
126 | +} | |
127 | + | |
128 | +//标识文档的落地模式 本地文档落地 0 ,不落地 1 | |
129 | +export const EnumDocLandMode = { | |
130 | + DLM_LocalDoc: 0, | |
131 | + DLM_OnlineDoc: 1 | |
132 | +} | |
\ No newline at end of file | ... | ... |
src/actions/formdata.js
0 → 100644
1 | +/* | |
2 | + * @Descripttion: | |
3 | + * @version: | |
4 | + * @Author: 魏永康 | |
5 | + * @Date: 2021-04-21 18:59:57 | |
6 | + * @LastEditors: sueRimn | |
7 | + * @LastEditTime: 2021-04-21 19:17:11 | |
8 | + */ | |
9 | +/** | |
10 | + * Emulate FormData for some browsers | |
11 | + * MIT License | |
12 | + * (c) 2010 François de Metz | |
13 | + */ | |
14 | +(function(w) { | |
15 | + if (w.FakeFormData) | |
16 | + return; | |
17 | + function FormData() { | |
18 | + this.fake = true; | |
19 | + this.boundary = "------WebKitFormBoundary" + Math.random(); | |
20 | + this._fields = []; | |
21 | + } | |
22 | + FormData.prototype.append = function(key, value) { | |
23 | + this._fields.push([key, value]); | |
24 | + } | |
25 | + FormData.prototype.toString = function() { | |
26 | + var boundary = this.boundary; | |
27 | + var body = ""; | |
28 | + this._fields.forEach(function(field) { | |
29 | + body += "--" + boundary + "\r\n"; | |
30 | + // file upload | |
31 | + if (field[1].name) { | |
32 | + var file = field[1]; | |
33 | + body += "Content-Disposition: form-data; name=\""+ field[0] +"\"; filename=\""+ file.name +"\"\r\n"; | |
34 | + body += "Content-Type: "+ file.type +"\r\n\r\n"; | |
35 | + body += file.getAsBinary() + "\r\n"; | |
36 | + } else { | |
37 | + body += "Content-Disposition: form-data; name=\""+ field[0] +"\";\r\n\r\n"; | |
38 | + body += field[1] + "\r\n"; | |
39 | + } | |
40 | + }); | |
41 | + body += "--" + boundary +"--"; | |
42 | + return body; | |
43 | + } | |
44 | + w.FakeFormData = FormData; | |
45 | +})(window); | |
\ No newline at end of file | ... | ... |
src/actions/index.js
0 → 100644
src/actions/systemAddin.js
0 → 100644
1 | +/* | |
2 | + * @Descripttion: | |
3 | + * @version: | |
4 | + * @Author: 魏永康 | |
5 | + * @Date: 2021-04-20 16:18:53 | |
6 | + * @LastEditors: sueRimn | |
7 | + * @LastEditTime: 2021-04-25 15:09:17 | |
8 | + */ | |
9 | + | |
10 | +import {GetDocParamsValue,UploadFile,OnUploadToServerSuccess,OnUploadToServerFail,OnShowDialog,InsertRedHeadDoc,DownloadFile} from "./common.js" | |
11 | +import {constStrEnum,EnumDocSaveFlag} from "./enum.js" | |
12 | + | |
13 | +var wps = window.wps||window | |
14 | + | |
15 | + | |
16 | +// 初始化 | |
17 | + function initWpsAddin() { | |
18 | + if(wps.FileSystem.Exists(wps.Env.GetTempPath())){ | |
19 | + wps.FileSystem.Remove(wps.Env.GetTempPath()); | |
20 | + wps.FileSystem.Mkdir(wps.Env.GetTempPath()) | |
21 | + } | |
22 | +} | |
23 | + | |
24 | +// 保存 | |
25 | +function OnSaveToServer() { | |
26 | + // console.log('SaveToServer'); | |
27 | + var doc = wps.WpsApplication().ActiveDocument; | |
28 | + if (!doc) { | |
29 | + alert("空文档不能保存!"); | |
30 | + return; | |
31 | + } | |
32 | + | |
33 | + var param = wps.PluginStorage.getItem(doc.DocID); | |
34 | + | |
35 | + if(typeof param == "string") param = JSON.parse(param); | |
36 | + | |
37 | + if(param == null || param.OADocLandMode === 0 ) { | |
38 | + wps.WpsApplication().CommandBars.ExecuteMso("SaveAll"); | |
39 | + return; | |
40 | + } | |
41 | + | |
42 | + | |
43 | + | |
44 | + | |
45 | + let {tokenIdKey,nid,token,openUrl,writeUrl,fullName} = param; | |
46 | + if(tokenIdKey == null ||nid == null || token == null || openUrl == null || writeUrl == null || fullName == null){ | |
47 | + alert("取参数失败,请确定此文档是OA文档,tokenIdKey,nid,token,openUrl,writeUrl,fullName 参数取值不可为空!") | |
48 | + } | |
49 | + | |
50 | + | |
51 | + // //非OA文档,不能上传到OA | |
52 | + // if (pCheckIfOADoc() == false) { | |
53 | + // alert("非系统打开的文档,不能直接上传到系统!"); | |
54 | + // return; | |
55 | + // } | |
56 | + | |
57 | + // //如果是OA打开的文档,并且设置了保护的文档,则不能再上传到OA服务器 | |
58 | + // if (pISOADocReadOnly(doc)) { | |
59 | + // wps.alert("系统设置了保护的文档,不能再提交到系统后台。"); | |
60 | + // return; | |
61 | + // } | |
62 | + | |
63 | + /** | |
64 | + * 参数定义:OAAsist.UploadFile(name, path, url, field, "OnSuccess", "OnFail") | |
65 | + * 上传一个文件到远程服务器。 | |
66 | + * name:为上传后的文件名称; | |
67 | + * path:是文件绝对路径; | |
68 | + * url:为上传地址; | |
69 | + * field:为请求中name的值; | |
70 | + * 最后两个参数为回调函数名称; | |
71 | + */ | |
72 | + | |
73 | + | |
74 | + var l_showConfirm = wps.PluginStorage.getItem(constStrEnum.Save2OAShowConfirm) | |
75 | + if (l_showConfirm) { | |
76 | + if (!wps.confirm("先保存文档,并开始上传到系统后台,请确认?")) { | |
77 | + return; | |
78 | + } | |
79 | + } | |
80 | + | |
81 | + var l_FieldName = GetDocParamsValue(doc, constStrEnum.uploadFieldName); //上载到后台的业务方自定义的字段名称 | |
82 | + if (l_FieldName == "") { | |
83 | + l_FieldName = wps.PluginStorage.getItem(constStrEnum.DefaultUploadFieldName); // 默认为‘file’ | |
84 | + } | |
85 | + | |
86 | + var l_UploadName = GetDocParamsValue(doc, constStrEnum.uploadFileName); //设置OA传入的文件名称参数 | |
87 | + if (l_UploadName == "") { | |
88 | + l_UploadName = doc.Name; //默认文件名称就是当前文件编辑名称 | |
89 | + } | |
90 | + | |
91 | + var docPath = doc.FullName; // 文件所在路径 | |
92 | + | |
93 | + // if (pIsOnlineOADoc(doc) == false) { | |
94 | + //对于本地磁盘文件上传OA,先用Save方法保存后,再上传 | |
95 | + //设置用户保存按钮标志,避免出现禁止OA文件保存的干扰信息 | |
96 | + wps.PluginStorage.setItem(constStrEnum.OADocUserSave, EnumDocSaveFlag.OADocSave); | |
97 | + doc.Save(); //执行一次保存方法 | |
98 | + //设置用户保存按钮标志 | |
99 | + wps.PluginStorage.setItem(constStrEnum.OADocUserSave, EnumDocSaveFlag.NoneOADocSave); | |
100 | + //落地文档,调用UploadFile方法上传到OA后台 | |
101 | + try { | |
102 | + //调用OA助手的上传方法 | |
103 | + UploadFile(fullName, docPath, writeUrl, null,param, OnUploadToServerSuccess, OnUploadToServerFail); | |
104 | + } catch (err) { | |
105 | + alert("上传文件失败!请检查系统上传参数及网络环境!"); | |
106 | + } | |
107 | + // } else { | |
108 | + // // 不落地的文档,调用 Document 对象的不落地上传方法 | |
109 | + // wps.PluginStorage.setItem(constStrEnum.OADocUserSave, EnumDocSaveFlag.OADocSave); | |
110 | + // try { | |
111 | + // //调用不落地上传方法 | |
112 | + // doc.SaveAsUrl(l_UploadName, l_uploadPath, l_FieldName, "OnUploadToServerSuccess", "OnUploadToServerFail"); | |
113 | + // } catch (err) { | |
114 | + // alert("上传文件失败!请检查系统上传参数及网络环境,重新上传。"); | |
115 | + // } | |
116 | + // wps.PluginStorage.setItem(constStrEnum.OADocUserSave, EnumDocSaveFlag.NoneOADocSave); | |
117 | + // } | |
118 | + | |
119 | + // //获取OA传入的 转其他格式上传属性 | |
120 | + // var l_suffix = GetDocParamsValue(doc, constStrEnum.suffix); | |
121 | + // if (l_suffix == "") { | |
122 | + // console.log("上传需转换的文件后缀名错误,无法进行转换上传!"); | |
123 | + // return; | |
124 | + // } | |
125 | + | |
126 | + //判断是否同时上传PDF等格式到OA后台 | |
127 | + var l_uploadWithAppendPath = GetDocParamsValue(doc, constStrEnum.uploadWithAppendPath); //标识是否同时上传suffix格式的文档 | |
128 | + if (l_uploadWithAppendPath == "1") { | |
129 | + //调用转pdf格式函数,强制关闭转换修订痕迹,不弹出用户确认的对话框 | |
130 | + // pDoChangeToOtherDocFormat(doc, l_suffix, false, false); | |
131 | + } | |
132 | + return; | |
133 | +} | |
134 | + | |
135 | +export function OnInsertRedHeaderClick() { | |
136 | + var l_Doc = wps.WpsApplication().ActiveDocument; | |
137 | + if (!l_Doc) { | |
138 | + return; | |
139 | + } | |
140 | + var l_insertFileUrl = GetDocParamsValue(l_Doc, constStrEnum.insertFileUrl); //插入文件的位置 | |
141 | + var l_BkFile = GetDocParamsValue(l_Doc, constStrEnum.bkInsertFile); | |
142 | + if (l_BkFile == "" || l_insertFileUrl == "") { | |
143 | + var height = 250; | |
144 | + var width = 400; | |
145 | + OnShowDialog("redhead.html", "OA助手", width, height); | |
146 | + return; | |
147 | + } | |
148 | + InsertRedHeadDoc(l_Doc); | |
149 | +} | |
150 | + | |
151 | + | |
152 | +function openWebFile(param){ | |
153 | + if(param == null) { | |
154 | + return {code:-1,msg:"参数错误!"} | |
155 | + } | |
156 | + | |
157 | + let {tokenIdKey,nid,token,openUrl,writeUrl,fullName} = param; | |
158 | + | |
159 | + if(tokenIdKey == null ||nid == null || token == null || openUrl == null || writeUrl == null || fullName == null){ | |
160 | + return {code:-1,msg:"参数错误!tokenIdKey,nid,token,openUrl,writeUrl,fullName 不可为空"} | |
161 | + } | |
162 | + | |
163 | + let url = `${openUrl}?nid=${nid}&token=${token}`; | |
164 | + | |
165 | + DownloadFile( | |
166 | + url, | |
167 | + fullName, | |
168 | + (path) => { | |
169 | + let doc = wps | |
170 | + .WpsApplication() | |
171 | + .Documents.Open(path, false, false, false, ""); | |
172 | + | |
173 | + if (!doc) return; | |
174 | + var l_Param = wps.PluginStorage.getItem(doc.DocID); | |
175 | + if(l_Param == null) { | |
176 | + l_Param = param; | |
177 | + }else if(typeof l_Param == "string"){ | |
178 | + l_Param = JSON.parse(l_Param); | |
179 | + } | |
180 | + //增加属性,或设置 | |
181 | + l_Param.OADocLandMode = 0; //设置OA文档的落地标志 | |
182 | + | |
183 | + //将OA文档落地模式标志存入系统变量对象保存 | |
184 | + | |
185 | + wps.PluginStorage.setItem(doc.DocID,JSON.stringify(param) ); | |
186 | + // 把WPS对象置前 | |
187 | + wps.WpsApplication().WindowState = 1; | |
188 | + wps.WpsApplication().Activate(); | |
189 | + } | |
190 | + ); | |
191 | +} | |
192 | + | |
193 | +export function onWebEvent(param){ | |
194 | + if(param == undefined || param.eventType == undefined){ | |
195 | + return {code:-1,msg:"无此类型!"} | |
196 | + } | |
197 | + | |
198 | + let eventType = param.eventType; | |
199 | + | |
200 | + switch (eventType){ | |
201 | + case "openOfficeEidt": | |
202 | + return openWebFile(param); | |
203 | + break; | |
204 | + | |
205 | + default: | |
206 | + return {code:-1,msg:`无此类型【${eventType}】`} | |
207 | + | |
208 | + } | |
209 | + | |
210 | +} | |
211 | + | |
212 | +export default {onWebEvent,openWebFile,OnSaveToServer,initWpsAddin} | |
\ No newline at end of file | ... | ... |
src/actions/taskpane.js
0 → 100644
1 | +export const DOCKLEFT = "dockLeft"; | |
2 | +export const DOCKRIGHT = "dockRight"; | |
3 | +export const HIDETASKPANE = "hideTaskPane"; | |
4 | +export const ADDSTRING = "addString"; | |
5 | +export const GETDOCNAME = "getDocName"; | |
6 | +export const SETDEMOSPAN = "setDemoSpan"; | |
7 | +export const OPENWEB = "openWeb"; | |
8 | + | |
9 | + | |
10 | +export function dockLeft(data) { | |
11 | + return { type: DOCKLEFT, data } | |
12 | +} | |
13 | + | |
14 | +export function dockRight(data) { | |
15 | + return { type: DOCKRIGHT, data } | |
16 | +} | |
17 | + | |
18 | +export function hideTaskPane(data) { | |
19 | + return { type: HIDETASKPANE, data } | |
20 | +} | |
21 | + | |
22 | +export function addString(data) { | |
23 | + return { type: ADDSTRING, data } | |
24 | +} | |
25 | + | |
26 | +export function getDocName(data) { | |
27 | + return { type: GETDOCNAME, data } | |
28 | +} | |
29 | + | |
30 | +export function setDemoSpan(data) { | |
31 | + return { type: SETDEMOSPAN, data } | |
32 | +} | |
33 | + | |
34 | +export function openWeb(data) { | |
35 | + return { type: OPENWEB, data } | |
36 | +} | |
\ No newline at end of file | ... | ... |
src/components/app.js
0 → 100644
1 | +import React, { Component } from 'react'; | |
2 | +import ribbon from './ribbon'; | |
3 | + | |
4 | + | |
5 | +class App extends Component { | |
6 | + constructor(props) { | |
7 | + super(props) | |
8 | + this.state = { | |
9 | + } | |
10 | + console.log("init ribbon") | |
11 | + window.ribbon = ribbon; | |
12 | + } | |
13 | + | |
14 | + render() { | |
15 | + return ( | |
16 | + <div> | |
17 | + this is index.html | |
18 | + </div> | |
19 | + ) | |
20 | + } | |
21 | +} | |
22 | + | |
23 | +export default App; | ... | ... |
src/components/dialog.css
0 → 100644
1 | +button { | |
2 | + margin: 4px; | |
3 | +} | |
4 | + | |
5 | +.global{ | |
6 | + font-size: 15px; | |
7 | + min-height: 95%; | |
8 | +} | |
9 | + | |
10 | +.divItem { | |
11 | + margin-left: 5px; | |
12 | + margin-bottom: 18px; | |
13 | + font-size: 15px; | |
14 | + word-wrap: break-word; | |
15 | +} | |
16 | + | |
17 | +.debug { | |
18 | + font-weight: bolder; | |
19 | +} | |
20 | + | |
21 | +.docs { | |
22 | + font-weight: bolder; | |
23 | + color: slateblue; | |
24 | +} | |
\ No newline at end of file | ... | ... |
src/components/dialog.js
0 → 100644
1 | +import React, { Component } from 'react'; | |
2 | +import { connect } from 'react-redux'; | |
3 | +import { getDocName, createTaskpane, newDoc, addString, closeDoc, setDemoSpan, openWeb } from '../actions/dialog'; | |
4 | +import './dialog.css'; | |
5 | +import axios from 'axios' | |
6 | + | |
7 | + | |
8 | +class Dialog extends Component { | |
9 | + constructor(props) { | |
10 | + super(props); | |
11 | + this.state = { | |
12 | + }; | |
13 | + } | |
14 | + | |
15 | + componentDidMount() { | |
16 | + axios.get('/.debugTemp/NotifyDemoUrl').then((res) => { | |
17 | + const { setDemoSpan } = this.props; | |
18 | + setDemoSpan(res.data); | |
19 | + }); | |
20 | + } | |
21 | + | |
22 | + onDocNameClick = () => { | |
23 | + const { getDocName } = this.props; | |
24 | + getDocName(); | |
25 | + } | |
26 | + | |
27 | + onCreateTaskpane = () => { | |
28 | + const { createTaskpane } = this.props; | |
29 | + createTaskpane(); | |
30 | + } | |
31 | + | |
32 | + onCreateDoc = () => { | |
33 | + const { newDoc } = this.props; | |
34 | + newDoc(); | |
35 | + } | |
36 | + | |
37 | + onAddString = () => { | |
38 | + const { addString } = this.props; | |
39 | + addString(); | |
40 | + } | |
41 | + | |
42 | + onCloseDoc = () => { | |
43 | + const { closeDoc } = this.props; | |
44 | + closeDoc(); | |
45 | + } | |
46 | + | |
47 | + onOpenWeb = () => { | |
48 | + const { openWeb } = this.props; | |
49 | + openWeb(); | |
50 | + } | |
51 | + | |
52 | + render() { | |
53 | + const { docName, demoSpan } = this.props; | |
54 | + | |
55 | + return ( | |
56 | + <div> | |
57 | + <div className="divItem"> | |
58 | + 这是一个网页,按<span className="debug">"F12"</span>可以打开调试器。 | |
59 | + </div> | |
60 | + <div className="divItem"> | |
61 | + 这个示例展示了wps加载项的相关基础能力,与B/S业务系统的交互,请用浏览器打开: | |
62 | + <span className="docs" onClick={this.onOpenWeb}>{demoSpan}</span> | |
63 | + </div> | |
64 | + <div className="divItem">开发文档: <span className="docs">https://open.wps.cn/docs/office</span></div> | |
65 | + <div> | |
66 | + <button onClick={this.onDocNameClick}>取文件名</button> | |
67 | + <button onClick={this.onCreateTaskpane}>创建任务窗格</button> | |
68 | + <button onClick={this.onCreateDoc}>新建文件</button> | |
69 | + <button onClick={this.onAddString}>文档开头添加字符串</button> | |
70 | + <button onClick={this.onCloseDoc}>关闭文件</button> | |
71 | + </div> | |
72 | + <hr /> | |
73 | + <div>文档文件名为:<span>{docName}</span></div> | |
74 | + </div> | |
75 | + ) | |
76 | + } | |
77 | +} | |
78 | + | |
79 | +const mapStateToProps = state => { | |
80 | + return { | |
81 | + docName: state.dialog.get('docName'), | |
82 | + demoSpan: state.dialog.get('demoSpan'), | |
83 | + } | |
84 | +} | |
85 | + | |
86 | +export default connect(mapStateToProps, { | |
87 | + getDocName, | |
88 | + createTaskpane, | |
89 | + newDoc, | |
90 | + addString, | |
91 | + closeDoc, | |
92 | + setDemoSpan, | |
93 | + openWeb | |
94 | +})(Dialog); | ... | ... |
src/components/ribbon.js
0 → 100644
1 | +import Util from "../js/util.js"; | |
2 | +import SystemDemo from "../js/systemdemo.js"; | |
3 | +import { | |
4 | + DownloadFile | |
5 | +} from "../actions/common.js"; | |
6 | + | |
7 | +import SystemAddin,{onWebEvent} from "../actions/systemAddin.js"; | |
8 | +/* global wps:false */ | |
9 | +var WebNotifycount = 0; | |
10 | + | |
11 | +var ribbon = { | |
12 | + //这个函数在整个wps加载项中是第一个执行的 | |
13 | + OnAddinLoad: function (ribbonUI) { | |
14 | + if (typeof wps.ribbonUI != "object") { | |
15 | + wps.ribbonUI = ribbonUI; | |
16 | + } | |
17 | + | |
18 | + if (typeof wps.Enum != "object") { | |
19 | + // 如果没有内置枚举值 | |
20 | + wps.Enum = Util.WPS_Enum; | |
21 | + } | |
22 | + | |
23 | + //这几个导出函数是给外部业务系统调用的 | |
24 | + window.openOfficeFileFromSystemDemo = | |
25 | + SystemDemo.openOfficeFileFromSystemDemo; | |
26 | + window.InvokeFromSystemDemo = SystemDemo.InvokeFromSystemDemo; | |
27 | + | |
28 | + window.onWebEvent = onWebEvent; | |
29 | + | |
30 | + wps.PluginStorage.setItem("EnableFlag", false); //往PluginStorage中设置一个标记,用于控制两个按钮的置灰 | |
31 | + wps.PluginStorage.setItem("ApiEventFlag", false); //往PluginStorage中设置一个标记,用于控制ApiEvent的按钮label | |
32 | + wps.ribbonUI.ActivateTab('SystemAddin'); // 切换tab | |
33 | + SystemAddin.initWpsAddin(); | |
34 | + | |
35 | + return true; | |
36 | + }, | |
37 | + | |
38 | + OnAction: function (control) { | |
39 | + const eleId = control.Id; | |
40 | + switch (eleId) { | |
41 | + case "btnShowMsg": { | |
42 | + const doc = wps.WpsApplication().ActiveDocument; | |
43 | + if (!doc) { | |
44 | + alert("当前没有打开任何文档"); | |
45 | + return; | |
46 | + } | |
47 | + alert(doc.Name); | |
48 | + } | |
49 | + break; | |
50 | + case "btnIsEnbable": { | |
51 | + let bFlag = wps.PluginStorage.getItem("EnableFlag"); | |
52 | + wps.PluginStorage.setItem("EnableFlag", !bFlag); | |
53 | + | |
54 | + //通知wps刷新以下几个按饰的状态 | |
55 | + wps.ribbonUI.InvalidateControl("btnIsEnbable"); | |
56 | + wps.ribbonUI.InvalidateControl("btnShowDialog"); | |
57 | + wps.ribbonUI.InvalidateControl("btnShowTaskPane"); | |
58 | + //wps.ribbonUI.Invalidate(); 这行代码打开则是刷新所有的按钮状态 | |
59 | + break; | |
60 | + } | |
61 | + case "btnShowDialog": | |
62 | + wps.ShowDialog( | |
63 | + Util.GetUrlPath() + "dialog", | |
64 | + "这是一个对话框网页", | |
65 | + 400 * window.devicePixelRatio, | |
66 | + 400 * window.devicePixelRatio, | |
67 | + false | |
68 | + ); | |
69 | + break; | |
70 | + case "btnShowTaskPane": { | |
71 | + let tsId = wps.PluginStorage.getItem("taskpane_id"); | |
72 | + if (!tsId) { | |
73 | + let tskpane = wps.CreateTaskPane(Util.GetUrlPath() + "taskpane"); | |
74 | + let id = tskpane.ID; | |
75 | + wps.PluginStorage.setItem("taskpane_id", id); | |
76 | + tskpane.Visible = true; | |
77 | + } else { | |
78 | + let tskpane = wps.GetTaskPane(tsId); | |
79 | + tskpane.Visible = !tskpane.Visible; | |
80 | + } | |
81 | + } | |
82 | + break; | |
83 | + case "btnApiEvent": { | |
84 | + let bFlag = wps.PluginStorage.getItem("ApiEventFlag"); | |
85 | + let bRegister = bFlag ? false : true; | |
86 | + wps.PluginStorage.setItem("ApiEventFlag", bRegister); | |
87 | + if (bRegister) { | |
88 | + wps.ApiEvent.AddApiEventListener( | |
89 | + "DocumentNew", | |
90 | + "ribbon.OnNewDocumentApiEvent" | |
91 | + ); | |
92 | + } else { | |
93 | + wps.ApiEvent.RemoveApiEventListener( | |
94 | + "DocumentNew", | |
95 | + "ribbon.OnNewDocumentApiEvent" | |
96 | + ); | |
97 | + } | |
98 | + | |
99 | + wps.ribbonUI.InvalidateControl("btnApiEvent"); | |
100 | + } | |
101 | + break; | |
102 | + case "btnWebNotify": { | |
103 | + let currentTime = new Date(); | |
104 | + let timeStr = | |
105 | + currentTime.getHours() + | |
106 | + ":" + | |
107 | + currentTime.getMinutes() + | |
108 | + ":" + | |
109 | + currentTime.getSeconds(); | |
110 | + wps.OAAssist.WebNotify( | |
111 | + "这行内容由wps加载项主动送达给业务系统,可以任意自定义, 比如时间值:" + | |
112 | + timeStr + | |
113 | + ",次数:" + | |
114 | + ++WebNotifycount, | |
115 | + true | |
116 | + ); | |
117 | + } | |
118 | + break; | |
119 | + case "btnOpenWebFile": { | |
120 | + DownloadFile( | |
121 | + "https://apps.chinadci.com/api/attach/stream/open.do?nid=uMLA3veiVV92b8mUGSW&token=3e299484-5286-4bc5-a538-0ab1bdeecfbc", | |
122 | + "收 入 证 明 .docx", | |
123 | + (path) => { | |
124 | + let doc = wps | |
125 | + .WpsApplication() | |
126 | + .Documents.Open(path, false, false, false, ""); | |
127 | + | |
128 | + if (!doc) return; | |
129 | + var l_Param = wps.PluginStorage.getItem(doc.DocID); | |
130 | + var l_objParam = JSON.parse(l_Param); | |
131 | + //增加属性,或设置 | |
132 | + l_objParam.OADocLandMode = 0; //设置OA文档的落地标志 | |
133 | + | |
134 | + var l_p = JSON.stringify(l_objParam); | |
135 | + //将OA文档落地模式标志存入系统变量对象保存 | |
136 | + | |
137 | + wps.PluginStorage.setItem(doc.DocID, l_p); | |
138 | + // 把WPS对象置前 | |
139 | + wps.WpsApplication().WindowState = 1; | |
140 | + wps.WpsApplication().Activate(); | |
141 | + } | |
142 | + ); | |
143 | + } | |
144 | + break; | |
145 | + case "btnSaveToServer": | |
146 | + { | |
147 | + SystemAddin.OnSaveToServer() | |
148 | + } | |
149 | + break; | |
150 | + case "btnInsertRedHeader": | |
151 | + { | |
152 | + | |
153 | + } | |
154 | + break; | |
155 | + default: | |
156 | + case "FileSave": | |
157 | + { | |
158 | + let doc = wps.WpsApplication().ActiveDocument; | |
159 | + if (!doc) { | |
160 | + alert("空文档不能保存!"); | |
161 | + return; | |
162 | + } | |
163 | + | |
164 | + let param = wps.PluginStorage.getItem(doc.DocID); | |
165 | + | |
166 | + if(param != null){ | |
167 | + param = JSON.parse(param); | |
168 | + if(param.OADocLandMode == 0){ | |
169 | + SystemAddin.OnSaveToServer(); | |
170 | + return; | |
171 | + } | |
172 | + } | |
173 | + | |
174 | + } | |
175 | + break; | |
176 | + } | |
177 | + return true; | |
178 | + }, | |
179 | + | |
180 | + GetImage: function (control) { | |
181 | + const eleId = control.Id; | |
182 | + switch (eleId) { | |
183 | + case "btnShowMsg": | |
184 | + return "images/1.svg"; | |
185 | + case "btnShowDialog": | |
186 | + return "images/2.svg"; | |
187 | + case "btnShowTaskPane": | |
188 | + return "images/3.svg"; | |
189 | + default: | |
190 | + } | |
191 | + return "images/newFromTemp.svg"; | |
192 | + }, | |
193 | + | |
194 | + OnGetEnabled: function (control) { | |
195 | + const eleId = control.Id; | |
196 | + switch (eleId) { | |
197 | + case "btnShowMsg": | |
198 | + return true; | |
199 | + case "btnShowDialog": { | |
200 | + let bFlag = wps.PluginStorage.getItem("EnableFlag"); | |
201 | + return bFlag; | |
202 | + } | |
203 | + case "btnShowTaskPane": { | |
204 | + let bFlag = wps.PluginStorage.getItem("EnableFlag"); | |
205 | + return bFlag; | |
206 | + } | |
207 | + default: | |
208 | + break; | |
209 | + } | |
210 | + return true; | |
211 | + }, | |
212 | + | |
213 | + OnGetVisible: function (control) { | |
214 | + const eleId = control.Id; | |
215 | + console.log(eleId); | |
216 | + return true; | |
217 | + }, | |
218 | + | |
219 | + OnGetLabel: function (control) { | |
220 | + const eleId = control.Id; | |
221 | + switch (eleId) { | |
222 | + case "btnIsEnbable": { | |
223 | + let bFlag = wps.PluginStorage.getItem("EnableFlag"); | |
224 | + return bFlag ? "按钮Disable" : "按钮Enable"; | |
225 | + } | |
226 | + case "btnApiEvent": { | |
227 | + let bFlag = wps.PluginStorage.getItem("ApiEventFlag"); | |
228 | + return bFlag ? "清除新建文件事件" : "注册新建文件事件"; | |
229 | + } | |
230 | + default: | |
231 | + break; | |
232 | + } | |
233 | + return ""; | |
234 | + }, | |
235 | + | |
236 | + OnNewDocumentApiEvent: function (doc) { | |
237 | + alert("新建文件事件响应,取文件名: " + doc.Name); | |
238 | + }, | |
239 | +}; | |
240 | + | |
241 | +export default ribbon; | |
\ No newline at end of file | ... | ... |
src/components/taskpane.js
0 → 100644
1 | +import React, { Component } from 'react'; | |
2 | +import { connect } from 'react-redux'; | |
3 | +import { dockLeft, dockRight, hideTaskPane, addString, getDocName, setDemoSpan, openWeb } from '../actions/taskpane'; | |
4 | +import './dialog.css'; | |
5 | +import axios from 'axios'; | |
6 | + | |
7 | + | |
8 | +class Taskpane extends Component { | |
9 | + | |
10 | + componentDidMount() { | |
11 | + axios.get('/.debugTemp/NotifyDemoUrl').then((res) => { | |
12 | + const { setDemoSpan } = this.props; | |
13 | + setDemoSpan(res.data); | |
14 | + }); | |
15 | + } | |
16 | + | |
17 | + onDockLeft = () => { | |
18 | + const { dockLeft } = this.props; | |
19 | + dockLeft(); | |
20 | + } | |
21 | + | |
22 | + onDockRight = () => { | |
23 | + const { dockRight } = this.props; | |
24 | + dockRight(); | |
25 | + } | |
26 | + onHideTaskPane = () => { | |
27 | + const { hideTaskPane } = this.props; | |
28 | + hideTaskPane(); | |
29 | + } | |
30 | + onAddString = () => { | |
31 | + const { addString } = this.props; | |
32 | + addString(); | |
33 | + } | |
34 | + onGetDocName = () => { | |
35 | + const { getDocName } = this.props; | |
36 | + getDocName(); | |
37 | + } | |
38 | + onOpenWeb = () => { | |
39 | + const { openWeb } = this.props; | |
40 | + openWeb(); | |
41 | + } | |
42 | + | |
43 | + render() { | |
44 | + const { docName, demoSpan } = this.props; | |
45 | + | |
46 | + return ( | |
47 | + <div className="global"> | |
48 | + <div className="divItem"> | |
49 | + 这是一个网页,按<span className="debug">"F12"</span>可以打开调试器。 | |
50 | + </div> | |
51 | + <div className="divItem"> | |
52 | + 这个示例展示了wps加载项的相关基础能力,与B/S业务系统的交互,请用浏览器打开: | |
53 | + <span className="docs" onClick={this.onOpenWeb}>{demoSpan}</span> | |
54 | + </div> | |
55 | + <div className="divItem">开发文档: <span className="docs">https://open.wps.cn/docs/office</span></div> | |
56 | + <hr /> | |
57 | + <div className="divItem"> | |
58 | + <button onClick={this.onDockLeft}>停靠左边</button> | |
59 | + <button onClick={this.onDockRight}>停靠右边</button> | |
60 | + <button onClick={this.onHideTaskPane}>隐藏TaskPane</button> | |
61 | + <button onClick={this.onAddString} > 文档开头添加字符串</button > | |
62 | + <button onClick={this.onGetDocName} > 取文件名</button > | |
63 | + </div > | |
64 | + <hr /> | |
65 | + <div className="divItem">文档文件名为:<span>{docName}</span></div> | |
66 | + </div> | |
67 | + ) | |
68 | + } | |
69 | +} | |
70 | + | |
71 | +const mapStateToProps = state => { | |
72 | + return { | |
73 | + docName: state.dialog.get('docName'), | |
74 | + demoSpan: state.dialog.get('demoSpan'), | |
75 | + } | |
76 | +} | |
77 | + | |
78 | +export default connect(mapStateToProps, { | |
79 | + dockLeft, | |
80 | + dockRight, | |
81 | + hideTaskPane, | |
82 | + addString, | |
83 | + getDocName, | |
84 | + setDemoSpan, | |
85 | + openWeb | |
86 | +})(Taskpane); | ... | ... |
src/index.js
0 → 100644
1 | +/* | |
2 | + * @Descripttion: | |
3 | + * @version: | |
4 | + * @Author: 魏永康 | |
5 | + * @Date: 2021-04-20 14:53:58 | |
6 | + * @LastEditors: sueRimn | |
7 | + * @LastEditTime: 2021-04-21 19:00:39 | |
8 | + */ | |
9 | +import React from 'react'; | |
10 | +import ReactDOM from 'react-dom'; | |
11 | +import { HashRouter, Route, Switch } from 'react-router-dom'; | |
12 | +import "./actions/formdata.js"; | |
13 | +import App from './components/app'; | |
14 | +import Dialog from './components/dialog'; | |
15 | +import TaskPane from './components/taskpane'; | |
16 | +import { Provider } from 'react-redux'; | |
17 | +import { createStore } from "redux"; | |
18 | +import rootReducer from './reducers'; | |
19 | + | |
20 | +const store = createStore(rootReducer, window.STATE_FROM_SERVER); | |
21 | + | |
22 | +ReactDOM.render(( | |
23 | + <Provider store={store}> | |
24 | + <HashRouter> | |
25 | + <Switch> | |
26 | + <Route path="/" exact component={App} /> | |
27 | + <Route path="/dialog" exact component={Dialog} /> | |
28 | + <Route path="/taskpane" exact component={TaskPane} /> | |
29 | + </Switch> | |
30 | + </HashRouter> | |
31 | + </Provider> | |
32 | +), document.getElementById("root") | |
33 | +); | ... | ... |
src/js/systemdemo.js
0 → 100644
1 | + | |
2 | +/* global wps:false */ | |
3 | + | |
4 | +function openOfficeFileFromSystemDemo(param){ | |
5 | + let jsonObj = (typeof(param)=='string' ? JSON.parse(param) : param) | |
6 | + alert("从业务系统传过来的参数为:" + JSON.stringify(jsonObj)) | |
7 | + return {wps加载项项返回: jsonObj.filepath + ", 这个地址给的不正确"} | |
8 | +} | |
9 | + | |
10 | +function InvokeFromSystemDemo(param){ | |
11 | + let jsonObj = (typeof(param)=='string' ? JSON.parse(param) : param) | |
12 | + let handleInfo = jsonObj.Index | |
13 | + switch (handleInfo){ | |
14 | + case "getDocumentName":{ | |
15 | + let docName = "" | |
16 | + if (wps.WpsApplication().ActiveDocument){ | |
17 | + docName = wps.WpsApplication().ActiveDocument.Name | |
18 | + } | |
19 | + | |
20 | + return {当前打开的文件名为:docName} | |
21 | + } | |
22 | + | |
23 | + case "newDocument":{ | |
24 | + let newDocName="" | |
25 | + let doc = wps.WpsApplication().Documents.Add() | |
26 | + newDocName = doc.Name | |
27 | + | |
28 | + return {操作结果:"新建文档成功,文档名为:" + newDocName} | |
29 | + } | |
30 | + | |
31 | + case "OpenFile":{ | |
32 | + let filePath = jsonObj.filepath | |
33 | + wps.WpsApplication().Documents.OpenFromUrl(filePath) | |
34 | + return {操作结果:"打开文件成功"} | |
35 | + } | |
36 | + default: | |
37 | + } | |
38 | + | |
39 | + return {其它xxx:""} | |
40 | +} | |
41 | + | |
42 | +export default{ | |
43 | + openOfficeFileFromSystemDemo, | |
44 | + InvokeFromSystemDemo | |
45 | +} | |
\ No newline at end of file | ... | ... |
src/js/util.js
0 → 100644
1 | +//在后续的wps版本中,wps的所有枚举值都会通过wps.Enum对象来自动支持,现阶段先人工定义 | |
2 | +var WPS_Enum = { | |
3 | + msoCTPDockPositionLeft: 0, | |
4 | + msoCTPDockPositionRight: 2 | |
5 | +} | |
6 | + | |
7 | +function GetUrlPath() { | |
8 | + let e = document.location.toString() | |
9 | + e = decodeURI(e) | |
10 | + if (-1 !== e.indexOf("/")) | |
11 | + e = e.substring(0, e.lastIndexOf("/")) | |
12 | + return e | |
13 | +} | |
14 | + | |
15 | +export default { | |
16 | + WPS_Enum, | |
17 | + GetUrlPath | |
18 | +} | ... | ... |
src/reducers/dialog.js
0 → 100644
1 | +import { GETDOCNAME, CREATETASKPANE, NEWDOC, ADDSTRING, CLOSEDOC, SETDEMOSPAN, OPENWEB } from "../actions/dialog"; | |
2 | +import * as Immutable from "immutable"; | |
3 | +import Util from "../js/util.js" | |
4 | + | |
5 | +/* global wps:false */ | |
6 | + | |
7 | +const defaultState = Immutable.Map({ | |
8 | + docName: null, | |
9 | + demoSpan: "waiting..." | |
10 | +}); | |
11 | + | |
12 | +export default function (state = defaultState, action) { | |
13 | + switch (action.type) { | |
14 | + case GETDOCNAME: | |
15 | + { | |
16 | + let docName = wps.WpsApplication().ActiveDocument.Name | |
17 | + let newState = state.set('docName', docName) | |
18 | + return newState | |
19 | + } | |
20 | + case NEWDOC: | |
21 | + { | |
22 | + wps.WpsApplication().Documents.Add() | |
23 | + break; | |
24 | + } | |
25 | + case CREATETASKPANE: | |
26 | + { | |
27 | + let tsId = wps.PluginStorage.getItem("taskpane_id") | |
28 | + if (!tsId){ | |
29 | + let tskpane = wps.CreateTaskPane(Util.GetUrlPath() + "taskpane") | |
30 | + let id = tskpane.ID | |
31 | + wps.PluginStorage.setItem("taskpane_id", id) | |
32 | + tskpane.Visible = true | |
33 | + }else{ | |
34 | + let tskpane = wps.GetTaskPane(tsId) | |
35 | + tskpane.Visible = true | |
36 | + } | |
37 | + break | |
38 | + } | |
39 | + case ADDSTRING: | |
40 | + { | |
41 | + let doc = wps.WpsApplication().ActiveDocument | |
42 | + if (doc){ | |
43 | + doc.Range(0, 0).Text="Hello, wps加载项!" | |
44 | + //好像是wps的bug, 这两句话触发wps重绘 | |
45 | + let rgSel = wps.WpsApplication().Selection.Range | |
46 | + if (rgSel) | |
47 | + rgSel.Select() | |
48 | + } | |
49 | + break; | |
50 | + } | |
51 | + case CLOSEDOC: | |
52 | + { | |
53 | + if (wps.WpsApplication().Documents.Count < 2) | |
54 | + { | |
55 | + alert("当前只有一个文档,别关了。") | |
56 | + break | |
57 | + } | |
58 | + | |
59 | + let doc = wps.WpsApplication().ActiveDocument | |
60 | + if (doc) | |
61 | + doc.Close() | |
62 | + break; | |
63 | + } | |
64 | + case SETDEMOSPAN: | |
65 | + { | |
66 | + let newState = state.set('demoSpan', action.data) | |
67 | + return newState | |
68 | + } | |
69 | + case OPENWEB: | |
70 | + { | |
71 | + let param = state.get('demoSpan') | |
72 | + wps.OAAssist.ShellExecute(param) | |
73 | + } | |
74 | + default: | |
75 | + } | |
76 | + return state; | |
77 | +} | |
\ No newline at end of file | ... | ... |
src/reducers/index.js
0 → 100644
src/reducers/taskpane.js
0 → 100644
1 | +import { DOCKLEFT, DOCKRIGHT, HIDETASKPANE, ADDSTRING, GETDOCNAME, SETDEMOSPAN, OPENWEB } from "../actions/taskpane"; | |
2 | +import * as Immutable from "immutable"; | |
3 | +import Util from "../js/util.js" | |
4 | + | |
5 | +/* global wps:false */ | |
6 | + | |
7 | +const defaultState = Immutable.Map({ | |
8 | + docName: null, | |
9 | + demoSpan: "waiting..." | |
10 | +}); | |
11 | + | |
12 | +export default function (state = defaultState, action) { | |
13 | + switch (action.type) { | |
14 | + case DOCKLEFT: | |
15 | + { | |
16 | + let tsId = wps.PluginStorage.getItem("taskpane_id") | |
17 | + if (tsId){ | |
18 | + let tskpane = wps.GetTaskPane(tsId) | |
19 | + let value; | |
20 | + if (wps.Enum) | |
21 | + value = wps.Enum.msoCTPDockPositionLeft; | |
22 | + else | |
23 | + value = Util.WPS_Enum.msoCTPDockPositionLeft | |
24 | + tskpane.DockPosition = value | |
25 | + } | |
26 | + break | |
27 | + } | |
28 | + case DOCKRIGHT: | |
29 | + { | |
30 | + let tsId = wps.PluginStorage.getItem("taskpane_id") | |
31 | + if (tsId){ | |
32 | + let tskpane = wps.GetTaskPane(tsId) | |
33 | + let value; | |
34 | + if (wps.Enum) | |
35 | + value = wps.Enum.msoCTPDockPositionRight; | |
36 | + else | |
37 | + value = Util.WPS_Enum.msoCTPDockPositionRight | |
38 | + tskpane.DockPosition = value | |
39 | + } | |
40 | + break | |
41 | + } | |
42 | + case HIDETASKPANE: | |
43 | + { | |
44 | + let tsId = wps.PluginStorage.getItem("taskpane_id") | |
45 | + if (tsId){ | |
46 | + let tskpane = wps.GetTaskPane(tsId) | |
47 | + tskpane.Visible = false | |
48 | + } | |
49 | + break | |
50 | + } | |
51 | + case ADDSTRING: | |
52 | + { | |
53 | + let doc = wps.WpsApplication().ActiveDocument | |
54 | + if (doc){ | |
55 | + doc.Range(0, 0).Text="Hello, wps加载项!" | |
56 | + //好像是wps的bug, 这两句话触发wps重绘 | |
57 | + let rgSel = wps.WpsApplication().Selection.Range | |
58 | + if (rgSel) | |
59 | + rgSel.Select() | |
60 | + } | |
61 | + break; | |
62 | + } | |
63 | + case GETDOCNAME: | |
64 | + { | |
65 | + let docName = wps.WpsApplication().ActiveDocument.Name | |
66 | + let newState = state.set('docName', docName) | |
67 | + return newState | |
68 | + } | |
69 | + case SETDEMOSPAN: | |
70 | + { | |
71 | + let newState = state.set('DemoSpan', action.data) | |
72 | + return newState | |
73 | + } | |
74 | + case OPENWEB: | |
75 | + { | |
76 | + let param = state.get('demoSpan') | |
77 | + wps.OAAssist.ShellExecute(param) | |
78 | + } | |
79 | + default: | |
80 | + } | |
81 | + return state; | |
82 | +} | |
\ No newline at end of file | ... | ... |
请
注册
或
登录
后发表评论