Merge remote-tracking branch 'origin/main'

product
BAWEI 2 years ago
commit c94d035644

@ -0,0 +1,5 @@
# .net单体预发布
ENV = 'dotNetPreview'
VUE_APP_BASE_API = 'http://dotnet.preview.jnpf.work'
VUE_APP_BASE_WSS = 'ws://dotnet.preview.jnpf.work/websocket'

@ -0,0 +1,5 @@
# java单体预生产
ENV = 'javaBootPreview'
VUE_APP_BASE_API = 'http://java.preview.jnpf.work'
VUE_APP_BASE_WSS = 'ws://java.preview.jnpf.work/websocket'

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.8 KiB

@ -0,0 +1,389 @@
tinymce.addI18n('zh_CN',{
"Redo": "\u91cd\u505a",
"Undo": "\u64a4\u9500",
"Cut": "\u526a\u5207",
"Copy": "\u590d\u5236",
"Paste": "\u7c98\u8d34",
"Select all": "\u5168\u9009",
"New document": "\u65b0\u6587\u4ef6",
"Ok": "\u786e\u5b9a",
"Cancel": "\u53d6\u6d88",
"Visual aids": "\u7f51\u683c\u7ebf",
"Bold": "\u7c97\u4f53",
"Italic": "\u659c\u4f53",
"Underline": "\u4e0b\u5212\u7ebf",
"Strikethrough": "\u5220\u9664\u7ebf",
"Superscript": "\u4e0a\u6807",
"Subscript": "\u4e0b\u6807",
"Clear formatting": "\u6e05\u9664\u683c\u5f0f",
"Align left": "\u5de6\u8fb9\u5bf9\u9f50",
"Align center": "\u4e2d\u95f4\u5bf9\u9f50",
"Align right": "\u53f3\u8fb9\u5bf9\u9f50",
"Justify": "\u4e24\u7aef\u5bf9\u9f50",
"Bullet list": "\u9879\u76ee\u7b26\u53f7",
"Numbered list": "\u7f16\u53f7\u5217\u8868",
"Decrease indent": "\u51cf\u5c11\u7f29\u8fdb",
"Increase indent": "\u589e\u52a0\u7f29\u8fdb",
"Close": "\u5173\u95ed",
"Formats": "\u683c\u5f0f",
"Your browser doesn't support direct access to the clipboard. Please use the Ctrl+X\/C\/V keyboard shortcuts instead.": "\u4f60\u7684\u6d4f\u89c8\u5668\u4e0d\u652f\u6301\u6253\u5f00\u526a\u8d34\u677f\uff0c\u8bf7\u4f7f\u7528Ctrl+X\/C\/V\u7b49\u5feb\u6377\u952e\u3002",
"Headers": "\u6807\u9898",
"Header 1": "\u6807\u98981",
"Header 2": "\u6807\u98982",
"Header 3": "\u6807\u98983",
"Header 4": "\u6807\u98984",
"Header 5": "\u6807\u98985",
"Header 6": "\u6807\u98986",
"Headings": "\u6807\u9898",
"Heading 1": "\u6807\u98981",
"Heading 2": "\u6807\u98982",
"Heading 3": "\u6807\u98983",
"Heading 4": "\u6807\u98984",
"Heading 5": "\u6807\u98985",
"Heading 6": "\u6807\u98986",
"Preformatted": "\u9884\u5148\u683c\u5f0f\u5316\u7684",
"Div": "Div",
"Pre": "Pre",
"Code": "\u4ee3\u7801",
"Paragraph": "\u6bb5\u843d",
"Blockquote": "\u5f15\u6587\u533a\u5757",
"Inline": "\u6587\u672c",
"Blocks": "\u57fa\u5757",
"Paste is now in plain text mode. Contents will now be pasted as plain text until you toggle this option off.": "\u5f53\u524d\u4e3a\u7eaf\u6587\u672c\u7c98\u8d34\u6a21\u5f0f\uff0c\u518d\u6b21\u70b9\u51fb\u53ef\u4ee5\u56de\u5230\u666e\u901a\u7c98\u8d34\u6a21\u5f0f\u3002",
"Fonts": "\u5b57\u4f53",
"Font Sizes": "\u5b57\u53f7",
"Class": "\u7c7b\u578b",
"Browse for an image": "\u6d4f\u89c8\u56fe\u50cf",
"OR": "\u6216",
"Drop an image here": "\u62d6\u653e\u4e00\u5f20\u56fe\u50cf\u81f3\u6b64",
"Upload": "\u4e0a\u4f20",
"Block": "\u5757",
"Align": "\u5bf9\u9f50",
"Default": "\u9ed8\u8ba4",
"Circle": "\u7a7a\u5fc3\u5706",
"Disc": "\u5b9e\u5fc3\u5706",
"Square": "\u65b9\u5757",
"Lower Alpha": "\u5c0f\u5199\u82f1\u6587\u5b57\u6bcd",
"Lower Greek": "\u5c0f\u5199\u5e0c\u814a\u5b57\u6bcd",
"Lower Roman": "\u5c0f\u5199\u7f57\u9a6c\u5b57\u6bcd",
"Upper Alpha": "\u5927\u5199\u82f1\u6587\u5b57\u6bcd",
"Upper Roman": "\u5927\u5199\u7f57\u9a6c\u5b57\u6bcd",
"Anchor...": "\u951a\u70b9...",
"Name": "\u540d\u79f0",
"Id": "\u6807\u8bc6\u7b26",
"Id should start with a letter, followed only by letters, numbers, dashes, dots, colons or underscores.": "\u6807\u8bc6\u7b26\u5e94\u8be5\u4ee5\u5b57\u6bcd\u5f00\u5934\uff0c\u540e\u8ddf\u5b57\u6bcd\u3001\u6570\u5b57\u3001\u7834\u6298\u53f7\u3001\u70b9\u3001\u5192\u53f7\u6216\u4e0b\u5212\u7ebf\u3002",
"You have unsaved changes are you sure you want to navigate away?": "\u4f60\u8fd8\u6709\u6587\u6863\u5c1a\u672a\u4fdd\u5b58\uff0c\u786e\u5b9a\u8981\u79bb\u5f00\uff1f",
"Restore last draft": "\u6062\u590d\u4e0a\u6b21\u7684\u8349\u7a3f",
"Special characters...": "\u7279\u6b8a\u5b57\u7b26...",
"Source code": "\u6e90\u4ee3\u7801",
"Insert\/Edit code sample": "\u63d2\u5165\/\u7f16\u8f91\u4ee3\u7801\u793a\u4f8b",
"Language": "\u8bed\u8a00",
"Code sample...": "\u793a\u4f8b\u4ee3\u7801...",
"Color Picker": "\u9009\u8272\u5668",
"R": "R",
"G": "G",
"B": "B",
"Left to right": "\u4ece\u5de6\u5230\u53f3",
"Right to left": "\u4ece\u53f3\u5230\u5de6",
"Emoticons...": "\u8868\u60c5\u7b26\u53f7...",
"Metadata and Document Properties": "\u5143\u6570\u636e\u548c\u6587\u6863\u5c5e\u6027",
"Title": "\u6807\u9898",
"Keywords": "\u5173\u952e\u8bcd",
"Description": "\u63cf\u8ff0",
"Robots": "\u673a\u5668\u4eba",
"Author": "\u4f5c\u8005",
"Encoding": "\u7f16\u7801",
"Fullscreen": "\u5168\u5c4f",
"Action": "\u64cd\u4f5c",
"Shortcut": "\u5feb\u6377\u952e",
"Help": "\u5e2e\u52a9",
"Address": "\u5730\u5740",
"Focus to menubar": "\u79fb\u52a8\u7126\u70b9\u5230\u83dc\u5355\u680f",
"Focus to toolbar": "\u79fb\u52a8\u7126\u70b9\u5230\u5de5\u5177\u680f",
"Focus to element path": "\u79fb\u52a8\u7126\u70b9\u5230\u5143\u7d20\u8def\u5f84",
"Focus to contextual toolbar": "\u79fb\u52a8\u7126\u70b9\u5230\u4e0a\u4e0b\u6587\u83dc\u5355",
"Insert link (if link plugin activated)": "\u63d2\u5165\u94fe\u63a5 (\u5982\u679c\u94fe\u63a5\u63d2\u4ef6\u5df2\u6fc0\u6d3b)",
"Save (if save plugin activated)": "\u4fdd\u5b58(\u5982\u679c\u4fdd\u5b58\u63d2\u4ef6\u5df2\u6fc0\u6d3b)",
"Find (if searchreplace plugin activated)": "\u67e5\u627e(\u5982\u679c\u67e5\u627e\u66ff\u6362\u63d2\u4ef6\u5df2\u6fc0\u6d3b)",
"Plugins installed ({0}):": "\u5df2\u5b89\u88c5\u63d2\u4ef6 ({0}):",
"Premium plugins:": "\u4f18\u79c0\u63d2\u4ef6\uff1a",
"Learn more...": "\u4e86\u89e3\u66f4\u591a...",
"You are using {0}": "\u4f60\u6b63\u5728\u4f7f\u7528 {0}",
"Plugins": "\u63d2\u4ef6",
"Handy Shortcuts": "\u5feb\u6377\u952e",
"Horizontal line": "\u6c34\u5e73\u5206\u5272\u7ebf",
"Insert\/edit image": "\u63d2\u5165\/\u7f16\u8f91\u56fe\u7247",
"Image description": "\u56fe\u7247\u63cf\u8ff0",
"Source": "\u5730\u5740",
"Dimensions": "\u5927\u5c0f",
"Constrain proportions": "\u4fdd\u6301\u7eb5\u6a2a\u6bd4",
"General": "\u666e\u901a",
"Advanced": "\u9ad8\u7ea7",
"Style": "\u6837\u5f0f",
"Vertical space": "\u5782\u76f4\u8fb9\u8ddd",
"Horizontal space": "\u6c34\u5e73\u8fb9\u8ddd",
"Border": "\u8fb9\u6846",
"Insert image": "\u63d2\u5165\u56fe\u7247",
"Image...": "\u56fe\u7247...",
"Image list": "\u56fe\u7247\u5217\u8868",
"Rotate counterclockwise": "\u9006\u65f6\u9488\u65cb\u8f6c",
"Rotate clockwise": "\u987a\u65f6\u9488\u65cb\u8f6c",
"Flip vertically": "\u5782\u76f4\u7ffb\u8f6c",
"Flip horizontally": "\u6c34\u5e73\u7ffb\u8f6c",
"Edit image": "\u7f16\u8f91\u56fe\u7247",
"Image options": "\u56fe\u7247\u9009\u9879",
"Zoom in": "\u653e\u5927",
"Zoom out": "\u7f29\u5c0f",
"Crop": "\u88c1\u526a",
"Resize": "\u8c03\u6574\u5927\u5c0f",
"Orientation": "\u65b9\u5411",
"Brightness": "\u4eae\u5ea6",
"Sharpen": "\u9510\u5316",
"Contrast": "\u5bf9\u6bd4\u5ea6",
"Color levels": "\u989c\u8272\u5c42\u6b21",
"Gamma": "\u4f3d\u9a6c\u503c",
"Invert": "\u53cd\u8f6c",
"Apply": "\u5e94\u7528",
"Back": "\u540e\u9000",
"Insert date\/time": "\u63d2\u5165\u65e5\u671f\/\u65f6\u95f4",
"Date\/time": "\u65e5\u671f\/\u65f6\u95f4",
"Insert\/Edit Link": "\u63d2\u5165\/\u7f16\u8f91\u94fe\u63a5",
"Insert\/edit link": "\u63d2\u5165\/\u7f16\u8f91\u94fe\u63a5",
"Text to display": "\u663e\u793a\u6587\u5b57",
"Url": "\u5730\u5740",
"Open link in...": "\u94fe\u63a5\u6253\u5f00\u4f4d\u7f6e...",
"Current window": "\u5f53\u524d\u7a97\u53e3",
"None": "\u65e0",
"New window": "\u5728\u65b0\u7a97\u53e3\u6253\u5f00",
"Remove link": "\u5220\u9664\u94fe\u63a5",
"Anchors": "\u951a\u70b9",
"Link...": "\u94fe\u63a5...",
"Paste or type a link": "\u7c98\u8d34\u6216\u8f93\u5165\u94fe\u63a5",
"The URL you entered seems to be an email address. Do you want to add the required mailto: prefix?": "\u4f60\u6240\u586b\u5199\u7684URL\u5730\u5740\u4e3a\u90ae\u4ef6\u5730\u5740\uff0c\u9700\u8981\u52a0\u4e0amailto:\u524d\u7f00\u5417\uff1f",
"The URL you entered seems to be an external link. Do you want to add the required http:\/\/ prefix?": "\u4f60\u6240\u586b\u5199\u7684URL\u5730\u5740\u5c5e\u4e8e\u5916\u90e8\u94fe\u63a5\uff0c\u9700\u8981\u52a0\u4e0ahttp:\/\/:\u524d\u7f00\u5417\uff1f",
"Link list": "\u94fe\u63a5\u5217\u8868",
"Insert video": "\u63d2\u5165\u89c6\u9891",
"Insert\/edit video": "\u63d2\u5165\/\u7f16\u8f91\u89c6\u9891",
"Insert\/edit media": "\u63d2\u5165\/\u7f16\u8f91\u5a92\u4f53",
"Alternative source": "\u955c\u50cf",
"Alternative source URL": "\u66ff\u4ee3\u6765\u6e90\u7f51\u5740",
"Media poster (Image URL)": "\u5c01\u9762(\u56fe\u7247\u5730\u5740)",
"Paste your embed code below:": "\u5c06\u5185\u5d4c\u4ee3\u7801\u7c98\u8d34\u5728\u4e0b\u9762:",
"Embed": "\u5185\u5d4c",
"Media...": "\u591a\u5a92\u4f53...",
"Nonbreaking space": "\u4e0d\u95f4\u65ad\u7a7a\u683c",
"Page break": "\u5206\u9875\u7b26",
"Paste as text": "\u7c98\u8d34\u4e3a\u6587\u672c",
"Preview": "\u9884\u89c8",
"Print...": "\u6253\u5370...",
"Save": "\u4fdd\u5b58",
"Find": "\u67e5\u627e",
"Replace with": "\u66ff\u6362\u4e3a",
"Replace": "\u66ff\u6362",
"Replace all": "\u5168\u90e8\u66ff\u6362",
"Previous": "\u4e0a\u4e00\u4e2a",
"Next": "\u4e0b\u4e00\u4e2a",
"Find and replace...": "\u67e5\u627e\u5e76\u66ff\u6362...",
"Could not find the specified string.": "\u672a\u627e\u5230\u641c\u7d22\u5185\u5bb9.",
"Match case": "\u533a\u5206\u5927\u5c0f\u5199",
"Find whole words only": "\u5168\u5b57\u5339\u914d",
"Spell check": "\u62fc\u5199\u68c0\u67e5",
"Ignore": "\u5ffd\u7565",
"Ignore all": "\u5168\u90e8\u5ffd\u7565",
"Finish": "\u5b8c\u6210",
"Add to Dictionary": "\u6dfb\u52a0\u5230\u5b57\u5178",
"Insert table": "\u63d2\u5165\u8868\u683c",
"Table properties": "\u8868\u683c\u5c5e\u6027",
"Delete table": "\u5220\u9664\u8868\u683c",
"Cell": "\u5355\u5143\u683c",
"Row": "\u884c",
"Column": "\u5217",
"Cell properties": "\u5355\u5143\u683c\u5c5e\u6027",
"Merge cells": "\u5408\u5e76\u5355\u5143\u683c",
"Split cell": "\u62c6\u5206\u5355\u5143\u683c",
"Insert row before": "\u5728\u4e0a\u65b9\u63d2\u5165",
"Insert row after": "\u5728\u4e0b\u65b9\u63d2\u5165",
"Delete row": "\u5220\u9664\u884c",
"Row properties": "\u884c\u5c5e\u6027",
"Cut row": "\u526a\u5207\u884c",
"Copy row": "\u590d\u5236\u884c",
"Paste row before": "\u7c98\u8d34\u5230\u4e0a\u65b9",
"Paste row after": "\u7c98\u8d34\u5230\u4e0b\u65b9",
"Insert column before": "\u5728\u5de6\u4fa7\u63d2\u5165",
"Insert column after": "\u5728\u53f3\u4fa7\u63d2\u5165",
"Delete column": "\u5220\u9664\u5217",
"Cols": "\u5217",
"Rows": "\u884c",
"Width": "\u5bbd",
"Height": "\u9ad8",
"Cell spacing": "\u5355\u5143\u683c\u5916\u95f4\u8ddd",
"Cell padding": "\u5355\u5143\u683c\u5185\u8fb9\u8ddd",
"Show caption": "\u663e\u793a\u6807\u9898",
"Left": "\u5de6\u5bf9\u9f50",
"Center": "\u5c45\u4e2d",
"Right": "\u53f3\u5bf9\u9f50",
"Cell type": "\u5355\u5143\u683c\u7c7b\u578b",
"Scope": "\u8303\u56f4",
"Alignment": "\u5bf9\u9f50\u65b9\u5f0f",
"H Align": "\u6c34\u5e73\u5bf9\u9f50",
"V Align": "\u5782\u76f4\u5bf9\u9f50",
"Top": "\u9876\u90e8\u5bf9\u9f50",
"Middle": "\u5782\u76f4\u5c45\u4e2d",
"Bottom": "\u5e95\u90e8\u5bf9\u9f50",
"Header cell": "\u8868\u5934\u5355\u5143\u683c",
"Row group": "\u884c\u7ec4",
"Column group": "\u5217\u7ec4",
"Row type": "\u884c\u7c7b\u578b",
"Header": "\u8868\u5934",
"Body": "\u8868\u4f53",
"Footer": "\u8868\u5c3e",
"Border color": "\u8fb9\u6846\u989c\u8272",
"Insert template...": "\u63d2\u5165\u6a21\u677f...",
"Templates": "\u6a21\u677f",
"Template": "\u6a21\u677f",
"Text color": "\u6587\u5b57\u989c\u8272",
"Background color": "\u80cc\u666f\u8272",
"Custom...": "\u81ea\u5b9a\u4e49...",
"Custom color": "\u81ea\u5b9a\u4e49\u989c\u8272",
"No color": "\u65e0",
"Remove color": "\u79fb\u9664\u989c\u8272",
"Table of Contents": "\u5185\u5bb9\u5217\u8868",
"Show blocks": "\u663e\u793a\u533a\u5757\u8fb9\u6846",
"Show invisible characters": "\u663e\u793a\u4e0d\u53ef\u89c1\u5b57\u7b26",
"Word count": "\u5b57\u6570",
"Words: {0}": "\u5b57\u6570\uff1a{0}",
"{0} words": "{0} \u5b57",
"File": "\u6587\u4ef6",
"Edit": "\u7f16\u8f91",
"Insert": "\u63d2\u5165",
"View": "\u89c6\u56fe",
"Format": "\u683c\u5f0f",
"Table": "\u8868\u683c",
"Tools": "\u5de5\u5177",
"Powered by {0}": "\u7531{0}\u9a71\u52a8",
"Rich Text Area. Press ALT-F9 for menu. Press ALT-F10 for toolbar. Press ALT-0 for help": "\u5728\u7f16\u8f91\u533a\u6309ALT-F9\u6253\u5f00\u83dc\u5355\uff0c\u6309ALT-F10\u6253\u5f00\u5de5\u5177\u680f\uff0c\u6309ALT-0\u67e5\u770b\u5e2e\u52a9",
"Image title": "\u56fe\u7247\u6807\u9898",
"Border width": "\u8fb9\u6846\u5bbd\u5ea6",
"Border style": "\u8fb9\u6846\u6837\u5f0f",
"Error": "\u9519\u8bef",
"Warn": "\u8b66\u544a",
"Valid": "\u6709\u6548",
"To open the popup, press Shift+Enter": "\u6309Shitf+Enter\u952e\u6253\u5f00\u5bf9\u8bdd\u6846",
"Rich Text Area. Press ALT-0 for help.": "\u7f16\u8f91\u533a\u3002\u6309Alt+0\u952e\u6253\u5f00\u5e2e\u52a9\u3002",
"System Font": "\u7cfb\u7edf\u5b57\u4f53",
"Failed to upload image: {0}": "\u56fe\u7247\u4e0a\u4f20\u5931\u8d25: {0}",
"Failed to load plugin: {0} from url {1}": "\u63d2\u4ef6\u52a0\u8f7d\u5931\u8d25: {0} \u6765\u81ea\u94fe\u63a5 {1}",
"Failed to load plugin url: {0}": "\u63d2\u4ef6\u52a0\u8f7d\u5931\u8d25 \u94fe\u63a5: {0}",
"Failed to initialize plugin: {0}": "\u63d2\u4ef6\u521d\u59cb\u5316\u5931\u8d25: {0}",
"example": "\u793a\u4f8b",
"Search": "\u641c\u7d22",
"All": "\u5168\u90e8",
"Currency": "\u8d27\u5e01",
"Text": "\u6587\u5b57",
"Quotations": "\u5f15\u7528",
"Mathematical": "\u6570\u5b66",
"Extended Latin": "\u62c9\u4e01\u8bed\u6269\u5145",
"Symbols": "\u7b26\u53f7",
"Arrows": "\u7bad\u5934",
"User Defined": "\u81ea\u5b9a\u4e49",
"dollar sign": "\u7f8e\u5143\u7b26\u53f7",
"currency sign": "\u8d27\u5e01\u7b26\u53f7",
"euro-currency sign": "\u6b27\u5143\u7b26\u53f7",
"colon sign": "\u5192\u53f7",
"cruzeiro sign": "\u514b\u9c81\u8d5b\u7f57\u5e01\u7b26\u53f7",
"french franc sign": "\u6cd5\u90ce\u7b26\u53f7",
"lira sign": "\u91cc\u62c9\u7b26\u53f7",
"mill sign": "\u5bc6\u5c14\u7b26\u53f7",
"naira sign": "\u5948\u62c9\u7b26\u53f7",
"peseta sign": "\u6bd4\u585e\u5854\u7b26\u53f7",
"rupee sign": "\u5362\u6bd4\u7b26\u53f7",
"won sign": "\u97e9\u5143\u7b26\u53f7",
"new sheqel sign": "\u65b0\u8c22\u514b\u5c14\u7b26\u53f7",
"dong sign": "\u8d8a\u5357\u76fe\u7b26\u53f7",
"kip sign": "\u8001\u631d\u57fa\u666e\u7b26\u53f7",
"tugrik sign": "\u56fe\u683c\u91cc\u514b\u7b26\u53f7",
"drachma sign": "\u5fb7\u62c9\u514b\u9a6c\u7b26\u53f7",
"german penny symbol": "\u5fb7\u56fd\u4fbf\u58eb\u7b26\u53f7",
"peso sign": "\u6bd4\u7d22\u7b26\u53f7",
"guarani sign": "\u74dc\u62c9\u5c3c\u7b26\u53f7",
"austral sign": "\u6fb3\u5143\u7b26\u53f7",
"hryvnia sign": "\u683c\u91cc\u592b\u5c3c\u4e9a\u7b26\u53f7",
"cedi sign": "\u585e\u5730\u7b26\u53f7",
"livre tournois sign": "\u91cc\u5f17\u5f17\u5c14\u7b26\u53f7",
"spesmilo sign": "spesmilo\u7b26\u53f7",
"tenge sign": "\u575a\u6208\u7b26\u53f7",
"indian rupee sign": "\u5370\u5ea6\u5362\u6bd4",
"turkish lira sign": "\u571f\u8033\u5176\u91cc\u62c9",
"nordic mark sign": "\u5317\u6b27\u9a6c\u514b",
"manat sign": "\u9a6c\u7eb3\u7279\u7b26\u53f7",
"ruble sign": "\u5362\u5e03\u7b26\u53f7",
"yen character": "\u65e5\u5143\u5b57\u6837",
"yuan character": "\u4eba\u6c11\u5e01\u5143\u5b57\u6837",
"yuan character, in hong kong and taiwan": "\u5143\u5b57\u6837\uff08\u6e2f\u53f0\u5730\u533a\uff09",
"yen\/yuan character variant one": "\u5143\u5b57\u6837\uff08\u5927\u5199\uff09",
"Loading emoticons...": "\u52a0\u8f7d\u8868\u60c5\u7b26\u53f7...",
"Could not load emoticons": "\u4e0d\u80fd\u52a0\u8f7d\u8868\u60c5\u7b26\u53f7",
"People": "\u4eba\u7c7b",
"Animals and Nature": "\u52a8\u7269\u548c\u81ea\u7136",
"Food and Drink": "\u98df\u7269\u548c\u996e\u54c1",
"Activity": "\u6d3b\u52a8",
"Travel and Places": "\u65c5\u6e38\u548c\u5730\u70b9",
"Objects": "\u7269\u4ef6",
"Flags": "\u65d7\u5e1c",
"Characters": "\u5b57\u7b26",
"Characters (no spaces)": "\u5b57\u7b26(\u65e0\u7a7a\u683c)",
"Error: Form submit field collision.": "\u9519\u8bef: \u8868\u5355\u63d0\u4ea4\u5b57\u6bb5\u51b2\u7a81\u3002",
"Error: No form element found.": "\u9519\u8bef: \u6ca1\u6709\u8868\u5355\u63a7\u4ef6\u3002",
"Update": "\u66f4\u65b0",
"Color swatch": "\u989c\u8272\u6837\u672c",
"Turquoise": "\u9752\u7eff\u8272",
"Green": "\u7eff\u8272",
"Blue": "\u84dd\u8272",
"Purple": "\u7d2b\u8272",
"Navy Blue": "\u6d77\u519b\u84dd",
"Dark Turquoise": "\u6df1\u84dd\u7eff\u8272",
"Dark Green": "\u6df1\u7eff\u8272",
"Medium Blue": "\u4e2d\u84dd\u8272",
"Medium Purple": "\u4e2d\u7d2b\u8272",
"Midnight Blue": "\u6df1\u84dd\u8272",
"Yellow": "\u9ec4\u8272",
"Orange": "\u6a59\u8272",
"Red": "\u7ea2\u8272",
"Light Gray": "\u6d45\u7070\u8272",
"Gray": "\u7070\u8272",
"Dark Yellow": "\u6697\u9ec4\u8272",
"Dark Orange": "\u6df1\u6a59\u8272",
"Dark Red": "\u6df1\u7ea2\u8272",
"Medium Gray": "\u4e2d\u7070\u8272",
"Dark Gray": "\u6df1\u7070\u8272",
"Black": "\u9ed1\u8272",
"White": "\u767d\u8272",
"Switch to or from fullscreen mode": "\u5207\u6362\u5168\u5c4f\u6a21\u5f0f",
"Open help dialog": "\u6253\u5f00\u5e2e\u52a9\u5bf9\u8bdd\u6846",
"history": "\u5386\u53f2",
"styles": "\u6837\u5f0f",
"formatting": "\u683c\u5f0f\u5316",
"alignment": "\u5bf9\u9f50",
"indentation": "\u7f29\u8fdb",
"permanent pen": "\u8bb0\u53f7\u7b14",
"comments": "\u5907\u6ce8",
"Anchor": "\u951a\u70b9",
"Special character": "\u7279\u6b8a\u7b26\u53f7",
"Code sample": "\u4ee3\u7801\u793a\u4f8b",
"Color": "\u989c\u8272",
"Emoticons": "\u8868\u60c5",
"Document properties": "\u6587\u6863\u5c5e\u6027",
"Image": "\u56fe\u7247",
"Insert link": "\u63d2\u5165\u94fe\u63a5",
"Target": "\u6253\u5f00\u65b9\u5f0f",
"Link": "\u94fe\u63a5",
"Poster": "\u5c01\u9762",
"Media": "\u5a92\u4f53",
"Print": "\u6253\u5370",
"Prev": "\u4e0a\u4e00\u4e2a",
"Find and replace": "\u67e5\u627e\u548c\u66ff\u6362",
"Whole words": "\u5168\u5b57\u5339\u914d",
"Spellcheck": "\u62fc\u5199\u68c0\u67e5",
"Caption": "\u6807\u9898",
"Insert template": "\u63d2\u5165\u6a21\u677f"
});

@ -0,0 +1,9 @@
/**
* Copyright (c) Tiny Technologies, Inc. All rights reserved.
* Licensed under the LGPL or a commercial license.
* For LGPL see License.txt in the project root for license information.
* For commercial licenses see https://www.tiny.cloud/
*
* Version: 5.2.0 (2020-02-13)
*/
!function(){"use strict";function n(){}function o(n){return function(){return n}}function t(){return d}var e,r=tinymce.util.Tools.resolve("tinymce.PluginManager"),u=tinymce.util.Tools.resolve("tinymce.util.Tools"),l=function(n,t,e){var r="UL"===t?"InsertUnorderedList":"InsertOrderedList";n.execCommand(r,!1,!1===e?null:{"list-style-type":e})},i=function(e){e.addCommand("ApplyUnorderedListStyle",function(n,t){l(e,"UL",t["list-style-type"])}),e.addCommand("ApplyOrderedListStyle",function(n,t){l(e,"OL",t["list-style-type"])})},c=function(n){var t=n.getParam("advlist_number_styles","default,lower-alpha,lower-greek,lower-roman,upper-alpha,upper-roman");return t?t.split(/[ ,]/):[]},s=function(n){var t=n.getParam("advlist_bullet_styles","default,circle,square");return t?t.split(/[ ,]/):[]},f=o(!1),a=o(!0),d=(e={fold:function(n,t){return n()},is:f,isSome:f,isNone:a,getOr:m,getOrThunk:p,getOrDie:function(n){throw new Error(n||"error: getOrDie called on none.")},getOrNull:o(null),getOrUndefined:o(undefined),or:m,orThunk:p,map:t,each:n,bind:t,exists:f,forall:a,filter:t,equals:g,equals_:g,toArray:function(){return[]},toString:o("none()")},Object.freeze&&Object.freeze(e),e);function g(n){return n.isNone()}function p(n){return n()}function m(n){return n}function y(n,t,e){var r=function(n,t){for(var e=0;e<n.length;e++){if(t(n[e]))return e}return-1}(t.parents,L),i=-1!==r?t.parents.slice(0,r):t.parents,o=u.grep(i,N(n));return 0<o.length&&o[0].nodeName===e}function O(n,t,e,r,i,o){0<o.length?function(e,n,t,r,i,o){e.ui.registry.addSplitButton(n,{tooltip:t,icon:"OL"===i?"ordered-list":"unordered-list",presets:"listpreview",columns:3,fetch:function(n){n(u.map(o,function(n){return{type:"choiceitem",value:"default"===n?"":n,icon:"list-"+("OL"===i?"num":"bull")+"-"+("disc"===n||"decimal"===n?"default":n),text:function(n){return n.replace(/\-/g," ").replace(/\b\w/g,function(n){return n.toUpperCase()})}(n)}}))},onAction:function(){return e.execCommand(r)},onItemAction:function(n,t){l(e,i,t)},select:function(t){return S(e).map(function(n){return t===n}).getOr(!1)},onSetup:function(t){function n(n){t.setActive(y(e,n,i))}return e.on("NodeChange",n),function(){return e.off("NodeChange",n)}}})}(n,t,e,r,i,o):function(e,n,t,r,i){e.ui.registry.addToggleButton(n,{active:!1,tooltip:t,icon:"OL"===i?"ordered-list":"unordered-list",onSetup:function(t){function n(n){t.setActive(y(e,n,i))}return e.on("NodeChange",n),function(){return e.off("NodeChange",n)}},onAction:function(){return e.execCommand(r)}})}(n,t,e,r,i)}var v=function(e){function n(){return i}function t(n){return n(e)}var r=o(e),i={fold:function(n,t){return t(e)},is:function(n){return e===n},isSome:a,isNone:f,getOr:r,getOrThunk:r,getOrDie:r,getOrNull:r,getOrUndefined:r,or:n,orThunk:n,map:function(n){return v(n(e))},each:function(n){n(e)},bind:t,exists:t,forall:t,filter:function(n){return n(e)?i:d},toArray:function(){return[e]},toString:function(){return"some("+e+")"},equals:function(n){return n.is(e)},equals_:function(n,t){return n.fold(f,function(n){return t(e,n)})}};return i},h=function(n){return null===n||n===undefined?d:v(n)},L=function(n){return n&&/^(TH|TD)$/.test(n.nodeName)},N=function(t){return function(n){return n&&/^(OL|UL|DL)$/.test(n.nodeName)&&function(n,t){return n.$.contains(n.getBody(),t)}(t,n)}},S=function(n){var t=n.dom.getParent(n.selection.getNode(),"ol,ul"),e=n.dom.getStyle(t,"listStyleType");return h(e)},T=function(n){O(n,"numlist","Numbered list","InsertOrderedList","OL",c(n)),O(n,"bullist","Bullet list","InsertUnorderedList","UL",s(n))};!function b(){r.add("advlist",function(n){var t,e,r;e="lists",r=(t=n).settings.plugins?t.settings.plugins:"",-1!==u.inArray(r.split(/[ ,]/),e)&&(T(n),i(n))})}()}();

