您最多选择25个主题 主题必须以字母或数字开头,可以包含连字符 (-),并且长度不得超过35个字符

310 行
11KB

  1. /**
  2. * 这是为了便于Demo能在开发者的本地快速运行起来,采用Nodejs模拟服务端,开发者可根据此文件的注释,自行在业务系统中实现对应的功能
  3. */
  4. const express = require('express');
  5. const fs = require('fs');
  6. const path = require('path');
  7. var urlencode = require('urlencode');
  8. const formidable = require('formidable')
  9. var ini = require('ini')
  10. var regedit = require('regedit')
  11. const os = require('os');
  12. const app = express()
  13. var cp = require('child_process');
  14. var mode=-1;
  15. const querystring=require("querystring")
  16. //----开发者将WPS加载项集成到业务系统中时,需要实现的功能 Start--------
  17. /**
  18. * 支持jsplugins.xml中,在线模式下,WPS加载项的请求地址
  19. * 开发者可在业务系统部署时,将WPS加载项合并部署到服务端,提供jsplugins.xml中对应的请求地址即可
  20. */
  21. app.all('*', function (req, res, next) {
  22. res.header('Access-Control-Allow-Origin', '*');
  23. console.log(getNow()+req.originalUrl)
  24. // res.setHeader('Content-Type','text/plain;charset=gbk');
  25. //Access-Control-Allow-Headers ,可根据浏览器的F12查看,把对应的粘贴在这里就行
  26. // res.header('Access-Control-Allow-Headers', 'Content-Type');
  27. // res.header('Access-Control-Allow-Methods', '*');
  28. // res.header('Content-Type', 'text/html;charset=utf-8');
  29. next();
  30. });
  31. app.use(express.static(path.join(__dirname, "wwwroot"))); //wwwroot代表http服务器根目录
  32. app.use('/plugin/et', express.static(path.join(__dirname, "../EtOAAssist")));
  33. app.use('/plugin/wps', express.static(path.join(__dirname, "../WpsOAAssist")));
  34. app.use('/plugin/wpp', express.static(path.join(__dirname, "../WppOAAssist")));
  35. /**
  36. * 文件下载
  37. * 开发者可将此方法更换为自己业务系统的文件下载方法, 请求中必须的参数为: filename
  38. * 如果业务系统有特殊的要求, 此方法可与各加载项中的 js / common / common.js: DownloadFile 方法对应着修改
  39. */
  40. app.use("/Download/:fileName", function (request, response) {
  41. var fileName = request.params.fileName;
  42. var filePath = path.join(__dirname, './wwwroot/file');
  43. filePath = path.join(filePath, fileName);
  44. var stats = fs.statSync(filePath);
  45. if (stats.isFile()) {
  46. let name = urlencode(fileName, "utf-8");
  47. response.set({
  48. 'Content-Type': 'application/octet-stream',
  49. //'Content-Disposition': "attachment; filename* = UTF-8''" + name,
  50. 'Content-Disposition': "attachment; filename=" + name,
  51. 'Content-Length': stats.size
  52. });
  53. fs.createReadStream(filePath).pipe(response);
  54. console.log(getNow() + "下载文件接被调用,文件路径:" + filePath)
  55. } else {
  56. response.writeHead(200, "Failed", {
  57. "Content-Type": "text/html; charset=utf-8"
  58. });
  59. response.end("文件不存在");
  60. }
  61. });
  62. /**
  63. * 文件上传
  64. * 开发者可将此方法更换为自己业务系统的接受文件上传的方法
  65. * 如果业务系统有特殊的要求, 此方法可与加载项中的 js / common / common.js: UploadFile 方法对应着修改
  66. */
  67. app.post("/Upload", function (request, response) {
  68. const form = new formidable.IncomingForm();
  69. var uploadDir = path.join(__dirname, './wwwroot/uploaded/');
  70. form.encoding = 'utf-8';
  71. form.uploadDir = uploadDir;
  72. console.log(getNow() + "上传文件夹地址是:" + uploadDir);
  73. //判断上传文件夹地址是否存在,如果不存在就创建
  74. if (!fs.existsSync(form.uploadDir)) {
  75. fs.mkdirSync(form.uploadDir);
  76. }
  77. form.parse(request, function (error, fields, files) {
  78. for (let key in files) {
  79. let file = files[key]
  80. // 过滤空文件
  81. if (file.size == 0 && file.name == '') continue
  82. var fileName = file.name
  83. if (!fileName)
  84. fileName = request.headers.filename
  85. let oldPath = file.path
  86. let newPath = uploadDir + fileName
  87. fs.rename(oldPath, newPath, function (error) {
  88. console.log(getNow() + "上传文件成功,路径:" + newPath)
  89. })
  90. }
  91. response.writeHead(200, {
  92. "Content-Type": "text/html;charset=utf-8"
  93. })
  94. response.end("测试");
  95. })
  96. });
  97. /**
  98. * 模拟填充到文件的服务端数据( 加载本地的模拟json数据并提供请求)
  99. * 开发者可将此方法更换为自己业务系统的数据接口
  100. * json数据格式及解析, 可与各加载项中的 js / common / func_docProcess.js: GetServerTemplateData 方法对应着修改
  101. */
  102. app.get('/getTemplateData', function (request, response) {
  103. var file = path.join(__dirname, './wwwroot/file/templateData.json');
  104. //读取json文件
  105. fs.readFile(file, 'utf-8', function (err, data) {
  106. if (err) {
  107. response.send('文件读取失败');
  108. } else {
  109. response.send(data);
  110. }
  111. });
  112. });
  113. //----开发者将WPS加载项集成到业务系统中时,需要实现的功能 End--------
  114. //获取file目录下文件列表
  115. app.use("/FileList", function (request, response) {
  116. var filePath = path.join(__dirname, './wwwroot/file');
  117. fs.readdir(filePath, function (err, results) {
  118. if (err) {
  119. response.writeHead(200, "OK", { "Content-Type": "text/html; charset=utf-8" });
  120. response.end("没有找到file文件夹");
  121. return;
  122. }
  123. if (results.length > 0) {
  124. var files = [];
  125. results.forEach(function (file) {
  126. if (fs.statSync(path.join(filePath, file)).isFile()) {
  127. files.push(file);
  128. }
  129. })
  130. response.writeHead(200, "OK", { "Content-Type": "text/html; charset=utf-8" });
  131. response.end(files.toString());
  132. } else {
  133. response.writeHead(200, "OK", { "Content-Type": "text/html; charset=utf-8" });
  134. response.end("当前目录下没有文件");
  135. }
  136. });
  137. });
  138. //wps安装包是否正确的检测
  139. app.use("/WpsSetup", (request, response) => {
  140. response.writeHead(200, "OK", { "Content-Type": "text/html; charset=utf-8" })
  141. response.end("成功");
  142. });
  143. //wps加载项配置是否正确的检测
  144. app.use("/OAAssistDeploy", (request, response) => {
  145. response.writeHead(200, "OK", { "Content-Type": "text/html; charset=utf-8" })
  146. response.end("成功");
  147. });
  148. //检测WPS客户端环境
  149. app.use("/WpsSetupTest", function (request, response) {
  150. configOem(request.query.pluginsMode,function (res) {
  151. response.writeHead(200, res.status, {
  152. "Content-Type": "text/html;charset=utf-8"
  153. });
  154. response.write('<head><meta charset="utf-8"/></head>');
  155. response.write("<br/>当前检测时间为: " + getNow() + "<br/>");
  156. response.end(res.msg);
  157. });
  158. });
  159. //定义node服务端口
  160. var server = app.listen(3888, function () {
  161. console.log(getNow() + "启动本地web服务(http://127.0.0.1:3888)成功!");
  162. let url="http://127.0.0.1:3888/index.html";
  163. let exec=cp.exec;
  164. try{
  165. switch (process.platform) {
  166. //mac系统使用 一下命令打开url在浏览器
  167. case "darwin":
  168. exec(`open ${url}`);
  169. break;
  170. //win系统使用 一下命令打开url在浏览器
  171. case "win32":
  172. exec(`start ${url}`);
  173. break;
  174. //linux系统使用 一下命令打开url在浏览器
  175. case "linux":
  176. exec(`xdg-open ${url}`)
  177. break;
  178. // 默认linux系统
  179. default:
  180. exec(`xdg-open ${url}`)
  181. break;
  182. }
  183. }catch(e){
  184. }
  185. });
  186. //启动node服务
  187. server.on('error', (e) => {
  188. if (e.code === 'EADDRINUSE') {
  189. console.log('地址正被使用,重试中...');
  190. setTimeout(() => {
  191. server.close();
  192. server.listen(3888);
  193. }, 2000);
  194. }
  195. });
  196. //获取当前时间
  197. function getNow() {
  198. let nowDate = new Date()
  199. let year = nowDate.getFullYear()
  200. let month = nowDate.getMonth() + 1
  201. let day = nowDate.getDate()
  202. let hour = nowDate.getHours()
  203. let minute = nowDate.getMinutes()
  204. let second = nowDate.getSeconds()
  205. return year + '年' + month + '月' + day + '日 ' + hour + ':' + minute + ':' + second + " "
  206. }
  207. //配置WPS客户端的WPS加载项的配置
  208. //此功能开发者无需实现和考虑,在生产环境中,WPS客户端的配置文件可通过
  209. //独立打包或开发者编写批处理命令实现修改,业务系统无法实现修改WPS客户端配置文件
  210. function configOemFileInner(oemPath,pluginsMode, callback) {
  211. var config = ini.parse(fs.readFileSync(oemPath, 'utf-8'))
  212. var sup = config.support || config.Support;
  213. var ser = config.server || config.Server;
  214. var needUpdate = false;
  215. if (!sup || !sup.JsApiPlugin || !sup.JsApiShowWebDebugger)
  216. needUpdate = true;
  217. if (!ser || !ser.JSPluginsServer || ser.JSPluginsServer != "http://127.0.0.1:3888/jsplugins.xml")
  218. needUpdate = true;
  219. if (!sup) {
  220. sup = {}
  221. config.Support = sup
  222. }
  223. if (!ser) {
  224. ser = {}
  225. config.Server = ser
  226. }
  227. if(pluginsMode!=0){
  228. sup.JsApiPlugin = false
  229. sup.JsApiShowWebDebugger = true
  230. ser.JSPluginsServer = ""
  231. }else{
  232. sup.JsApiPlugin = true
  233. sup.JsApiShowWebDebugger = true
  234. ser.JSPluginsServer = "http://127.0.0.1:3888/jsplugins.xml"
  235. }
  236. if (pluginsMode!=mode) {
  237. fs.writeFileSync(oemPath, ini.stringify(config))
  238. if (os.platform() != 'win32')
  239. cp.exec("quickstartoffice restart");
  240. }
  241. callback({ status: 0, msg: "wps安装正常," + oemPath + "文件设置正常。" })
  242. }
  243. //检测WPS客户端的安装情况
  244. function configOem(pluginsMode,callback) {
  245. let oemPath;
  246. try {
  247. if (os.platform() == 'win32') {
  248. cp.exec("REG QUERY HKEY_CLASSES_ROOT\\KWPS.Document.12\\shell\\open\\command /ve", function (error, stdout, stderr) {
  249. try {
  250. var val = stdout.split(" ")[3].split('"')[1];
  251. if (typeof (val) == "undefined" || val == null) {
  252. return callback({
  253. status: 1,
  254. msg: "WPS未安装。"
  255. })
  256. }
  257. fs.exists(val, function (exists) {
  258. if(!exists){
  259. return callback({
  260. status: 1,
  261. msg: "WSP安装异常,请确认有没有正确的安装WPS2019。"
  262. })
  263. }
  264. oemPath = path.dirname(val) + '\\cfgs\\oem.ini';
  265. configOemFileInner(oemPath,pluginsMode, callback);
  266. });
  267. } catch (e) {
  268. oemResult = "配置" + oemPath + "失败,请尝试以管理员重新运行!!";
  269. console.log(oemResult)
  270. console.log(e)
  271. return callback({ status: 1, msg: oemResult })
  272. }
  273. });
  274. } else {
  275. oemPath = "/opt/kingsoft/wps-office/office6/cfgs/oem.ini";
  276. if (!fs.existsSync(oemPath))
  277. oemPath = "/opt/apps/cn.wps.wps-office-pro/files/kingsoft/wps-office/office6/cfgs/oem.ini";
  278. configOemFileInner(oemPath,pluginsMode, callback);
  279. }
  280. } catch (e) {
  281. oemResult = "配置" + oemPath + "失败,请尝试以管理员重新运行!!";
  282. console.log(oemResult)
  283. console.log(e)
  284. return callback({ status: 1, msg: oemResult })
  285. }
  286. }
  287. //获取服务端IP地址
  288. function getServerIPAdress() {
  289. var interfaces = require('os').networkInterfaces();
  290. for (var devName in interfaces) {
  291. var iface = interfaces[devName];
  292. for (var i = 0; i < iface.length; i++) {
  293. var alias = iface[i];
  294. if (alias.family === 'IPv4' && alias.address !== '127.0.0.1' && !alias.internal) {
  295. return alias.address;
  296. }
  297. }
  298. }
  299. }
  300. //----模拟服务端的特有功能,开发者无需关心 End--------