@ -0,0 +1,9 @@
/**
* Copyright (c) Tiny Technologies, Inc. All rights reserved.
* Licensed under the LGPL or a commercial license.
* For LGPL see License.txt in the project root for license information.
* For commercial licenses see https://www.tiny.cloud/
*
* Version: 5.2.0 (2020-02-13)
*/
!function(){"use strict";function e(o){return function(t){for(var e=0;e<t.length;e++)(n=t[e]).attr("href")||!n.attr("id")&&!n.attr("name")||n.firstChild||t[e].attr("contenteditable",o);var n}}var t=tinymce.util.Tools.resolve("tinymce.PluginManager"),n=function(t){return/^[A-Za-z][A-Za-z0-9\-:._]*$/.test(t)},o=function(t){var e=t.selection.getNode();return"A"===e.tagName&&""===t.dom.getAttrib(e,"href")?e.getAttribute("id")||e.getAttribute("name"):""},r=function(t,e){var n=t.selection.getNode();"A"===n.tagName&&""===t.dom.getAttrib(n,"href")?(n.removeAttribute("name"),n.id=e,t.undoManager.add()):(t.focus(),t.selection.collapse(!0),t.execCommand("mceInsertContent",!1,t.dom.createHTML("a",{id:e})))},a=function(e){var t=o(e);e.windowManager.open({title:"Anchor",size:"normal",body:{type:"panel",items:[{name:"id",type:"input",label:"ID",placeholder:"example"}]},buttons:[{type:"cancel",name:"cancel",text:"Cancel"},{type:"submit",name:"save",text:"Save",primary:!0}],initialData:{id:t},onSubmit:function(t){!function(t,e){return n(e)?(r(t,e),!1):(t.windowManager.alert("Id should start with a letter, followed only by letters, numbers, dashes, dots, colons or underscores."),!0)}(e,t.getData().id)&&t.close()}})},i=function(t){t.addCommand("mceAnchor",function(){a(t)})},c=function(t){t.on("PreInit",function(){t.parser.addNodeFilter("a",e("false")),t.serializer.addNodeFilter("a",e(null))})},d=function(e){e.ui.registry.addToggleButton("anchor",{icon:"bookmark",tooltip:"Anchor",onAction:function(){return e.execCommand("mceAnchor")},onSetup:function(t){return e.selection.selectorChangedWithUnbind("a:not([href])",t.setActive).unbind}}),e.ui.registry.addMenuItem("anchor",{icon:"bookmark",text:"Anchor...",onAction:function(){return e.execCommand("mceAnchor")}})};!function u(){t.add("anchor",function(t){c(t),i(t),d(t)})}()}();

@ -0,0 +1,9 @@
/**
* Copyright (c) Tiny Technologies, Inc. All rights reserved.
* Licensed under the LGPL or a commercial license.
* For LGPL see License.txt in the project root for license information.
* For commercial licenses see https://www.tiny.cloud/
*
* Version: 5.2.0 (2020-02-13)
*/
!function(){"use strict";function i(t,e){if(e<0&&(e=0),3===t.nodeType){var n=t.data.length;n<e&&(e=n)}return e}function C(t,e,n){1!==e.nodeType||e.hasChildNodes()?t.setStart(e,i(e,n)):t.setStartBefore(e)}function y(t,e,n){1!==e.nodeType||e.hasChildNodes()?t.setEnd(e,i(e,n)):t.setEndAfter(e)}var t=tinymce.util.Tools.resolve("tinymce.PluginManager"),o=tinymce.util.Tools.resolve("tinymce.Env"),k=function(t){return t.getParam("autolink_pattern",/^(https?:\/\/|ssh:\/\/|ftp:\/\/|file:\/|www\.|(?:mailto:)?[A-Z0-9._%+\-]+@)(.+)$/i)},p=function(t){return t.getParam("default_link_target",!1)},w=function(t){return t.getParam("link_default_protocol","http","string")},r=function(t,e,n){var i,o,r,f,a,s,d,l,c,u,g=k(t),h=p(t);if("A"!==t.selection.getNode().tagName){if((i=t.selection.getRng(!0).cloneRange()).startOffset<5){if(!(l=i.endContainer.previousSibling)){if(!i.endContainer.firstChild||!i.endContainer.firstChild.nextSibling)return;l=i.endContainer.firstChild.nextSibling}if(c=l.length,C(i,l,c),y(i,l,c),i.endOffset<5)return;o=i.endOffset,f=l}else{if(3!==(f=i.endContainer).nodeType&&f.firstChild){for(;3!==f.nodeType&&f.firstChild;)f=f.firstChild;3===f.nodeType&&(C(i,f,0),y(i,f,f.nodeValue.length))}o=1===i.endOffset?2:i.endOffset-1-e}for(r=o;C(i,f,2<=o?o-2:0),y(i,f,1<=o?o-1:0),o-=1," "!==(u=i.toString())&&""!==u&&160!==u.charCodeAt(0)&&0<=o-2&&u!==n;);!function(t,e){return t===e||" "===t||160===t.charCodeAt(0)}(i.toString(),n)?(0===i.startOffset?C(i,f,0):C(i,f,o),y(i,f,r)):(C(i,f,o),y(i,f,r),o+=1),"."===(s=i.toString()).charAt(s.length-1)&&y(i,f,r-1),d=(s=i.toString().trim()).match(g);var m=w(t);d&&("www."===d[1]?d[1]=m+"://www.":/@$/.test(d[1])&&!/^mailto:/.test(d[1])&&(d[1]="mailto:"+d[1]),a=t.selection.getBookmark(),t.selection.setRng(i),t.execCommand("createlink",!1,d[1]+d[2]),!1!==h&&t.dom.setAttrib(t.selection.getNode(),"target",h),t.selection.moveToBookmark(a),t.nodeChanged())}},e=function(e){var n;e.on("keydown",function(t){if(13===t.keyCode)return function(t){r(t,-1,"")}(e)}),o.browser.isIE()?e.on("focus",function(){if(!n){n=!0;try{e.execCommand("AutoUrlDetect",!1,!0)}catch(t){}}}):(e.on("keypress",function(t){if(41===t.keyCode)return function(t){r(t,-1,"(")}(e)}),e.on("keyup",function(t){if(32===t.keyCode)return function(t){r(t,0,"")}(e)}))};!function n(){t.add("autolink",function(t){e(t)})}()}();

@ -0,0 +1,9 @@
/**
* Copyright (c) Tiny Technologies, Inc. All rights reserved.
* Licensed under the LGPL or a commercial license.
* For LGPL see License.txt in the project root for license information.
* For commercial licenses see https://www.tiny.cloud/
*
* Version: 5.2.0 (2020-02-13)
*/
!function(n){"use strict";function r(t,e){var n=t||e,r=/^(\d+)([ms]?)$/.exec(""+n);return(r[2]?{s:1e3,m:6e4}[r[2]]:1)*parseInt(n,10)}function o(t){var e=t.getParam("autosave_prefix","tinymce-autosave-{path}{query}{hash}-{id}-");return e=(e=(e=(e=e.replace(/\{path\}/g,n.document.location.pathname)).replace(/\{query\}/g,n.document.location.search)).replace(/\{hash\}/g,n.document.location.hash)).replace(/\{id\}/g,t.id)}function a(t,e){var n=t.settings.forced_root_block;return""===(e=d.trim(void 0===e?t.getBody().innerHTML:e))||new RegExp("^<"+n+"[^>]*>((\xa0|&nbsp;|[ \t]|<br[^>]*>)+?|)</"+n+">|<br>$","i").test(e)}function i(t){var e=parseInt(v.getItem(o(t)+"time"),10)||0;return!((new Date).getTime()-e>function(t){return r(t.settings.autosave_retention,"20m")}(t))||(g(t,!1),!1)}function u(t){var e=o(t);!a(t)&&t.isDirty()&&(v.setItem(e+"draft",t.getContent({format:"raw",no_events:!0})),v.setItem(e+"time",(new Date).getTime().toString()),function(t){t.fire("StoreDraft")}(t))}function s(t){var e=o(t);i(t)&&(t.setContent(v.getItem(e+"draft"),{format:"raw"}),function(t){t.fire("RestoreDraft")}(t))}function c(t,e){var n=function(t){return r(t.settings.autosave_interval,"30s")}(t);e.get()||(m.setInterval(function(){t.removed||u(t)},n),e.set(!0))}function f(t){t.undoManager.transact(function(){s(t),g(t)}),t.focus()}var l=function(t){function e(){return n}var n=t;return{get:e,set:function(t){n=t},clone:function(){return l(e())}}},t=tinymce.util.Tools.resolve("tinymce.PluginManager"),m=tinymce.util.Tools.resolve("tinymce.util.Delay"),v=tinymce.util.Tools.resolve("tinymce.util.LocalStorage"),d=tinymce.util.Tools.resolve("tinymce.util.Tools"),g=function(t,e){var n=o(t);v.removeItem(n+"draft"),v.removeItem(n+"time"),!1!==e&&function(t){t.fire("RemoveDraft")}(t)};function y(r){for(var o=[],t=1;t<arguments.length;t++)o[t-1]=arguments[t];return function(){for(var t=[],e=0;e<arguments.length;e++)t[e]=arguments[e];var n=o.concat(t);return r.apply(null,n)}}function p(n,t){return function(t){t.setDisabled(!i(n));function e(){return t.setDisabled(!i(n))}return n.on("StoreDraft RestoreDraft RemoveDraft",e),function(){return n.off("StoreDraft RestoreDraft RemoveDraft",e)}}}var D=tinymce.util.Tools.resolve("tinymce.EditorManager");!function e(){t.add("autosave",function(t){var e=l(!1);return function(t){t.editorManager.on("BeforeUnload",function(t){var e;d.each(D.get(),function(t){t.plugins.autosave&&t.plugins.autosave.storeDraft(),!e&&t.isDirty()&&function(t){return t.getParam("autosave_ask_before_unload",!0)}(t)&&(e=t.translate("You have unsaved changes are you sure you want to navigate away?"))}),e&&(t.preventDefault(),t.returnValue=e)})}(t),function(t,e){c(t,e),t.ui.registry.addButton("restoredraft",{tooltip:"Restore last draft",icon:"restore-draft",onAction:function(){f(t)},onSetup:p(t)}),t.ui.registry.addMenuItem("restoredraft",{text:"Restore last draft",icon:"restore-draft",onAction:function(){f(t)},onSetup:p(t)})}(t,e),t.on("init",function(){(function(t){return t.getParam("autosave_restore_when_empty",!1)})(t)&&t.dom.isEmpty(t.getBody())&&s(t)}),function(t){return{hasDraft:y(i,t),storeDraft:y(u,t),restoreDraft:y(s,t),removeDraft:y(g,t),isEmpty:y(a,t)}}(t)})}()}(window);

File diff suppressed because one or more lines are too long

@ -0,0 +1,9 @@
/**
* Copyright (c) Tiny Technologies, Inc. All rights reserved.
* Licensed under the LGPL or a commercial license.
* For LGPL see License.txt in the project root for license information.
* For commercial licenses see https://www.tiny.cloud/
*
* Version: 5.2.0 (2020-02-13)
*/
!function(){"use strict";var e=tinymce.util.Tools.resolve("tinymce.PluginManager"),t=function(e,n){e.focus(),e.undoManager.transact(function(){e.setContent(n)}),e.selection.setCursorLocation(),e.nodeChanged()},o=function(e){return e.getContent({source_view:!0})},n=function(n){var e=o(n);n.windowManager.open({title:"Source Code",size:"large",body:{type:"panel",items:[{type:"textarea",name:"code"}]},buttons:[{type:"cancel",name:"cancel",text:"Cancel"},{type:"submit",name:"save",text:"Save",primary:!0}],initialData:{code:e},onSubmit:function(e){t(n,e.getData().code),e.close()}})},c=function(e){e.addCommand("mceCodeEditor",function(){n(e)})},i=function(e){e.ui.registry.addButton("code",{icon:"sourcecode",tooltip:"Source code",onAction:function(){return n(e)}}),e.ui.registry.addMenuItem("code",{icon:"sourcecode",text:"Source code",onAction:function(){return n(e)}})};!function u(){e.add("code",function(e){return c(e),i(e),{}})}()}();

File diff suppressed because one or more lines are too long

@ -0,0 +1,9 @@
/**
* Copyright (c) Tiny Technologies, Inc. All rights reserved.
* Licensed under the LGPL or a commercial license.
* For LGPL see License.txt in the project root for license information.
* For commercial licenses see https://www.tiny.cloud/
*
* Version: 5.2.0 (2020-02-13)
*/
!function(i){"use strict";function n(){}function u(n){return function(){return n}}function t(){return a}var e,r=tinymce.util.Tools.resolve("tinymce.PluginManager"),c=tinymce.util.Tools.resolve("tinymce.util.Tools"),o=function(n,t){var e,r=n.dom,o=n.selection.getSelectedBlocks();o.length&&(e=r.getAttrib(o[0],"dir"),c.each(o,function(n){r.getParent(n.parentNode,'*[dir="'+t+'"]',r.getRoot())||r.setAttrib(n,"dir",e!==t?t:null)}),n.nodeChanged())},d=function(n){n.addCommand("mceDirectionLTR",function(){o(n,"ltr")}),n.addCommand("mceDirectionRTL",function(){o(n,"rtl")})},f=u(!1),l=u(!0),a=(e={fold:function(n,t){return n()},is:f,isSome:f,isNone:l,getOr:s,getOrThunk:N,getOrDie:function(n){throw new Error(n||"error: getOrDie called on none.")},getOrNull:u(null),getOrUndefined:u(undefined),or:s,orThunk:N,map:t,each:n,bind:t,exists:f,forall:l,filter:t,equals:m,equals_:m,toArray:function(){return[]},toString:u("none()")},Object.freeze&&Object.freeze(e),e);function m(n){return n.isNone()}function N(n){return n()}function s(n){return n}function g(n,t){var e=n.dom(),r=i.window.getComputedStyle(e).getPropertyValue(t),o=""!==r||function(n){var t=A(n)?n.dom().parentNode:n.dom();return t!==undefined&&null!==t&&t.ownerDocument.body.contains(t)}(n)?r:w(e,t);return null===o?undefined:o}function T(t,r){return function(e){function n(n){var t=p.fromDom(n.element);e.setActive(function(n){return"rtl"===g(n,"direction")?"rtl":"ltr"}(t)===r)}return t.on("NodeChange",n),function(){return t.off("NodeChange",n)}}}var E,O,y=function(e){function n(){return o}function t(n){return n(e)}var r=u(e),o={fold:function(n,t){return t(e)},is:function(n){return e===n},isSome:l,isNone:f,getOr:r,getOrThunk:r,getOrDie:r,getOrNull:r,getOrUndefined:r,or:n,orThunk:n,map:function(n){return y(n(e))},each:function(n){n(e)},bind:t,exists:t,forall:t,filter:function(n){return n(e)?o:a},toArray:function(){return[e]},toString:function(){return"some("+e+")"},equals:function(n){return n.is(e)},equals_:function(n,t){return n.fold(f,function(n){return t(e,n)})}};return o},D=function(n){return null===n||n===undefined?a:y(n)},h=function(n){if(null===n||n===undefined)throw new Error("Node cannot be null or undefined");return{dom:u(n)}},p={fromHtml:function(n,t){var e=(t||i.document).createElement("div");if(e.innerHTML=n,!e.hasChildNodes()||1<e.childNodes.length)throw i.console.error("HTML does not have a single root node",n),new Error("HTML must have a single root node");return h(e.childNodes[0])},fromTag:function(n,t){var e=(t||i.document).createElement(n);return h(e)},fromText:function(n,t){var e=(t||i.document).createTextNode(n);return h(e)},fromDom:h,fromPoint:function(n,t,e){var r=n.dom();return D(r.elementFromPoint(t,e)).map(h)}},_=(E="function",function(n){return function(n){if(null===n)return"null";var t=typeof n;return"object"==t&&(Array.prototype.isPrototypeOf(n)||n.constructor&&"Array"===n.constructor.name)?"array":"object"==t&&(String.prototype.isPrototypeOf(n)||n.constructor&&"String"===n.constructor.name)?"string":t}(n)===E}),v=Array.prototype.slice,C=(_(Array.from)&&Array.from,i.Node.ATTRIBUTE_NODE,i.Node.CDATA_SECTION_NODE,i.Node.COMMENT_NODE,i.Node.DOCUMENT_NODE,i.Node.DOCUMENT_TYPE_NODE,i.Node.DOCUMENT_FRAGMENT_NODE,i.Node.ELEMENT_NODE,i.Node.TEXT_NODE),A=(i.Node.PROCESSING_INSTRUCTION_NODE,i.Node.ENTITY_REFERENCE_NODE,i.Node.ENTITY_NODE,i.Node.NOTATION_NODE,"undefined"!=typeof i.window?i.window:Function("return this;")(),O=C,function(n){return function(n){return n.dom().nodeType}(n)===O}),w=function(n,t){return function(n){return n.style!==undefined&&_(n.style.getPropertyValue)}(n)?n.style.getPropertyValue(t):""},S=function(n){n.ui.registry.addToggleButton("ltr",{tooltip:"Left to right",icon:"ltr",onAction:function(){return n.execCommand("mceDirectionLTR")},onSetup:T(n,"ltr")}),n.ui.registry.addToggleButton("rtl",{tooltip:"Right to left",icon:"rtl",onAction:function(){return n.execCommand("mceDirectionRTL")},onSetup:T(n,"rtl")})};!function R(){r.add("directionality",function(n){d(n),S(n)})}()}(window);

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

@ -0,0 +1,9 @@
/**
* Copyright (c) Tiny Technologies, Inc. All rights reserved.
* Licensed under the LGPL or a commercial license.
* For LGPL see License.txt in the project root for license information.
* For commercial licenses see https://www.tiny.cloud/
*
* Version: 5.2.0 (2020-02-13)
*/
!function(){"use strict";var n=tinymce.util.Tools.resolve("tinymce.PluginManager"),o=function(n){n.addCommand("InsertHorizontalRule",function(){n.execCommand("mceInsertContent",!1,"<hr />")})},t=function(n){n.ui.registry.addButton("hr",{icon:"horizontal-rule",tooltip:"Horizontal line",onAction:function(){return n.execCommand("InsertHorizontalRule")}}),n.ui.registry.addMenuItem("hr",{icon:"horizontal-rule",text:"Horizontal line",onAction:function(){return n.execCommand("InsertHorizontalRule")}})};!function e(){n.add("hr",function(n){o(n),t(n)})}()}();

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

@ -0,0 +1,9 @@
/**
* Copyright (c) Tiny Technologies, Inc. All rights reserved.
* Licensed under the LGPL or a commercial license.
* For LGPL see License.txt in the project root for license information.
* For commercial licenses see https://www.tiny.cloud/
*
* Version: 5.2.0 (2020-02-13)
*/
!function(){"use strict";function t(){}function n(t){return function(){return t}}function e(){return h}var r,o=tinymce.util.Tools.resolve("tinymce.PluginManager"),a=tinymce.util.Tools.resolve("tinymce.dom.DOMUtils"),f=tinymce.util.Tools.resolve("tinymce.EditorManager"),l=tinymce.util.Tools.resolve("tinymce.Env"),m=tinymce.util.Tools.resolve("tinymce.util.Tools"),c=function(t){return t.getParam("importcss_merge_classes")},i=function(t){return t.getParam("importcss_exclusive")},p=function(t){return t.getParam("importcss_selector_converter")},g=function(t){return t.getParam("importcss_selector_filter")},y=function(t){return t.getParam("importcss_groups")},v=function(t){return t.getParam("importcss_append")},d=function(t){return t.getParam("importcss_file_filter")},u=n(!1),s=n(!0),h=(r={fold:function(t,n){return t()},is:u,isSome:u,isNone:s,getOr:O,getOrThunk:x,getOrDie:function(t){throw new Error(t||"error: getOrDie called on none.")},getOrNull:n(null),getOrUndefined:n(undefined),or:O,orThunk:x,map:e,each:t,bind:e,exists:u,forall:s,filter:e,equals:_,equals_:_,toArray:function(){return[]},toString:n("none()")},Object.freeze&&Object.freeze(r),r);function _(t){return t.isNone()}function x(t){return t()}function O(t){return t}function T(n){return function(t){return function(t){if(null===t)return"null";var n=typeof t;return"object"==n&&(Array.prototype.isPrototypeOf(t)||t.constructor&&"Array"===t.constructor.name)?"array":"object"==n&&(String.prototype.isPrototypeOf(t)||t.constructor&&"String"===t.constructor.name)?"string":n}(t)===n}}function b(t,n){return function(t){for(var n=[],e=0,r=t.length;e<r;++e){if(!w(t[e]))throw new Error("Arr.flatten item "+e+" was not an array, input: "+t);M.apply(n,t[e])}return n}(function(t,n){for(var e=t.length,r=new Array(e),o=0;o<e;o++){var i=t[o];r[o]=n(i,o)}return r}(t,n))}function k(n){return"string"==typeof n?function(t){return-1!==t.indexOf(n)}:n instanceof RegExp?function(t){return n.test(t)}:n}function S(i,t,u){var c=[],e={};function s(t,n){var e,r=t.href;if((r=function(t){var n=l.cacheSuffix;return"string"==typeof t&&(t=t.replace("?"+n,"").replace("&"+n,"")),t}(r))&&u(r,n)&&!function(t,n){var e=t.settings,r=!1!==e.skin&&(e.skin||"oxide");if(r){var o=e.skin_url?t.documentBaseURI.toAbsolute(e.skin_url):f.baseURL+"/skins/ui/"+r,i=f.baseURL+"/skins/content/";return n===o+"/content"+(t.inline?".inline":"")+".min.css"||-1!==n.indexOf(i)}return!1}(i,r)){m.each(t.imports,function(t){s(t,!0)});try{e=t.cssRules||t.rules}catch(o){}m.each(e,function(t){t.styleSheet?s(t.styleSheet,!0):t.selectorText&&m.each(t.selectorText.split(","),function(t){c.push(m.trim(t))})})}}m.each(i.contentCSS,function(t){e[t]=!0}),u=u||function(t,n){return n||e[t]};try{m.each(t.styleSheets,function(t){s(t)})}catch(n){}return c}function A(t,n){var e,r=/^(?:([a-z0-9\-_]+))?(\.[a-z0-9_\-\.]+)$/i.exec(n);if(r){var o=r[1],i=r[2].substr(1).split(".").join(" "),u=m.makeMap("a,img");return r[1]?(e={title:n},t.schema.getTextBlockElements()[o]?e.block=o:t.schema.getBlockElements()[o]||u[o.toLowerCase()]?e.selector=o:e.inline=o):r[2]&&(e={inline:"span",title:n.substr(1),classes:i}),!1!==c(t)?e.classes=i:e.attributes={"class":i},e}}function P(t,n){return null===n||!1!==i(t)}var w=T("array"),E=T("function"),I=Array.prototype.slice,M=Array.prototype.push,j=(E(Array.from)&&Array.from,A),D=function(s){s.on("init",function(t){function r(t,n){if(function(t,n,e,r){return!(P(t,e)?n in r:n in e.selectors)}(s,t,n,i)){!function(t,n,e,r){P(t,e)?r[n]=!0:e.selectors[n]=!0}(s,t,n,i);var e=function(t,n,e,r){return(r&&r.selector_converter?r.selector_converter:p(t)?p(t):function(){return A(t,e)}).call(n,e,r)}(s,s.plugins.importcss,t,n);if(e){var r=e.name||a.DOM.uniqueId();return s.formatter.register(r,e),m.extend({},{title:e.title,format:r})}}return null}var o=function(){var n=[],e=[],r={};return{addItemToGroup:function(t,n){r[t]?r[t].push(n):(e.push(t),r[t]=[n])},addItem:function(t){n.push(t)},toFormats:function(){return b(e,function(t){var n=r[t];return 0===n.length?[]:[{title:t,items:n}]}).concat(n)}}}(),i={},u=k(g(s)),c=function(t){return m.map(t,function(t){return m.extend({},t,{original:t,selectors:{},filter:k(t.filter),item:{text:t.title,menu:[]}})})}(y(s));m.each(S(s,s.getDoc(),k(d(s))),function(e){if(-1===e.indexOf(".mce-")&&(!u||u(e))){var t=function(t,n){return m.grep(t,function(t){return!t.filter||t.filter(n)})}(c,e);if(0<t.length)m.each(t,function(t){var n=r(e,t);n&&o.addItemToGroup(t.title,n)});else{var n=r(e,null);n&&o.addItem(n)}}});var n=o.toFormats();s.fire("addStyleModifications",{items:n,replace:!v(s)})})},R=function(n){return{convertSelectorToFormat:function(t){return j(n,t)}}};!function U(){o.add("importcss",function(t){return D(t),R(t)})}()}();

@ -0,0 +1,9 @@
/**
* Copyright (c) Tiny Technologies, Inc. All rights reserved.
* Licensed under the LGPL or a commercial license.
* For LGPL see License.txt in the project root for license information.
* For commercial licenses see https://www.tiny.cloud/
*
* Version: 5.2.0 (2020-02-13)
*/
!function(){"use strict";function n(e){return e.getParam("insertdatetime_timeformat",e.translate("%H:%M:%S"))}function r(e){return e.getParam("insertdatetime_formats",["%H:%M:%S","%Y-%m-%d","%I:%M:%S %p","%D"])}function a(e,t){if((e=""+e).length<t)for(var n=0;n<t-e.length;n++)e="0"+e;return e}function i(e,t,n){return n=n||new Date,t=(t=(t=(t=(t=(t=(t=(t=(t=(t=(t=(t=(t=(t=(t=(t=t.replace("%D","%m/%d/%Y")).replace("%r","%I:%M:%S %p")).replace("%Y",""+n.getFullYear())).replace("%y",""+n.getYear())).replace("%m",a(n.getMonth()+1,2))).replace("%d",a(n.getDate(),2))).replace("%H",""+a(n.getHours(),2))).replace("%M",""+a(n.getMinutes(),2))).replace("%S",""+a(n.getSeconds(),2))).replace("%I",""+((n.getHours()+11)%12+1))).replace("%p",n.getHours()<12?"AM":"PM")).replace("%B",""+e.translate(f[n.getMonth()]))).replace("%b",""+e.translate(d[n.getMonth()]))).replace("%A",""+e.translate(s[n.getDay()]))).replace("%a",""+e.translate(l[n.getDay()]))).replace("%%","%")}var e=tinymce.util.Tools.resolve("tinymce.PluginManager"),t=function(e){return e.getParam("insertdatetime_dateformat",e.translate("%Y-%m-%d"))},o=n,u=r,c=function(e){var t=r(e);return 0<t.length?t[0]:n(e)},m=function(e){return e.getParam("insertdatetime_element",!1)},l="Sun Mon Tue Wed Thu Fri Sat Sun".split(" "),s="Sunday Monday Tuesday Wednesday Thursday Friday Saturday Sunday".split(" "),d="Jan Feb Mar Apr May Jun Jul Aug Sep Oct Nov Dec".split(" "),f="January February March April May June July August September October November December".split(" "),p=function(e,t){if(m(e)){var n=i(e,t),r=void 0;r=/%[HMSIp]/.test(t)?i(e,"%Y-%m-%dT%H:%M"):i(e,"%Y-%m-%d");var a=e.dom.getParent(e.selection.getStart(),"time");a?function(e,t,n,r){var a=e.dom.create("time",{datetime:n},r);t.parentNode.insertBefore(a,t),e.dom.remove(t),e.selection.select(a,!0),e.selection.collapse(!1)}(e,a,r,n):e.insertContent('<time datetime="'+r+'">'+n+"</time>")}else e.insertContent(i(e,t))},g=i,y=function(e){e.addCommand("mceInsertDate",function(){p(e,t(e))}),e.addCommand("mceInsertTime",function(){p(e,o(e))})},M=tinymce.util.Tools.resolve("tinymce.util.Tools"),S=function(e){function t(){return n}var n=e;return{get:t,set:function(e){n=e},clone:function(){return S(t())}}},v=function(n){var t=u(n),r=S(c(n));n.ui.registry.addSplitButton("insertdatetime",{icon:"insert-time",tooltip:"Insert date/time",select:function(e){return e===r.get()},fetch:function(e){e(M.map(t,function(e){return{type:"choiceitem",text:g(n,e),value:e}}))},onAction:function(){for(var e=[],t=0;t<arguments.length;t++)e[t]=arguments[t];p(n,r.get())},onItemAction:function(e,t){r.set(t),p(n,t)}});n.ui.registry.addNestedMenuItem("insertdatetime",{icon:"insert-time",text:"Date/time",getSubmenuItems:function(){return M.map(t,function(e){return{type:"menuitem",text:g(n,e),onAction:function(e){return function(){r.set(e),p(n,e)}}(e)}})}})};!function h(){e.add("insertdatetime",function(e){y(e),v(e)})}()}();

@ -0,0 +1,58 @@
tinymce.PluginManager.add('lineheight', function(editor, url) {
var pluginName='设置行高';
var global$1 = tinymce.util.Tools.resolve('tinymce.util.Tools');
var lineheight_val = editor.getParam('lineheight_val', '1 1.5 1.6 1.75 1.8 2 3 4 5');
editor.on('init', function() {
editor.formatter.register({
lineheight: {
selector: 'p,h1,h2,h3,h4,h5,h6,td,th,div,ul,ol,li,table',
styles: { 'line-height': '%value' }
}
});
});
var doAct = function (value) {
editor.formatter.apply('lineheight', { value: value });
editor.fire('change', {});
};
editor.ui.registry.getAll().icons.lineheight || editor.ui.registry.addIcon('lineheight','<svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24"><path d="M9.984 12.984v-1.969h12v1.969h-12zM9.984 18.984v-1.969h12v1.969h-12zM9.984 5.016h12v1.969h-12v-1.969zM6 6.984v10.031h2.484l-3.469 3.469-3.516-3.469h2.484v-10.031h-2.484l3.516-3.469 3.469 3.469h-2.484z"></path></svg>');
editor.ui.registry.addMenuButton('lineheight', {
icon: 'lineheight',
tooltip: pluginName,
fetch: function(callback) {
var dom = editor.dom;
var blocks = editor.selection.getSelectedBlocks();
var lhv = 0;
global$1.each(blocks, function(block) {
if(lhv==0){
lhv = dom.getStyle(block,'line-height') ? dom.getStyle(block,'line-height') : 0;
}
});
var items = lineheight_val.split(' ').map(function(item){
var text = item;
var value = item;
return {
type: 'togglemenuitem',
text: text,
active : lhv==value ? true :false,
onAction: function() {
doAct(value);
}
};
});
callback(items);
}
});
return {
getMetadata: function () {
return {
name: pluginName
};
}
};
});

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

@ -0,0 +1,9 @@
/**
* Copyright (c) Tiny Technologies, Inc. All rights reserved.
* Licensed under the LGPL or a commercial license.
* For LGPL see License.txt in the project root for license information.
* For commercial licenses see https://www.tiny.cloud/
*
* Version: 5.2.0 (2020-02-13)
*/
!function(){"use strict";function o(n,e){for(var t="",o=0;o<e;o++)t+=n;return t}var n=tinymce.util.Tools.resolve("tinymce.PluginManager"),i=function(n){var e=n.getParam("nonbreaking_force_tab",0);return"boolean"==typeof e?!0===e?3:0:e},a=function(n){return n.getParam("nonbreaking_wrap",!0,"boolean")},r=function(n,e){var t=a(n)||n.plugins.visualchars?'<span class="'+(function(n){return!!n.plugins.visualchars&&n.plugins.visualchars.isEnabled()}(n)?"mce-nbsp-wrap mce-nbsp":"mce-nbsp-wrap")+'" contenteditable="false">'+o("&nbsp;",e)+"</span>":o("&nbsp;",e);n.undoManager.transact(function(){return n.insertContent(t)})},e=function(n){n.addCommand("mceNonBreaking",function(){r(n,1)})},c=tinymce.util.Tools.resolve("tinymce.util.VK"),t=function(e){var t=i(e);0<t&&e.on("keydown",function(n){if(n.keyCode===c.TAB&&!n.isDefaultPrevented()){if(n.shiftKey)return;n.preventDefault(),n.stopImmediatePropagation(),r(e,t)}})},u=function(n){n.ui.registry.addButton("nonbreaking",{icon:"non-breaking",tooltip:"Nonbreaking space",onAction:function(){return n.execCommand("mceNonBreaking")}}),n.ui.registry.addMenuItem("nonbreaking",{icon:"non-breaking",text:"Nonbreaking space",onAction:function(){return n.execCommand("mceNonBreaking")}})};!function s(){n.add("nonbreaking",function(n){e(n),u(n),t(n)})}()}();

@ -0,0 +1,9 @@
/**
* Copyright (c) Tiny Technologies, Inc. All rights reserved.
* Licensed under the LGPL or a commercial license.
* For LGPL see License.txt in the project root for license information.
* For commercial licenses see https://www.tiny.cloud/
*
* Version: 5.2.0 (2020-02-13)
*/
!function(){"use strict";function c(n){return function(t){return-1!==(" "+t.attr("class")+" ").indexOf(n)}}function l(i,o,c){return function(t){var n=arguments,e=n[n.length-2],r=0<e?o.charAt(e-1):"";if('"'===r)return t;if(">"===r){var a=o.lastIndexOf("<",e);if(-1!==a)if(-1!==o.substring(a,e).indexOf('contenteditable="false"'))return t}return'<span class="'+c+'" data-mce-content="'+i.dom.encode(n[0])+'">'+i.dom.encode("string"==typeof n[1]?n[1]:n[0])+"</span>"}}var t=tinymce.util.Tools.resolve("tinymce.PluginManager"),u=tinymce.util.Tools.resolve("tinymce.util.Tools"),f=function(t){return t.getParam("noneditable_noneditable_class","mceNonEditable")},s=function(t){return t.getParam("noneditable_editable_class","mceEditable")},d=function(t){var n=t.getParam("noneditable_regexp",[]);return n&&n.constructor===RegExp?[n]:n},n=function(n){var t,e,r="contenteditable";t=" "+u.trim(s(n))+" ",e=" "+u.trim(f(n))+" ";var a=c(t),i=c(e),o=d(n);n.on("PreInit",function(){0<o.length&&n.on("BeforeSetContent",function(t){!function(t,n,e){var r=n.length,a=e.content;if("raw"!==e.format){for(;r--;)a=a.replace(n[r],l(t,a,f(t)));e.content=a}}(n,o,t)}),n.parser.addAttributeFilter("class",function(t){for(var n,e=t.length;e--;)n=t[e],a(n)?n.attr(r,"true"):i(n)&&n.attr(r,"false")}),n.serializer.addAttributeFilter(r,function(t){for(var n,e=t.length;e--;)n=t[e],(a(n)||i(n))&&(0<o.length&&n.attr("data-mce-content")?(n.name="#text",n.type=3,n.raw=!0,n.value=n.attr("data-mce-content")):n.attr(r,null))})})};!function e(){t.add("noneditable",function(t){n(t)})}()}();

@ -0,0 +1,9 @@
/**
* Copyright (c) Tiny Technologies, Inc. All rights reserved.
* Licensed under the LGPL or a commercial license.
* For LGPL see License.txt in the project root for license information.
* For commercial licenses see https://www.tiny.cloud/
*
* Version: 5.2.0 (2020-02-13)
*/
!function(){"use strict";function e(){return"mce-pagebreak"}function a(){return'<img src="'+t.transparentSrc+'" class="mce-pagebreak" data-mce-resize="false" data-mce-placeholder />'}var n=tinymce.util.Tools.resolve("tinymce.PluginManager"),t=tinymce.util.Tools.resolve("tinymce.Env"),r=function(e){return e.getParam("pagebreak_separator","\x3c!-- pagebreak --\x3e")},i=function(e){return e.getParam("pagebreak_split_block",!1)},o=function(o){var c=r(o),n=new RegExp(c.replace(/[\?\.\*\[\]\(\)\{\}\+\^\$\:]/g,function(e){return"\\"+e}),"gi");o.on("BeforeSetContent",function(e){e.content=e.content.replace(n,a())}),o.on("PreInit",function(){o.serializer.addNodeFilter("img",function(e){for(var n,a,t=e.length;t--;)if((a=(n=e[t]).attr("class"))&&-1!==a.indexOf("mce-pagebreak")){var r=n.parent;if(o.schema.getBlockElements()[r.name]&&i(o)){r.type=3,r.value=c,r.raw=!0,n.remove();continue}n.type=3,n.value=c,n.raw=!0}})})},c=a,u=e,g=function(e){e.addCommand("mcePageBreak",function(){e.settings.pagebreak_split_block?e.insertContent("<p>"+c()+"</p>"):e.insertContent(c())})},m=function(n){n.on("ResolveName",function(e){"IMG"===e.target.nodeName&&n.dom.hasClass(e.target,u())&&(e.name="pagebreak")})},s=function(e){e.ui.registry.addButton("pagebreak",{icon:"page-break",tooltip:"Page break",onAction:function(){return e.execCommand("mcePageBreak")}}),e.ui.registry.addMenuItem("pagebreak",{text:"Page break",icon:"page-break",onAction:function(){return e.execCommand("mcePageBreak")}})};!function l(){n.add("pagebreak",function(e){g(e),s(e),o(e),m(e)})}()}();

File diff suppressed because one or more lines are too long

@ -0,0 +1,9 @@
/**
* Copyright (c) Tiny Technologies, Inc. All rights reserved.
* Licensed under the LGPL or a commercial license.
* For LGPL see License.txt in the project root for license information.
* For commercial licenses see https://www.tiny.cloud/
*
* Version: 5.2.0 (2020-02-13)
*/
!function(){"use strict";var e=tinymce.util.Tools.resolve("tinymce.PluginManager"),l=tinymce.util.Tools.resolve("tinymce.util.Tools"),m=function(e){return e.getParam("content_style","")},u=function(e){return e.getParam("content_css_cors",!1,"boolean")},y=tinymce.util.Tools.resolve("tinymce.Env"),n=function(t){var n="",i=t.dom.encode,e=m(t);n+='<base href="'+i(t.documentBaseURI.getURI())+'">',e&&(n+='<style type="text/css">'+e+"</style>");var o=u(t)?' crossorigin="anonymous"':"";l.each(t.contentCSS,function(e){n+='<link type="text/css" rel="stylesheet" href="'+i(t.documentBaseURI.toAbsolute(e))+'"'+o+">"});var r=t.settings.body_id||"tinymce";-1!==r.indexOf("=")&&(r=(r=t.getParam("body_id","","hash"))[t.id]||r);var a=t.settings.body_class||"";-1!==a.indexOf("=")&&(a=(a=t.getParam("body_class","","hash"))[t.id]||"");var c='<script>document.addEventListener && document.addEventListener("click", function(e) {for (var elm = e.target; elm; elm = elm.parentNode) {if (elm.nodeName === "A" && !('+(y.mac?"e.metaKey":"e.ctrlKey && !e.altKey")+")) {e.preventDefault();}}}, false);<\/script> ",s=t.getBody().dir,d=s?' dir="'+i(s)+'"':"";return"<!DOCTYPE html><html><head>"+n+'</head><body id="'+i(r)+'" class="mce-content-body '+i(a)+'"'+d+">"+t.getContent()+c+"</body></html>"},t=function(e){e.addCommand("mcePreview",function(){!function(e){var t=n(e);e.windowManager.open({title:"Preview",size:"large",body:{type:"panel",items:[{name:"preview",type:"iframe",sandboxed:!0}]},buttons:[{type:"cancel",name:"close",text:"Close",primary:!0}],initialData:{preview:t}}).focus("close")}(e)})},i=function(e){e.ui.registry.addButton("preview",{icon:"preview",tooltip:"Preview",onAction:function(){return e.execCommand("mcePreview")}}),e.ui.registry.addMenuItem("preview",{icon:"preview",text:"Preview",onAction:function(){return e.execCommand("mcePreview")}})};!function o(){e.add("preview",function(e){t(e),i(e)})}()}();

@ -0,0 +1,9 @@
/**
* Copyright (c) Tiny Technologies, Inc. All rights reserved.
* Licensed under the LGPL or a commercial license.
* For LGPL see License.txt in the project root for license information.
* For commercial licenses see https://www.tiny.cloud/
*
* Version: 5.2.0 (2020-02-13)
*/
!function(){"use strict";var n=tinymce.util.Tools.resolve("tinymce.PluginManager"),t=tinymce.util.Tools.resolve("tinymce.Env"),i=function(n){n.addCommand("mcePrint",function(){t.browser.isIE()?n.getDoc().execCommand("print",!1,null):n.getWin().print()})},e=function(n){n.ui.registry.addButton("print",{icon:"print",tooltip:"Print",onAction:function(){return n.execCommand("mcePrint")}}),n.ui.registry.addMenuItem("print",{text:"Print...",icon:"print",onAction:function(){return n.execCommand("mcePrint")}})};!function o(){n.add("print",function(n){i(n),e(n),n.addShortcut("Meta+P","","mcePrint")})}()}();

File diff suppressed because one or more lines are too long

@ -0,0 +1,97 @@
tinymce.PluginManager.add('rowspacing', function(editor, url) {
var pluginName='设置段间距';
var global$1 = tinymce.util.Tools.resolve('tinymce.util.Tools');
var rowspacing_val = editor.getParam('rowspacing_val', '5px 10px 15px 20px 25px 30px');
editor.on('init', function() {
editor.formatter.register({
rowspacingtop: {
selector: 'p,h1,h2,h3,h4,h5,h6,td,th,div,ul,ol,li,table',
styles: { 'margin-top': '%value' }
},
rowspacingbottom: {
selector: 'p,h1,h2,h3,h4,h5,h6,td,th,div,ul,ol,li,table',
styles: { 'margin-bottom': '%value' }
}
});
});
var doTopAct = function (value) {
editor.formatter.apply('rowspacingtop', { value: value });
editor.fire('change', {});
};
var doBottomAct = function (value) {
editor.formatter.apply('rowspacingbottom', { value: value });
editor.fire('change', {});
};
editor.ui.registry.getAll().icons.rowspacingtop || editor.ui.registry.addIcon('rowspacingtop','<svg t="1588054802814" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="7912" xmlns:xlink="http://www.w3.org/1999/xlink" width="18" height="18"><defs><style type="text/css"></style></defs><path d="M894.29333333 493.72273778L129.70666667 493.72273778c-30.14656001 0-54.61333333-16.31118222-54.61333334-36.40888889s24.46677333-36.40888888 54.61333334-36.4088889l764.58666666 0c30.14656001 0 54.61333333 16.31118222 54.61333334 36.4088889s-24.46677333 36.40888888-54.61333334 36.40888889m-1.16508444 227.55555555l-764.58666667-1e-8c-29.70965333-0.36408889-53.44824889-16.52963555-53.44824889-36.40888887 0-19.80643555 23.73859555-35.97198222 53.44824889-36.40888891l764.58666667 1e-8c19.80643555-0.21845333 38.22933333 6.62641778 48.27818666 18.0588089a26.36003555 26.36003555 0 0 1 0 36.84579555c-10.04885333 11.35957333-28.47175111 18.20444445-48.27818666 17.91317333M917.95911112 948.90666667L106.62343111 948.90666667c-17.25781332 0-31.23882667-16.31118222-31.23882666-36.40888889s13.98101333-36.40888889 31.23882665-36.40888889l811.33568001 2e-8c17.25781332 0 31.23882667 16.31118222 31.23882667 36.40888887s-13.98101333 36.40888889-31.23882666 36.40888889M480.97962667 84.55964445L373.79185778 213.66556445c-16.16554667 19.6608-4.22343111 52.4288 19.22389333 52.42880001l214.22990222-1e-8c23.52014222 0 35.53507556-32.768 19.29671112-52.42879999L519.28177778 84.55964445a24.17550222 24.17550222 0 0 0-38.37496889 0" fill="#333333" p-id="7913"></path></svg>');
editor.ui.registry.getAll().icons.rowspacingbottom || editor.ui.registry.addIcon('rowspacingbottom','<svg t="1588054797622" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="7792" xmlns:xlink="http://www.w3.org/1999/xlink" width="18" height="18"><defs><style type="text/css"></style></defs><path d="M129.70666667 530.27726222L894.29333333 530.27726222c30.14656001 0 54.61333333 16.31118222 54.61333334 36.40888889s-24.46677333 36.40888888-54.61333334 36.40888889l-764.58666666 0c-30.14656001 0-54.61333333-16.31118222-54.61333334-36.40888889s24.46677333-36.40888888 54.61333334-36.40888889m1.16508444-227.55555555l764.58666667 0c29.70965333 0.36408889 53.44824889 16.52963555 53.44824889 36.40888888 0 19.80643555-23.73859555 35.97198222-53.44824889 36.4088889l-764.58666667 0c-19.80643555 0.21845333-38.22933333-6.62641778-48.27818666-18.0588089a26.36003555 26.36003555 0 0 1 0-36.84579555c10.04885333-11.35957333 28.47175111-18.20444445 48.27818666-17.91317333M106.04088888 75.09333333L917.37656889 75.09333333c17.25781332 0 31.23882667 16.31118222 31.23882666 36.40888889s-13.98101333 36.40888889-31.23882666 36.40888889l-811.33568-1e-8c-17.25781332 0-31.23882667-16.31118222-31.23882667-36.40888888s13.98101333-36.40888889 31.23882666-36.40888889M543.02037333 939.44035555L650.20814222 810.33443555c16.16554667-19.6608 4.22343111-52.4288-19.22389333-52.4288l-214.22990222 0c-23.52014222 0-35.53507556 32.768-19.29671112 52.4288L504.71822222 939.44035555a24.17550222 24.17550222 0 0 0 38.37496889 0" fill="#333333" p-id="7793"></path></svg>');
editor.ui.registry.addMenuButton('rowspacingtop', {
icon: 'rowspacingtop',
tooltip: pluginName,
fetch: function(callback) {
var dom = editor.dom;
var blocks = editor.selection.getSelectedBlocks();
var lhv = 0;
global$1.each(blocks, function(block) {
if(lhv==0){
lhv = dom.getStyle(block,'margin-top') ? dom.getStyle(block,'margin-top') : 0;
}
});
var items = rowspacing_val.split(' ').map(function(item){
var text = item;
var value = item;
return {
type: 'togglemenuitem',
text: text,
active : lhv==value ? true :false,
onAction: function() {
doTopAct(value);
}
};
});
callback(items);
}
});
editor.ui.registry.addMenuButton('rowspacingbottom', {
icon: 'rowspacingbottom',
tooltip: pluginName,
fetch: function(callback) {
var dom = editor.dom;
var blocks = editor.selection.getSelectedBlocks();
var lhv = 0;
global$1.each(blocks, function(block) {
if(lhv==0){
lhv = dom.getStyle(block,'margin-bottom') ? dom.getStyle(block,'margin-bottom') : 0;
}
});
var items = rowspacing_val.split(' ').map(function(item){
var text = item;
var value = item;
return {
type: 'togglemenuitem',
text: text,
active : lhv==value ? true :false,
onAction: function() {
doBottomAct(value);
}
};
});
callback(items);
}
});
return {
getMetadata: function () {
return {
name: pluginName
};
}
};
});

@ -0,0 +1,9 @@
/**
* Copyright (c) Tiny Technologies, Inc. All rights reserved.
* Licensed under the LGPL or a commercial license.
* For LGPL see License.txt in the project root for license information.
* For commercial licenses see https://www.tiny.cloud/
*
* Version: 5.2.0 (2020-02-13)
*/
!function(){"use strict";function t(n,e){n.notificationManager.open({text:e,type:"error"})}function e(t){return function(n){function e(){n.setDisabled(a(t)&&!t.isDirty())}return t.on("NodeChange dirty",e),function(){return t.off("NodeChange dirty",e)}}}var n=tinymce.util.Tools.resolve("tinymce.PluginManager"),o=tinymce.util.Tools.resolve("tinymce.dom.DOMUtils"),i=tinymce.util.Tools.resolve("tinymce.util.Tools"),a=function(n){return n.getParam("save_enablewhendirty",!0)},c=function(n){return!!n.getParam("save_onsavecallback")},r=function(n){return!!n.getParam("save_oncancelcallback")},u=function(n){var e;if(e=o.DOM.getParent(n.id,"form"),!a(n)||n.isDirty()){if(n.save(),c(n))return n.execCallback("save_onsavecallback",n),void n.nodeChanged();e?(n.setDirty(!1),e.onsubmit&&!e.onsubmit()||("function"==typeof e.submit?e.submit():t(n,"Error: Form submit field collision.")),n.nodeChanged()):t(n,"Error: No form element found.")}},l=function(n){var e=i.trim(n.startContent);r(n)?n.execCallback("save_oncancelcallback",n):n.resetContent(e)},s=function(n){n.addCommand("mceSave",function(){u(n)}),n.addCommand("mceCancel",function(){l(n)})},d=function(n){n.ui.registry.addButton("save",{icon:"save",tooltip:"Save",disabled:!0,onAction:function(){return n.execCommand("mceSave")},onSetup:e(n)}),n.ui.registry.addButton("cancel",{icon:"cancel",tooltip:"Cancel",disabled:!0,onAction:function(){return n.execCommand("mceCancel")},onSetup:e(n)}),n.addShortcut("Meta+S","","mceSave")};!function m(){n.add("save",function(n){d(n),s(n)})}()}();

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

@ -0,0 +1,9 @@
/**
* Copyright (c) Tiny Technologies, Inc. All rights reserved.
* Licensed under the LGPL or a commercial license.
* For LGPL see License.txt in the project root for license information.
* For commercial licenses see https://www.tiny.cloud/
*
* Version: 5.2.0 (2020-02-13)
*/
!function(){"use strict";function e(n){return function(t){function e(){return t.setDisabled(n.readonly||!v.hasHeaders(n))}return e(),n.on("LoadContent SetContent change",e),function(){return n.on("LoadContent SetContent change",e)}}}var t=tinymce.util.Tools.resolve("tinymce.PluginManager"),u=tinymce.util.Tools.resolve("tinymce.dom.DOMUtils"),l=tinymce.util.Tools.resolve("tinymce.util.I18n"),i=tinymce.util.Tools.resolve("tinymce.util.Tools"),c=function(t){return t.getParam("toc_class","mce-toc")},d=function(t){var e=t.getParam("toc_header","h2");return/^h[1-6]$/.test(e)?e:"h2"},a=function(t){var e=parseInt(t.getParam("toc_depth","3"),10);return 1<=e&&e<=9?e:3},s=function(e){var n=0;return function(){var t=(new Date).getTime().toString(32);return e+t+(n++).toString(32)}}("mcetoc_"),f=function f(t){var e,n=[];for(e=1;e<=t;e++)n.push("h"+e);return n.join(",")},m=function(n){var o=c(n),t=d(n),e=f(a(n)),r=n.$(e);return r.length&&/^h[1-9]$/i.test(t)&&(r=r.filter(function(t,e){return!n.dom.hasClass(e.parentNode,o)})),i.map(r,function(t){return{id:t.id?t.id:s(),level:parseInt(t.nodeName.replace(/^H/i,""),10),title:n.$.text(t),element:t}})},o=function(t){var e,n,o,r,i="",c=m(t),a=function(t){var e,n=9;for(e=0;e<t.length;e++)if(t[e].level<n&&(n=t[e].level),1===n)return n;return n}(c)-1;if(!c.length)return"";for(i+=function(t,e){var n="</"+t+">";return"<"+t+' contenteditable="true">'+u.DOM.encode(e)+n}(d(t),l.translate("Table of Contents")),e=0;e<c.length;e++){if((o=c[e]).element.id=o.id,r=c[e+1]&&c[e+1].level,a===o.level)i+="<li>";else for(n=a;n<o.level;n++)i+="<ul><li>";if(i+='<a href="#'+o.id+'">'+o.title+"</a>",r!==o.level&&r)for(n=o.level;r<n;n--)i+="</li></ul><li>";else i+="</li>",r||(i+="</ul>");a=o.level}return i},r=function(t){var e=c(t),n=t.$("."+e);n.length&&t.undoManager.transact(function(){n.html(o(t))})},v={hasHeaders:function(t){return 0<m(t).length},insertToc:function(t){var e=c(t),n=t.$("."+e);!function(t,e){return!e.length||0<t.dom.getParents(e[0],".mce-offscreen-selection").length}(t,n)?r(t):t.insertContent(function(t){var e=o(t);return'<div class="'+t.dom.encode(c(t))+'" contenteditable="false">'+e+"</div>"}(t))},updateToc:r},n=function(t){t.addCommand("mceInsertToc",function(){v.insertToc(t)}),t.addCommand("mceUpdateToc",function(){v.updateToc(t)})},g=function(t){var n=t.$,o=c(t);t.on("PreProcess",function(t){var e=n("."+o,t.node);e.length&&(e.removeAttr("contentEditable"),e.find("[contenteditable]").removeAttr("contentEditable"))}),t.on("SetContent",function(){var t=n("."+o);t.length&&(t.attr("contentEditable",!1),t.children(":first-child").attr("contentEditable",!0))})},h=function(t){t.ui.registry.addButton("toc",{icon:"toc",tooltip:"Table of contents",onAction:function(){return t.execCommand("mceInsertToc")},onSetup:e(t)}),t.ui.registry.addButton("tocupdate",{icon:"reload",tooltip:"Update",onAction:function(){return t.execCommand("mceUpdateToc")}}),t.ui.registry.addMenuItem("toc",{icon:"toc",text:"Table of contents",onAction:function(){return t.execCommand("mceInsertToc")},onSetup:e(t)}),t.ui.registry.addContextToolbar("toc",{items:"tocupdate",predicate:function(e){return function(t){return t&&e.dom.is(t,"."+c(e))&&e.getBody().contains(t)}}(t),scope:"node",position:"node"})};!function p(){t.add("toc",function(t){n(t),h(t),g(t)})}()}();

@ -0,0 +1,9 @@
/**
* Copyright (c) Tiny Technologies, Inc. All rights reserved.
* Licensed under the LGPL or a commercial license.
* For LGPL see License.txt in the project root for license information.
* For commercial licenses see https://www.tiny.cloud/
*
* Version: 5.2.0 (2020-02-13)
*/
!function(){"use strict";function n(n,e){return function(o){o.setActive(e.get());function t(t){return o.setActive(t.state)}return n.on("VisualBlocks",t),function(){return n.off("VisualBlocks",t)}}}var e=function(t){function o(){return n}var n=t;return{get:o,set:function(t){n=t},clone:function(){return e(o())}}},t=tinymce.util.Tools.resolve("tinymce.PluginManager"),i=function(t,o){t.fire("VisualBlocks",{state:o})},u=function(t,o,n){t.dom.toggleClass(t.getBody(),"mce-visualblocks"),n.set(!n.get()),i(t,n.get())},c=function(t,o,n){t.addCommand("mceVisualBlocks",function(){u(t,o,n)})},s=function(t){return t.getParam("visualblocks_default_state",!1,"boolean")},l=function(o,t,n){o.on("PreviewFormats AfterPreviewFormats",function(t){n.get()&&o.dom.toggleClass(o.getBody(),"mce-visualblocks","afterpreviewformats"===t.type)}),o.on("init",function(){s(o)&&u(o,t,n)}),o.on("remove",function(){o.dom.removeClass(o.getBody(),"mce-visualblocks")})},r=function(t,o){t.ui.registry.addToggleButton("visualblocks",{icon:"visualblocks",tooltip:"Show blocks",onAction:function(){return t.execCommand("mceVisualBlocks")},onSetup:n(t,o)}),t.ui.registry.addToggleMenuItem("visualblocks",{text:"Show blocks",onAction:function(){return t.execCommand("mceVisualBlocks")},onSetup:n(t,o)})};!function o(){t.add("visualblocks",function(t,o){var n=e(!1);c(t,o,n),r(t,n),l(t,o,n)})}()}();

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

@ -0,0 +1,8 @@
/**
* Copyright (c) Tiny Technologies, Inc. All rights reserved.
* Licensed under the LGPL or a commercial license.
* For LGPL see License.txt in the project root for license information.
* For commercial licenses see https://www.tiny.cloud/
*/
body{font-family:-apple-system,BlinkMacSystemFont,'Segoe UI',Roboto,Oxygen,Ubuntu,Cantarell,'Open Sans','Helvetica Neue',sans-serif;line-height:1.4;margin:1rem}table{border-collapse:collapse}table td,table th{border:1px solid #ccc;padding:.4rem}figure{display:table;margin:1rem auto}figure figcaption{color:#999;display:block;margin-top:.25rem;text-align:center}hr{border-color:#ccc;border-style:solid;border-width:1px 0 0 0}code{background-color:#e8e8e8;border-radius:3px;padding:.1rem .2rem}.mce-content-body:not([dir=rtl]) blockquote{border-left:2px solid #ccc;margin-left:1.5rem;padding-left:1rem}.mce-content-body[dir=rtl] blockquote{border-right:2px solid #ccc;margin-right:1.5rem;padding-right:1rem}
/*# sourceMappingURL=content.min.css.map */

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

@ -0,0 +1,61 @@
import request from '@/utils/request'
// 列表
export const getConfigList = data => {
return request({
url: '/api/message/AccountConfig',
method: 'GET',
data
})
}
// 新增
export const createConfig = data => {
return request({
url: '/api/message/AccountConfig',
method: 'POST',
data
})
}
// 详情
export const getConfigDetail = id => {
return request({
url: `/api/message/AccountConfig/${id}`,
method: 'GET'
})
}
// 编辑
export const updateConfig = data => {
return request({
url: `/api/message/AccountConfig/${data.id}`,
method: 'PUT',
data
})
}
// 测试
export const testConfig = (data, type) => {
return request({
url: `/api/message/AccountConfig/${type}`,
method: 'POST',
data
})
}
// 复制
export const copyConfig = id => {
return request({
url: `/api/message/AccountConfig/copy/${id}`,
method: 'post'
})
}
// 刪除
export const delConfig = id => {
return request({
url: `/api/message/AccountConfig/${id}`,
method: 'DELETE'
})
}
// 导出
export const exportConfig = id => {
return request({
url: `/api/message/AccountConfig/${id}/Action/Export`,
method: 'GET'
})
}

@ -0,0 +1,31 @@
import request from '@/utils/request'
// 列表
export const getMsgMonitorList = data => {
return request({
url: '/api/message/MessageMonitor',
method: 'GET',
data
})
}
// 详情
export const getMsgMonitorDetail = id => {
return request({
url: `/api/message/MessageMonitor/detail/${id}`,
method: 'GET'
})
}
// 批量删除
export const delMsgMonitor = (data) => {
return request({
url: '/api/message/MessageMonitor/batchRemove',
method: 'DELETE',
data
})
}
// 一键清空
export const emptyMsgMonitor = () => {
return request({
url: '/api/message/MessageMonitor/empty',
method: 'DELETE'
})
}

@ -0,0 +1,61 @@
import request from '@/utils/request'
// 列表
export const getMsgTemplateList = data => {
return request({
url: '/api/message/MessageTemplateConfig',
method: 'GET',
data
})
}
// 新增
export const addMsgTemplate = data => {
return request({
url: '/api/message/MessageTemplateConfig',
method: 'POST',
data
})
}
// 编辑
export const editMsgTemplate = data => {
return request({
url: `/api/message/MessageTemplateConfig/${data.id}`,
method: 'PUT',
data
})
}
// 详情
export const getMsgTemplateDetail = id => {
return request({
url: `/api/message/MessageTemplateConfig/${id}`,
method: 'GET'
})
}
// 测试
export const testMsgTemplate = data => {
return request({
url: '/api/message/MessageTemplateConfig/testSendMail',
method: 'POST',
data
})
}
// 复制
export const copyMsgTemplate = id => {
return request({
url: `/api/message/MessageTemplateConfig/copy/${id}`,
method: 'post'
})
}
// 刪除
export const delMsgTemplate = id => {
return request({
url: `/api/message/MessageTemplateConfig/${id}`,
method: 'DELETE'
})
}
//数据类型具体对应数据1消息类型2渠道3webhook类型4消息来源
export const getMsgTypeList = type => {
return request({
url: `/api/message/MessageDataType/getTypeList/${type}`,
method: 'GET'
})
}

@ -0,0 +1,70 @@
import request from '@/utils/request'
// 列表
export const getSendConfigList = data => {
return request({
url: '/api/message/SendMessageConfig',
method: 'GET',
data
})
}
// 详情
export const getSendConfigDetail = id => {
return request({
url: `/api/message/SendMessageConfig/${id}`,
method: 'GET'
})
}
// 新增
export const addMsgTemplate = data => {
return request({
url: '/api/message/SendMessageConfig',
method: 'POST',
data
})
}
// 编辑
export const editMsgTemplate = data => {
return request({
url: `/api/message/SendMessageConfig/${data.id}`,
method: 'PUT',
data
})
}
// 测试发送配置获取配置信息
export const testSendConfigInfo = id => {
return request({
url: `/api/message/SendMessageConfig/getTestConfig/${id}`,
method: 'POST',
id
})
}
// 测试发送配置
export const testSendConfig = data => {
return request({
url: '/api/message/SendMessageConfig/testSendConfig',
method: 'POST',
data
})
}
// 复制
export const copySendConfig = id => {
return request({
url: `/api/message/SendMessageConfig/copy/${id}`,
method: 'post'
})
}
// 刪除
export const delMsgTemplate = id => {
return request({
url: `/api/message/SendMessageConfig/${id}`,
method: 'DELETE'
})
}
// 列表
export const getMsgTemplate = data => {
return request({
url: '/api/message/SendMessageConfig/getSendConfigList',
method: 'GET',
data
})
}

@ -0,0 +1,37 @@
import request from '@/utils/request'
// 获取分级管理员列表
export const getGradeManageList = (data) => {
return request({
url: `/api/permission/organizeAdminIsTrator`,
method: 'GET',
data
})
}
//获取组织下拉框列表
export const getSelectorOrgList = (userId) => {
return request({
url: `/api/permission/organizeAdminIsTrator/Selector/` + '?userId=' + userId,
method: 'GET'
})
}
//删除二级管理员
export const delGradeManage = (id) => {
return request({
url: `/api/permission/organizeAdminIsTrator/${id}`,
method: 'DELETE'
})
}
//新建二级管理员
export const saveGradeManage = (data) => {
return request({
url: `/api/permission/organizeAdminIsTrator`,
method: 'POST',
data
})
}

@ -0,0 +1,78 @@
import request from '@/utils/request'
// 第三方登录获取登录页面
export function otherLogin(data, param) {
return request({
url: `/api/oauth/socials/render/${data}?ticket=${param}`,
method: 'get',
})
}
// 第三方登录回调列表后点击登录
export function socialsLogin(data) {
return request({
url: `/api/oauth/Login/socials`,
method: 'post',
headers: {
'Content-Type': 'application/x-www-form-urlencoded'
},
data
})
}
//获取登录配置
export function getLoginConfig() {
return request({
url: `/api/oauth/getLoginConfig`,
method: 'get',
})
}
//获取登录票据
export function getTicket() {
return request({
url: `/api/oauth/getTicket`,
method: 'get',
})
}
//根据票据获取登录状态
export function getTicketStatus(data) {
return request({
url: `/api/oauth/getTicketStatus/${data}`,
method: 'get',
})
}
// 获取用户授权列表
export function getSocialsLoginList(data) {
return request({
url: '/api/permission/socials/login',
method: 'GET',
data
})
}
// 获取用户授权列表
export function getSocialsUserList() {
return request({
url: '/api/permission/socials',
method: 'GET',
})
}
// 获取用户授权列表
export function getSocialsUserListByUser(userId) {
return request({
url: '/api/permission/socials?userId=' + userId,
method: 'GET',
})
}
// 获取用户授权列表
export function binding(data) {
return request({
url: `/api/permission/socials/render/${data}`,
method: 'GET',
})
}
// 解绑
export function deleteSocials(userId, id) {
return request({
url: `/api/permission/socials/${id}?userId=${userId}`,
method: 'DELETE',
})
}

@ -0,0 +1,40 @@
import request from '@/utils/request'
// 获取方案列表
export function getAdvancedQueryList(moduleId) {
return request({
url: `/api/system/AdvancedQuery/${moduleId}/List`,
method: 'get'
})
}
// 获取方案详情
export function getAdvancedQueryInfo(id) {
return request({
url: `/api/system/AdvancedQuery/${id}`,
method: 'get'
})
}
// 删除
export function Delete(id) {
return request({
url: `/api/system/AdvancedQuery/${id}`,
method: 'DELETE'
})
}
// 新建
export function Create(data) {
return request({
url: '/api/system/AdvancedQuery',
method: 'post',
data
})
}
// 编辑
export function Update(data) {
return request({
url: `/api/system/AdvancedQuery/${data.id}`,
method: 'put',
data
})
}

@ -0,0 +1,35 @@
import request from '@/utils/request'
//获取表名
export function getVisualTables(menudId, type) {
return request({
url: `/api/system/ModuleDataAuthorizeLink/getVisualTables/${menudId}/${type}`,
method: 'get',
})
}
//据表名获取数据表字段
export function getTableInfoByTableName(linkId, tableName, menuType, dataType, data) {
return request({
url: `/api/system/ModuleDataAuthorizeLink/${linkId}/Tables/${tableName}/Fields/${menuType}/${dataType}`,
method: 'get',
data
})
}
//保存编辑数据连接
export function saveLinkData(data) {
return request({
url: `/api/system/ModuleDataAuthorizeLink/saveLinkData`,
method: 'post',
data
})
}
//数据连接信息
export function getInfo(menudId, type) {
return request({
url: `/api/system/ModuleDataAuthorizeLink/getInfo/${menudId}/${type}`,
method: 'get',
})
}

@ -0,0 +1,47 @@
import request from '@/utils/request'
// 获取菜单列表
export const getSystem = (data) => {
return request({
url: '/api/system/System',
method: 'GET',
data
})
}
//新建菜单列表
export const create = (data) => {
return request({
url: '/api/system/System',
method: 'post',
data
})
}
//修改菜单列表
export const update = (data) => {
return request({
url: `/api/system/System/${data.id}`,
method: 'put',
data
})
}
//菜单详情
export const info = (id) => {
return request({
url: `/api/system/System/${id}`,
method: 'get'
})
}
//删除菜单
export const delSystem = (id) => {
return request({
url: `/api/system/System/${id}`,
method: 'delete'
})
}

@ -0,0 +1,78 @@
import request from '@/utils/request'
// 获取接口认证列表(分页)
export function getInterfaceOauthList(data) {
return request({
url: '/api/system/InterfaceOauth',
method: 'GET',
data
})
}
// 创建
export function create(data) {
return request({
url: '/api/system/InterfaceOauth',
method: 'POST',
data
})
}
// 获取详情
export function getInfo(id) {
return request({
url: `/api/system/InterfaceOauth/${id}`,
method: 'GET',
})
}
// 修改接口
export function update(data) {
return request({
url: `/api/system/InterfaceOauth/${data.id}`,
method: 'PUT',
data
})
}
// 删除接口认证数据
export function deleteInterfaceIdent(id) {
return request({
url: `/api/system/InterfaceOauth/${id}`,
method: 'DELETE'
})
}
// 获取秘钥
export function getAppSecret() {
return request({
url: `/api/system/InterfaceOauth/getAppSecret`,
method: 'GET'
})
}
// 保存认证接口列表
export function saveInterfaceList(data) {
return request({
url: `/api/system/InterfaceOauth/saveInterfaceList`,
method: 'POST',
data
})
}
// 获取认证接口列表
export function getInterfaceList(id) {
return request({
url: `/api/system/InterfaceOauth/getInterfaceList/${id}`,
method: 'GET',
})
}
// 获取接口日志列表
export function dataInterfaceLog(id, data) {
return request({
url: `/api/system/InterfaceOauth/dataInterfaceLog/${id}`,
method: 'GET',
data
})
}

@ -0,0 +1,90 @@
import request from '@/utils/request'
//表单列表
export function getFormList(data) {
return request({
url: `/api/flowForm/Form`,
method: 'get',
data
})
}
//查看
export function getFormInfo(id) {
return request({
url: `/api/flowForm/Form/${id}`,
method: 'get'
})
}
//新建表单
export function Create(data) {
return request({
url: `/api/flowForm/Form`,
method: 'post',
data
})
}
//修改表单
export function Update(data) {
return request({
url: `/api/flowForm/Form`,
method: 'put',
data
})
}
//发布/回滚
export function release(id, isRelease) {
return request({
url: `/api/flowForm/Form/Release/${id}` + '?isRelease=' + isRelease,
method: 'post',
})
}
//复制表单
export function copyForm(id) {
return request({
url: `/api/flowForm/Form/${id}/Actions/Copy`,
method: 'get',
})
}
//删除表单
export function del(id) {
return request({
url: `/api/flowForm/Form/${id}`,
method: 'delete',
})
}
//导出
export function exportData(id) {
return request({
url: `/api/flowForm/Form/${id}/Actions/ExportData`,
method: 'get',
})
}
//根据表单id获取表单字段
export function getFormField(id) {
return request({
url: `/api/flowForm/Form/${id}/getField`,
method: 'get',
})
}
//根据表单id获取表单字段
export function getFormSelect(data) {
return request({
url: `/api/flowForm/Form/select`,
method: 'get',
data
})
}
//通过表单id获取流程id
export function getFormById(id) {
return request({
url: `/api/flowForm/Form/getFormById/${id}`,
method: 'get'
})
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 105 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 13 KiB

@ -0,0 +1,110 @@
<template>
<el-dialog title="模板设置" :close-on-click-modal="false"
class="JNPF-dialog JNPF-dialog_center JNPF-dialog-export" lock-scroll append-to-body
v-bind="$attrs" width="600px" :modal-append-to-body="false" v-on="$listeners">
<div class="dialog-main">
<el-form ref="dataForm" :model="dataForm" label-width="100px" label-position="left">
<el-form-item label="导入模式">
<el-radio-group v-model="dataForm.dataType">
<el-radio label="1">仅新增数据
<el-tooltip content="导入数据只能进行新增,同一条数据无法重复导入" placement="top-start">
<a class="el-icon-warning-outline"></a>
</el-tooltip>
</el-radio>
<el-radio label="2">更新和新增数据
<el-tooltip content="允许新增数据的同时支持导入数据更新" placement="top-start">
<a class="el-icon-warning-outline"></a>
</el-tooltip>
</el-radio>
</el-radio-group>
</el-form-item>
<div class="upload-line">
<p slot="label" class="export-label">表单数据<span>请选择要导入的字段</span></p>
</div>
<el-checkbox :indeterminate="isIndeterminate" v-model="checkAll"
@change="handleCheckAllChange">全选</el-checkbox>
<el-checkbox-group v-model="checkedList" @change="handleCheckedChange">
<el-checkbox v-for="item in columnList" :label="item.__vModel__" :key="item.__vModel__"
:disabled="item.disabled" class="column-item">
{{item.label}}
</el-checkbox>
</el-checkbox-group>
</el-form>
</div>
<span slot="footer" class="dialog-footer">
<el-button @click="closeDialog">{{$t('common.cancelButton')}}</el-button>
<el-button type="primary" @click="onConfirm()">{{$t('common.confirmButton')}}</el-button>
</span>
</el-dialog>
</template>
<script>
import { noVModelList, systemComponentsList } from '@/components/Generator/generator/comConfig'
const excludeList = [...noVModelList, 'uploadFz', 'uploadImg', 'colorPicker', 'popupTableSelect', 'relationForm', 'popupSelect', 'calculate', 'groupTitle']
export default {
props: ['value'],
data() {
return {
visible: false,
dataForm: {
dataType: "1"
},
checkAll: false,
checkedList: [],
isIndeterminate: false,
columnList: [],
defaultCheckedList: []
}
},
methods: {
init(columnList, selectData, dataType) {
this.visible = true
this.checkedList = []
this.defaultCheckedList = []
for (let i = 0; i < columnList.length; i++) {
const element = columnList[i]
const label = element.__config__.label
const required = element.__config__.required
const jnpfKey = element.__config__.jnpfKey
const disabled = systemComponentsList.includes(jnpfKey) || required
this.columnList.push({ __vModel__: element.__vModel__, label, disabled })
if ((required || systemComponentsList.includes(jnpfKey))) {
this.checkedList.push(element.__vModel__)
this.defaultCheckedList.push(element.__vModel__)
}
}
if (selectData && selectData.length) {
this.checkedList.push(...selectData)
this.checkedList = Array.from(new Set(this.checkedList))
}
if (this.checkedList.length) {
this.isIndeterminate = this.checkedList.length > 0 && this.checkedList.length < this.columnList.length;
this.checkAll = this.checkedList.length === this.columnList.length;
}
if (dataType) this.dataForm.dataType = dataType
},
closeDialog() {
this.$emit('update:visible', false)
},
handleCheckAllChange(val) {
this.checkedList = val ? this.columnList.map(o => o.__vModel__) : this.defaultCheckedList
this.isIndeterminate = false;
},
handleCheckedChange(value) {
let checkedCount = value.length;
this.checkAll = checkedCount === this.columnList.length;
this.isIndeterminate = checkedCount > 0 && checkedCount < this.columnList.length;
},
onConfirm() {
if (!this.checkedList.length) return this.$message.warning('请至少选择一个导入字段')
this.$emit('onConfirm', { dataType: this.dataForm.dataType, selectKey: this.checkedList })
this.closeDialog()
}
}
}
</script>
<style lang="scss" scoped>
.el-checkbox {
line-height: 32px;
}
</style>

@ -0,0 +1,67 @@
<template>
<el-dialog title="导出数据" :close-on-click-modal="false" :visible.sync="visible"
class="JNPF-dialog JNPF-dialog_center JNPF-dialog-export" lock-scroll width="600px">
<el-form label-position="top">
<el-form-item>
<el-radio-group v-model="type">
<el-radio :label="0">当前页面数据</el-radio>
<el-radio :label="1">全部页面数据</el-radio>
</el-radio-group>
</el-form-item>
<el-form-item class="export-line">
<p slot="label" class="export-label">列表数据<span>请选择导出字段</span></p>
<el-checkbox :indeterminate="isIndeterminate" v-model="checkAll"
@change="handleCheckAllChange">全选</el-checkbox>
<el-checkbox-group v-model="columns" @change="handleCheckedChange">
<el-checkbox v-for="item in columnList" :label="item.prop" :key="item.prop"
class="column-item">
{{item.label}}
</el-checkbox>
</el-checkbox-group>
</el-form-item>
</el-form>
<span slot="footer" class="dialog-footer">
<p class="footer-tip">提示:系统将导出列表中选中的数据</p>
<el-button @click="visible=false">{{$t('common.cancelButton')}}</el-button>
<el-button type="primary" @click="downLoad"> </el-button>
</span>
</el-dialog>
</template>
<script>
export default {
data() {
return {
visible: false,
btnLoading: false,
type: 0,
columns: [],
checkAll: true,
isIndeterminate: false,
columnList: []
}
},
methods: {
init(columnList) {
this.visible = true
this.checkAll = true
this.isIndeterminate = false
this.columnList = columnList
this.columns = columnList.map(o => o.prop)
},
handleCheckAllChange(val) {
this.columns = val ? this.columnList.map(o => o.prop) : [];
this.isIndeterminate = false;
},
handleCheckedChange(value) {
let checkedCount = value.length;
this.checkAll = checkedCount === this.columnList.length;
this.isIndeterminate = checkedCount > 0 && checkedCount < this.columnList.length;
},
downLoad() {
if (!this.columns.length) return this.$message.warning(`请至少选择一个导出字段`)
this.$emit('download', { dataType: this.type, selectKey: this.columns })
}
}
}
</script>

@ -0,0 +1,345 @@
<template>
<div class="popupSelect-container">
<div class="el-select" @click.stop="openDialog">
<div class="el-select__tags" v-if="multiple" ref="tags"
:style="{ 'max-width': inputWidth - 32 + 'px', width: '100%',cursor:'pointer' }">
<span v-if="collapseTags && tagsList.length">
<el-tag :closable="!selectDisabled" :size="collapseTagSize" type="info"
@close="deleteTag($event, 0)" disable-transitions>
<span class="el-select__tags-text">{{ tagsList[0].fullName }}</span>
</el-tag>
<el-tag v-if="tagsList.length > 1" :closable="false" type="info" disable-transitions>
<span class="el-select__tags-text">+ {{ tagsList.length - 1 }}</span>
</el-tag>
</span>
<transition-group @after-leave="resetInputHeight" v-if="!collapseTags">
<el-tag v-for="(item,i) in tagsList" :key="item.id" :size="collapseTagSize"
:closable="!selectDisabled" type="info" @close="deleteTag($event, i)"
disable-transitions>
<span class="el-select__tags-text">{{ item.fullName }}</span>
</el-tag>
</transition-group>
</div>
<el-input ref="reference" v-model="innerValue" type="text" :placeholder="currentPlaceholder"
:disabled="selectDisabled" readonly :validate-event="false"
:tabindex="(multiple) ? '-1' : null" @mouseenter.native="inputHovering = true"
@mouseleave.native="inputHovering = false">
<template slot="suffix">
<i v-show="!showClose"
:class="['el-select__caret', 'el-input__icon', 'el-icon-arrow-up']"></i>
<i v-if="showClose" class="el-select__caret el-input__icon el-icon-circle-close"
@click="handleClearClick"></i>
</template>
</el-input>
</div>
<el-dialog title="分组选择" :close-on-click-modal="false" :visible.sync="visible"
class="JNPF-dialog JNPF-dialog_center transfer-dialog" lock-scroll append-to-body
width="800px" :modal-append-to-body="false" @close="onClose">
<div class="transfer__body">
<div class="transfer-pane">
<div class="transfer-pane__tools">
<el-input placeholder="请输入关键词查询" v-model="keyword" @keyup.enter.native="search"
clearable class="search-input">
<el-button slot="append" icon="el-icon-search" @click="search"></el-button>
</el-input>
</div>
<div class="transfer-pane__body">
<el-tree :data="treeData" :props="props" check-on-click-node
:expand-on-click-node="false" default-expand-all @node-click="handleNodeClick"
class="JNPF-common-el-tree" node-key="id" v-loading="loading" ref="tree"
:filter-node-method="filterNode">
<span class="custom-tree-node" slot-scope="{ node, data }">
<i :class="data.icon"></i>
<span class="text">{{node.label}}</span>
</span>
</el-tree>
</div>
</div>
<div class="transfer-pane">
<div class="transfer-pane__tools">
<span>已选</span>
<el-button @click="removeAll" type="text" class="removeAllBtn">清空列表</el-button>
</div>
<div class="transfer-pane__body shadow right-pane">
<template>
<div v-for="(item, index) in selectedData" :key="index" class="selected-item">
<span>{{item.fullName}}</span>
<i class="el-icon-delete" @click="removeData(index)"></i>
</div>
</template>
</div>
</div>
</div>
<span slot="footer" class="dialog-footer">
<el-button @click="setDefault(),visible=false">{{$t('common.cancelButton')}}</el-button>
<el-button type="primary" @click="confirm">{{$t('common.confirmButton')}}</el-button>
</span>
</el-dialog>
</div>
</template>
<script>
import { addResizeListener, removeResizeListener } from 'element-ui/src/utils/resize-event';
export default {
name: 'groupSelect',
inject: {
elForm: {
default: ''
},
elFormItem: {
default: ''
}
},
props: {
value: {
default: ''
},
placeholder: {
type: String,
default: '请选择'
},
disabled: {
type: Boolean,
default: false
},
multiple: {
type: Boolean,
default: false
},
collapseTags: {
type: Boolean,
default: false
},
clearable: {
type: Boolean,
default: false
},
size: String,
},
data() {
return {
treeData: [],
allList: [],
keyword: '',
innerValue: '',
visible: false,
loading: false,
props: {
children: 'children',
label: 'fullName',
isLeaf: 'isLeaf'
},
selectedData: [],
tagsList: [],
inputHovering: false,
inputWidth: 0,
initialInputHeight: 0,
}
},
computed: {
showClose() {
let hasValue = this.multiple
? Array.isArray(this.value) && this.value.length > 0
: this.value !== undefined && this.value !== null && this.value !== '';
let criteria = this.clearable &&
!this.selectDisabled &&
this.inputHovering &&
hasValue;
return criteria;
},
currentPlaceholder() {
if (this.multiple && Array.isArray(this.value) && this.value.length) {
return ''
} else {
return this.placeholder
}
},
selectDisabled() {
return this.disabled || (this.elForm || {}).disabled;
},
_elFormItemSize() {
return (this.elFormItem || {}).elFormItemSize;
},
selectSize() {
return this.size || this._elFormItemSize || (this.$ELEMENT || {}).size;
},
collapseTagSize() {
return ['small', 'mini'].indexOf(this.selectSize) > -1
? 'mini'
: 'small';
},
},
created() {
this.getData()
},
mounted() {
addResizeListener(this.$el, this.handleResize);
const reference = this.$refs.reference;
if (reference && reference.$el) {
const sizeMap = {
medium: 36,
small: 32,
mini: 28
};
const input = reference.$el.querySelector('input');
this.initialInputHeight = input.getBoundingClientRect().height || sizeMap[this.selectSize];
}
if (this.multiple) {
this.resetInputHeight();
}
this.$nextTick(() => {
if (reference && reference.$el) {
this.inputWidth = reference.$el.getBoundingClientRect().width;
}
});
this.setDefault()
},
beforeDestroy() {
if (this.$el && this.handleResize) removeResizeListener(this.$el, this.handleResize);
},
watch: {
value(val) {
this.setDefault()
},
selectDisabled() {
this.$nextTick(() => {
this.resetInputHeight();
});
},
allList: {
handler: function (val) {
this.setDefault()
},
deep: true
}
},
methods: {
async getData() {
this.treeData = await this.$store.dispatch('generator/getGroupTree')
this.allList = await this.$store.getters.groupList
},
onClose() { },
openDialog() {
if (this.selectDisabled) return
this.keyword = ''
this.search()
this.setDefault()
this.visible = true
},
search() {
this.$refs.tree && this.$refs.tree.filter(this.keyword)
},
filterNode(value, data) {
if (!value) return true;
return data[this.props.label].indexOf(value) !== -1;
},
handleNodeClick(data) {
if (data.type !== 'group') return
const boo = this.selectedData.some(o => o.id === data.id)
if (boo) return
this.multiple ? this.selectedData.push(data) : this.selectedData = [data]
},
removeAll() {
this.selectedData = []
},
removeData(index) {
this.selectedData.splice(index, 1)
},
confirm() {
if (this.multiple) {
this.innerValue = ''
this.tagsList = JSON.parse(JSON.stringify(this.selectedData))
let selectedIds = this.selectedData.map(o => o.id)
this.$emit('input', selectedIds)
this.$emit('change', selectedIds, this.selectedData)
} else {
if (!this.selectedData.length) {
this.innerValue = ''
this.$emit('input', '')
this.$emit('change', '', {})
this.visible = false
return
}
this.innerValue = this.selectedData[0].fullName
let selectedIds = this.selectedData[0].id
this.$emit('input', selectedIds)
this.$emit('change', selectedIds, this.selectedData[0])
}
this.visible = false
},
setDefault() {
if (!this.value || !this.value.length) {
this.innerValue = ''
this.selectedData = []
this.tagsList = []
return
}
const arr = this.multiple ? this.value : [this.value]
let selectedData = []
for (let i = 0; i < arr.length; i++) {
const item = arr[i];
inner: for (let j = 0; j < this.allList.length; j++) {
if (item === this.allList[j].id) {
selectedData.push(this.allList[j])
break inner
}
}
}
this.selectedData = selectedData
if (this.multiple) {
this.innerValue = ''
this.tagsList = JSON.parse(JSON.stringify(this.selectedData))
this.$nextTick(() => {
this.resetInputHeight();
})
} else {
if (!this.selectedData.length) return this.innerValue = ''
this.innerValue = this.selectedData[0].fullName
}
},
deleteTag(event, index) {
this.selectedData.splice(index, 1)
this.confirm()
event.stopPropagation();
},
handleClearClick(event) {
this.selectedData = []
this.confirm()
event.stopPropagation();
},
resetInputWidth() {
this.inputWidth = this.$refs.reference.$el.getBoundingClientRect().width;
},
handleResize() {
this.resetInputWidth();
if (this.multiple) this.resetInputHeight();
},
resetInputHeight() {
if (this.collapseTags) return;
this.$nextTick(() => {
if (!this.$refs.reference) return;
let inputChildNodes = this.$refs.reference.$el.childNodes;
let input = [].filter.call(inputChildNodes, item => item.tagName === 'INPUT')[0];
const tags = this.$refs.tags;
const tagsHeight = tags ? Math.round(tags.getBoundingClientRect().height) : 0;
const sizeInMap = this.initialInputHeight || 40;
input.style.height = this.selectedData.length === 0
? sizeInMap + 'px'
: Math.max(
tags ? (tagsHeight + (tagsHeight > sizeInMap ? 6 : 0)) : 0,
sizeInMap
) + 'px';
});
},
resetInputWidth() {
this.inputWidth = this.$refs.reference.$el.getBoundingClientRect().width;
},
handleResize() {
this.resetInputWidth();
if (this.multiple) this.resetInputHeight();
}
}
}
</script>

@ -0,0 +1,46 @@
<template>
<p :style="_style">
<el-link :underline="false" @click="onClickLink" type="primary">{{ content }}</el-link>
</p>
</template>
<script>
const Base64 = require('js-base64').Base64
export default {
props: {
textStyle: {
type: Object,
default: () => ({
'text-align': 'left',
})
},
content: {
type: String,
default: ""
},
href: {
type: String,
default: ""
},
target: {
type: String,
default: "_self"
}
},
computed: {
_style() {
return { ...this.textStyle }
}
},
methods: {
onClickLink(event) {
this.$emit('click', event)
if (!this.href) return
if (this.target === '_self') {
this.$router.push({ path: `/externalLink?href=${encodeURIComponent(Base64.encode(this.href))}` })
} else if (this.target === '_blank') {
window.open(this.href, this.target)
}
}
}
}
</script>

@ -0,0 +1,480 @@
<template>
<div class="popupSelect-container">
<el-popover placement="bottom-start" width="700" trigger="click" ref="popover"
:disabled="selectDisabled" @after-enter="openDialog" class="popover-container">
<div class="el-select" slot="reference">
<div class="el-select__tags" v-if="multiple" ref="tags"
:style="{ 'max-width': inputWidth - 32 + 'px', width: '100%',cursor:'pointer' }">
<span v-if="collapseTags && tagsList.length">
<el-tag :closable="!selectDisabled" :size="collapseTagSize" type="info"
@close="deleteTag($event, 0)" disable-transitions>
<span class="el-select__tags-text">{{ tagsList[0][relationField] }}</span>
</el-tag>
<el-tag v-if="tagsList.length > 1" :closable="false" type="info" disable-transitions>
<span class="el-select__tags-text">+ {{ tagsList.length - 1 }}</span>
</el-tag>
</span>
<transition-group @after-leave="resetInputHeight" v-if="!collapseTags">
<el-tag v-for="(item,i) in tagsList" :key="item[propsValue]" :size="collapseTagSize"
:closable="!selectDisabled" type="info" @close="deleteTag($event, i)"
disable-transitions>
<span class="el-select__tags-text">{{ item[relationField] }}</span>
</el-tag>
</transition-group>
</div>
<el-input ref="reference" v-model="innerValue" type="text" :placeholder="currentPlaceholder"
:disabled="selectDisabled" readonly :validate-event="false"
:tabindex="(multiple) ? '-1' : null" @mouseenter.native="inputHovering = true"
@mouseleave.native="inputHovering = false">
<template slot="suffix">
<i v-show="!showClose"
:class="['el-select__caret', 'el-input__icon', 'el-icon-arrow-up']"></i>
<i v-if="showClose" class="el-select__caret el-input__icon el-icon-circle-close"
@click.stop="handleClearClick"></i>
</template>
</el-input>
</div>
<template>
<el-form @submit.native.prevent :inline="true" v-if="filterable">
<el-form-item label="关键词">
<el-input size="small" v-model="listQuery.keyword" placeholder="请输入关键词查询" clearable
@keyup.enter.native="search()" />
</el-form-item>
<el-form-item>
<el-row :gutter="5">
<el-col :span="12">
<el-button type="primary" size="small" icon="el-icon-search" @click="search()">
{{$t('common.search')}}
</el-button>
</el-col>
<el-col :span="12">
<el-button size="small" icon="el-icon-refresh-right" @click="reset()">
{{$t('common.reset')}}
</el-button>
</el-col>
</el-row>
</el-form-item>
</el-form>
<JNPF-table v-loading="listLoading" :data="list" :border="false" highlight-current-row
@row-click="rowClick" :hasNO="false" height="300">
<el-table-column width="35" v-if="multiple">
<template slot-scope="scope">
<el-checkbox :value="selectedIds.includes(scope.row[propsValue])" disabled
class="table-checkbox">&nbsp;</el-checkbox>
</template>
</el-table-column>
<el-table-column width="35" v-if="!multiple">
<template slot-scope="scope">
<el-radio :label="scope.row[propsValue]" v-model="checked">&nbsp;</el-radio>
</template>
</el-table-column>
<el-table-column type="index" width="50" label="序号" align="center" />
<el-table-column :prop="item.value" :label="item.label" v-for="(item,i) in columnOptions"
:key="i" />
</JNPF-table>
<pagination :total="total" :page.sync="listQuery.currentPage" :pager-count="5"
:limit.sync="listQuery.pageSize" @pagination="initData" v-if="hasPage" class="mb-10" />
<div class="fr">
<el-button @click="closePopover" size="small">{{$t('common.cancelButton')}}
</el-button>
<el-button type="primary" @click="confirm()" size="small">{{$t('common.confirmButton')}}
</el-button>
</div>
</template>
</el-popover>
</div>
</template>
<script>
import { getDataInterfaceDataSelect, getDataInterfaceDataInfoByIds } from '@/api/systemData/dataInterface'
import { addResizeListener, removeResizeListener } from 'element-ui/src/utils/resize-event';
export default {
name: 'PopupTableSelect',
inject: {
elForm: {
default: ''
},
elFormItem: {
default: ''
}
},
props: {
value: {
type: [String, Number, Array],
default: ''
},
rowIndex: {
default: null
},
formData: {
type: Object
},
templateJson: {
type: Array,
default: () => []
},
interfaceId: {
type: String,
default: ''
},
placeholder: {
type: String,
default: '请选择'
},
propsValue: {
type: String,
default: 'id'
},
relationField: {
type: String,
default: 'fullName'
},
popupType: {
type: String,
default: 'popover'
},
popupTitle: {
type: String,
default: '选择数据'
},
popupWidth: {
type: String,
default: '800px'
},
field: {
type: String,
default: ''
},
columnOptions: {
type: Array,
default: () => []
},
hasPage: {
type: Boolean,
default: false
},
pageSize: {
type: Number,
default: 20
},
multiple: {
type: Boolean,
default: false
},
disabled: {
type: Boolean,
default: false
},
filterable: {
type: Boolean,
default: false
},
clearable: {
type: Boolean,
default: true
},
collapseTags: {
type: Boolean,
default: false
},
size: String,
},
model: {
prop: 'value',
event: 'input'
},
data() {
return {
list: [],
innerValue: '',
listQuery: {
keyword: '',
currentPage: 1,
pageSize: 20
},
total: 0,
checked: '',
checkedTxt: '',
checkedRow: {},
selectedData: [],
selectedIds: [],
tagsList: [],
listLoading: false,
inputHovering: false,
inputWidth: 0,
initialInputHeight: 0,
}
},
watch: {
value(val) {
this.setDefault()
},
selectDisabled() {
this.$nextTick(() => {
this.resetInputHeight();
});
},
},
computed: {
showClose() {
let hasValue = this.multiple
? Array.isArray(this.value) && this.value.length > 0
: this.value !== undefined && this.value !== null && this.value !== '';
let criteria = this.clearable &&
!this.selectDisabled &&
this.inputHovering &&
hasValue;
return criteria;
},
currentPlaceholder() {
if (this.multiple && Array.isArray(this.value) && this.value.length) {
return ''
} else {
return this.placeholder
}
},
selectDisabled() {
return this.disabled || (this.elForm || {}).disabled;
},
_elFormItemSize() {
return (this.elFormItem || {}).elFormItemSize;
},
selectSize() {
return this.size || this._elFormItemSize || (this.$ELEMENT || {}).size;
},
collapseTagSize() {
return ['small', 'mini'].indexOf(this.selectSize) > -1
? 'mini'
: 'small';
},
},
created() {
this.listQuery.pageSize = this.hasPage ? this.pageSize : 10000
this.setDefault()
},
mounted() {
addResizeListener(this.$el, this.handleResize);
const reference = this.$refs.reference;
if (reference && reference.$el) {
const sizeMap = {
medium: 36,
small: 32,
mini: 28
};
const input = reference.$el.querySelector('input');
this.initialInputHeight = input.getBoundingClientRect().height || sizeMap[this.selectSize];
}
if (this.multiple) {
this.resetInputHeight();
}
this.$nextTick(() => {
if (reference && reference.$el) {
this.inputWidth = reference.$el.getBoundingClientRect().width;
}
});
this.setDefault()
},
beforeDestroy() {
if (this.$el && this.handleResize) removeResizeListener(this.$el, this.handleResize);
},
methods: {
closePopover() {
this.$refs.popover.doClose()
},
initData() {
if (!this.interfaceId) return
this.listLoading = true
const paramList = this.getParamList()
const columnOptions = this.columnOptions.map(o => o.value)
let query = {
...this.listQuery,
interfaceId: this.interfaceId,
propsValue: this.propsValue,
relationField: this.relationField,
columnOptions: columnOptions.join(','),
paramList
}
getDataInterfaceDataSelect(this.interfaceId, query).then(res => {
this.list = res.data.list
this.total = res.data.pagination.total
this.listLoading = false
}).catch(() => { this.listLoading = false })
},
getParamList() {
let templateJson = this.templateJson
for (let i = 0; i < templateJson.length; i++) {
if (templateJson[i].relationField && this.formData) {
if (templateJson[i].relationField.includes('-')) {
let tableVModel = templateJson[i].relationField.split('-')[0]
let childVModel = templateJson[i].relationField.split('-')[1]
templateJson[i].defaultValue = this.formData[tableVModel] && this.formData[tableVModel][this.rowIndex] && this.formData[tableVModel][this.rowIndex][childVModel] || ''
} else {
templateJson[i].defaultValue = this.formData[templateJson[i].relationField] || ''
}
}
}
return templateJson
},
interfaceDataHandler(data) {
if (!data.dataProcessing) return data.list
const dataHandler = this.jnpf.getScriptFunc.call(this, data.dataProcessing)
if (!dataHandler) return data.list
return dataHandler(data.list)
},
search() {
this.initData()
this.listQuery.currentPage = 1
this.listQuery.pageSize = this.hasPage ? this.pageSize : 10000
},
reset() {
this.listQuery.keyword = ''
this.listQuery.currentPage = 1
this.listQuery.pageSize = this.hasPage ? this.pageSize : 10000
this.initData()
},
openDialog() {
if (this.disabled) return
this.reset()
},
confirm() {
if (this.multiple) {
this.innerValue = ''
this.tagsList = JSON.parse(JSON.stringify(this.selectedData))
this.selectedIds = this.selectedData.map(o => o[this.propsValue])
this.$emit('input', this.selectedIds)
this.$emit('change', this.selectedIds, this.selectedData)
} else {
if (!this.checked) {
this.innerValue = ''
this.checkedRow = {}
this.$emit('input', '')
this.$emit('change', '', {})
this.closePopover()
return
}
this.innerValue = this.checkedTxt
this.$emit('input', this.checked)
this.$emit('change', this.checked, this.checkedRow)
}
this.closePopover()
},
rowClick(row) {
if (this.multiple) {
const boo = this.selectedData.some(o => o[this.propsValue] === row[this.propsValue])
if (boo) {
this.selectedData = this.selectedData.filter(o => o[this.propsValue] !== row[this.propsValue])
this.selectedIds = this.selectedIds.filter(o => o !== row[this.propsValue])
} else {
this.selectedData.push(row)
this.selectedIds.push(row[this.propsValue])
}
} else {
this.checked = row[this.propsValue]
this.checkedTxt = row[this.relationField]
this.checkedRow = row
}
},
setDefault() {
if (!this.value || !this.value.length) {
this.innerValue = ''
this.checked = ''
this.selectedIds = []
this.selectedData = []
this.tagsList = []
// if (!this.field) return
// let relationData = this.$store.state.generator.relationData
// this.$set(relationData, this.field, [])
// this.$store.commit('generator/UPDATE_RELATION_DATA', relationData)
return
}
if (!this.interfaceId) return
const arr = this.multiple ? this.value : [this.value]
if (this.multiple && !Array.isArray(this.value)) {
this.value = []
arr = []
}
const paramList = this.getParamList()
let query = {
ids: arr,
interfaceId: this.interfaceId,
propsValue: this.propsValue,
relationField: this.relationField,
paramList
}
getDataInterfaceDataInfoByIds(this.interfaceId, query).then(res => {
this.selectedData = res.data
this.selectedIds = this.selectedData.map(o => o[this.propsValue])
if (this.multiple) {
this.innerValue = ''
this.tagsList = JSON.parse(JSON.stringify(this.selectedData))
} else {
this.checked = this.value
this.innerValue = this.selectedData.length ? this.selectedData[0][this.relationField] : ''
this.checkedRow = this.selectedData[0]
}
// if (!this.field) return
// let relationData = this.$store.state.generator.relationData
// this.$set(relationData, this.field, res.data)
// this.$store.commit('generator/UPDATE_RELATION_DATA', relationData)
this.$nextTick(() => {
if (this.multiple) {
this.resetInputHeight();
}
});
})
},
deleteTag(event, index) {
this.selectedData.splice(index, 1)
this.confirm()
event.stopPropagation();
},
handleClearClick(event) {
this.checked = ''
this.innerValue = ''
this.checkedRow = {}
this.selectedIds = []
this.selectedData = []
this.$emit('input', this.checked)
this.$emit('change', this.checked, this.checkedRow)
event.stopPropagation();
},
resetInputWidth() {
this.inputWidth = this.$refs.reference.$el.getBoundingClientRect().width;
},
handleResize() {
this.resetInputWidth();
if (this.multiple) this.resetInputHeight();
},
resetInputHeight() {
if (this.collapseTags) return;
this.$nextTick(() => {
if (!this.$refs.reference) return;
let inputChildNodes = this.$refs.reference.$el.childNodes;
let input = [].filter.call(inputChildNodes, item => item.tagName === 'INPUT')[0];
const tags = this.$refs.tags;
const tagsHeight = tags ? Math.round(tags.getBoundingClientRect().height) : 0;
const sizeInMap = this.initialInputHeight || 40;
input.style.height = this.selectedData.length === 0
? sizeInMap + 'px'
: Math.max(
tags ? (tagsHeight + (tagsHeight > sizeInMap ? 6 : 0)) : 0,
sizeInMap
) + 'px';
});
},
resetInputWidth() {
this.inputWidth = this.$refs.reference.$el.getBoundingClientRect().width;
},
handleResize() {
this.resetInputWidth();
if (this.multiple) this.resetInputHeight();
}
}
}
</script>
<style lang="scss" scoped>
.fr {
float: right;
}
</style>

@ -0,0 +1,391 @@
<template>
<div class="popupSelect-container">
<div class="el-select" @click.stop="openDialog">
<div class="el-select__tags" v-if="multiple" ref="tags"
:style="{ 'max-width': inputWidth - 32 + 'px', width: '100%',cursor:'pointer' }">
<span v-if="collapseTags && tagsList.length">
<el-tag :closable="!selectDisabled" :size="collapseTagSize" type="info"
@close="deleteTag($event, 0)" disable-transitions>
<span class="el-select__tags-text">{{ tagsList[0].fullName }}</span>
</el-tag>
<el-tag v-if="tagsList.length > 1" :closable="false" type="info" disable-transitions>
<span class="el-select__tags-text">+ {{ tagsList.length - 1 }}</span>
</el-tag>
</span>
<transition-group @after-leave="resetInputHeight" v-if="!collapseTags">
<el-tag v-for="(item,i) in tagsList" :key="item.id" :size="collapseTagSize"
:closable="!selectDisabled" type="info" @close="deleteTag($event, i)"
disable-transitions>
<span class="el-select__tags-text">{{ item.fullName }}</span>
</el-tag>
</transition-group>
</div>
<el-input ref="reference" v-model="innerValue" type="text" :placeholder="currentPlaceholder"
:disabled="selectDisabled" readonly :validate-event="false"
:tabindex="(multiple) ? '-1' : null" @mouseenter.native="inputHovering = true"
@mouseleave.native="inputHovering = false">
<template slot="suffix">
<i v-show="!showClose"
:class="['el-select__caret', 'el-input__icon', 'el-icon-arrow-up']"></i>
<i v-if="showClose" class="el-select__caret el-input__icon el-icon-circle-close"
@click="handleClearClick"></i>
</template>
</el-input>
</div>
<el-dialog title="选择角色" :close-on-click-modal="false" :visible.sync="visible"
class="JNPF-dialog JNPF-dialog_center transfer-dialog" lock-scroll append-to-body
width="800px" :modal-append-to-body="false" @close="onClose">
<div class="transfer__body">
<div class="transfer-pane">
<div class="transfer-pane__tools">
<el-input placeholder="请输入关键词查询" v-model="keyword" @keyup.enter.native="search"
clearable class="search-input">
<el-button slot="append" icon="el-icon-search" @click="search"></el-button>
</el-input>
</div>
<div class="transfer-pane__body">
<el-tabs v-model="activeName" class="transfer-pane__body-tab">
<el-tab-pane label="组织" name="organize">
<el-tree :data="treeData2" :props="props" ref="tree2" default-expand-all
:filter-node-method="filterNode" :expand-on-click-node="false" check-on-click-node
@node-click="handleNodeClick" class="JNPF-common-el-tree" node-key="onlyId"
v-loading="loading">
<span class="custom-tree-node" slot-scope="{ node,data }">
<i :class="data.icon" />
<span class="text">{{node.label}}</span>
</span>
</el-tree>
</el-tab-pane>
<el-tab-pane label="全局" name="all">
<el-tree :data="treeData" :props="props" ref="tree1" default-expand-all
:filter-node-method="filterNode" :expand-on-click-node="false" check-on-click-node
@node-click="handleNodeClick" class="JNPF-common-el-tree" node-key="onlyId"
v-loading="loading">
<span class="custom-tree-node" slot-scope="{ node,data }">
<i :class="data.icon" />
<span class="text">{{node.label}}</span>
</span>
</el-tree>
</el-tab-pane>
</el-tabs>
</div>
</div>
<div class="transfer-pane">
<div class="transfer-pane__tools">
<span>已选</span>
<el-button @click="removeAll" type="text" class="removeAllBtn">清空列表</el-button>
</div>
<div class="transfer-pane__body shadow right-pane">
<template>
<div v-for="(item, index) in selectedData" :key="index" class="selected-item">
<span>{{item.fullName}}</span>
<i class="el-icon-delete" @click="removeData(index)"></i>
</div>
</template>
</div>
</div>
</div>
<span slot="footer" class="dialog-footer">
<el-button @click="setDefault(),visible=false">{{$t('common.cancelButton')}}</el-button>
<el-button type="primary" @click="confirm">{{$t('common.confirmButton')}}</el-button>
</span>
</el-dialog>
</div>
</template>
<script>
import { addResizeListener, removeResizeListener } from 'element-ui/src/utils/resize-event';
export default {
name: 'groupSelect',
inject: {
elForm: {
default: ''
},
elFormItem: {
default: ''
}
},
props: {
value: {
default: ''
},
placeholder: {
type: String,
default: '请选择'
},
disabled: {
type: Boolean,
default: false
},
multiple: {
type: Boolean,
default: false
},
collapseTags: {
type: Boolean,
default: false
},
clearable: {
type: Boolean,
default: false
},
size: String,
},
data() {
return {
allLoading: false,
activeName: '',
treeData2: [],
ids: [],
treeData: [],
allList: [],
keyword: '',
innerValue: '',
visible: false,
loading: false,
props: {
children: 'children',
label: 'fullName',
isLeaf: 'isLeaf'
},
selectedData: [],
tagsList: [],
inputHovering: false,
inputWidth: 0,
initialInputHeight: 0,
}
},
computed: {
showClose() {
let hasValue = this.multiple
? Array.isArray(this.value) && this.value.length > 0
: this.value !== undefined && this.value !== null && this.value !== '';
let criteria = this.clearable &&
!this.selectDisabled &&
this.inputHovering &&
hasValue;
return criteria;
},
currentPlaceholder() {
if (this.multiple && Array.isArray(this.value) && this.value.length) {
return ''
} else {
return this.placeholder
}
},
selectDisabled() {
return this.disabled || (this.elForm || {}).disabled;
},
_elFormItemSize() {
return (this.elFormItem || {}).elFormItemSize;
},
selectSize() {
return this.size || this._elFormItemSize || (this.$ELEMENT || {}).size;
},
collapseTagSize() {
return ['small', 'mini'].indexOf(this.selectSize) > -1
? 'mini'
: 'small';
},
},
created() {
this.getData()
},
mounted() {
addResizeListener(this.$el, this.handleResize);
const reference = this.$refs.reference;
if (reference && reference.$el) {
const sizeMap = {
medium: 36,
small: 32,
mini: 28
};
const input = reference.$el.querySelector('input');
this.initialInputHeight = input.getBoundingClientRect().height || sizeMap[this.selectSize];
}
if (this.multiple) {
this.resetInputHeight();
}
this.$nextTick(() => {
if (reference && reference.$el) {
this.inputWidth = reference.$el.getBoundingClientRect().width;
}
});
this.setDefault()
this.getData()
},
beforeDestroy() {
if (this.$el && this.handleResize) removeResizeListener(this.$el, this.handleResize);
},
watch: {
value(val) {
this.setDefault()
},
selectDisabled() {
this.$nextTick(() => {
this.resetInputHeight();
});
},
allList: {
handler: function (val) {
this.setDefault()
},
deep: true
}
},
methods: {
async getData() {
this.selectedData = []
this.ids = []
this.keyword = ''
this.activeName = 'organize'
this.getList()
},
getList() {
this.loading = true
this.$store.dispatch('base/getRoleTree').then(res => {
this.treeData = res.filter(o => o.id === '1')
this.treeData2 = res.filter(o => o.id !== '1')
this.$store.dispatch('base/getRoleList').then(res => {
this.allList = res
this.loading = false
})
})
},
onClose() { },
openDialog() {
if (this.selectDisabled) return
this.visible = true
this.$nextTick(() => {
this.keyword = ''
this.search()
this.setDefault()
})
},
search() {
const tree = this.activeName === 'organize' ? 'tree2' : 'tree1'
this.$refs[tree].filter(this.keyword)
},
filterNode(value, data) {
if (!value) return true;
return data[this.props.label].indexOf(value) !== -1;
},
handleNodeClick(data) {
if (data.type !== 'role') return
const boo = this.selectedData.some(o => o.id === data.id)
if (boo) return
this.multiple ? this.selectedData.push(data) : this.selectedData = [data]
},
removeAll() {
this.selectedData = []
},
removeData(index) {
this.selectedData.splice(index, 1)
},
confirm() {
if (this.multiple) {
this.innerValue = ''
this.tagsList = JSON.parse(JSON.stringify(this.selectedData))
let selectedIds = this.selectedData.map(o => o.id)
this.$emit('input', selectedIds)
this.$emit('change', selectedIds, this.selectedData)
} else {
if (!this.selectedData.length) {
this.innerValue = ''
this.$emit('input', '')
this.$emit('change', '', {})
this.visible = false
return
}
this.tagsList = JSON.parse(JSON.stringify(this.selectedData))
this.innerValue = this.selectedData[0].fullName
let selectedIds = this.selectedData[0].id
this.$emit('input', selectedIds)
this.$emit('change', selectedIds, this.selectedData[0])
}
this.visible = false
},
setDefault() {
if (!this.value || !this.value.length) {
this.innerValue = ''
this.selectedData = []
this.tagsList = []
return
}
const arr = this.multiple ? this.value : [this.value]
let selectedData = []
for (let i = 0; i < arr.length; i++) {
const item = arr[i];
inner: for (let j = 0; j < this.allList.length; j++) {
if (item === this.allList[j].id) {
selectedData.push(this.allList[j])
break inner
}
}
}
this.selectedData = selectedData
if (this.multiple) {
this.innerValue = ''
this.tagsList = JSON.parse(JSON.stringify(this.selectedData))
this.$nextTick(() => {
this.resetInputHeight();
})
} else {
if (!this.selectedData.length) return this.innerValue = ''
this.innerValue = this.selectedData[0].fullName
}
},
deleteTag(event, index) {
this.selectedData.splice(index, 1)
this.confirm()
event.stopPropagation();
},
handleClearClick(event) {
this.selectedData = []
this.confirm()
event.stopPropagation();
},
resetInputWidth() {
this.inputWidth = this.$refs.reference.$el.getBoundingClientRect().width;
},
handleResize() {
this.resetInputWidth();
if (this.multiple) this.resetInputHeight();
},
resetInputHeight() {
if (this.collapseTags) return;
this.$nextTick(() => {
if (!this.$refs.reference) return;
let inputChildNodes = this.$refs.reference.$el.childNodes;
let input = [].filter.call(inputChildNodes, item => item.tagName === 'INPUT')[0];
const tags = this.$refs.tags;
const tagsHeight = tags ? Math.round(tags.getBoundingClientRect().height) : 0;
const sizeInMap = this.initialInputHeight || 40;
input.style.height = this.selectedData.length === 0
? sizeInMap + 'px'
: Math.max(
tags ? (tagsHeight + (tagsHeight > sizeInMap ? 6 : 0)) : 0,
sizeInMap
) + 'px';
});
},
resetInputWidth() {
this.inputWidth = this.$refs.reference.$el.getBoundingClientRect().width;
},
handleResize() {
this.resetInputWidth();
if (this.multiple) this.resetInputHeight();
}
}
}
</script>
<style lang="scss" scoped>
.transfer-pane__body-tab {
>>> .el-tabs__item {
width: 50% !important;
}
}
</style>

@ -0,0 +1,224 @@
<template>
<el-dialog title="字段设置" :close-on-click-modal="false" width="1000px"
class="JNPF-dialog JNPF-dialog_center field-dialog" lock-scroll append-to-body
:visible.sync="visible">
<div class="main">
<JNPF-table v-loading="listLoading" :data="list">
<el-table-column prop="field" label="列名">
<template slot-scope="scope">
<span class="table-cell" v-if="scope.row.disabled">{{scope.row.field}}</span>
<el-input v-model="scope.row.field" placeholder="请输入列名" maxlength="50" v-else />
</template>
</el-table-column>
<el-table-column prop="dataType" label="类型">
<template slot-scope="scope">
<span class="table-cell"
v-if="scope.row.disabled">{{scope.row.dataType|dataType}}</span>
<el-select v-model="scope.row.dataType" placeholder="请选择" v-else>
<el-option v-for="item in options" :key="item.value" :label="item.label"
:value="item.value" />
</el-select>
</template>
</el-table-column>
<el-table-column prop="dataLength" label="长度">
<template slot-scope="scope">
<span class="table-cell" v-if="scope.row.disabled">{{scope.row.dataLength}}</span>
<el-input v-model="scope.row.dataLength" placeholder="请输入长度" v-else
:disabled="scope.row.dataType!=='varchar'&&scope.row.dataType!=='decimal'" />
</template>
</el-table-column>
<el-table-column prop="allowNull" label="允许空" width="60" align="center">
<template slot-scope="scope">
<el-checkbox :value='!!scope.row.allowNull' v-if="scope.row.disabled" />
<el-checkbox v-model="scope.row.allowNull" :true-label="1" :false-label="0" v-else />
</template>
</el-table-column>
<el-table-column prop="fieldName" label="说明">
<template slot-scope="scope">
<span class="table-cell" v-if="scope.row.disabled">{{scope.row.fieldName}}</span>
<el-input v-model="scope.row.fieldName" placeholder="请输入说明" v-else />
</template>
</el-table-column>
<el-table-column label="操作" width="50">
<template slot-scope="scope">
<el-button class="JNPF-table-delBtn" size="mini" type="text" v-if="!scope.row.disabled"
@click="handleDel(scope.$index)">删除
</el-button>
</template>
</el-table-column>
</JNPF-table>
<div class="table-actions" @click="addHandle()">
<el-button type="text" icon="el-icon-plus">新建字段</el-button>
</div>
</div>
<span slot="footer" class="dialog-footer">
<el-button @click="closeDialog">{{$t('common.cancelButton')}}</el-button>
<el-button type="primary" @click="dataFormSubmit()" :loading="btnLoading">
{{$t('common.confirmButton')}}</el-button>
</span>
</el-dialog>
</template>
<script>
import { DataModelInfo, addTableFields } from '@/api/systemData/dataModel'
export default {
data() {
return {
visible: false,
listLoading: true,
btnLoading: false,
options: [
{ label: '字符串', value: 'varchar' },
{ label: '整型', value: 'int' },
{ label: '日期时间', value: 'datetime' },
{ label: '浮点', value: 'decimal' },
{ label: '长整型', value: 'bigint' },
{ label: '文本', value: 'text' }
],
list: [],
dataForm: {},
dataBase: '0'
}
},
methods: {
init(dataBase, table) {
this.visible = true
this.dataBase = dataBase
if (!dataBase || !table) return
this.initData(table)
},
closeDialog() {
this.$emit('close')
this.visible = false
},
initData(table) {
this.listLoading = true
DataModelInfo(this.dataBase, table).then(res => {
this.dataForm = res.data.tableInfo
this.$set(this.dataForm, 'newTable', this.dataForm.table)
this.list = res.data.tableFieldList.map((o, i) => ({ disabled: true, ...o }))
this.listLoading = false
})
},
dataFormSubmit() {
let tableFieldList = this.list.filter(o => !o.disabled)
if (!tableFieldList.length) {
this.$message({
message: `请至少新增一个字段`,
type: 'error',
duration: 1000
});
return
}
if (!this.exist()) return
this.btnLoading = true
let query = {
tableFieldList,
tableInfo: this.dataForm
}
addTableFields(this.dataBase, query).then((res) => {
this.$message({
message: res.msg,
type: 'success',
duration: 1500,
onClose: () => {
this.visible = false
this.btnLoading = false
this.$emit('updateOptions', this.list)
this.$emit('close')
}
})
}).catch(() => { this.btnLoading = false })
},
exist() {
let isOk = true;
//
for (let i = 0; i < this.list.length; i++) {
const e = this.list[i];
if (e.disabled) continue
if (!e.field) {
this.$message({
message: `${i + 1}行列名不能为空`,
type: 'error',
duration: 1000
});
isOk = false
break
}
let reg = /(^_([a-zA-Z0-9]_?)*$)|(^[a-zA-Z](_?[a-zA-Z0-9])*_?$)/
if (!reg.test(e.field)) {
this.$message({
message: `${i + 1}行列名格式错误,请重新输入`,
type: 'error',
duration: 1000
});
isOk = false
break
}
let num = this.list.filter(o => o.field == e.field)
if (num.length > 1) {
this.$message({
message: `${i + 1}行列名'${e.field}'已重复`,
type: 'error',
duration: 1000
});
isOk = false
break
}
if (!e.fieldName) {
this.$message({
message: `${i + 1}行说明不能为空`,
type: 'error',
duration: 1000
});
isOk = false
break
}
}
return isOk;
},
handleDel(index) {
this.list.splice(index, 1)
},
addHandle(row) {
let item = {}
if (!row) {
item = {
field: "", dataType: "varchar", dataLength: 50, allowNull: 1, primaryKey: 0, fieldName: "", disabled: false
}
} else {
item = {
field: row.field,
dataType: row.dataType,
dataLength: row.dataLength,
allowNull: row.allowNull,
fieldName: row.fieldName,
primaryKey: 0,
disabled: false
}
}
this.list.push(item)
}
}
}
</script>
<style lang="scss" scoped>
.field-dialog {
>>> .el-dialog__body {
height: 70vh;
padding: 0 !important;
.main {
height: 100%;
display: flex;
flex-direction: column;
overflow: hidden;
}
.el-table {
border-top: 0;
}
.table-cell {
font-size: 13px;
}
}
}
</style>

@ -0,0 +1,70 @@
<template>
<el-row>
<el-form-item label="提示文本">
<el-input v-model="activeData.title" placeholder="请输入提示文本" />
</el-form-item>
<el-form-item label="提示图标">
<el-switch v-model="activeData['show-icon']" />
</el-form-item>
<el-form-item label="样式效果">
<div class="type-list">
<div class="type-list-item" :class="{active:activeData.type===item.id}"
v-for="(item,i) in typeList" :key="i" @click="activeData.type=item.id">
<el-alert :title="item.fullName" :type="item.id" :closable="false" center />
</div>
</div>
</el-form-item>
</el-row>
</template>
<script>
import comMixin from "./mixin";
export default {
props: ["activeData"],
mixins: [comMixin],
data() {
return {
typeList: [
{
id: 'success',
fullName: '成功提示'
},
{
id: 'info',
fullName: '消息提示'
},
{
id: 'warning',
fullName: '警告提示'
},
{
id: 'error',
fullName: '错误提示'
},
]
};
},
created() { },
methods: {}
};
</script>
<style lang="scss" scoped>
.type-list {
display: flex;
justify-content: space-between;
flex-wrap: wrap;
.type-list-item {
width: 110px;
margin-bottom: 10px;
cursor: pointer;
border-radius: 4px;
border: 1px solid #fff;
&:last-child,
&:nth-last-child(2) {
margin-bottom: 0;
}
&.active {
border: 1px solid #999;
}
}
}
</style>

@ -0,0 +1,34 @@
<template>
<el-row>
<el-form-item label="链接文本">
<el-input v-model="activeData.content" placeholder="请输入链接文本" />
</el-form-item>
<el-form-item label="链接地址">
<el-input v-model="activeData.href" placeholder="请输入链接地址">
<el-select slot="append" v-model="activeData.target" style="width: 85px;" placeholder="请选择">
<el-option label="_self" value="_self" />
<el-option label="_blank" value="_blank" />
</el-select>
</el-input>
</el-form-item>
<el-form-item label="对齐方式">
<el-radio-group v-model="activeData.textStyle['text-align']">
<el-radio-button label="left">左对齐</el-radio-button>
<el-radio-button label="center">居中对齐</el-radio-button>
<el-radio-button label="right">右对齐</el-radio-button>
</el-radio-group>
</el-form-item>
</el-row>
</template>
<script>
import comMixin from "./mixin";
export default {
props: ["activeData"],
mixins: [comMixin],
data() {
return {};
},
created() { },
methods: {}
};
</script>

@ -0,0 +1,213 @@
<template>
<el-dialog title="配置表单" :close-on-click-modal="false" append-to-body :visible.sync="visible"
class="JNPF-dialog JNPF-dialog_center" lock-scroll width="600px">
<el-form ref="dataForm" :model="dataForm" :rules="dataRule" v-loading="formLoading"
label-width="70px" label-position="left">
<el-form-item label="弹窗标题">
<el-input v-model="dataForm.popupTitle" placeholder="请输入弹窗标题" />
</el-form-item>
<el-form-item label="弹窗类型">
<el-select v-model="dataForm.popupType" placeholder="请选择弹窗类型">
<el-option label="居中弹窗" value="dialog"></el-option>
<el-option label="右侧弹窗" value="drawer"></el-option>
</el-select>
</el-form-item>
<el-form-item label="弹窗宽度">
<el-select v-model="dataForm.popupWidth" placeholder="请选择弹窗宽度">
<el-option v-for="item in popupWidthOptions" :label="item" :value="item" :key="item" />
</el-select>
</el-form-item>
<el-form-item label="远端数据" prop="interfaceName">
<interface-dialog :value="dataForm.interfaceId" :title="dataForm.interfaceName"
@change="onInterfaceChange" />
</el-form-item>
<el-form-item label="参数设置" style="margin-bottom: 0;"></el-form-item>
<el-table :data="dataForm.templateJson" style="margin-bottom: 18px;">
<el-table-column type="index" width="50" label="序号" align="center" />
<el-table-column prop="field" label="参数名称" width="200">
<template slot-scope="scope">
<span class="required-sign">{{scope.row.required?'*':''}}</span>
{{scope.row.fieldName?scope.row.field+'('+scope.row.fieldName+')':scope.row.field}}
</template>
</el-table-column>
<el-table-column prop="value" label="表单字段">
<template slot-scope="scope">
<el-select v-model="scope.row.relationField" placeholder="请选择表单字段" clearable filterable
@change="onRelationFieldChange($event,scope.row)">
<el-option v-for="item in formFieldsOptions" :key="item.__vModel__"
:label="item.__config__.label?item.__vModel__+'('+item.__config__.label+')':item.__vModel__"
:value="item.__vModel__">
</el-option>
</el-select>
</template>
</el-table-column>
</el-table>
<el-form-item label="设置列表字段" label-width="100px" style="margin-bottom: 0;"></el-form-item>
<el-table :data="dataForm.columnOptions">
<el-table-column type="index" width="50" label="序号" align="center" />
<el-table-column prop="field" label="列名">
<template slot-scope="scope">
<el-input v-model="scope.row.label" placeholder="请输入列名"></el-input>
</template>
</el-table-column>
<el-table-column prop="value" label="字段">
<template slot-scope="scope">
<el-input v-model="scope.row.value" placeholder="请输入字段"></el-input>
</template>
</el-table-column>
<el-table-column label="操作" width="50">
<template slot-scope="scope">
<el-button size="mini" type="text" class="JNPF-table-delBtn"
@click="handleDel(scope.$index,'columnOptions')">删除
</el-button>
</template>
</el-table-column>
</el-table>
<div class="table-actions" @click="addColumn" style="margin-bottom: 18px;">
<el-button type="text" icon="el-icon-plus">新增</el-button>
</div>
<el-form-item label="设置关联字段" label-width="100px" style="margin-bottom: 0;"></el-form-item>
<el-table :data="dataForm.relationOptions">
<el-table-column type="index" width="50" label="序号" align="center" />
<el-table-column prop="field" label="目标表单字段">
<template slot-scope="scope">
<el-select v-model="scope.row.field" placeholder="请选择表单字段" filterable>
<el-option v-for="item in childList" :key="item.__vModel__"
:label="item.__config__.label" :value="item.__vModel__">
</el-option>
</el-select>
</template>
</el-table-column>
<el-table-column prop="type" label="映射来源" width="120">
<template slot-scope="scope">
<el-select v-model="scope.row.type" placeholder="请选择映射来源"
@change="onTypeChange(scope.row)">
<el-option label="接口字段" :value="1" />
<el-option label="固定值" :value="2" />
</el-select>
</template>
</el-table-column>
<el-table-column prop="value" label="映射值/业务对象">
<template slot-scope="scope">
<el-input v-model="scope.row.value" placeholder="请输入接口字段" v-if="scope.row.type==1" />
<el-input v-model="scope.row.value" placeholder="请输入固定值" v-else />
</template>
</el-table-column>
<el-table-column label="操作" width="50">
<template slot-scope="scope">
<el-button size="mini" type="text" class="JNPF-table-delBtn"
@click="handleDel(scope.$index,'relationOptions')">删除
</el-button>
</template>
</el-table-column>
</el-table>
<div class="table-actions" @click="addRelationOption" style="margin-bottom: 18px;">
<el-button type="text" icon="el-icon-plus">新增</el-button>
</div>
</el-form>
<span slot="footer" class="dialog-footer">
<el-button @click="visible = false">{{$t('common.cancelButton')}}</el-button>
<el-button type="primary" :loading="btnLoading" @click="dataFormSubmit()">
{{$t('common.confirmButton')}}</el-button>
</span>
</el-dialog>
</template>
<script>
import { getDrawingList } from '@/components/Generator/utils/db'
import InterfaceDialog from '@/components/Process/PropPanel/InterfaceDialog'
export default {
components: { InterfaceDialog },
data() {
return {
visible: false,
formLoading: false,
btnLoading: false,
childList: [],
dataForm: {
interfaceId: '',
interfaceName: '',
templateJson: [],
hasPage: true,
pageSize: 20,
columnOptions: [],
relationOptions: []
},
dataRule: {},
popupWidthOptions: ['600px', '800px', '1000px', '40%', '50%', '60%', '70%', '80%'],
}
},
computed: {
formFieldsOptions() {
const noAllowList = ['table', 'uploadImg', 'uploadFz', 'modifyUser', 'modifyTime']
let list = []
const loop = (data, parent) => {
if (!data) return
if (data.__config__ && data.__config__.jnpfKey !== 'table' && data.__config__.children && Array.isArray(data.__config__.children)) {
loop(data.__config__.children, data)
}
if (Array.isArray(data)) data.forEach(d => loop(d, parent))
if (data.__vModel__ && !noAllowList.includes(data.__config__.jnpfKey)) list.push(data)
}
loop(getDrawingList())
return list
}
},
methods: {
init(data, children) {
this.dataForm = JSON.parse(JSON.stringify(data))
this.childList = children.filter(o => o.__vModel__)
this.visible = true
},
onInterfaceChange(id, row) {
if (!id) {
this.dataForm.interfaceId = ''
this.dataForm.interfaceName = ''
this.dataForm.templateJson = []
return
}
if (this.dataForm.interfaceId === id) return
this.dataForm.interfaceId = id
this.dataForm.interfaceName = row.fullName
this.dataForm.templateJson = row.templateJson ? row.templateJson.map(o => ({
...o,
relationField: ''
})) : []
},
onRelationFieldChange(val, row) {
if (!val) return row.jnpfKey = ''
let list = this.formFieldsOptions.filter(o => o.__vModel__ === val)
if (!list.length) return row.jnpfKey = ''
let item = list[0]
row.jnpfKey = item.__config__.jnpfKey
},
addColumn() {
this.dataForm.columnOptions.push({
value: '',
label: ''
})
},
addRelationOption() {
this.dataForm.relationOptions.push({
value: '',
field: '',
type: 1
})
},
handleDel(index, key) {
this.dataForm[key].splice(index, 1)
},
onTypeChange(row) {
row.value = ''
},
dataFormSubmit() {
this.$refs['dataForm'].validate((valid) => {
if (valid) {
this.$emit('submit', this.dataForm)
this.visible = false
}
})
}
}
}
</script>

@ -0,0 +1,68 @@
<template>
<el-row>
<el-form-item label="显示标题">
<el-switch v-model="activeData.__config__.showTitle" />
</el-form-item>
<el-form-item v-if="activeData.actionText !== undefined" label="动作文字">
<el-input v-model="activeData.actionText" placeholder="请输入动作文字" />
</el-form-item>
<el-form-item label="动作设置">
<el-switch v-model="activeData.addType" :active-value="1" :inactive-value="0" />
</el-form-item>
<el-form-item label="动作表单" v-if="activeData.addType==1">
<el-button style="width: 100%;" @click="editConf()"></el-button>
</el-form-item>
<el-form-item label="合计设置">
<el-switch v-model="activeData['show-summary']" />
</el-form-item>
<el-form-item label="合计字段" v-if="activeData['show-summary']">
<el-select v-model="activeData.summaryField" multiple placeholder="请选择合计字段">
<template v-for="(item,i) in activeData.__config__.children">
<el-option :key="i" :label="item.__config__.label" :value="item.__vModel__"
v-if="['comInput','numInput','calculate'].includes(item.__config__.jnpfKey)" />
</template>
</el-select>
</el-form-item>
<Form v-if="formVisible" ref="Form" @submit="updateConf" />
</el-row>
</template>
<script>
import Form from './AddTableForm'
const defaultAddTableConf = {
popupTitle: '选择数据',
popupType: 'dialog',
popupWidth: '800px',
interfaceId: '',
interfaceName: '',
templateJson: [],
hasPage: true,
pageSize: 20,
columnOptions: [],
relationOptions: []
}
export default {
props: ['activeData'],
components: { Form },
data() {
return {
formVisible: false
}
},
methods: {
editConf() {
if (!this.activeData.addTableConf) {
this.activeData.addTableConf = JSON.parse(JSON.stringify(defaultAddTableConf))
}
let addTableConf = JSON.parse(JSON.stringify(this.activeData.addTableConf))
this.formVisible = true
this.$nextTick(() => {
this.$refs.Form.init(addTableConf, this.activeData.__config__.children)
})
},
updateConf(data) {
this.activeData.addTableConf = data
}
}
}
</script>

@ -0,0 +1,119 @@
import { noAllowRelationList } from '@/components/Generator/generator/comConfig'
import { getDrawingList } from '@/components/Generator/utils/db'
import { getDictionaryDataSelector } from '@/api/systemData/dictionary'
import { getDataInterfaceRes } from '@/api/systemData/dataInterface'
import draggable from 'vuedraggable'
import InterfaceDialog from '@/components/Process/PropPanel/InterfaceDialog'
export default {
props: ['activeData', 'dictionaryOptions', 'dataInterfaceOptions'],
components: { draggable, InterfaceDialog },
data() {
return {}
},
computed: {
dicOptions() {
return this.dictionaryOptions
},
interfaceOptions() {
return this.dataInterfaceOptions
},
defaultValue() {
let defaultValue = ''
if (this.activeData.__config__.jnpfKey === 'checkbox' || this.activeData.multiple) defaultValue = []
return defaultValue
},
formFieldsOptions() {
let list = []
const loop = (data, parent) => {
if (!data) return
if (data.__config__ && this.isIncludesTable(data) && data.__config__.children && Array.isArray(data.__config__.children)) {
loop(data.__config__.children, data)
}
if (Array.isArray(data)) data.forEach(d => loop(d, parent))
if (data.__vModel__ && !noAllowRelationList.includes(data.__config__.jnpfKey) && data.__vModel__ !== this.activeData.__vModel__) {
const isTableChild = parent && parent.__config__ && parent.__config__.jnpfKey === 'table'
list.push({
realVModel: isTableChild ? parent.__vModel__ + '-' + data.__vModel__ : data.__vModel__,
realLabel: isTableChild ? parent.__config__.label + '-' + data.__config__.label : data.__config__.label,
...data
})
}
}
loop(getDrawingList())
return list
},
},
methods: {
isIncludesTable(data) {
if ((!data.__config__.layout || data.__config__.layout === 'rowFormItem') && data.__config__.jnpfKey !== 'table') return true
if (this.activeData.__config__.isSubTable) return this.activeData.__config__.parentVModel === data.__vModel__
return data.__config__.jnpfKey !== 'table'
},
onRelationFieldChange(val, row) {
if (!val) return row.jnpfKey = ''
let list = this.formFieldsOptions.filter(o => o.realVModel === val)
if (!list.length) return row.jnpfKey = ''
let item = list[0]
row.jnpfKey = item.__config__.jnpfKey
},
multipleChange(val) {
this.$set(this.activeData.__config__, 'defaultValue', val ? [] : '')
},
addSelectItem() {
this.activeData.__slot__.options.push({
fullName: '',
id: ''
})
},
dataTypeChange(val) {
this.activeData.__config__.defaultValue = this.defaultValue
this.activeData.__slot__.options = []
this.activeData.__config__.props.value = 'id'
this.activeData.__config__.props.label = 'fullName'
this.activeData.__config__.dictionaryType = ''
this.activeData.__config__.propsUrl = ''
this.activeData.__config__.propsName = ''
this.activeData.__config__.templateJson = []
},
dictionaryTypeChange(val) {
this.activeData.__config__.defaultValue = this.defaultValue
if (!val) {
this.activeData.__slot__.options = []
return
}
getDictionaryDataSelector(val).then(res => {
this.activeData.__slot__.options = res.data.list
})
},
propsUrlChange(val, row) {
this.activeData.__config__.defaultValue = this.defaultValue
if (!val) {
this.activeData.__config__.propsUrl = ''
this.activeData.__config__.propsName = ''
this.activeData.__config__.templateJson = []
this.activeData.__slot__.options = []
return
}
let list = row.requestParameters ? JSON.parse(row.requestParameters) : []
this.activeData.__config__.propsUrl = val
this.activeData.__config__.propsName = row.fullName
this.activeData.__config__.templateJson = list.map(o => ({ ...o, relationField: '' }))
let query = {
paramList: this.activeData.__config__.templateJson || [],
}
getDataInterfaceRes(val, query).then(res => {
let data = res.data
if (Array.isArray(data)) {
this.activeData.__slot__.options = data
} else {
this.activeData.__slot__.options = []
}
}).catch(() => {
this.activeData.__config__.propsUrl = ''
this.activeData.__config__.propsName = ''
this.activeData.__config__.templateJson = []
this.activeData.__slot__.options = []
})
}
}
}

@ -0,0 +1,58 @@
<template>
<el-dialog :close-on-click-modal="false" class="JNPF-dialog JNPF-dialog_center form-script-dialog"
lock-scroll append-to-body v-bind="$attrs" width="1000px" :modal-append-to-body="false"
title="表单样式" v-on="$listeners" @open="onOpen">
<!-- <span slot="title" class="dialog-title">
<span>
<el-tooltip content="小程序不支持在线JS脚本" placement="top-start">
<a class="el-icon-warning-outline"></a>
</el-tooltip>
</span>
</span> -->
<div class="form-script-dialog-body">
<div class="right-main">
<div class="codeEditor">
<JNPFCodeEditor v-model="text" :options="options" ref="CodeEditor" />
</div>
</div>
</div>
<span slot="footer" class="dialog-footer">
<el-button @click="closeDialog">{{$t('common.cancelButton')}}</el-button>
<el-button type="primary" @click="onClose()">{{$t('common.confirmButton')}}</el-button>
</span>
</el-dialog>
</template>
<script>
import JNPFCodeEditor from '@/components/JNPFEditor/monaco'
export default {
components: { JNPFCodeEditor },
props: ['value'],
data() {
return {
text: '',
options: {
language: 'css'
},
}
},
methods: {
onOpen() {
this.text = this.value
this.$nextTick(() => {
this.$refs.CodeEditor.changeEditor({
value: this.text,
options: this.options
})
});
},
onClose() {
this.$emit('updateStyleScript', this.text)
this.closeDialog()
},
closeDialog() {
this.$emit('update:visible', false)
}
}
}
</script>

@ -0,0 +1,669 @@
<template>
<div class="popupSelect-container">
<div class="el-select" @click.stop="openDialog">
<div class="el-select__tags" v-if="multiple" ref="tags"
:style="{ 'max-width': inputWidth - 32 + 'px', width: '100%',cursor:'pointer' }">
<span v-if="collapseTags && tagsList.length">
<el-tag :closable="!selectDisabled" :size="collapseTagSize" type="info"
@close="deleteTag($event, 0)" disable-transitions>
<span class="el-select__tags-text">{{ tagsList[0].fullName }}</span>
</el-tag>
<el-tag v-if="tagsList.length > 1" :closable="false" type="info" disable-transitions>
<span class="el-select__tags-text">+ {{ tagsList.length - 1 }}</span>
</el-tag>
</span>
<transition-group @after-leave="resetInputHeight" v-if="!collapseTags">
<el-tag v-for="(item,i) in tagsList" :key="item.id" :size="collapseTagSize"
:closable="!selectDisabled" type="info" @close="deleteTag($event, i)"
disable-transitions>
<span class="el-select__tags-text">{{ item.fullName }}</span>
</el-tag>
</transition-group>
</div>
<el-input ref="reference" v-model="innerValue" type="text" :placeholder="currentPlaceholder"
:disabled="selectDisabled" readonly :validate-event="false"
:tabindex="(multiple) ? '-1' : null" @mouseenter.native="inputHovering = true"
@mouseleave.native="inputHovering = false">
<template slot="suffix">
<i v-show="!showClose"
:class="['el-select__caret', 'el-input__icon', 'el-icon-arrow-up']"></i>
<i v-if="showClose" class="el-select__caret el-input__icon el-icon-circle-close"
@click="handleClearClick"></i>
</template>
</el-input>
</div>
<el-dialog :title="title" :close-on-click-modal="false" :visible.sync="visible"
class="JNPF-dialog JNPF-dialog_center transfer-dialog" lock-scroll append-to-body
width="800px" :modal-append-to-body="false" @close="onClose">
<div class="transfer__body">
<div class="transfer-pane">
<div class="transfer-pane__tools">
<el-input placeholder="请输入关键词查询" v-model="pagination.keyword"
@keyup.enter.native="search" clearable class="search-input">
<el-button slot="append" icon="el-icon-search" @click="search"></el-button>
</el-input>
</div>
<div class="transfer-pane__body left-pane">
<el-tabs v-model="activeName" class="transfer-pane__body-tab hasSys-tab"
v-if="selectType==='all'">
<el-tab-pane label="部门" name="department">
<el-tree :data="treeData" :props="props" check-on-click-node
:expand-on-click-node="false" @node-click="handleNodeClick"
class="JNPF-common-el-tree" node-key="id" v-loading="loading" lazy
:load="loadNode" v-if="!this.isAsync">
<span class="custom-tree-node" slot-scope="{ node, data }">
<i :class="data.icon"></i>
<span class="text">{{node.label}}</span>
</span>
</el-tree>
<div class="single-list" ref="infiniteBody" v-if="this.isAsync"
v-loading="loading && pagination.currentPage==1">
<template v-if="treeData.length">
<div v-for="(item,index) in treeData" :key="index" class="selected-item-user"
@click="handleNodeClick(item)">
<div class="selected-item-main">
<el-avatar :size="36" :src="define.comUrl+item.headIcon"
class="selected-item-headIcon">
</el-avatar>
<div class="selected-item-text">
<p class="name">{{item.fullName}}</p>
<p class="organize" :title="item.organize">{{item.organize}}</p>
</div>
</div>
</div>
</template>
<el-empty description="暂无数据" :image-size="120" v-else></el-empty>
</div>
</el-tab-pane>
<el-tab-pane label="角色" name="role" v-if="multiple">
<el-tree :data="treeData2" :props="props" :expand-on-click-node="false"
default-expand-all check-on-click-node @node-click="handleNodeClick"
class="JNPF-common-el-tree" node-key="id" v-loading="roleLoading" ref="roleTree"
:filter-node-method="filterNode">
<span class="custom-tree-node" slot-scope="{ node, data }">
<i :class="data.icon"></i>
<span class="text">{{node.label}}</span>
</span>
</el-tree>
</el-tab-pane>
<el-tab-pane label="岗位" name="position" v-if="multiple">
<el-tree :data="treeData3" :props="props" :expand-on-click-node="false"
default-expand-all check-on-click-node @node-click="handleNodeClick"
class="JNPF-common-el-tree" node-key="id" v-loading="positionLoading"
ref="positionTree" :filter-node-method="filterNode">
<span class="custom-tree-node" slot-scope="{ node, data }">
<i :class="data.icon"></i>
<span class="text">{{node.label}}</span>
</span>
</el-tree>
</el-tab-pane>
<el-tab-pane label="分组" name="group" v-if="multiple">
<el-tree :data="treeData4" :props="props" :expand-on-click-node="false"
default-expand-all check-on-click-node @node-click="handleNodeClick"
class="JNPF-common-el-tree" node-key="id" v-loading="groupLoading" ref="groupTree"
:filter-node-method="filterNode">
<span class="custom-tree-node" slot-scope="{ node, data }">
<i :class="data.icon"></i>
<span class="text">{{node.label}}</span>
</span>
</el-tree>
</el-tab-pane>
</el-tabs>
<template v-if="selectType === 'custom'">
<div class="custom-title">全部数据</div>
<div class="single-list" ref="infiniteBody"
v-loading="loading && pagination.currentPage==1">
<template v-if="ableList.length">
<div v-for="(item,index) in ableList" :key="index" class="selected-item-user"
@click="handleNodeClick(item)">
<div class="selected-item-main">
<el-avatar :size="36" :src="define.comUrl+item.headIcon"
class="selected-item-headIcon">
</el-avatar>
<div class="selected-item-text">
<p class="name">{{item.fullName}}</p>
<p class="organize" :title="item.organize">{{item.organize}}</p>
</div>
</div>
</div>
</template>
<el-empty description="暂无数据" :image-size="120" v-else></el-empty>
</div>
</template>
</div>
</div>
<div class="transfer-pane">
<div class="transfer-pane__tools">
<span>已选</span>
<el-button @click="removeAll" type="text" class="removeAllBtn">清空列表</el-button>
</div>
<div class="transfer-pane__body shadow right-pane">
<template v-if="(selectedData.length&&!multiple)||selectType == 'custom'">
<div v-for="(item,index) in selectedData" :key="index" class="selected-item-user">
<div class="selected-item-main">
<el-avatar :size="36" :src="define.comUrl+item.headIcon"
class="selected-item-headIcon" v-if="item.type==='user'">
</el-avatar>
<div class="selected-item-headIcon icon" v-else>
<i :class="item.icon"></i>
</div>
<div class="selected-item-text">
<p class="name">{{item.fullName}}</p>
<p class="organize" :title="item.organize">{{item.organize}}</p>
</div>
<i class="el-icon-delete" @click="removeData(index)"></i>
</div>
</div>
</template>
<template v-else-if="haveData&&multiple">
<div v-for="(item,index) in selectedList" :key="index"
class="selected-item-user-multiple">
<template v-if="item.children.length">
<p class="selected-item-title">
<i :class="item.icon"></i><span>{{item.fullName}}</span>
</p>
<div class="selected-item-main" v-for="(child,i) in item.children" :key="i">
<el-avatar :size="36" :src="define.comUrl+child.headIcon"
class="selected-item-headIcon" v-if="child.type==='user'">
</el-avatar>
<div class="selected-item-icon" v-else>{{child.fullName.substring(0,1)}}</div>
<div class="selected-item-text">
<p class="name">{{child.fullName}}</p>
<p class="organize" :title="child.organize">{{child.organize}}</p>
</div>
<i class="el-icon-delete delete" @click="removeMulData(child.id)"></i>
</div>
</template>
</div>
</template>
<el-empty description="暂无数据" :image-size="120" v-else></el-empty>
</div>
</div>
</div>
<span slot="footer" class="dialog-footer">
<el-button @click="setDefault(),visible=false">{{$t('common.cancelButton')}}</el-button>
<el-button type="primary" @click="confirm">{{$t('common.confirmButton')}}</el-button>
</span>
</el-dialog>
</div>
</template>
<script>
import { getImUserSelector, getSelectedList, getSelectedUserList } from '@/api/permission/user'
import { addResizeListener, removeResizeListener } from 'element-ui/src/utils/resize-event';
import { getPositionSelector } from '@/api/permission/position'
import { getRoleSelector } from '@/api/permission/role'
import { getGroupSelector } from '@/api/permission/group'
const defaultSelectedList = [
{
id: "department",
type: "department",
fullName: "部门",
icon: "icon-ym icon-ym-tree-department1",
children: []
},
{
id: "position",
type: "position",
fullName: "岗位",
icon: "icon-ym icon-ym-tree-position1",
children: []
},
{
id: "user",
type: "user",
fullName: "用户",
icon: "icon-ym icon-ym-tree-user2",
children: []
},
{
id: "group",
type: "group",
fullName: "分组",
icon: "icon-ym icon-ym-generator-group1",
children: []
},
{
id: "role",
type: "role",
fullName: "角色",
icon: "icon-ym icon-ym-generator-role",
children: []
}
]
export default {
name: 'userSelect',
inject: {
elForm: {
default: ''
},
elFormItem: {
default: ''
}
},
props: {
value: {
type: [String, Array],
default: ''
},
placeholder: {
type: String,
default: '请选择'
},
title: {
type: String,
default: '选择用户'
},
disabled: {
type: Boolean,
default: false
},
multiple: {
type: Boolean,
default: false
},
collapseTags: {
type: Boolean,
default: false
},
clearable: {
type: Boolean,
default: true
},
hasSys: {
type: Boolean,
default: false
},
selectType: {
type: String,
default: 'all'
},
ableIds: {
type: Array,
default: () => []
},
size: String,
},
data() {
return {
visible: false,
activeName: '',
nodeId: '',
innerValue: '',
loading: false,
roleLoading: true,
positionLoading: true,
groupLoading: true,
props: {
children: 'children',
label: 'fullName',
isLeaf: 'isLeaf'
},
treeData: [],
treeData2: [],
treeData3: [],
treeData4: [],
ableList: [],
selectedData: [],
tagsList: [],
inputHovering: false,
inputWidth: 0,
initialInputHeight: 0,
total: 0,
isAsync: false,
finish: false,
pagination: {
keyword: '',
currentPage: 1,
pageSize: 20,
},
selectedList: defaultSelectedList,
haveData: false
}
},
watch: {
value(val) {
this.setDefault()
},
selectDisabled() {
this.$nextTick(() => {
this.resetInputHeight();
});
},
activeName(val) {
this.pagination.keyword = ''
this.isAsync = false
if (!val) return
this.nodeId = '0'
this.treeData = []
this.getData()
},
selectedData(val) {
if (!this.multiple) return
this.selectedList = JSON.parse(JSON.stringify(defaultSelectedList))
this.haveData = false
for (let i = 0; i < this.selectedData.length; i++) {
const item = this.selectedData[i];
const type = item.type == 'company' ? 'department' : item.type
this.selectedList.map(res => {
if (res.type == type) {
const obj = {
fullName: item.fullName,
type: type,
headIcon: item.headIcon,
organize: item.organize,
id: item.id
}
res.children.push(obj)
this.haveData = true
}
})
}
}
},
computed: {
showClose() {
let hasValue = this.multiple
? Array.isArray(this.value) && this.value.length > 0
: this.value !== undefined && this.value !== null && this.value !== '';
let criteria = this.clearable &&
!this.selectDisabled &&
this.inputHovering &&
hasValue;
return criteria;
},
currentPlaceholder() {
if (this.multiple && Array.isArray(this.value) && this.value.length) {
return ''
} else {
return this.placeholder
}
},
selectDisabled() {
return this.disabled || (this.elForm || {}).disabled;
},
_elFormItemSize() {
return (this.elFormItem || {}).elFormItemSize;
},
selectSize() {
return this.size || this._elFormItemSize || (this.$ELEMENT || {}).size;
},
collapseTagSize() {
return ['small', 'mini'].indexOf(this.selectSize) > -1
? 'mini'
: 'small';
},
},
created() {
this.setDefault()
this.getOtherData()
},
mounted() {
addResizeListener(this.$el, this.handleResize);
const reference = this.$refs.reference;
if (reference && reference.$el) {
const sizeMap = {
medium: 36,
small: 32,
mini: 28
};
const input = reference.$el.querySelector('input');
this.initialInputHeight = input.getBoundingClientRect().height || sizeMap[this.selectSize];
}
if (this.multiple) {
this.resetInputHeight();
}
this.$nextTick(() => {
if (reference && reference.$el) {
this.inputWidth = reference.$el.getBoundingClientRect().width;
}
});
this.setDefault()
},
beforeDestroy() {
if (this.$el && this.handleResize) removeResizeListener(this.$el, this.handleResize);
},
methods: {
getAbleList() {
this.loading = true
let query = {
pagination: this.pagination,
userId: this.ableIds
}
getSelectedUserList(query).then(res => {
if (res.data.list.length < this.pagination.pageSize) {
this.finish = true
}
this.ableList = [...this.ableList, ...res.data.list]
this.total = res.data.pagination.total
this.loading = false
}).catch(() => {
this.loading = false
})
},
bindScroll() {
let _this = this,
vBody = _this.$refs.infiniteBody;
vBody.addEventListener("scroll", function () {
if (vBody.scrollHeight - vBody.clientHeight - vBody.scrollTop <= 200 && !_this.loading && !_this.finish) {
_this.pagination.currentPage += 1
if (_this.selectType === 'all') {
_this.getAllList()
}
if (_this.selectType === 'custom') {
_this.getAbleList()
}
}
});
},
onClose() {
this.activeName = ''
},
openDialog() {
if (this.selectDisabled) return
this.visible = true
this.pagination.keyword = ''
this.pagination.currentPage = 1
this.nodeId = '0'
this.isAsync = false
this.finish = false
this.selectedData = []
if (this.selectType === 'all') {
this.activeName = 'department'
this.setDefault()
}
if (this.selectType === 'custom') {
this.ableList = []
this.getAbleList()
this.$nextTick(() => {
this.bindScroll()
this.setDefault()
})
}
},
confirm() {
if (this.multiple) {
this.innerValue = ''
this.tagsList = JSON.parse(JSON.stringify(this.selectedData))
let selectedIds = this.selectedData.map(o => o.id)
this.$emit('input', selectedIds)
this.$emit('change', selectedIds, this.selectedData)
} else {
if (!this.selectedData.length) {
this.innerValue = ''
this.$emit('input', '')
this.$emit('change', '', {})
this.visible = false
return
}
this.innerValue = this.selectedData[0].fullName
let selectedIds = this.selectedData.map(o => o.id)
this.$emit('input', selectedIds[0])
this.$emit('change', selectedIds[0], this.selectedData[0])
}
this.visible = false
},
setDefault() {
if (!this.value || !this.value.length) {
this.innerValue = ''
this.selectedData = []
this.tagsList = []
return
}
const arr = this.multiple ? this.value : [this.value]
getSelectedList(arr).then(res => {
this.selectedData = res.data.list.map(o => ({ ...o, id: o.type ? o.id + '--' + o.type : o.id }))
if (this.multiple) {
this.innerValue = ''
this.tagsList = JSON.parse(JSON.stringify(this.selectedData))
} else {
this.innerValue = this.selectedData.length ? this.selectedData[0].fullName : ''
}
this.$nextTick(() => {
if (this.multiple) {
this.resetInputHeight();
}
});
})
},
getData() {
if (this.selectType === 'all') {
if (this.activeName === 'department') {
this.getAllList()
} else if (['role', 'position', 'group'].includes(this.activeName)) {
this.$refs[this.activeName + 'Tree'] && this.$refs[this.activeName + 'Tree'].filter(this.pagination.keyword)
} else {
this.loading = false
}
}
},
getOtherData() {
this.roleLoading = true
this.positionLoading = true
this.groupLoading = true
getRoleSelector().then(res => {
this.treeData2 = res.data.list
this.roleLoading = false
})
getPositionSelector().then(res => {
this.treeData3 = res.data.list
this.positionLoading = false
})
getGroupSelector().then(res => {
this.treeData4 = res.data
this.groupLoading = false
})
},
search() {
this.nodeId = '0'
this.treeData = []
this.pagination.currentPage = 1
this.isAsync = !!this.pagination.keyword
this.finish = false
if (this.isAsync && this.activeName === 'department') {
this.$nextTick(() => {
this.bindScroll()
})
}
if (this.selectType === 'all') {
this.getData()
} else {
this.ableList = []
this.getAbleList()
}
},
filterNode(value, data) {
if (!value) return true;
return data[this.props.label].indexOf(value) !== -1;
},
getAllList() {
this.loading = true
if (this.pagination.keyword) this.nodeId = '0'
getImUserSelector(this.nodeId, this.pagination).then(res => {
if (this.pagination.keyword) {
if (res.data.list.length < this.pagination.pageSize) {
this.finish = true
}
this.treeData = [...this.treeData, ...res.data.list]
this.total = res.data.pagination.total
} else {
this.treeData = res.data.list
}
this.loading = false
})
},
loadNode(node, resolve) {
if (node.level === 0) {
this.nodeId = '0'
return resolve(this.treeData)
}
this.nodeId = node.data.id
getImUserSelector(this.nodeId).then(res => {
resolve(res.data.list)
})
},
handleNodeClick(data) {
const usableList = this.multiple ? ['company', 'department', 'role', 'position', 'group', 'user'] : ['user']
if (!usableList.includes(data.type)) return
const boo = this.selectedData.some(o => o.id === data.id + '--' + data.type)
let item = JSON.parse(JSON.stringify(data))
item.id += '--' + item.type
if (boo) return
this.multiple ? this.selectedData.push(item) : this.selectedData = [item]
},
removeAll() {
this.selectedData = []
},
removeData(index) {
this.selectedData.splice(index, 1)
},
removeMulData(id) {
const index = this.selectedData.findIndex((item) => {
return item.id == id
})
if (index != -1) this.selectedData.splice(index, 1)
},
deleteTag(event, index) {
this.selectedData.splice(index, 1)
this.confirm()
event.stopPropagation();
},
handleClearClick(event) {
this.selectedData = []
this.confirm()
event.stopPropagation();
},
resetInputWidth() {
this.inputWidth = this.$refs.reference.$el.getBoundingClientRect().width;
},
handleResize() {
this.resetInputWidth();
if (this.multiple) this.resetInputHeight();
},
resetInputHeight() {
if (this.collapseTags) return;
this.$nextTick(() => {
if (!this.$refs.reference) return;
let inputChildNodes = this.$refs.reference.$el.childNodes;
let input = [].filter.call(inputChildNodes, item => item.tagName === 'INPUT')[0];
const tags = this.$refs.tags;
const tagsHeight = tags ? Math.round(tags.getBoundingClientRect().height) : 0;
const sizeInMap = this.initialInputHeight || 40;
input.style.height = this.selectedData.length === 0
? sizeInMap + 'px'
: Math.max(
tags ? (tagsHeight + (tagsHeight > sizeInMap ? 6 : 0)) : 0,
sizeInMap
) + 'px';
});
},
resetInputWidth() {
this.inputWidth = this.$refs.reference.$el.getBoundingClientRect().width;
},
handleResize() {
this.resetInputWidth();
if (this.multiple) this.resetInputHeight();
}
},
}
</script>

@ -0,0 +1,300 @@
<template>
<div class="transfer__body" v-loading="allLoading" :style="{height}">
<div class="transfer-pane">
<div class="transfer-pane__tools">
<el-input placeholder="输入关键词进行搜索" v-model="pagination.keyword" @keyup.enter.native="search"
clearable>
<el-button slot="append" icon="el-icon-search" @click="search"></el-button>
</el-input>
</div>
<div class="transfer-pane__body left-pane">
<el-tabs v-model="activeName" class="transfer-pane__body-tab hasSys-tab">
<el-tab-pane label="部门" name="department">
<el-tree :data="treeData" :props="props" check-on-click-node
:expand-on-click-node="false" @node-click="handleNodeClick"
class="JNPF-common-el-tree" node-key="id" v-loading="loading" lazy :load="loadNode"
v-if="!this.isAsync">
<span class="custom-tree-node" slot-scope="{ node, data }">
<i :class="data.icon"></i>
<span class="text">{{node.label}}</span>
</span>
</el-tree>
<div class="single-list" ref="infiniteBody" v-if="this.isAsync"
v-loading="loading && pagination.currentPage==1">
<template v-if="treeData.length">
<div v-for="(item,index) in treeData" :key="index" class="selected-item-user"
@click="handleNodeClick(item)">
<div class="selected-item-main">
<el-avatar :size="36" :src="define.comUrl+item.headIcon"
class="selected-item-headIcon">
</el-avatar>
<div class="selected-item-text">
<p class="name">{{item.fullName}}</p>
<p class="organize" :title="item.organize">{{item.organize}}</p>
</div>
</div>
</div>
</template>
<el-empty description="暂无数据" :image-size="120" v-else></el-empty>
</div>
</el-tab-pane>
<el-tab-pane label="角色" name="role" v-if="multiple">
<el-tree :data="treeData2" :props="props" :expand-on-click-node="false"
default-expand-all check-on-click-node @node-click="handleNodeClick"
class="JNPF-common-el-tree" node-key="id" v-loading="roleLoading" ref="roleTree"
:filter-node-method="filterNode">
<span class="custom-tree-node" slot-scope="{ node, data }">
<i :class="data.icon"></i>
<span class="text">{{node.label}}</span>
</span>
</el-tree>
</el-tab-pane>
<el-tab-pane label="岗位" name="position" v-if="multiple">
<el-tree :data="treeData3" :props="props" :expand-on-click-node="false"
default-expand-all check-on-click-node @node-click="handleNodeClick"
class="JNPF-common-el-tree" node-key="id" v-loading="positionLoading"
ref="positionTree" :filter-node-method="filterNode">
<span class="custom-tree-node" slot-scope="{ node, data }">
<i :class="data.icon"></i>
<span class="text">{{node.label}}</span>
</span>
</el-tree>
</el-tab-pane>
<el-tab-pane label="分组" name="group" v-if="multiple">
<el-tree :data="treeData4" :props="props" :expand-on-click-node="false"
default-expand-all check-on-click-node @node-click="handleNodeClick"
class="JNPF-common-el-tree" node-key="id" v-loading="groupLoading" ref="groupTree"
:filter-node-method="filterNode">
<span class="custom-tree-node" slot-scope="{ node, data }">
<i :class="data.icon"></i>
<span class="text">{{node.label}}</span>
</span>
</el-tree>
</el-tab-pane>
</el-tabs>
</div>
</div>
<div class="transfer-pane">
<div class="transfer-pane__tools">
<span>已选</span>
<el-button @click="removeAll" type="text" class="removeAllBtn">清空列表</el-button>
</div>
<div class="transfer-pane__body shadow right-pane">
<template v-if="selectedData.length">
<div v-for="(item,index) in selectedData" :key="index" class="selected-item-user">
<div class="selected-item-main">
<el-avatar :size="36" :src="define.comUrl+item.headIcon"
class="selected-item-headIcon" v-if="item.type==='user'">
</el-avatar>
<div class="selected-item-headIcon icon" v-else>
<i :class="item.icon"></i>
</div>
<div class="selected-item-text">
<p class="name">{{item.fullName}}</p>
<p class="organize" :title="item.organize">{{item.organize}}</p>
</div>
<i class="el-icon-delete" @click="removeData(index)"></i>
</div>
</div>
</template>
<el-empty description="暂无数据" :image-size="120" v-else></el-empty>
</div>
</div>
</div>
</template>
<script>
import { getImUserSelector, getSelectedList } from '@/api/permission/user'
import { getPositionSelector } from '@/api/permission/position'
import { getRoleSelector } from '@/api/permission/role'
import { getGroupSelector } from '@/api/permission/group'
export default {
name: 'JNPF-userTransfer',
data() {
return {
allLoading: false,
loading: false,
roleLoading: true,
positionLoading: true,
groupLoading: true,
activeName: '',
treeData: [],
treeData2: [],
treeData3: [],
treeData4: [],
selectedData: [],
props: {
children: 'children',
label: 'fullName',
isLeaf: 'isLeaf'
},
nodeId: '0',
ids: [],
total: 0,
isAsync: false,
finish: false,
pagination: {
keyword: '',
currentPage: 1,
pageSize: 20,
}
}
},
props: {
height: {
type: String,
default: "400px"
},
// allLoading: {
// type: Boolean,
// default: false
// },
value: {
type: Array,
default: () => []
},
multiple: {
type: Boolean,
default: false
},
},
watch: {
activeName(val) {
this.pagination.keyword = ''
this.isAsync = false
if (!val) return
this.nodeId = '0'
this.treeData = []
this.getData()
}
},
methods: {
init() {
this.getOtherData()
this.selectedData = []
this.ids = []
this.pagination.keyword = ''
this.activeName = ''
this.nodeId = '0'
this.isAsync = false
this.finish = false
this.$nextTick(() => {
this.activeName = 'department'
this.getSelectList()
})
},
bindScroll() {
let _this = this,
vBody = _this.$refs.infiniteBody;
vBody.addEventListener("scroll", function () {
if (vBody.scrollHeight - vBody.clientHeight - vBody.scrollTop <= 200 && !_this.loading && !_this.finish) {
_this.pagination.currentPage += 1
_this.getList()
}
});
},
getData() {
if (this.activeName === 'department') {
this.getList()
} else if (['role', 'position', 'group'].includes(this.activeName)) {
this.$refs[this.activeName + 'Tree'] && this.$refs[this.activeName + 'Tree'].filter(this.pagination.keyword)
} else {
this.loading = false
}
},
getSelectList() {
this.allLoading = true
if (!this.value.length) return this.allLoading = false
getSelectedList(this.value).then(res => {
this.selectedData = res.data.list.map(o => ({ ...o, id: o.type ? o.id + '--' + o.type : o.id }))
this.ids = this.selectedData.map(o => o.id)
this.allLoading = false
})
},
getOtherData() {
this.roleLoading = true
this.positionLoading = true
this.groupLoading = true
getRoleSelector().then(res => {
this.treeData2 = res.data.list
this.roleLoading = false
})
getPositionSelector().then(res => {
this.treeData3 = res.data.list
this.positionLoading = false
})
getGroupSelector().then(res => {
this.treeData4 = res.data
this.groupLoading = false
})
},
search() {
this.nodeId = '0'
this.treeData = []
this.pagination.currentPage = 1
this.isAsync = !!this.pagination.keyword
this.finish = false
if (this.isAsync && this.activeName === 'department') {
this.$nextTick(() => {
this.bindScroll()
})
}
this.getData()
},
filterNode(value, data) {
if (!value) return true;
return data[this.props.label].indexOf(value) !== -1;
},
getList() {
this.loading = true
if (this.pagination.keyword) this.nodeId = '0'
getImUserSelector(this.nodeId, this.pagination).then(res => {
if (this.pagination.keyword) {
if (res.data.list.length < this.pagination.pageSize) {
this.finish = true
}
this.treeData = [...this.treeData, ...res.data.list]
this.total = res.data.pagination.total
} else {
this.treeData = res.data.list
}
this.loading = false
})
},
loadNode(node, resolve) {
if (node.level === 0) {
this.nodeId = '0'
return resolve(this.treeData)
}
this.nodeId = node.data.id
getImUserSelector(this.nodeId).then(res => {
resolve(res.data.list)
})
},
handleNodeClick(data) {
const usableList = this.multiple ? ['company', 'department', 'role', 'position', 'group', 'user'] : ['user']
if (!usableList.includes(data.type)) return
const boo = this.selectedData.some(o => o.id === data.id + '--' + data.type)
let item = JSON.parse(JSON.stringify(data))
item.id += '--' + item.type
if (boo) return
this.multiple ? this.selectedData.push(item) : this.selectedData = [item]
this.multiple ? this.ids.push(item.id) : this.ids = [item.id]
this.$emit('input', this.ids)
this.$emit('getValue', this.ids, this.selectedData)
},
removeAll() {
this.selectedData = []
this.ids = []
this.$emit('input', this.ids)
this.$emit('getValue', this.ids, this.selectedData)
},
removeData(index) {
this.selectedData.splice(index, 1)
this.ids.splice(index, 1)
this.$emit('input', this.ids)
this.$emit('getValue', this.ids, this.selectedData)
},
}
};
</script>

@ -0,0 +1,305 @@
<template>
<el-dialog title="批量导入" :close-on-click-modal="false" :visible.sync="visible"
class="JNPF-dialog JNPF-dialog_center JNPF-dialog-import" lock-scroll width="1000px">
<el-steps :active="active" align-center>
<el-step title="上传文件"></el-step>
<el-step title="数据预览"></el-step>
<el-step title="导入数据"></el-step>
</el-steps>
<div class="import-main" v-show="active==1">
<div class="upload">
<div class="up_left">
<img src="@/assets/images/upload.png">
</div>
<div class="up_right">
<p class="title">
上传填好的数据表
<p class="tip">文件后缀名必须是xls或xlsx文件大小不超过500KB最多支持导入1000条数据</p>
<el-upload :action="actionUrl" :headers="{ Authorization: $store.getters.token}"
:on-success="handleSuccess" :on-remove="handleRemove" :before-remove="beforeRemove"
:on-change="handleChange" :file-list="fileList" accept=".xls,.xlsx"
:before-upload="beforeUpload" class="upload-area">
<el-button type="text">上传文件</el-button>
</el-upload>
</div>
</div>
<div class="upload">
<div class="up_left">
<img src="@/assets/images/import.png">
</div>
<div class="up_right">
<p class="title">填写导入数据信息</p>
<p class="tip">请按照数据模板的格式准备导入数据模板中的表头名称不可更改表头行不能删除</p>
<el-button type="text" @click="templateDownload"></el-button>
</div>
</div>
</div>
<div class="import-main" v-show="active==2">
<JNPF-table v-loading="listLoading" :data="list" :span-method="arraySpanMethod">
<el-table-column :prop="item.id" :label="item.fullName" min-width="150"
v-for="(item,index) in headerList" :key="index" :align="item.children?'center':'left'">
<template slot-scope="scope" v-if="!item.children">
<el-input v-model="scope.row[item.id]" />
</template>
<template v-if="item.children">
<el-table-column :prop="item.id+'-'+it.id" :label="it.fullName"
:width="it.id=='delete'?50:150" v-for="(it,i) in item.children" :key="i"
class-name="child-table-box">>
<template slot-scope="scope">
<div class="child-table-column">
<tr v-for="(row,j) in scope.row[item.id]" :key="j"
class="child-table__row no-border-bottom">
<td v-for="(obj,k) in item.children" :key="k"
:class="obj.id=='delete'?'delete':'td-flex-1 m-0-10'">
<el-input v-model="row[obj.id]" v-if="obj.id!='delete'" />
<el-button v-else size="mini" type="text" class="JNPF-table-delBtn"
@click="handleTableDel(scope.$index,j,item)">删除</el-button>
</td>
</tr>
</div>
</template>
</el-table-column>
</template>
</el-table-column>
<el-table-column label="操作" fixed="right" width="50">
<template slot-scope="scope">
<el-button size="mini" type="text" class="JNPF-table-delBtn"
@click="handleDel(scope.$index)">删除</el-button>
</template>
</el-table-column>
</JNPF-table>
</div>
<div class="import-main import-main-overflow" v-show="active==3">
<div class="success" v-if="!result.resultType">
<img src="@/assets/images/success.png" alt="">
<p class="success-title">批量导入成功</p>
<p class="success-tip">您已成功导入{{result.snum}}条数据</p>
</div>
<div class="unsuccess" v-if="result.resultType">
<el-alert title="错误提醒:导入失败数据展示" type="warning" show-icon :closable="false" />
<div class="upload error-show">
<div class="up_left">
<img class="" src="@/assets/images/tip.png">
</div>
<div class="up_right">
<p class="tip">正常数量条数<el-link type="success" :underline="false">{{result.snum}}
</el-link>
</p>
<p class="tip">异常数量条数<el-link type="danger" :underline="false">{{result.fnum}}
</el-link>
</p>
</div>
</div>
<div class="contips">
<p>以下文件数据为导入异常数据</p>
<el-button type="text" icon="el-icon-upload2" @click="exportExceptionData">
</el-button>
</div>
<JNPF-table v-loading="listLoading" :data="resultList" :span-method="arraySpanMethod">
<el-table-column :prop="item.id" :label="item.fullName" min-width="150"
v-for="(item,index) in resultHeaderList" :key="index"
:align="item.children?'center':'left'">
<template slot-scope="scope" v-if="!item.children">
{{scope.row[item.id]}}
</template>
<template v-if="item.children">
<el-table-column :prop="item.id+'-'+it.id" :label="it.fullName"
:width="it.id=='delete'?50:150" v-for="(it,i) in item.children" :key="i"
class-name="child-table-box">>
<template slot-scope="scope">
<div class="child-table-column">
<tr v-for="(row,j) in scope.row[item.id]" :key="j"
class="child-table__row no-border-bottom">
<td v-for="(obj,k) in item.children" :key="k"
:class="obj.id=='delete'?'delete':'td-flex-1 m-0-10'">
{{row[obj.id]}}
</td>
</tr>
</div>
</template>
</el-table-column>
</template>
</el-table-column>
<el-table-column label="异常原因" prop="errorsInfo" fixed="right" width="150">
</el-table-column>
</JNPF-table>
</div>
</div>
<span slot="footer" class="dialog-footer">
<el-button @click="cancel()" v-if="active == 1"> </el-button>
<el-button @click="prev" v-if="active == 2"></el-button>
<el-button @click="next" type="primary" v-if="active < 3" :loading="btnLoading"
:disabled="active == 1 && !fileName">下一步
</el-button>
<el-button @click="cancel(true)" type="primary" v-else> </el-button>
</span>
</el-dialog>
</template>
<script>
import { getTemplateDownload, getImportPreview, importData, getImportExceptionData } from '@/api/common'
export default {
data() {
return {
visible: false,
btnLoading: false,
listLoading: false,
fileName: '',
fileList: [],
active: 1,
list: [],
headerList: [],
resultHeaderList: [],
resultList: [],
result: {
resultType: 0,
snum: 0,
fnum: 0
},
modelId: "",
url: '',
actionUrl: '',
mergeList: []
}
},
methods: {
init(modelId, url) {
this.active = 1
this.fileList = []
this.fileName = ''
this.visible = true
this.modelId = modelId || ''
this.actionUrl = `${this.define.comUrl}/api/${url ? url : 'visualdev/OnlineDev'}/Uploader`
this.url = url ? url : `visualdev/OnlineDev/${this.modelId}`
},
beforeUpload(file) {
let isRightSize = file.size / 1024 < 500
if (!isRightSize) this.$message.error(`文件大小不能超过500KB`)
return isRightSize
},
handleRemove(file, fileList) {
this.fileList = []
},
beforeRemove(file, fileList) {
return this.$confirm(`确定移除 ${file.name}`).then(() => { })
},
handleChange(file, fileList) {
this.fileList = fileList.slice(-1)
},
handleSuccess(res, file, fileList) {
if (res.code == 200) {
this.fileList = fileList.slice(-1)
this.fileName = res.data.name
} else {
this.fileList = fileList.filter(o => o.uid != file.uid)
this.$message({ message: res.msg, type: 'error', duration: 1000 })
}
},
templateDownload() {
getTemplateDownload(this.modelId, this.url).then(res => {
this.jnpf.downloadFile(res.data.url)
})
},
prev() {
if (this.active == 1) return
this.active--
},
next() {
if (this.active == 2) {
if (!this.list.length) return this.$message({ message: '导入数据为空', type: 'warning' })
this.btnLoading = true
importData(this.modelId, { list: this.list }, this.url).then(res => {
this.result = res.data
this.resultList = res.data.failResult
this.btnLoading = false
this.active++
this.getMergeList(this.resultHeaderList)
}).catch(() => { this.btnLoading = false })
}
if (this.active == 1) {
if (!this.fileList.length || !this.fileName) return this.$message({ message: '请先上传文件', type: 'warning' })
this.btnLoading = true
getImportPreview(this.modelId, { fileName: this.fileName }, this.url).then(res => {
this.list = res.data.dataRow
this.resultHeaderList = JSON.parse(JSON.stringify(res.data.headerRow))
for (let index = 0; index < res.data.headerRow.length; index++) {
const item = res.data.headerRow[index];
if (item.children && item.children.length) {
item.children.push({
fullName: "操作",
id: 'delete'
})
}
}
this.headerList = JSON.parse(JSON.stringify(res.data.headerRow))
this.btnLoading = false
this.active++
this.getMergeList(this.headerList)
}).catch(() => { this.btnLoading = false })
}
},
getMergeList(list) {
this.mergeList = []
list.forEach(item => {
if (item.children && item.children.length > 0) {
item.children.forEach((child, index) => {
if (index == 0) {
this.mergeList.push({
prop: item.id + '-' + child.id,
rowspan: 1,
colspan: item.children.length
})
} else {
this.mergeList.push({
prop: item.id + '-' + child.id,
rowspan: 0,
colspan: 0
})
}
})
} else {
this.mergeList.push({
prop: item.id,
rowspan: 1,
colspan: 1
})
}
})
},
arraySpanMethod({ row, column, rowIndex, columnIndex }) {
for (let i = 0; i < this.mergeList.length; i++) {
if (column.property == this.mergeList[i].prop) {
return [this.mergeList[i].rowspan, this.mergeList[i].colspan]
}
}
},
handleDel(index) {
this.list.splice(index, 1)
},
handleTableDel(index, i, item) {
this.list[index] && this.list[index][item.id] && this.list[index][item.id].splice(i, 1)
},
cancel(isRefresh) {
this.visible = false
if (isRefresh) this.$emit('refresh')
},
exportExceptionData() {
getImportExceptionData(this.modelId, { list: this.resultList }, this.url).then(res => {
this.jnpf.downloadFile(res.data.url)
})
}
}
}
</script>
<style lang="scss" scoped>
.delete {
width: 50px;
text-align: center;
}
.no-border-bottom {
border-bottom: unset;
}
.import-main-overflow {
overflow: unset;
}
</style>

@ -0,0 +1,537 @@
/* BASICS */
.CodeMirror {
--base: #545281;
--comment: hsl(210deg 25% 60%);
--keyword: #af4ab1;
--variable: #1890ff;
--function: #c25205;
--string: #2ba46d;
--number: #c25205;
--tags: #d00;
--qualifier: #ff6032;
--field: var(--tags);
--important: var(--string);
position: relative;
height: auto;
height: 100%;
overflow: hidden;
font-family: var(--font-code);
background: white;
direction: ltr;
}
/* PADDING */
.CodeMirror-lines {
min-height: 1px;
/* prevents collapsing before first draw */
padding: 4px 0;
/* Vertical padding around content */
cursor: text;
}
.CodeMirror-scrollbar-filler,
.CodeMirror-gutter-filler {
background-color: white;
/* The little square between H and V scrollbars */
}
/* GUTTER */
.CodeMirror-gutters {
position: absolute;
top: 0;
left: 0;
z-index: 3;
min-height: 100%;
white-space: nowrap;
background-color: transparent;
border-right: 1px solid #ddd;
}
.CodeMirror-linenumber {
min-width: 20px;
padding: 0 3px 0 5px;
color: var(--comment);
text-align: right;
white-space: nowrap;
opacity: 0.6;
}
.CodeMirror-guttermarker {
color: black;
}
.CodeMirror-guttermarker-subtle {
color: #999;
}
/* FOLD GUTTER */
.CodeMirror-foldmarker {
font-family: arial;
line-height: 0.3;
color: #414141;
text-shadow: #f96 1px 1px 2px, #f96 -1px -1px 2px, #f96 1px -1px 2px, #f96 -1px 1px 2px;
cursor: pointer;
}
.CodeMirror-foldgutter {
width: 0.7em;
}
.CodeMirror-foldgutter-open,
.CodeMirror-foldgutter-folded {
cursor: pointer;
}
.CodeMirror-foldgutter-open::after,
.CodeMirror-foldgutter-folded::after {
position: relative;
top: -0.1em;
display: inline-block;
font-size: 0.8em;
content: '>';
opacity: 0.8;
transform: rotate(90deg);
transition: transform 0.2s;
}
.CodeMirror-foldgutter-folded::after {
transform: none;
}
/* CURSOR */
.CodeMirror-cursor {
position: absolute;
width: 0;
pointer-events: none;
border-right: none;
border-left: 1px solid black;
}
/* Shown when moving in bi-directional text */
.CodeMirror div.CodeMirror-secondarycursor {
border-left: 1px solid silver;
}
.cm-fat-cursor .CodeMirror-cursor {
width: auto;
background: #7e7;
border: 0 !important;
}
.cm-fat-cursor div.CodeMirror-cursors {
z-index: 1;
}
.cm-fat-cursor-mark {
background-color: rgb(20 255 20 / 50%);
animation: blink 1.06s steps(1) infinite;
}
.cm-animate-fat-cursor {
width: auto;
background-color: #7e7;
border: 0;
animation: blink 1.06s steps(1) infinite;
}
@keyframes blink {
50% {
background-color: transparent;
}
}
@keyframes blink {
50% {
background-color: transparent;
}
}
@keyframes blink {
50% {
background-color: transparent;
}
}
.cm-tab {
display: inline-block;
text-decoration: inherit;
}
.CodeMirror-rulers {
position: absolute;
top: -50px;
right: 0;
bottom: -20px;
left: 0;
overflow: hidden;
}
.CodeMirror-ruler {
position: absolute;
top: 0;
bottom: 0;
border-left: 1px solid #ccc;
}
/* DEFAULT THEME */
.cm-s-default.CodeMirror {
background-color: transparent;
}
.cm-s-default .cm-header {
color: blue;
}
.cm-s-default .cm-quote {
color: #090;
}
.cm-negative {
color: #d44;
}
.cm-positive {
color: #292;
}
.cm-header,
.cm-strong {
font-weight: bold;
}
.cm-em {
font-style: italic;
}
.cm-link {
text-decoration: underline;
}
.cm-strikethrough {
text-decoration: line-through;
}
.cm-s-default .cm-atom,
.cm-s-default .cm-def,
.cm-s-default .cm-property,
.cm-s-default .cm-variable-2,
.cm-s-default .cm-variable-3,
.cm-s-default .cm-punctuation {
color: var(--base);
}
.cm-s-default .cm-hr,
.cm-s-default .cm-comment {
color: var(--comment);
}
.cm-s-default .cm-attribute,
.cm-s-default .cm-keyword {
color: var(--keyword);
}
.cm-s-default .cm-variable {
color: var(--variable);
}
.cm-s-default .cm-bracket,
.cm-s-default .cm-tag {
color: var(--tags);
}
.cm-s-default .cm-number {
color: var(--number);
}
.cm-s-default .cm-string,
.cm-s-default .cm-string-2 {
color: var(--string);
}
.cm-s-default .cm-type {
color: #085;
}
.cm-s-default .cm-meta {
color: #555;
}
.cm-s-default .cm-qualifier {
color: var(--qualifier);
}
.cm-s-default .cm-builtin {
color: #7539ff;
}
.cm-s-default .cm-link {
color: var(--flash);
}
.cm-s-default .cm-error {
color: #ff008c;
}
.cm-invalidchar {
color: #ff008c;
}
.CodeMirror-composing {
border-bottom: 2px solid;
}
/* Default styles for common addons */
div.CodeMirror span.CodeMirror-matchingbracket {
color: #0b0;
}
div.CodeMirror span.CodeMirror-nonmatchingbracket {
color: #a22;
}
.CodeMirror-matchingtag {
background: rgb(255 150 0 / 30%);
}
.CodeMirror-activeline-background {
background: #e8f2ff;
}
/* STOP */
/* The rest of this file contains styles related to the mechanics of
the editor. You probably shouldn't touch them. */
.CodeMirror-scroll {
position: relative;
height: 100%;
padding-bottom: 30px;
margin-right: -30px;
/* 30px is the magic margin used to hide the element's real scrollbars */
/* See overflow: hidden in .CodeMirror */
margin-bottom: -30px;
overflow: scroll !important;
/* Things will break if this is overridden */
outline: none;
/* Prevent dragging from highlighting the element */
}
.CodeMirror-sizer {
position: relative;
margin-bottom: 20px !important;
border-right: 30px solid transparent;
}
/* The fake, visible scrollbars. Used to force redraw during scrolling
before actual scrolling happens, thus preventing shaking and
flickering artifacts. */
.CodeMirror-vscrollbar,
.CodeMirror-hscrollbar,
.CodeMirror-scrollbar-filler,
.CodeMirror-gutter-filler {
position: absolute;
z-index: 6;
display: none;
}
.CodeMirror-vscrollbar {
top: 0;
right: 0;
overflow-x: hidden;
overflow-y: scroll;
}
.CodeMirror-hscrollbar {
bottom: 0;
left: 0;
overflow-x: scroll;
overflow-y: hidden;
}
.CodeMirror-scrollbar-filler {
right: 0;
bottom: 0;
}
.CodeMirror-gutter-filler {
bottom: 0;
left: 0;
}
.CodeMirror-gutter {
display: inline-block;
height: 100%;
margin-bottom: -30px;
white-space: normal;
vertical-align: top;
}
.CodeMirror-gutter-wrapper {
position: absolute;
z-index: 4;
background: none !important;
border: none !important;
}
.CodeMirror-gutter-background {
position: absolute;
top: 0;
bottom: 0;
z-index: 4;
}
.CodeMirror-gutter-elt {
position: absolute;
z-index: 4;
cursor: default;
}
.CodeMirror-gutter-wrapper ::selection {
background-color: transparent;
}
.CodeMirrorwrapper ::selection {
background-color: transparent;
}
.CodeMirror pre {
position: relative;
z-index: 2;
padding: 0 4px;
/* Horizontal padding of content */
margin: 0;
overflow: visible;
font-family: inherit;
font-size: inherit;
line-height: inherit;
color: inherit;
word-wrap: normal;
white-space: pre;
background: transparent;
border-width: 0;
/* Reset some styles that the rest of the page might have set */
border-radius: 0;
-webkit-tap-highlight-color: transparent;
font-variant-ligatures: contextual;
}
.CodeMirror-wrap pre {
word-break: normal;
word-wrap: break-word;
white-space: pre-wrap;
}
.CodeMirror-linebackground {
position: absolute;
top: 0;
right: 0;
bottom: 0;
left: 0;
z-index: 0;
}
.CodeMirror-linewidget {
position: relative;
z-index: 2;
padding: 0.1px;
/* Force widget margins to stay inside of the container */
}
.CodeMirror-rtl pre {
direction: rtl;
}
.CodeMirror-code {
outline: none;
}
/* Force content-box sizing for the elements where we expect it */
.CodeMirror-scroll,
.CodeMirror-sizer,
.CodeMirror-gutter,
.CodeMirror-gutters,
.CodeMirror-linenumber {
box-sizing: content-box;
}
.CodeMirror-measure {
position: absolute;
width: 100%;
height: 0;
overflow: hidden;
visibility: hidden;
}
.CodeMirror-measure pre {
position: static;
}
div.CodeMirror-cursors {
position: relative;
z-index: 3;
visibility: hidden;
}
div.CodeMirror-dragcursors {
visibility: visible;
}
.CodeMirror-focused div.CodeMirror-cursors {
visibility: visible;
}
.CodeMirror-selected {
background: #d9d9d9;
}
.CodeMirror-focused .CodeMirror-selected {
background: #d7d4f0;
}
.CodeMirror-crosshair {
cursor: crosshair;
}
.CodeMirror-line::selection,
.CodeMirror-line>span::selection,
.CodeMirror-line>span>span::selection {
background: #d7d4f0;
}
.cm-searching {
background-color: #ffa;
background-color: rgb(255 255 0 / 40%);
}
/* Used to force a border model for a node */
.cm-force-border {
padding-right: 0.1px;
}
@media print {
/* Hide the cursor when printing */
.CodeMirror div.CodeMirror-cursors {
visibility: hidden;
}
}
/* See issue #2901 */
.cm-tab-wrap-hack::after {
content: '';
}
/* Help users use markselection to safely style text background */
span.CodeMirror-selectedtext {
background: none;
}

@ -0,0 +1,201 @@
<template>
<div class="popupSelect-container">
<div class="el-select" @click="openDialog">
<el-input placeholder="请选择子流程" readonly :validate-event="false" v-model="title"
@mouseenter.native="inputHovering = true" @mouseleave.native="inputHovering = false">
<template slot="suffix">
<i v-show="!showClose"
:class="['el-select__caret', 'el-input__icon', 'el-icon-arrow-up']"></i>
<i v-if="showClose" class="el-select__caret el-input__icon el-icon-circle-close"
@click.stop="clear"></i>
</template>
</el-input>
</div>
<el-dialog title="选择子流程" :close-on-click-modal="false" :visible.sync="visible"
class="JNPF-dialog JNPF-dialog_center JNPF-dialog-tree-select" lock-scroll append-to-body
width="1000px">
<div class="JNPF-common-layout">
<div class="JNPF-common-layout-left">
<el-scrollbar class="JNPF-common-el-tree-scrollbar" v-loading="treeLoading">
<el-tree ref="treeBox" :data="treeData" :props="defaultProps" default-expand-all
highlight-current :expand-on-click-node="false" node-key="id"
@node-click="handleNodeClick" class="JNPF-common-el-tree" />
</el-scrollbar>
</div>
<div class="JNPF-common-layout-center">
<el-row class="JNPF-common-search-box" :gutter="16">
<el-form @submit.native.prevent>
<el-col :span="8">
<el-form-item label="关键词">
<el-input v-model="keyword" placeholder="请输入关键词查询" clearable
@keyup.enter.native="search()" class="search-input" />
</el-form-item>
</el-col>
<el-col :span="8">
<el-form-item>
<el-button type="primary" icon="el-icon-search" @click="search()"></el-button>
<el-button icon="el-icon-refresh-right" @click="reset()"></el-button>
</el-form-item>
</el-col>
</el-form>
<div class="JNPF-common-search-box-right">
<el-tooltip effect="dark" content="刷新" placement="top">
<el-link icon="icon-ym icon-ym-Refresh JNPF-common-head-icon" :underline="false"
@click="initData()" />
</el-tooltip>
</div>
</el-row>
<div class="JNPF-common-layout-main JNPF-flex-main">
<JNPF-table v-loading="listLoading" :data="list" :border="false" highlight-current-row
@row-click="rowClick" :hasNO="false">
<el-table-column width="35">
<template slot-scope="scope">
<el-radio :label="scope.row.id" v-model="checked">&nbsp;</el-radio>
</template>
</el-table-column>
<el-table-column type="index" width="50" label="序号" align="center" />
<el-table-column prop="fullName" label="流程名称" />
<el-table-column prop="enCode" label="流程编码" />
</JNPF-table>
<pagination :total="total" :page.sync="listQuery.currentPage"
:limit.sync="listQuery.pageSize" @pagination="initData" />
</div>
</div>
</div>
<span slot="footer" class="dialog-footer">
<el-button @click="visible = false">{{$t('common.cancelButton')}}</el-button>
<el-button type="primary" @click="select()">{{$t('common.confirmButton')}}</el-button>
</span>
</el-dialog>
</div>
</template>
<script>
import { FlowEnginePageList } from '@/api/workFlow/FlowEngine'
export default {
props: {
value: {
default: ''
},
title: {
default: ''
},
clearable: {
type: Boolean,
default: true
},
disabled: {
type: Boolean,
default: false
},
flowType: {
default: ""
}
},
model: {
prop: 'value',
event: 'input'
},
data() {
return {
list: [],
innerValue: '',
listQuery: {
currentPage: 1,
pageSize: 20,
sort: 'desc',
sidx: ''
},
keyword: '',
total: 0,
checked: '',
checkedRow: {},
listLoading: false,
defaultProps: {
id: 'id',
label: 'fullName',
enCode: 'enCode'
},
query: {
categoryId: '',
keyword: '',
dataType: null,
},
treeLoading: false,
treeData: [],
inputHovering: false,
visible: false,
tableName: '',
category: ''
}
},
computed: {
showClose() {
let hasValue = this.value !== undefined && this.value !== null && this.value !== '';
let criteria = this.clearable &&
!this.disabled &&
this.inputHovering &&
hasValue;
return criteria;
}
},
created() {
this.$store.dispatch('base/getDictionaryData', { sort: 'WorkFlowCategory' }).then((res) => {
this.treeData = [{ fullName: '全部流程', id: '', enCode: '' }, ...res]
})
this.reset()
},
methods: {
initData() {
this.listLoading = true
let query = {
keyword: this.keyword,
...this.listQuery,
category: this.category == '' ? '' : this.category,
flowType: this.flowType
}
FlowEnginePageList(query).then((res) => {
this.list = res.data.list
this.total = res.data.pagination.total
this.listLoading = false
}).catch(() => { this.listLoading = false })
},
handleNodeClick(data) {
if (data.id == this.category) return
this.category = data.id || ''
this.reset()
},
reset() {
this.keyword = ''
this.search()
},
search() {
this.listQuery.currentPage = 1
this.listQuery.pageSize = 20
this.listQuery.sort = 'desc'
this.initData()
},
openDialog() {
if (this.disabled) return
this.checked = this.value
this.visible = true
},
clear() {
this.checked = ''
this.checkedRow = {}
this.$emit('input', this.checked)
this.$emit('change', this.checked, this.checkedRow)
},
select() {
if (!this.checked) return
this.$emit('input', this.checked)
this.$emit('change', this.checked, this.checkedRow)
this.visible = false
},
rowClick(row) {
this.checked = row.id
this.checkedRow = row
}
}
}
</script>

@ -0,0 +1,204 @@
<template>
<div class="popupSelect-container">
<div class="el-select" @click="openDialog">
<el-input :placeholder="placeholder" v-model="title" readonly :validate-event="false"
@mouseenter.native="inputHovering = true" @mouseleave.native="inputHovering = false">
<template slot="suffix">
<i v-show="!showClose"
:class="['el-select__caret', 'el-input__icon', 'el-icon-arrow-up']"></i>
<i v-if="showClose" class="el-select__caret el-input__icon el-icon-circle-close"
@click.stop="clear"></i>
</template>
</el-input>
</div>
<el-dialog :title="label+'选择'" :close-on-click-modal="false" :visible.sync="visible"
class="JNPF-dialog JNPF-dialog_center JNPF-dialog-tree-select" lock-scroll append-to-body
width='800px'>
<div class="JNPF-common-layout">
<div class="JNPF-common-layout-center">
<el-row class="JNPF-common-search-box" :gutter="16">
<el-form @submit.native.prevent>
<el-col :span="10">
<el-form-item label="关键词">
<el-input v-model="listQuery.keyword" placeholder="请输入关键词查询" clearable
@keyup.enter.native="search()" class="search-input" />
</el-form-item>
</el-col>
<el-col :span="8">
<el-form-item>
<el-button type="primary" icon="el-icon-search" @click="search()"></el-button>
<el-button icon="el-icon-refresh-right" @click="reset()"></el-button>
</el-form-item>
</el-col>
</el-form>
<div class="JNPF-common-search-box-right">
<el-tooltip effect="dark" content="刷新" placement="top">
<el-link icon="icon-ym icon-ym-Refresh JNPF-common-head-icon" :underline="false"
@click="initData()" />
</el-tooltip>
</div>
</el-row>
<div class="JNPF-common-layout-main JNPF-flex-main">
<JNPF-table v-loading="listLoading" :data="list" :border="false" highlight-current-row
@row-click="rowClick" :hasNO="false">
<el-table-column width="50">
<template slot-scope="scope">
<el-radio :label="scope.row.id" v-model="checked">&nbsp;</el-radio>
</template>
</el-table-column>
<el-table-column type="index" label="序号" />
<el-table-column prop="fullName" :label="label+'名称'" show-overflow-tooltip />
<el-table-column prop="enCode" :label="label+'编码'" />
<el-table-column prop="formType" :label="label+'类型'" width="100">
<template slot-scope="scope">
<span>{{ scope.row.formType == 2 ? "自定义"+label : "系统"+label}}</span>
</template>
</el-table-column>
</JNPF-table>
<pagination :total="total" :page.sync="listQuery.currentPage"
:limit.sync="listQuery.pageSize" @pagination="initData" />
</div>
</div>
</div>
<span slot="footer" class="dialog-footer">
<el-button @click="visible = false" size="small">{{$t('common.cancelButton')}}</el-button>
<el-button type="primary" @click="select()" size="small">{{$t('common.confirmButton')}}
</el-button>
</span>
</el-dialog>
</div>
</template>
<script>
import { getFormSelect } from '@/api/workFlow/FormDesign.js'
export default {
name: 'FlowFormDialog',
props: {
value: {
default: ''
},
title: {
type: String,
default: ''
},
placeholder: {
type: String,
default: '请选择'
},
clearable: {
type: Boolean,
default: true
},
disabled: {
type: Boolean,
default: false
},
type: {
type: Number,
default: 1
},
formType: {
default: null
},
},
model: {
prop: 'value',
event: 'input'
},
data() {
return {
list: [],
innerValue: '',
listQuery: {
keyword: '',
currentPage: 1,
pageSize: 20,
},
total: 0,
checked: '',
checkedRow: {},
listLoading: false,
inputHovering: false,
visible: false
}
},
computed: {
showClose() {
let hasValue = this.value !== undefined && this.value !== null && this.value !== '';
let criteria = this.clearable &&
!this.disabled &&
this.inputHovering &&
hasValue;
return criteria;
},
label() {
return this.type == 1 ? "功能" : "表单"
}
},
methods: {
initData() {
this.listLoading = true
let q = {
...this.listQuery,
flowType: this.type,
formType: this.formType,
}
getFormSelect(q).then(res => {
this.list = res.data.list
this.total = res.data.pagination.total
this.listLoading = false
}).catch(() => { this.listLoading = false })
},
openDialog() {
if (this.disabled) return
this.checked = this.value
this.checkedRow = {
id: this.value,
fullName: this.title
}
this.visible = true
this.reset()
},
reset() {
this.listQuery.keyword = ''
this.search()
},
search() {
this.listQuery.currentPage = 1
this.listQuery.pageSize = 20
this.initData()
},
clear() {
this.checked = ''
this.checkedRow = {}
this.$emit('input', this.checked)
this.$emit('change', this.checked, this.checkedRow)
},
select() {
if (!this.checked) return
this.$emit('input', this.checked)
this.$emit('change', this.checked, this.checkedRow)
this.visible = false
},
rowClick(row) {
this.checked = row.id
this.checkedRow = row
}
}
}
</script>
<style lang="scss" scoped>
>>> .el-dialog__body {
max-height: 70vh;
padding: 0 0 10px !important;
display: flex;
flex-direction: column;
overflow: hidden;
.JNPF-common-search-box {
margin-bottom: 0;
.JNPF-common-search-box-right {
padding: 10px 10px 0 0;
}
}
}
</style>

@ -0,0 +1,332 @@
<template>
<el-dialog title="查看模板" :close-on-click-modal="false" :visible.sync="visible"
class="JNPF-dialog JNPF-dialog_center" lock-scroll append-to-body width='1000px'>
<el-row class="main" v-loading="loading">
<el-form :model="dataForm" ref="dataForm" label-width="100px" @submit.native.prevent>
<el-col :span="12">
<el-form-item label="名称" prop="fullName">
<p>{{dataForm.fullName}}</p>
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="编码" prop="enCode">
<p>{{dataForm.enCode}}</p>
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="模板类型">
<p>{{dataForm.templateType=='0'?'自定义模板':'系统模板'}}</p>
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="消息来源" prop="messageSource">
<p>{{dataForm.messageSourceVal}}</p>
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="消息类型" prop="messageType">
<p>{{dataForm.messageTypeVal}}</p>
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="状态" prop="enabledMark">
<el-switch v-model="dataForm.enabledMark" :active-value="1" :inactive-value="0"
disabled />
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="排序" prop="sortCode">
<p>{{dataForm.sortCode}}</p>
</el-form-item>
</el-col>
<el-col :span="24">
<el-form-item label="说明" prop="description">
<p>{{dataForm.description}}</p>
</el-form-item>
</el-col>
<el-col :span="24">
<div class="parameter-box">
<div class="left-pane">
<div class="left-pane-list">
<div class="list">
<div class="header">
<span>参数名称</span>
<span>参数说明</span>
</div>
<el-input v-model="keyword" placeholder="输入关键字" suffix-icon="el-icon-search"
clearable @input='searchParameter' />
<el-table :data="parameterList" :showHeader="false" ref="dragTable" row-key="id"
size='mini' height="100%">
<el-table-column prop="field" label="参数名称">
<template slot-scope="scope">
<p style="cursor:pointer">
{{scope.row.field}}
</p>
</template>
</el-table-column>
<el-table-column prop="fieldName" label="参数说明">
<template slot-scope="scope">
<p style="cursor:pointer;line-height:36px">
{{scope.row.fieldName}}
</p>
</template>
</el-table-column>
</el-table>
</div>
</div>
</div>
<div class="right-pane" v-if="dataForm.messageType != 3&&dataForm.messageType != 7">
<jnpf-form-tip-item label="消息标题" prop="title" tipLabel='参数格式:{参数名}'>
<p>{{dataForm.title}}</p>
</jnpf-form-tip-item>
<jnpf-form-tip-item label="消息内容" prop="content" v-if="dataForm.messageType == 2"
tipLabel='参数格式:{参数名}'>
<p v-html="dataForm.content"></p>
</jnpf-form-tip-item>
<jnpf-form-tip-item label="消息内容" prop="content"
v-else-if="dataForm.messageType != 1||dataForm.messageSource != 1"
tipLabel='参数格式:{参数名}'>
<p>{{dataForm.content}}</p>
</jnpf-form-tip-item>
</div>
<div class="right-pane" v-else>
<el-row :gutter="20">
<el-col :span="12">
<jnpf-form-tip-item label="模版编号" prop="templateCode"
:tipLabel="dataForm.messageType==3?'阿里云:请在【阿里云管理后台-模板管理】⻚⾯查看模板CODE<br/>腾讯云:请在【腾讯云管理后台-正⽂模板管理】⻚⾯查看模板ID':'在【微信公众号管理后台-广告与服务-模板消息】⻚⾯查看模板ID'">
<p>{{dataForm.templateCode}}</p>
</jnpf-form-tip-item>
</el-col>
<el-col :span="12" :offset="12"></el-col>
<el-col :span="12" v-if="dataForm.messageType == 7">
<jnpf-form-tip-item label="跳转方式" prop="wxSkip">
<p>{{dataForm.wxSkip==1?'小程序':'页面'}}</p>
</jnpf-form-tip-item>
</el-col>
<el-col :span="12" v-if="dataForm.messageType == 7&&dataForm.wxSkip == 1">
<jnpf-form-tip-item label="关联小程序ID" prop="xcxAppId" label-width="126px"
tipLabel="在【微信公众号管理后台-广告与服务-小程序管理】⻚⾯查看小程序ID">
<p>{{dataForm.xcxAppId}}</p>
</jnpf-form-tip-item>
</el-col>
</el-row>
<div class="msg-pane">
<div class="list">
<el-table :data="smsList" ref="dragTable" row-key="id" size='mini' height="100%">
<el-table-column label="序号" type="index" width="50"></el-table-column>
<el-table-column prop="name">
<template slot="header">
<p v-if="dataForm.messageType==3">
短信变量
<el-tooltip content="内容在第三方平台维护,绑定第三方平台短信变量,如:腾讯云:{1},阿里云格式:${name}"
placement="top">
<a class="el-icon-warning-outline"></a>
</el-tooltip>
</p>
<p v-else>
变量
<el-tooltip content="内容在微信公众号管理后台维护,绑定模板变量,如:{first.DATA}。"
placement="top">
<a class="el-icon-warning-outline"></a>
</el-tooltip>
</p>
</template>
<template slot-scope="scope">
<p>{{scope.row.smsField}}</p>
</template>
</el-table-column>
<el-table-column label="参数">
<template slot-scope="scope">
<p style="line-height:36px">{{scope.row.field}}</p>
</template>
</el-table-column>
<el-table-column label="标题" v-if="dataForm.messageType==7">
<template slot-scope="scope">
<el-checkbox v-model="scope.row.isTitle" disabled
@change='changeKey($event,scope.row)' :true-label="1" :false-label="0" />
</template>
</el-table-column>
</el-table>
</div>
</div>
</div>
</div>
</el-col>
</el-form>
</el-row>
<span slot="footer" class="dialog-footer">
<el-button @click="visible = false" size="small">{{$t('common.cancelButton')}}</el-button>
</span>
</el-dialog>
</template>
<script>
import { getMsgTemplateDetail, getMsgTypeList } from '@/api/msgCenter/msgTemplate'
export default {
name: 'msgTemplate-Detail',
data() {
return {
dataForm: {
id: '',
fullName: '',
enCode: '',
templateType: 0,
messageType: '',
messageSource: '',
enabledMark: 0,
sortCode: '',
description: '',
title: '',
content: '',
templateCode: '',
},
btnLoading: false,
loading: false,
messageSourceList: [],
messageTypeList: [],
smsList: [],
visible: false,
keyword: "",
parameterList: [],
allParameterList: [],
}
},
methods: {
init(id) {
this.visible = true
this.dataForm.id = id || ''
this.$nextTick(() => {
this.$refs['dataForm'].resetFields()
this.getConfig()
})
},
getConfig() {
this.loading = true
this.$store.dispatch('base/getMsgTypeList').then((res) => {
this.messageTypeList = res
getMsgTypeList(4).then(res => {
this.messageSourceList = res.data
if (this.dataForm.id) {
getMsgTemplateDetail(this.dataForm.id).then(res => {
this.loading = false
this.dataForm = res.data
this.parameterList = res.data.templateParamList
this.allParameterList = this.parameterList
if (this.dataForm.enabledMark) this.dataForm.enabledMark = Number(this.dataForm.enabledMark)
this.smsList = res.data.smsFieldList
const sourceItem = this.messageSourceList.find(item => {
return item.enCode == this.dataForm.messageSource
})
const typeItem = this.messageTypeList.find(item => {
return item.enCode == this.dataForm.messageType
})
if (sourceItem) this.dataForm.messageSourceVal = sourceItem.fullName
if (typeItem) this.dataForm.messageTypeVal = typeItem.fullName
}).catch(() => {
this.loading = false
})
}
}).catch(() => {
this.loading = false
})
}).catch(() => {
this.loading = false
})
},
goBack() {
this.$emit('close')
},
searchParameter() {
this.parameterList = this.allParameterList.filter(item => {
if (item.field.toLowerCase().includes(this.keyword.toLowerCase()) || item.fieldName.toLowerCase().includes(this.keyword.toLowerCase())) {
return item
}
})
},
}
}
</script>
<style lang="scss" scoped>
.main {
margin-top: 20px;
p {
color: #606266;
}
.parameter-box {
display: flex;
.left-pane {
width: 350px;
height: 323px;
flex-shrink: 0;
display: flex;
flex-direction: column;
overflow: hidden;
margin: 0 10px 18px 20px;
.left-pane-list {
border: 1px solid #dcdfe6;
border-radius: 4px;
flex: 1;
display: flex;
flex-direction: column;
overflow: hidden;
.list {
flex: 1;
display: flex;
flex-direction: column;
overflow: hidden;
.header {
background-color: #f5f7fa;
display: flex;
span {
font-size: 12px;
color: #606266;
padding: 6px 10px;
display: inline-block;
line-height: 23px;
flex: 1;
}
.operation {
width: 70px;
flex: unset;
}
}
}
>>> .el-input {
width: auto;
margin: 5px 10px;
}
>>> .el-table {
border-top: unset;
}
>>> .el-icon-edit-outline,
>>> .el-icon-delete {
font-size: 16px;
}
}
}
.right-pane {
flex: 1;
display: flex;
flex-direction: column;
.msg-pane {
margin-left: 10px;
flex: 1;
display: flex;
flex-direction: column;
.list {
flex: 1;
}
>>> .el-icon-delete {
font-size: 16px;
}
}
>>> .ql-editor {
min-height: 300px !important;
}
}
}
}
</style>

@ -0,0 +1,57 @@
const formulaData = [
{
id: 'maths',
fullName: '数学函数',
desc: '',
children: [
{
id: 'SUM',
fullName: 'SUM',
desc: `<ul class="formula-desc-wrapper">
<li><span class="formula-name">SUM</span></li>
<li>用法<span class="formula-name">SUM</span>(1,2,...)</li>
<li>示例<span class="formula-name">SUM</span>()</li>
</ul>`
},
{
id: 'SUBTRACT',
fullName: 'SUBTRACT',
desc: `<ul class="formula-desc-wrapper">
<li><span class="formula-name">SUBTRACT</span></li>
<li>用法<span class="formula-name">SUBTRACT</span>(,)</li>
<li>示例<span class="formula-name">SUBTRACT</span>()</li>
</ul>`
},
{
id: 'PRODUCT',
fullName: 'PRODUCT',
desc: `<ul class="formula-desc-wrapper">
<li><span class="formula-name">PRODUCT</span></li>
<li>用法<span class="formula-name">PRODUCT</span>(1,2,...)</li>
<li>示例<span class="formula-name">PRODUCT</span>()</li>
</ul>`
},
{
id: 'DIVIDE',
fullName: 'DIVIDE',
desc: `<ul class="formula-desc-wrapper">
<li><span class="formula-name">DIVIDE</span></li>
<li>用法<span class="formula-name">DIVIDE</span>(,)</li>
<li>示例<span class="formula-name">DIVIDE</span>()</li>
</ul>`
},
{
id: 'COUNT',
fullName: 'COUNT',
desc: `<ul class="formula-desc-wrapper">
<li><span class="formula-name">COUNT</span></li>
<li>用法<span class="formula-name">COUNT</span>(,,...)</li>
<li>示例<span class="formula-name">COUNT</span>(,)2,</li>
</ul>`
}
]
}
]
export default formulaData

@ -0,0 +1,94 @@
<template>
<el-dialog title="公式编辑" :close-on-click-modal="false" v-on="$listeners"
class="JNPF-dialog JNPF-dialog_center formula-dialog" lock-scroll append-to-body v-bind="$attrs"
width="800px" :modal-append-to-body="false" @open="onOpen">
<div class="formula-dialog-body">
<div class="code-editor-area">
<JSONEditor v-model="text" mode="javascript" ref="codemirror" class="json-editor" />
</div>
<div class="operation-area">
<div class="area-item field-area">
<div class="area-title">当前表单字段</div>
<div class="area-content">
<el-tree :data="fieldsOptions" node-key="id" default-expand-all
:expand-on-click-node="false" :props="treeProps" @node-click="handleNodeClick">
</el-tree>
</div>
</div>
<div class="area-item formula-area">
<div class="area-title">函数</div>
<div class="area-content">
<el-tree :data="formulaData" node-key="id" default-expand-all
:expand-on-click-node="false" :props="treeProps" @node-click="formulaNodeClick">
<span class="custom-tree-node" slot-scope="{ node,data }">
<span class="text" @mouseenter="formulaMouseenter(data)">{{node.label}}</span>
</span>
</el-tree>
</div>
</div>
<div class="area-item formula-desc-area">
<div class="area-title">{{descTitle}}</div>
<div class="area-content" v-html="descContent"></div>
</div>
</div>
</div>
<span slot="footer" class="dialog-footer">
<el-button @click="closeDialog">{{$t('common.cancelButton')}}</el-button>
<el-button type="primary" @click="onClose()">{{$t('common.confirmButton')}}</el-button>
</span>
</el-dialog>
</template>
<script>
import JSONEditor from '@/components/JsonEditor'
import formulaData from "./formulaData";
export default {
components: { JSONEditor },
props: ['value', 'formFieldsOptions'],
data() {
return {
text: '111',
treeProps: {
children: 'children',
label: 'fullName'
},
formulaData,
descTitle: '',
descContent: '请从左侧面板选择字段名和函数',
}
},
computed: {
fieldsOptions() {
let list = this.formFieldsOptions.map(o => ({
id: o.__vModel__,
fullName: o.__config__.label
}))
return list
}
},
methods: {
onOpen() {
this.text = this.value
},
handleNodeClick(item) {
this.$refs.codemirror.insert('{' + item.id + '}')
},
formulaNodeClick(item) {
if (!item.desc) return
this.$refs.codemirror.insert(item.id + '()', true)
},
formulaMouseenter(item) {
if (!item.desc) return
this.descContent = item.desc
this.descTitle = item.fullName
},
onClose() {
this.$emit('updateFormula', this.text)
this.closeDialog()
},
closeDialog() {
this.$emit('update:visible', false)
}
}
}
</script>

@ -0,0 +1,213 @@
<template>
<div class="main">
<template v-if="config.popupType==='dialog'">
<el-dialog :title="config.popupTitle" :close-on-click-modal="false" :visible.sync="visible"
class="JNPF-dialog JNPF-dialog_center" lock-scroll append-to-body :width='config.popupWidth'
@close="$emit('close')">
<el-row class="JNPF-common-search-box" :gutter="16">
<el-form @submit.native.prevent>
<el-col :span="10">
<el-form-item label="关键词">
<el-input v-model="listQuery.keyword" placeholder="请输入关键词搜索" clearable
@keyup.enter.native="search()" class="search-input" />
</el-form-item>
</el-col>
<el-col :span="8">
<el-form-item>
<el-button type="primary" icon="el-icon-search" @click="search()">
{{$t('common.search')}}
</el-button>
<el-button icon="el-icon-refresh-right" @click="reset()">{{$t('common.reset')}}
</el-button>
</el-form-item>
</el-col>
</el-form>
</el-row>
<JNPF-table v-loading="listLoading" :data="list" hasC
@selection-change="handleSelectionChange">
<el-table-column :prop="item.value" :label="item.label"
v-for="(item,i) in config.columnOptions" :key="i" />
</JNPF-table>
<pagination :total="total" :page.sync="listQuery.currentPage"
:limit.sync="listQuery.pageSize" @pagination="initData" v-if="config.hasPage"
:pager-count="5" />
<span slot="footer" class="dialog-footer">
<el-button @click="visible = false">{{$t('common.cancelButton')}}</el-button>
<el-button type="primary" @click="select()" :loading="btnLoading">
{{$t('common.confirmButton')}}</el-button>
</span>
</el-dialog>
</template>
<template v-if="config.popupType==='drawer'">
<el-drawer :title="config.popupTitle" :visible.sync="visible" :wrapperClosable="false"
ref="drawer" :size='config.popupWidth' append-to-body class="JNPF-common-drawer"
@close="$emit('close')">
<div class="JNPF-flex-main">
<el-row class="JNPF-common-search-box" :gutter="16">
<el-form @submit.native.prevent>
<el-col :span="10">
<el-form-item label="关键词">
<el-input v-model="listQuery.keyword" placeholder="请输入关键词搜索" clearable
@keyup.enter.native="search()" class="search-input" />
</el-form-item>
</el-col>
<el-col :span="8">
<el-form-item>
<el-button type="primary" icon="el-icon-search" @click="search()">
{{$t('common.search')}}
</el-button>
<el-button icon="el-icon-refresh-right" @click="reset()">{{$t('common.reset')}}
</el-button>
</el-form-item>
</el-col>
</el-form>
</el-row>
<JNPF-table v-loading="listLoading" :data="list" hasC
@selection-change="handleSelectionChange">
<el-table-column :prop="item.value" :label="item.label"
v-for="(item,i) in config.columnOptions" :key="i" />
</JNPF-table>
<pagination :total="total" :page.sync="listQuery.currentPage"
:limit.sync="listQuery.pageSize" @pagination="initData" v-if="config.hasPage" />
<div class="drawer-footer">
<el-button @click="visible = false">{{$t('common.cancelButton')}}</el-button>
<el-button type="primary" @click="select()" :loading="btnLoading">
{{$t('common.confirmButton')}}</el-button>
</div>
</div>
</el-drawer>
</template>
</div>
</template>
<script>
import { getDataInterfaceDataSelect } from '@/api/systemData/dataInterface'
import { mapGetters } from "vuex"
export default {
name: 'SelectDialog',
props: {
config: {
type: Object,
default: () => { }
},
formData: Object,
multiple: {
type: Boolean,
default: true
}
},
data() {
return {
visible: false,
listLoading: true,
btnLoading: false,
listQuery: {
keyword: '',
currentPage: 1,
pageSize: 20
},
list: [],
total: 0,
checked: []
}
},
computed: {
...mapGetters(['userInfo']),
},
methods: {
init() {
this.listQuery.keyword = ''
this.listQuery.pageSize = this.config.hasPage ? this.config.pageSize : 10000
this.visible = true
this.btnLoading = false
this.initData()
},
initData() {
if (!this.config.interfaceId) return
this.listLoading = true
const paramList = this.getParamList()
const columnOptions = this.config.columnOptions.map(o => o.value)
let query = {
...this.listQuery,
interfaceId: this.config.interfaceId,
columnOptions: columnOptions.join(','),
paramList
}
getDataInterfaceDataSelect(this.config.interfaceId, query).then(res => {
this.list = res.data.list
if (this.config.hasPage) this.total = res.data.pagination.total
this.listLoading = false
}).catch(() => { this.listLoading = false })
},
getParamList() {
let templateJson = this.config.templateJson
for (let i = 0; i < templateJson.length; i++) {
templateJson[i].defaultValue = this.formData[templateJson[i].relationField] || ''
if (templateJson[i].jnpfKey === 'createUser') {
templateJson[i].defaultValue = this.userInfo.userId
}
if (templateJson[i].jnpfKey === 'createTime') {
templateJson[i].defaultValue = new Date().getTime()
}
if (templateJson[i].jnpfKey === 'currOrganize') {
templateJson[i].defaultValue = this.userInfo.organizeId
}
if (templateJson[i].jnpfKey === 'currPosition') {
if (this.userInfo.positionIds && this.userInfo.positionIds.length) {
let item = this.userInfo.positionIds[0]
templateJson[i].defaultValue = item.id
}
}
}
return templateJson
},
select() {
if (!this.checked.length) return
this.btnLoading = true
this.visible = false
let checked = []
for (let i = 0; i < this.checked.length; i++) {
const e = this.checked[i]
let item = {}
for (let j = 0; j < this.config.relationOptions.length; j++) {
const row = this.config.relationOptions[j]
item[row.field] = row.type === 1 ? e[row.value] : row.value
}
checked.push(item)
}
this.$emit('close')
this.$emit('select', checked)
},
handleSelectionChange(val) {
this.checked = val
},
search() {
this.listQuery.currentPage = 1
this.listQuery.pageSize = this.config.hasPage ? this.config.pageSize : 10000
this.initData()
},
reset() {
this.listQuery.keyword = ''
this.search()
},
}
}
</script>
<style lang="scss" scoped>
>>> .el-dialog__body {
height: 70vh;
padding: 0 0 10px !important;
display: flex;
flex-direction: column;
overflow: hidden;
.JNPF-common-search-box {
margin-bottom: 0;
.JNPF-common-search-box-right {
padding: 10px 10px 0 0;
}
}
.el-table {
border-top: none !important;
}
}
</style>

@ -0,0 +1,142 @@
<template>
<div>
<el-dialog title="请签名" class="JNPF-dialog JNPF-dialog_center sign-dialog"
:closeOnClickModal='false' :visible.sync="signVisible" append-to-body width="600px">
<div class="sign-main-box">
<vue-esign ref="esign" :height='300' :width="560" :lineWidth="lineWidth" />
<div class="tip" v-show="showTip">使</div>
</div>
<span slot="footer" class="dialog-footer">
<el-button @click="handleReset"></el-button>
<el-button type="primary" :loading="loading" @click="handleGenerate()"></el-button>
</span>
</el-dialog>
</div>
</template>
<script>
import { createSign } from '@/api/permission/userSetting'
import vueEsign from 'vue-esign'
export default {
name: 'SignImgDialog',
components: { vueEsign },
props: {
lineWidth: {
required: true,
type: Number
},
isDefault: {
required: true,
type: Number
},
userInfo: {
type: Object,
default() {
return {}
}
}
},
data() {
return {
signVisible: false,
loading: false,
signImg: '',
showTip: true
}
},
methods: {
init() {
this.handleReset()
this.signVisible = true
this.showTip = true
this.$nextTick(() => {
this.$watch(
() => {
return this.$refs.esign.hasDrew
},
(val) => {
this.showTip = !val
}
)
})
},
handleReset() {
this.signImg = ''
this.$nextTick(() => {
this.$refs.esign && this.$refs.esign.reset()
})
},
handleGenerate() {
this.loading = true
this.$refs.esign.generate().then(res => {
if (res) this.signImg = res
let query = {
signImg: this.signImg,
isDefault: this.isDefault
}
createSign(query).then(res => {
if (this.isDefault == 0) {
this.$message({
message: res.msg,
type: 'success',
duration: 1500
})
if (!this.userInfo.signImg) this.$store.commit('user/SET_USERINFO_SIGNIMG', this.signImg)
}
if (this.isDefault == 1) {
this.$store.commit('user/SET_USERINFO_SIGNIMG', this.signImg)
}
this.signVisible = false
this.loading = false
this.$emit('close', this.signImg)
this.handleReset()
}).catch(err => {
this.signVisible = false
this.loading = false
this.$emit('close')
this.handleReset()
})
}).catch(err => {
this.loading = false
this.$message.warning("请签名")
})
},
}
}
</script>
<style lang="scss" scoped>
.sign-dialog {
>>> .el-dialog__body {
overflow: hidden;
height: 320px;
overflow: auto;
overflow-x: hidden;
padding: 23px 14px 2px !important;
}
}
.sign-main-box {
border: 1px solid rgb(224, 238, 238);
width: 100%;
height: 300px;
background-color: rgb(247, 247, 247);
display: flex;
justify-content: center;
align-items: center;
margin-top: -10px;
margin-bottom: -10px;
position: relative;
.tip {
height: 300px;
line-height: 300px;
text-align: center;
position: absolute;
left: 0;
top: 0;
right: 0;
color: #9d9d9f;
font-size: 16px;
pointer-events: none;
}
}
</style>

@ -0,0 +1,565 @@
<template>
<el-dialog title="高级查询" :close-on-click-modal="false" :visible.sync="visible"
class="JNPF-dialog JNPF-dialog_center superQuery-dialog" lock-scroll width="800px">
<div class="superQuery-main" v-loading="loading">
<template v-if="conditionList.length">
<div class="matchLogic">
<span>匹配逻辑</span>
<el-select v-model="matchLogic" placeholder="请选择">
<el-option label="AND(所有条件都要求匹配)" value="AND"></el-option>
<el-option label="OR(条件中的任意一个匹配)" value="OR"></el-option>
</el-select>
</div>
<div>
<template v-for="(item, index) in conditionList">
<el-row class="condition-list" :key="index" :gutter="20">
<el-col :span="8">
<el-select v-model="item.field" placeholder="请选择查询字段" filterable
@change="onFieldChange($event,item,index)" clearable>
<el-option v-for="item in fieldOptions" :key="item.__vModel__"
:label="item.__config__.label" :value="item.__vModel__">
</el-option>
</el-select>
</el-col>
<el-col :span="4">
<el-select v-model="item.symbol" placeholder="请选择">
<el-option v-for="item in symbolOptions" :key="item.value" :label="item.label"
:value="item.value">
</el-option>
</el-select>
</el-col>
<el-col :span="8">
<template v-if="item.jnpfKey==='numInput'">
<el-input-number v-model="item.fieldValue" placeholder="请输入"
:precision="item.attr.precision" controls-position="right" style="width:100%" />
</template>
<template v-else-if="item.jnpfKey==='calculate'">
<el-input-number v-model="item.fieldValue" placeholder="请输入" :precision="2"
controls-position="right" style="width:100%" />
</template>
<template v-else-if="['rate','slider'].includes(item.jnpfKey)">
<el-input-number v-model="item.fieldValue" placeholder="请输入"
controls-position="right" style="width:100%" />
</template>
<div v-else-if="item.jnpfKey==='switch'" style="padding-top: 5px;">
<el-switch v-model="item.fieldValue" :active-value="1" :inactive-value="0" />
</div>
<template v-else-if="item.jnpfKey==='time'">
<el-time-picker v-model="item.fieldValue" style="width:100%"
:picker-options="item.attr['picker-options']" placeholder="请选择" clearable
:value-format="item.attr['value-format']" :format="item.attr.format">
</el-time-picker>
</template>
<template v-else-if="['date','createTime', 'modifyTime'].includes(item.jnpfKey)">
<el-date-picker v-model="item.fieldValue" clearable placeholder="请选择"
:type="item.jnpfKey==='date'&&item.attr.type?item.attr.type:'datetime'"
value-format="timestamp" style="width:100%"
:format="item.attr.format||'yyyy-MM-dd HH:mm:ss'">
</el-date-picker>
</template>
<template v-else-if="['comSelect','currOrganize'].includes(item.jnpfKey)">
<comSelect v-model="item.fieldValue" placeholder="请选择" clearable />
</template>
<template v-else-if="['depSelect'].includes(item.jnpfKey)">
<depSelect v-model="item.fieldValue" placeholder="请选择" clearable
:selectType="item.attr.selectType" :ableDepIds="item.attr.ableDepIds" />
</template>
<template v-else-if="['createUser','modifyUser'].includes(item.jnpfKey)">
<userSelect v-model="item.fieldValue" placeholder="请选择" clearable />
</template>
<template v-else-if="['userSelect'].includes(item.jnpfKey)">
<userSelect v-model="item.fieldValue" placeholder="请选择" clearable
:selectType="item.attr.selectType!='all'||item.attr.selectType!='custom'?'all':item.attr.selectType"
:ableDepIds="item.attr.ableDepIds" :ablePosIds="item.attr.ablePosIds"
:ableUserIds="item.attr.ableUserIds" :ableRoleIds="item.attr.ableRoleIds"
:ableGroupIds="item.attr.ableGroupIds" />
</template>
<template v-else-if="['usersSelect'].includes(item.jnpfKey)">
<usersSelect v-model="item.fieldValue" placeholder="请选择" clearable
:selectType="item.attr.selectType" :ableIds="item.attr.ableIds" />
</template>
<template v-else-if="['currPosition'].includes(item.jnpfKey)">
<posSelect v-model="item.fieldValue" placeholder="请选择" clearable />
</template>
<template v-else-if="['posSelect'].includes(item.jnpfKey)">
<posSelect v-model="item.fieldValue" placeholder="请选择" clearable
:selectType="item.attr.selectType" :ableDepIds="item.attr.ableDepIds"
:ablePosIds="item.attr.ablePosIds" />
</template>
<template v-else-if="item.jnpfKey==='groupSelect'">
<groupSelect v-model="item.fieldValue" placeholder="请选择" clearable />
</template>
<template v-else-if="item.jnpfKey==='roleSelect'">
<roleSelect v-model="item.fieldValue" placeholder="请选择" clearable />
</template>
<template v-else-if="item.jnpfKey==='address'">
<JNPFAddress v-model="item.fieldValue" placeholder="请选择" :level="item.attr.level"
clearable :key="item.cellKey" />
</template>
<template v-else-if="['select','radio','checkbox'].includes(item.jnpfKey)">
<el-select v-model="item.fieldValue" placeholder="请选择" clearable filterable>
<el-option :label="oItem[item.attr.__config__.props.label]"
v-for="(oItem, i) in item.attr.__slot__.options"
:value="oItem[item.attr.__config__.props.value]" :key="i"></el-option>
</el-select>
</template>
<template v-else-if="item.jnpfKey==='cascader'">
<el-cascader v-model="item.fieldValue" :options="item.attr.options" clearable
:show-all-levels="item.attr['show-all-levels']" :props="item.attr.props.props"
filterable placeholder="请选择" style="width:100%">
</el-cascader>
</template>
<template v-else-if="item.jnpfKey==='treeSelect'">
<JNPF-TreeSelect v-model="item.fieldValue" placeholder="请选择"
:options="item.attr.options" :props="item.attr.props.props" clearable />
</template>
<template v-else-if="item.jnpfKey==='relationForm'">
<relationForm v-model="item.fieldValue" placeholder="请选择"
:modelId="item.attr.modelId" clearable :columnOptions="item.attr.columnOptions"
:relationField="item.attr.relationField" :hasPage="item.attr.hasPage"
:pageSize="item.attr.pageSize" />
</template>
<template v-else-if="item.jnpfKey==='popupSelect'">
<popupSelect v-model="item.fieldValue" placeholder="请选择"
:interfaceId="item.attr.interfaceId" clearable
:columnOptions="item.attr.columnOptions" :propsValue="item.attr.propsValue"
:relationField="item.attr.relationField" :hasPage="item.attr.hasPage"
:pageSize="item.attr.pageSize" :popupType="item.attr.popupType"
:popupTitle="item.attr.popupTitle" :popupWidth="item.attr.popupWidth" />
</template>
<template v-else-if="item.jnpfKey==='popupTableSelect'">
<popupTableSelect v-model="item.fieldValue" :placeholder="item.attr.placeholder"
:interfaceId="item.attr.interfaceId" :columnOptions="item.attr.columnOptions"
:propsValue="item.attr.propsValue" :relationField="item.attr.relationField"
:hasPage="item.attr.hasPage" :pageSize="item.attr.pageSize"
:popupType="item.attr.popupType" :popupTitle="item.attr.popupTitle"
:popupWidth="item.attr.popupWidth" :filterable="item.attr.filterable"
clearable />
</template>
<template v-else>
<el-input v-model="item.fieldValue" placeholder="请输入" clearable />
</template>
</el-col>
<el-col :span="4">
<el-button @click="addCondition" icon="el-icon-plus"></el-button>
<el-button @click="delCondition(index)" icon="el-icon-minus"></el-button>
</el-col>
</el-row>
</template>
</div>
</template>
<div class="query-noData" v-else>
<img src="@/assets/images/query-noData.png" alt="" class="noData-img">
<div class="noData-txt">
<span>没有任何查询条件</span>
<el-divider direction="vertical"></el-divider>
<el-link type="primary" :underline="false" @click="addCondition"></el-link>
</div>
</div>
</div>
<span slot="footer" class="dialog-footer">
<div class="footer-options">
<el-button @click="addPlan" class="add-btn">保存方案</el-button>
<el-popover width="240" trigger="click" popper-class="plan-popper" ref="planPopper">
<el-button slot="reference">方案选择<i class="el-icon-arrow-down el-icon--right"></i>
</el-button>
<div class="plan-list" v-if="planList.length">
<div class="plan-list-item" v-for="(item,i) in planList" :key="i"
@click="selectPlan(item)">
<el-link type="primary" :underline="false" class="plan-list-name">{{item.fullName}}
</el-link>
<i class="el-icon-close" @click.stop="delPlan(item.id,i)"></i>
</div>
</div>
<div class="noData-txt" v-else></div>
</el-popover>
</div>
<el-button @click="visible = false">{{$t('common.cancelButton')}}</el-button>
<el-button type="primary" :loading="btnLoading" @click="query()"> </el-button>
</span>
<el-dialog title="保存方案" :visible.sync="addPlanVisible" width="600px" append-to-body lock-scroll
class="JNPF-dialog JNPF-dialog_center">
<el-form ref="dataForm" :model="dataForm" :rules="dataRule" label-width="80px">
<el-form-item label="方案名称" prop="fullName">
<el-input v-model="dataForm.fullName" placeholder="请输入保存的方案名称" />
</el-form-item>
</el-form>
<span slot="footer" class="dialog-footer">
<el-button @click="addPlanVisible = false">{{$t('common.cancelButton')}}</el-button>
<el-button type="primary" :loading="saveBtnLoading" @click="savePlan()">
{{$t('common.confirmButton')}}</el-button>
</span>
</el-dialog>
</el-dialog>
</template>
<script>
import { getAdvancedQueryList, Delete, Create, Update } from "@/api/system/advancedQuery";
import { dyOptionsList } from '@/components/Generator/generator/comConfig'
import { getDictionaryDataSelector } from '@/api/systemData/dictionary'
import { getDataInterfaceRes } from '@/api/systemData/dataInterface'
export default {
props: {
columnOptions: {
type: Array,
default: () => []
}
},
data() {
return {
visible: false,
addPlanVisible: false,
loading: false,
btnLoading: false,
saveBtnLoading: false,
matchLogic: 'AND',
conditionList: [{
field: '',
fieldValue: '',
symbol: '==',
jnpfKey: '',
attr: {}
}],
planList: [],
fieldOptions: [],
symbolOptions: [
{
label: '大于等于',
value: ">="
},
{
label: '大于',
value: ">"
},
{
label: '等于',
value: "=="
},
{
label: '小于等于',
value: "<="
},
{
label: '小于',
value: "<"
},
{
label: '不等于',
value: "<>"
},
{
label: '包含',
value: "like"
},
{
label: '不包含',
value: "notLike"
}],
dataForm: {
fullName: ''
},
dataRule: {
fullName: [
{ required: true, message: '请输入保存的方案名称', trigger: 'blur' }
]
}
}
},
computed: {
currMenuId() {
return this.$route.meta.modelId || ''
}
},
methods: {
init() {
this.visible = true
this.loading = true
let componentList = JSON.parse(JSON.stringify(this.columnOptions))
this.fieldOptions = componentList
this.getAdvancedQueryList()
this.$nextTick(() => {
this.loading = false
})
},
buildOptions(componentList) {
componentList.forEach(cur => {
const config = cur.__config__
if (config.jnpfKey === 'cascader') cur.props.props.multiple = false
if (dyOptionsList.indexOf(config.jnpfKey) > -1) {
let isTreeSelect = config.jnpfKey === 'treeSelect' || config.jnpfKey === 'cascader'
if (config.dataType === 'dictionary') {
if (!config.dictionaryType) return
getDictionaryDataSelector(config.dictionaryType).then(res => {
isTreeSelect ? cur.options = res.data.list : cur.__slot__.options = res.data.list
})
}
if (config.dataType === 'dynamic') {
if (!config.propsUrl) return
getDataInterfaceRes(config.propsUrl).then(res => {
let data = res.data
if (Array.isArray(data)) {
isTreeSelect ? cur.options = data : cur.__slot__.options = data
} else {
isTreeSelect ? cur.options = [] : cur.__slot__.options = []
}
})
}
}
})
return componentList
},
getAdvancedQueryList() {
if (!this.currMenuId) return
getAdvancedQueryList(this.currMenuId).then(res => {
this.planList = res.data.list
})
},
onFieldChange(val, item, i) {
item.cellKey = +new Date()
if (!val) {
item.jnpfKey = ''
item.fieldValue = undefined
item.attr = {}
return
}
let obj = this.columnOptions.filter(o => o.__vModel__ == val)[0]
item.jnpfKey = obj.__config__.jnpfKey
item.attr = obj
if (item.jnpfKey === 'cascader') item.attr.props.props.multiple = false
let config = item.attr.__config__
if (dyOptionsList.indexOf(config.jnpfKey) > -1) {
let isTreeSelect = config.jnpfKey === 'treeSelect' || config.jnpfKey === 'cascader'
if (config.dataType === 'dictionary') {
if (!config.dictionaryType) return
getDictionaryDataSelector(config.dictionaryType).then(res => {
isTreeSelect ? item.attr.options = res.data.list : item.attr.__slot__.options = res.data.list
})
}
if (config.dataType === 'dynamic') {
if (!config.propsUrl) return
getDataInterfaceRes(config.propsUrl).then(res => {
let data = res.data
if (Array.isArray(data)) {
isTreeSelect ? item.attr.options = data : item.attr.__slot__.options = data
} else {
isTreeSelect ? item.attr.options = [] : item.attr.__slot__.options = []
}
})
}
}
item.fieldValue = undefined
this.$set(this.conditionList, i, item)
},
addCondition() {
let item = {
field: '',
fieldValue: '',
symbol: '==',
jnpfKey: '',
cellKey: +new Date(),
attr: {}
}
this.conditionList.push(item)
},
delCondition(index) {
this.conditionList.splice(index, 1)
},
delPlan(id, i) {
Delete(id).then(res => {
this.$message({
type: 'success',
message: res.msg,
duration: 1500,
onClose: () => {
this.planList.splice(i, 1)
}
})
})
},
selectPlan(item) {
this.matchLogic = item.matchLogic
this.conditionList = item.conditionJson ? JSON.parse(item.conditionJson) : []
this.$refs.planPopper.doClose()
},
addPlan() {
if (!this.exist()) return
this.addPlanVisible = true
this.$nextTick(() => {
this.$refs['dataForm'].resetFields()
})
},
savePlan() {
this.$refs['dataForm'].validate((valid) => {
if (valid) {
let boo = this.planList.some(o => o.fullName === this.dataForm.fullName)
if (!boo) return this.submit()
let list = this.planList.filter(o => o.fullName === this.dataForm.fullName)
this.$confirm(`${list[0].fullName}已存在, 是否覆盖方案?`, '', {
type: 'warning'
}).then(() => {
this.submit(list[0].id)
}).catch(() => { });
}
})
},
submit(id) {
this.saveBtnLoading = true
let query = {
id: id || '',
...this.dataForm,
matchLogic: this.matchLogic,
moduleId: this.currMenuId,
conditionJson: JSON.stringify(this.conditionList)
}
const formMethod = query.id ? Update : Create
formMethod(query).then(res => {
this.getAdvancedQueryList()
this.addPlanVisible = false
this.saveBtnLoading = false
this.$message({
message: res.msg,
type: 'success',
duration: 1500
})
}).catch(() => {
this.saveBtnLoading = false
})
},
getDataType(jnpfKey) {
if (!jnpfKey) return ''
if (['numInput', 'date', 'rate', 'slider'].includes(jnpfKey)) {
return 'number'
} else if (['uploadFz', 'uploadImg', 'cascader', 'comSelect', 'address'].includes(jnpfKey)) {
return 'array'
}
return ''
},
exist(type) {
let isOk = true
for (let i = 0; i < this.conditionList.length; i++) {
const e = this.conditionList[i];
if (!e.field) {
this.$message({
message: `请选择查询字段`,
type: 'error',
duration: 1000
});
isOk = false
break
}
let flag = false
if (this.getDataType(e.jnpfKey) === 'array') {
flag = this.jnpf.isEmptyArray(e.fieldValue)
} else {
flag = this.jnpf.isEmpty(e.fieldValue)
}
if (flag) {
const mes = type == 'query' ? '查询' : '保存'
this.$message({
message: `空条件不能${mes}`,
type: 'error',
duration: 1000
});
isOk = false
break
}
}
return isOk
},
query() {
if (!this.exist('query')) return
let query = {
matchLogic: this.matchLogic,
conditionJson: JSON.stringify(this.conditionList)
}
query = JSON.stringify(query)
if (!this.conditionList.length) query = ""
this.$emit('superQuery', query)
this.visible = false
}
}
}
</script>
<style lang="scss" scoped>
.superQuery-dialog {
>>> .el-dialog {
.el-dialog__body {
padding: 20px 20px 10px 24px;
}
.footer-options {
float: left;
.add-btn {
margin-right: 10px;
}
}
}
.superQuery-main {
.query-noData {
text-align: center;
padding: 20px 0;
.noData-img {
width: 160px;
margin-bottom: 10px;
}
.noData-txt {
color: #909399;
}
}
.matchLogic {
margin-bottom: 10px;
display: flex;
align-items: center;
line-height: 32px;
.el-select {
width: 220px;
}
}
.condition-list {
margin-bottom: 10px;
}
}
}
</style>
<style lang="scss">
.plan-popper {
padding: 0 !important;
.plan-list {
padding: 6px 0;
max-height: 182px;
overflow: auto;
&-item {
height: 34px;
display: flex;
align-items: center;
justify-content: space-between;
color: #606266;
font-size: 14px;
cursor: pointer;
padding: 0 20px;
&:hover {
background-color: #f5f7fa;
}
}
.plan-list-name {
.el-link--inner {
width: 160px;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
}
.el-icon-close:hover {
color: #f56c6c;
}
}
.noData-txt {
height: 34px;
color: #999;
font-size: 14px;
line-height: 34px;
text-align: center;
}
}
</style>

@ -0,0 +1,73 @@
<template>
<div>
<el-input :value="value||innerValue" :placeholder="placeholder" readonly v-if="!detailed" />
<p v-else>{{value||innerValue}}</p>
</div>
</template>
<script>
import { mapGetters } from "vuex"
export default {
name: 'jnpf-open-data',
computed: {
...mapGetters(['userInfo'])
},
props: {
value: {
type: String,
default: ''
},
/**
* currUser - 当前用户
* currTime - 当前时间
* currOrganize - 所属组织
* currPosition - 所属岗位
*/
type: {
type: String,
default: 'currUser'
},
showLevel: {
type: String,
default: 'last'
},
detailed: {
type: Boolean,
default: false
},
placeholder: {
type: String,
default: '系统自动生成'
},
},
data() {
return {
innerValue: ''
}
},
watch: {
showLevel() {
this.setDefault()
}
},
created() {
this.setDefault()
},
methods: {
setDefault() {
if (this.type === 'currUser') {
this.innerValue = this.userInfo.userName + '/' + this.userInfo.userAccount
}
if (this.type === 'currTime') {
this.innerValue = this.jnpf.toDate(new Date().getTime(), 'yyyy-MM-dd HH:mm:ss')
}
if (this.type === 'currOrganize') {
this.innerValue = this.showLevel === 'last' ? this.userInfo.departmentName : this.userInfo.organizeName
}
if (this.type === 'currPosition') {
this.innerValue = this.userInfo.positionName
}
}
}
}
</script>
Loading…
Cancel
Save