yujialong 1 year ago
parent d038fbeb37
commit 3a07f53216
  1. 2
      .env
  2. 1
      .env.production
  3. 0
      .env.staging
  4. 1
      .env.test
  5. 1
      package.json
  6. 462
      public/tinymce/langs/zh_CN.js
  7. 419
      public/tinymce/langs/zh_TW.js
  8. 7
      public/tinymce/skins/content/dark/content.min.css
  9. 7
      public/tinymce/skins/content/default/content.min.css
  10. 7
      public/tinymce/skins/content/document/content.min.css
  11. 7
      public/tinymce/skins/content/writer/content.min.css
  12. 7
      public/tinymce/skins/ui/oxide-dark/content.inline.min.css
  13. 7
      public/tinymce/skins/ui/oxide-dark/content.min.css
  14. 7
      public/tinymce/skins/ui/oxide-dark/content.mobile.min.css
  15. BIN
      public/tinymce/skins/ui/oxide-dark/fonts/tinymce-mobile.woff
  16. 7
      public/tinymce/skins/ui/oxide-dark/skin.min.css
  17. 7
      public/tinymce/skins/ui/oxide-dark/skin.mobile.min.css
  18. 7
      public/tinymce/skins/ui/oxide-dark/skin.shadowdom.min.css
  19. 7
      public/tinymce/skins/ui/oxide/content.inline.min.css
  20. 7
      public/tinymce/skins/ui/oxide/content.min.css
  21. 7
      public/tinymce/skins/ui/oxide/content.mobile.min.css
  22. BIN
      public/tinymce/skins/ui/oxide/fonts/tinymce-mobile.woff
  23. 7
      public/tinymce/skins/ui/oxide/skin.min.css
  24. 7
      public/tinymce/skins/ui/oxide/skin.mobile.min.css
  25. 7
      public/tinymce/skins/ui/oxide/skin.shadowdom.min.css
  26. 5
      src/api/config.ts
  27. 30
      src/api/content.ts
  28. 2
      src/components/Back.vue
  29. 4
      src/components/LabelTip.vue
  30. 17
      src/components/ListMove.vue
  31. 2
      src/components/QueryForm/QueryForm.vue
  32. 55
      src/components/QueryForm/QueryItem.vue
  33. 29
      src/components/Search.vue
  34. 20
      src/components/TableList/ColumnSetting.vue
  35. 83
      src/components/Upload/FileListUpload.vue
  36. 93
      src/components/Upload/ImageListUpload.vue
  37. 74
      src/components/Upload/ImageUpload.vue
  38. 14
      src/layout/components/AppHeader.vue
  39. 2
      src/layout/components/AppSidebar/Menu.vue
  40. 1
      src/layout/index.vue
  41. 4
      src/main.ts
  42. 59
      src/store/useCurrentUser.ts
  43. 21
      src/utils/auth.ts
  44. 18
      src/views/config/Buyer.vue
  45. 24
      src/views/config/Index.vue
  46. 9
      src/views/finance/Account.vue
  47. 39
      src/views/finance/Armory.vue
  48. 9
      src/views/finance/BankDetail.vue
  49. 9
      src/views/finance/Order.vue
  50. 9
      src/views/finance/Publish.vue
  51. 2
      src/views/product/List.vue
  52. 67
      src/views/user/RoleForm.vue
  53. 2
      src/views/user/UserForm.vue

@ -2,6 +2,6 @@ VITE_APP_TITLE=金融产品设计及数字化营销沙盘
VITE_PORT=9520 VITE_PORT=9520
VITE_PROXY=http://192.168.31.125:8080 VITE_PROXY=http://192.168.31.125:8080
VITE_PUBLIC_PATH=./ VITE_PUBLIC_PATH=./
VITE_BASE_API=http://192.168.31.217:9000 VITE_BASE_API=http://192.168.31.51:9000
VITE_I18N_LOCALE=zh-cn VITE_I18N_LOCALE=zh-cn
VITE_I18N_FALLBACK_LOCALE=zh-cn VITE_I18N_FALLBACK_LOCALE=zh-cn

@ -0,0 +1 @@
VITE_BASE_API=http://121.37.12.51

@ -0,0 +1 @@
VITE_BASE_API=http://121.37.12.51

@ -4,6 +4,7 @@
"private": true, "private": true,
"scripts": { "scripts": {
"dev": "vite", "dev": "vite",
"test": "vite build --mode test",
"build": "vite build", "build": "vite build",
"preview": "vite preview", "preview": "vite preview",
"plop": "plop" "plop": "plop"

@ -1,462 +0,0 @@
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 character...": "\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",
"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",
"Alternative description": "\u66ff\u4ee3\u63cf\u8ff0",
"Accessibility": "\u8f85\u52a9\u529f\u80fd",
"Image is decorative": "\u56fe\u50cf\u662f\u88c5\u9970\u6027\u7684",
"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",
"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",
"Open link": "\u6253\u5f00\u94fe\u63a5",
"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",
"The URL you entered seems to be an external link. Do you want to add the required https:\/\/ prefix?": "\u60a8\u8f93\u5165\u7684 URL \u4f3c\u4e4e\u662f\u4e00\u4e2a\u5916\u90e8\u94fe\u63a5\u3002\u60a8\u60f3\u6dfb\u52a0\u6240\u9700\u7684 https:\/\/ \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\u548c\u66ff\u6362",
"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",
"Find in selection": "\u5728\u9009\u533a\u4e2d\u67e5\u627e",
"Spellcheck": "\u62fc\u5199\u68c0\u67e5",
"Spellcheck Language": "\u62fc\u5199\u68c0\u67e5\u8bed\u8a00",
"No misspellings found.": "\u6ca1\u6709\u53d1\u73b0\u62fc\u5199\u9519\u8bef",
"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",
"Caption": "\u6807\u9898",
"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",
"Count": "\u8ba1\u6570",
"Document": "\u6587\u6863",
"Selection": "\u9009\u62e9",
"Words": "\u5355\u8bcd",
"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)",
"{0} characters": "{0} \u4e2a\u5b57\u7b26",
"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",
"Light Green": "\u6d45\u7eff\u8272",
"Light Yellow": "\u6d45\u9ec4\u8272",
"Light Red": "\u6d45\u7ea2\u8272",
"Light Purple": "\u6d45\u7d2b\u8272",
"Light Blue": "\u6d45\u84dd\u8272",
"Dark Purple": "\u6df1\u7d2b\u8272",
"Dark Blue": "\u6df1\u84dd\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",
"Font": "\u5b57\u4f53",
"Size": "\u5b57\u53f7",
"More...": "\u66f4\u591a...",
"Select...": "\u9009\u62e9...",
"Preferences": "\u9996\u9009\u9879",
"Yes": "\u662f",
"No": "\u5426",
"Keyboard Navigation": "\u952e\u76d8\u6307\u5f15",
"Version": "\u7248\u672c",
"Code view": "\u4ee3\u7801\u89c6\u56fe",
"Open popup menu for split buttons": "\u6253\u5f00\u5f39\u51fa\u5f0f\u83dc\u5355\uff0c\u7528\u4e8e\u62c6\u5206\u6309\u94ae",
"List Properties": "\u5217\u8868\u5c5e\u6027",
"List properties...": "\u6807\u9898\u5b57\u4f53\u5c5e\u6027",
"Start list at number": "\u4ee5\u6570\u5b57\u5f00\u59cb\u5217\u8868",
"Line height": "\u884c\u9ad8",
"comments": "\u5907\u6ce8",
"Format Painter": "\u683c\u5f0f\u5237",
"Insert\/edit iframe": "\u63d2\u5165\/\u7f16\u8f91\u6846\u67b6",
"Capitalization": "\u5927\u5199",
"lowercase": "\u5c0f\u5199",
"UPPERCASE": "\u5927\u5199",
"Title Case": "\u9996\u5b57\u6bcd\u5927\u5199",
"permanent pen": "\u8bb0\u53f7\u7b14",
"Permanent Pen Properties": "\u6c38\u4e45\u7b14\u5c5e\u6027",
"Permanent pen properties...": "\u6c38\u4e45\u7b14\u5c5e\u6027...",
"case change": "\u6848\u4f8b\u66f4\u6539",
"page embed": "\u9875\u9762\u5d4c\u5165",
"Advanced sort...": "\u9ad8\u7ea7\u6392\u5e8f...",
"Advanced Sort": "\u9ad8\u7ea7\u6392\u5e8f",
"Sort table by column ascending": "\u6309\u5217\u5347\u5e8f\u8868",
"Sort table by column descending": "\u6309\u5217\u964d\u5e8f\u8868",
"Sort": "\u6392\u5e8f",
"Order": "\u6392\u5e8f",
"Sort by": "\u6392\u5e8f\u65b9\u5f0f",
"Ascending": "\u5347\u5e8f",
"Descending": "\u964d\u5e8f",
"Column {0}": "\u5217{0}",
"Row {0}": "\u884c{0}",
"Spellcheck...": "\u62fc\u5199\u68c0\u67e5...",
"Misspelled word": "\u62fc\u5199\u9519\u8bef\u7684\u5355\u8bcd",
"Suggestions": "\u5efa\u8bae",
"Change": "\u66f4\u6539",
"Finding word suggestions": "\u67e5\u627e\u5355\u8bcd\u5efa\u8bae",
"Success": "\u6210\u529f",
"Repair": "\u4fee\u590d",
"Issue {0} of {1}": "\u5171\u8ba1{1}\u95ee\u9898{0}",
"Images must be marked as decorative or have an alternative text description": "\u56fe\u50cf\u5fc5\u987b\u6807\u8bb0\u4e3a\u88c5\u9970\u6027\u6216\u5177\u6709\u66ff\u4ee3\u6587\u672c\u63cf\u8ff0",
"Images must have an alternative text description. Decorative images are not allowed.": "\u56fe\u50cf\u5fc5\u987b\u5177\u6709\u66ff\u4ee3\u6587\u672c\u63cf\u8ff0\u3002\u4e0d\u5141\u8bb8\u4f7f\u7528\u88c5\u9970\u56fe\u50cf\u3002",
"Or provide alternative text:": "\u6216\u63d0\u4f9b\u5907\u9009\u6587\u672c\uff1a",
"Make image decorative:": "\u4f7f\u56fe\u50cf\u88c5\u9970\uff1a",
"ID attribute must be unique": "ID \u5c5e\u6027\u5fc5\u987b\u662f\u552f\u4e00\u7684",
"Make ID unique": "\u4f7f ID \u72ec\u4e00\u65e0\u4e8c",
"Keep this ID and remove all others": "\u4fdd\u7559\u6b64 ID \u5e76\u5220\u9664\u6240\u6709\u5176\u4ed6",
"Remove this ID": "\u5220\u9664\u6b64 ID",
"Remove all IDs": "\u6e05\u9664\u5168\u90e8IDs",
"Checklist": "\u6e05\u5355",
"Anchor": "\u951a\u70b9",
"Special character": "\u7279\u6b8a\u7b26\u53f7",
"Code sample": "\u4ee3\u7801\u793a\u4f8b",
"Color": "\u989c\u8272",
"Document properties": "\u6587\u6863\u5c5e\u6027",
"Image description": "\u56fe\u7247\u63cf\u8ff0",
"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",
"Insert template": "\u63d2\u5165\u6a21\u677f"
});

@ -1,419 +0,0 @@
tinymce.addI18n('zh_TW',{
"Redo": "\u91cd\u505a",
"Undo": "\u64a4\u92b7",
"Cut": "\u526a\u4e0b",
"Copy": "\u8907\u88fd",
"Paste": "\u8cbc\u4e0a",
"Select all": "\u5168\u9078",
"New document": "\u65b0\u6587\u4ef6",
"Ok": "\u78ba\u5b9a",
"Cancel": "\u53d6\u6d88",
"Visual aids": "\u5c0f\u5e6b\u624b",
"Bold": "\u7c97\u9ad4",
"Italic": "\u659c\u9ad4",
"Underline": "\u4e0b\u5283\u7dda",
"Strikethrough": "\u522a\u9664\u7dda",
"Superscript": "\u4e0a\u6a19",
"Subscript": "\u4e0b\u6a19",
"Clear formatting": "\u6e05\u9664\u683c\u5f0f",
"Align left": "\u5de6\u908a\u5c0d\u9f4a",
"Align center": "\u4e2d\u9593\u5c0d\u9f4a",
"Align right": "\u53f3\u908a\u5c0d\u9f4a",
"Justify": "\u5de6\u53f3\u5c0d\u9f4a",
"Bullet list": "\u9805\u76ee\u6e05\u55ae",
"Numbered list": "\u6578\u5b57\u6e05\u55ae",
"Decrease indent": "\u6e1b\u5c11\u7e2e\u6392",
"Increase indent": "\u589e\u52a0\u7e2e\u6392",
"Close": "\u95dc\u9589",
"Formats": "\u683c\u5f0f",
"Your browser doesn't support direct access to the clipboard. Please use the Ctrl+X\/C\/V keyboard shortcuts instead.": "\u60a8\u7684\u700f\u89bd\u5668\u4e0d\u652f\u63f4\u5b58\u53d6\u526a\u8cbc\u7c3f\uff0c\u53ef\u4ee5\u4f7f\u7528\u5feb\u901f\u9375 Ctrl + X\/C\/V \u4ee3\u66ff\u526a\u4e0b\u3001\u8907\u88fd\u8207\u8cbc\u4e0a\u3002",
"Headers": "\u6a19\u984c",
"Header 1": "\u6a19\u984c 1",
"Header 2": "\u6a19\u984c 2",
"Header 3": "\u6a19\u984c 3",
"Header 4": "\u6a19\u984c 4",
"Header 5": "\u6a19\u984c 5",
"Header 6": "\u6a19\u984c 6",
"Headings": "\u6a19\u984c",
"Heading 1": "\u6a19\u984c1",
"Heading 2": "\u6a19\u984c2",
"Heading 3": "\u6a19\u984c3",
"Heading 4": "\u6a19\u984c4",
"Heading 5": "\u6a19\u984c5",
"Heading 6": "\u6a19\u984c6",
"Preformatted": "\u9810\u5148\u683c\u5f0f\u5316\u7684",
"Div": "Div",
"Pre": "Pre",
"Code": "\u4ee3\u78bc",
"Paragraph": "\u6bb5\u843d",
"Blockquote": "\u5f15\u6587\u5340\u584a",
"Inline": "\u5167\u806f",
"Blocks": "\u57fa\u584a",
"Paste is now in plain text mode. Contents will now be pasted as plain text until you toggle this option off.": "\u76ee\u524d\u5c07\u4ee5\u7d14\u6587\u5b57\u7684\u6a21\u5f0f\u8cbc\u4e0a\uff0c\u60a8\u53ef\u4ee5\u518d\u9ede\u9078\u4e00\u6b21\u53d6\u6d88\u3002",
"Fonts": "\u5b57\u578b",
"Font Sizes": "\u5b57\u578b\u5927\u5c0f",
"Class": "\u985e\u578b",
"Browse for an image": "\u5f9e\u5716\u7247\u4e2d\u700f\u89bd",
"OR": "\u6216",
"Drop an image here": "\u62d6\u66f3\u5716\u7247\u81f3\u6b64",
"Upload": "\u4e0a\u50b3",
"Block": "\u5340\u584a",
"Align": "\u5c0d\u9f4a",
"Default": "\u9810\u8a2d",
"Circle": "\u7a7a\u5fc3\u5713",
"Disc": "\u5be6\u5fc3\u5713",
"Square": "\u6b63\u65b9\u5f62",
"Lower Alpha": "\u5c0f\u5beb\u82f1\u6587\u5b57\u6bcd",
"Lower Greek": "\u5e0c\u81d8\u5b57\u6bcd",
"Lower Roman": "\u5c0f\u5beb\u7f85\u99ac\u6578\u5b57",
"Upper Alpha": "\u5927\u5beb\u82f1\u6587\u5b57\u6bcd",
"Upper Roman": "\u5927\u5beb\u7f85\u99ac\u6578\u5b57",
"Anchor...": "\u9328\u9ede...",
"Name": "\u540d\u7a31",
"Id": "Id",
"Id should start with a letter, followed only by letters, numbers, dashes, dots, colons or underscores.": "Id\u61c9\u4ee5\u5b57\u6bcd\u958b\u982d\uff0c\u5f8c\u9762\u63a5\u8457\u5b57\u6bcd\uff0c\u6578\u5b57\uff0c\u7834\u6298\u865f\uff0c\u9ede\u6578\uff0c\u5192\u865f\u6216\u4e0b\u5283\u7dda\u3002",
"You have unsaved changes are you sure you want to navigate away?": "\u7de8\u8f2f\u5c1a\u672a\u88ab\u5132\u5b58\uff0c\u4f60\u78ba\u5b9a\u8981\u96e2\u958b\uff1f",
"Restore last draft": "\u8f09\u5165\u4e0a\u4e00\u6b21\u7de8\u8f2f\u7684\u8349\u7a3f",
"Special character...": "\u7279\u6b8a\u5b57\u5143......",
"Source code": "\u539f\u59cb\u78bc",
"Insert\/Edit code sample": "\u63d2\u5165\/\u7de8\u8f2f \u7a0b\u5f0f\u78bc\u7bc4\u4f8b",
"Language": "\u8a9e\u8a00",
"Code sample...": "\u7a0b\u5f0f\u78bc\u7bc4\u4f8b...",
"Color Picker": "\u9078\u8272\u5668",
"R": "\u7d05",
"G": "\u7da0",
"B": "\u85cd",
"Left to right": "\u5f9e\u5de6\u5230\u53f3",
"Right to left": "\u5f9e\u53f3\u5230\u5de6",
"Emoticons...": "\u8868\u60c5\u7b26\u865f\u2026",
"Metadata and Document Properties": "\u5f8c\u8a2d\u8cc7\u6599\u8207\u6587\u4ef6\u5c6c\u6027",
"Title": "\u6a19\u984c",
"Keywords": "\u95dc\u9375\u5b57",
"Description": "\u63cf\u8ff0",
"Robots": "\u6a5f\u5668\u4eba",
"Author": "\u4f5c\u8005",
"Encoding": "\u7de8\u78bc",
"Fullscreen": "\u5168\u87a2\u5e55",
"Action": "\u52d5\u4f5c",
"Shortcut": "\u5feb\u901f\u9375",
"Help": "\u5e6b\u52a9",
"Address": "\u5730\u5740",
"Focus to menubar": "\u8df3\u81f3\u9078\u55ae\u5217",
"Focus to toolbar": "\u8df3\u81f3\u5de5\u5177\u5217",
"Focus to element path": "\u8df3\u81f3HTML\u5143\u7d20\u5217",
"Focus to contextual toolbar": "\u8df3\u81f3\u5feb\u6377\u9078\u55ae",
"Insert link (if link plugin activated)": "\u65b0\u589e\u6377\u5f91 (\u6377\u5f91\u5916\u639b\u555f\u7528\u6642)",
"Save (if save plugin activated)": "\u5132\u5b58 (\u5132\u5b58\u5916\u639b\u555f\u7528\u6642)",
"Find (if searchreplace plugin activated)": "\u5c0b\u627e (\u5c0b\u627e\u53d6\u4ee3\u5916\u639b\u555f\u7528\u6642)",
"Plugins installed ({0}):": "({0}) \u500b\u5916\u639b\u5df2\u5b89\u88dd\uff1a",
"Premium plugins:": "\u52a0\u503c\u5916\u639b\uff1a",
"Learn more...": "\u4e86\u89e3\u66f4\u591a...",
"You are using {0}": "\u60a8\u6b63\u5728\u4f7f\u7528 {0}",
"Plugins": "\u5916\u639b",
"Handy Shortcuts": "\u5feb\u901f\u9375",
"Horizontal line": "\u6c34\u5e73\u7dda",
"Insert\/edit image": "\u63d2\u5165\/\u7de8\u8f2f \u5716\u7247",
"Image description": "\u5716\u7247\u63cf\u8ff0",
"Source": "\u5716\u7247\u7db2\u5740",
"Dimensions": "\u5c3a\u5bf8",
"Constrain proportions": "\u7b49\u6bd4\u4f8b\u7e2e\u653e",
"General": "\u4e00\u822c",
"Advanced": "\u9032\u968e",
"Style": "\u6a23\u5f0f",
"Vertical space": "\u9ad8\u5ea6",
"Horizontal space": "\u5bec\u5ea6",
"Border": "\u908a\u6846",
"Insert image": "\u63d2\u5165\u5716\u7247",
"Image...": "\u5716\u7247......",
"Image list": "\u5716\u7247\u6e05\u55ae",
"Rotate counterclockwise": "\u9006\u6642\u91dd\u65cb\u8f49",
"Rotate clockwise": "\u9806\u6642\u91dd\u65cb\u8f49",
"Flip vertically": "\u5782\u76f4\u7ffb\u8f49",
"Flip horizontally": "\u6c34\u5e73\u7ffb\u8f49",
"Edit image": "\u7de8\u8f2f\u5716\u7247",
"Image options": "\u5716\u7247\u9078\u9805",
"Zoom in": "\u653e\u5927",
"Zoom out": "\u7e2e\u5c0f",
"Crop": "\u88c1\u526a",
"Resize": "\u8abf\u6574\u5927\u5c0f",
"Orientation": "\u65b9\u5411",
"Brightness": "\u4eae\u5ea6",
"Sharpen": "\u92b3\u5316",
"Contrast": "\u5c0d\u6bd4",
"Color levels": "\u984f\u8272\u5c64\u6b21",
"Gamma": "\u4f3d\u99ac\u503c",
"Invert": "\u53cd\u8f49",
"Apply": "\u61c9\u7528",
"Back": "\u5f8c\u9000",
"Insert date\/time": "\u63d2\u5165 \u65e5\u671f\/\u6642\u9593",
"Date\/time": "\u65e5\u671f\/\u6642\u9593",
"Insert\/Edit Link": "\u63d2\u5165\/\u7de8\u8f2f\u9023\u7d50",
"Insert\/edit link": "\u63d2\u5165\/\u7de8\u8f2f\u9023\u7d50",
"Text to display": "\u986f\u793a\u6587\u5b57",
"Url": "\u7db2\u5740",
"Open link in...": "\u958b\u555f\u9023\u7d50\u65bc...",
"Current window": "\u76ee\u524d\u8996\u7a97",
"None": "\u7121",
"New window": "\u53e6\u958b\u8996\u7a97",
"Remove link": "\u79fb\u9664\u9023\u7d50",
"Anchors": "\u52a0\u5165\u9328\u9ede",
"Link...": "\u9023\u7d50...",
"Paste or type a link": "\u8cbc\u4e0a\u6216\u8f38\u5165\u9023\u7d50",
"The URL you entered seems to be an email address. Do you want to add the required mailto: prefix?": "\u4f60\u6240\u586b\u5beb\u7684URL\u70ba\u96fb\u5b50\u90f5\u4ef6\uff0c\u9700\u8981\u52a0\u4e0amailto:\u524d\u7db4\u55ce\uff1f",
"The URL you entered seems to be an external link. Do you want to add the required http:\/\/ prefix?": "\u4f60\u6240\u586b\u5beb\u7684URL\u5c6c\u65bc\u5916\u90e8\u93c8\u63a5\uff0c\u9700\u8981\u52a0\u4e0ahttp:\/\/:\u524d\u7db4\u55ce\uff1f",
"Link list": "\u9023\u7d50\u6e05\u55ae",
"Insert video": "\u63d2\u5165\u5f71\u97f3",
"Insert\/edit video": "\u63d2\u4ef6\/\u7de8\u8f2f \u5f71\u97f3",
"Insert\/edit media": "\u63d2\u5165\/\u7de8\u8f2f \u5a92\u9ad4",
"Alternative source": "\u66ff\u4ee3\u5f71\u97f3",
"Alternative source URL": "\u66ff\u4ee3\u4f86\u6e90URL",
"Media poster (Image URL)": "\u5a92\u9ad4\u6d77\u5831\uff08\u5f71\u50cfImage URL\uff09",
"Paste your embed code below:": "\u8acb\u5c07\u60a8\u7684\u5d4c\u5165\u5f0f\u7a0b\u5f0f\u78bc\u8cbc\u5728\u4e0b\u9762:",
"Embed": "\u5d4c\u5165\u78bc",
"Media...": "\u5a92\u9ad4...",
"Nonbreaking space": "\u4e0d\u5206\u884c\u7684\u7a7a\u683c",
"Page break": "\u5206\u9801",
"Paste as text": "\u4ee5\u7d14\u6587\u5b57\u8cbc\u4e0a",
"Preview": "\u9810\u89bd",
"Print...": "\u5217\u5370...",
"Save": "\u5132\u5b58",
"Find": "\u641c\u5c0b",
"Replace with": "\u66f4\u63db",
"Replace": "\u66ff\u63db",
"Replace all": "\u66ff\u63db\u5168\u90e8",
"Previous": "\u4e0a\u4e00\u500b",
"Next": "\u4e0b\u4e00\u500b",
"Find and replace...": "\u5c0b\u627e\u53ca\u53d6\u4ee3...",
"Could not find the specified string.": "\u7121\u6cd5\u67e5\u8a62\u5230\u6b64\u7279\u5b9a\u5b57\u4e32",
"Match case": "\u76f8\u5339\u914d\u6848\u4ef6",
"Find whole words only": "\u50c5\u627e\u51fa\u5b8c\u6574\u5b57\u532f",
"Spell check": "\u62fc\u5beb\u6aa2\u67e5",
"Ignore": "\u5ffd\u7565",
"Ignore all": "\u5ffd\u7565\u6240\u6709",
"Finish": "\u5b8c\u6210",
"Add to Dictionary": "\u52a0\u5165\u5b57\u5178\u4e2d",
"Insert table": "\u63d2\u5165\u8868\u683c",
"Table properties": "\u8868\u683c\u5c6c\u6027",
"Delete table": "\u522a\u9664\u8868\u683c",
"Cell": "\u5132\u5b58\u683c",
"Row": "\u5217",
"Column": "\u884c",
"Cell properties": "\u5132\u5b58\u683c\u5c6c\u6027",
"Merge cells": "\u5408\u4f75\u5132\u5b58\u683c",
"Split cell": "\u5206\u5272\u5132\u5b58\u683c",
"Insert row before": "\u63d2\u5165\u5217\u5728...\u4e4b\u524d",
"Insert row after": "\u63d2\u5165\u5217\u5728...\u4e4b\u5f8c",
"Delete row": "\u522a\u9664\u5217",
"Row properties": "\u5217\u5c6c\u6027",
"Cut row": "\u526a\u4e0b\u5217",
"Copy row": "\u8907\u88fd\u5217",
"Paste row before": "\u8cbc\u4e0a\u5217\u5728...\u4e4b\u524d",
"Paste row after": "\u8cbc\u4e0a\u5217\u5728...\u4e4b\u5f8c",
"Insert column before": "\u63d2\u5165\u6b04\u4f4d\u5728...\u4e4b\u524d",
"Insert column after": "\u63d2\u5165\u6b04\u4f4d\u5728...\u4e4b\u5f8c",
"Delete column": "\u522a\u9664\u884c",
"Cols": "\u6b04\u4f4d\u6bb5",
"Rows": "\u5217",
"Width": "\u5bec\u5ea6",
"Height": "\u9ad8\u5ea6",
"Cell spacing": "\u5132\u5b58\u683c\u5f97\u9593\u8ddd",
"Cell padding": "\u5132\u5b58\u683c\u7684\u908a\u8ddd",
"Show caption": "\u986f\u793a\u6a19\u984c",
"Left": "\u5de6\u908a",
"Center": "\u4e2d\u9593",
"Right": "\u53f3\u908a",
"Cell type": "\u5132\u5b58\u683c\u7684\u985e\u578b",
"Scope": "\u7bc4\u570d",
"Alignment": "\u5c0d\u9f4a",
"H Align": "\u6c34\u5e73\u4f4d\u7f6e",
"V Align": "\u5782\u76f4\u4f4d\u7f6e",
"Top": "\u7f6e\u9802",
"Middle": "\u7f6e\u4e2d",
"Bottom": "\u7f6e\u5e95",
"Header cell": "\u6a19\u982d\u5132\u5b58\u683c",
"Row group": "\u5217\u7fa4\u7d44",
"Column group": "\u6b04\u4f4d\u7fa4\u7d44",
"Row type": "\u884c\u7684\u985e\u578b",
"Header": "\u6a19\u982d",
"Body": "\u4e3b\u9ad4",
"Footer": "\u9801\u5c3e",
"Border color": "\u908a\u6846\u984f\u8272",
"Insert template...": "\u63d2\u5165\u6a23\u7248...",
"Templates": "\u6a23\u7248",
"Template": "\u6a23\u677f",
"Text color": "\u6587\u5b57\u984f\u8272",
"Background color": "\u80cc\u666f\u984f\u8272",
"Custom...": "\u81ea\u8a02",
"Custom color": "\u81ea\u8a02\u984f\u8272",
"No color": "No color",
"Remove color": "\u79fb\u9664\u984f\u8272",
"Table of Contents": "\u76ee\u9304",
"Show blocks": "\u986f\u793a\u5340\u584a\u8cc7\u8a0a",
"Show invisible characters": "\u986f\u793a\u96b1\u85cf\u5b57\u5143",
"Word count": "\u8a08\u7b97\u5b57\u6578",
"Count": "\u8a08\u7b97",
"Document": "\u6587\u4ef6",
"Selection": "\u9078\u9805",
"Words": "\u5b57\u6578",
"Words: {0}": "\u5b57\u6578\uff1a{0}",
"{0} words": "{0} \u5b57\u5143",
"File": "\u6a94\u6848",
"Edit": "\u7de8\u8f2f",
"Insert": "\u63d2\u5165",
"View": "\u6aa2\u8996",
"Format": "\u683c\u5f0f",
"Table": "\u8868\u683c",
"Tools": "\u5de5\u5177",
"Powered by {0}": "\u7531 {0} \u63d0\u4f9b",
"Rich Text Area. Press ALT-F9 for menu. Press ALT-F10 for toolbar. Press ALT-0 for help": "\u8c50\u5bcc\u7684\u6587\u672c\u5340\u57df\u3002\u6309ALT-F9\u524d\u5f80\u4e3b\u9078\u55ae\u3002\u6309ALT-F10\u547c\u53eb\u5de5\u5177\u6b04\u3002\u6309ALT-0\u5c0b\u6c42\u5e6b\u52a9",
"Image title": "\u5716\u7247\u6a19\u984c",
"Border width": "\u6846\u7dda\u5bec\u5ea6",
"Border style": "\u6846\u7dda\u6a23\u5f0f",
"Error": "\u932f\u8aa4",
"Warn": "\u8b66\u544a",
"Valid": "\u6709\u6548",
"To open the popup, press Shift+Enter": "\u8981\u958b\u555f\u5f48\u51fa\u8996\u7a97\uff0c\u8acb\u6309Shift+Enter",
"Rich Text Area. Press ALT-0 for help.": "\u5bcc\u6587\u672c\u5340\u57df\u3002\u8acb\u6309ALT-0\u5c0b\u6c42\u5354\u52a9\u3002",
"System Font": "\u7cfb\u7d71\u5b57\u578b",
"Failed to upload image: {0}": "\u7121\u6cd5\u4e0a\u50b3\u5f71\u50cf\uff1a{0}",
"Failed to load plugin: {0} from url {1}": "\u7121\u6cd5\u4e0a\u50b3\u63d2\u4ef6\uff1a{0}\u81eaurl{1}",
"Failed to load plugin url: {0}": "\u7121\u6cd5\u4e0a\u50b3\u63d2\u4ef6\uff1a{0}",
"Failed to initialize plugin: {0}": "\u7121\u6cd5\u555f\u52d5\u63d2\u4ef6\uff1a{0}",
"example": "\u7bc4\u4f8b",
"Search": "\u641c\u7d22",
"All": "\u5168\u90e8",
"Currency": "\u8ca8\u5e63",
"Text": "\u6587\u672c",
"Quotations": "\u5f15\u7528",
"Mathematical": "\u6578\u5b78",
"Extended Latin": "\u62c9\u4e01\u5b57\u6bcd\u64f4\u5145",
"Symbols": "\u7b26\u865f",
"Arrows": "\u7bad\u982d",
"User Defined": "\u4f7f\u7528\u8005\u5df2\u5b9a\u7fa9",
"dollar sign": "\u7f8e\u5143\u7b26\u865f",
"currency sign": "\u8ca8\u5e63\u7b26\u865f",
"euro-currency sign": "\u6b50\u5143\u7b26\u865f",
"colon sign": "\u79d1\u6717\u7b26\u865f",
"cruzeiro sign": "\u514b\u9b6f\u8cfd\u7f85\u7b26\u865f",
"french franc sign": "\u6cd5\u6717\u7b26\u865f",
"lira sign": "\u91cc\u62c9\u7b26\u865f",
"mill sign": "\u6587\u7b26\u865f",
"naira sign": "\u5948\u62c9\u7b26\u865f",
"peseta sign": "\u6bd4\u585e\u5854\u7b26\u865f",
"rupee sign": "\u76e7\u6bd4\u7b26\u865f",
"won sign": "\u97d3\u571c\u7b26\u865f",
"new sheqel sign": "\u65b0\u8b1d\u514b\u723e\u7b26\u865f",
"dong sign": "\u8d8a\u5357\u76fe\u7b26\u865f",
"kip sign": "\u8001\u64be\u5e63\u7b26\u865f",
"tugrik sign": "\u8499\u53e4\u5e63\u7b26\u865f",
"drachma sign": "\u5fb7\u514b\u62c9\u99ac\u7b26\u865f",
"german penny symbol": "\u5fb7\u570b\u5206\u7b26\u865f",
"peso sign": "\u62ab\u7d22\u7b26\u865f",
"guarani sign": "\u5df4\u62c9\u572d\u5e63\u7b26\u865f",
"austral sign": "\u963f\u6839\u5ef7\u5e63\u7b26\u865f",
"hryvnia sign": "\u70cf\u514b\u862d\u5e63\u7b26\u865f",
"cedi sign": "\u8fe6\u7d0d\u5e63\u7b26\u865f",
"livre tournois sign": "\u91cc\u5f17\u723e\u7b26\u865f",
"spesmilo sign": "\u570b\u969b\u5e63\u7b26\u865f",
"tenge sign": "\u54c8\u85a9\u514b\u5e63\u7b26\u865f",
"indian rupee sign": "\u5370\u5ea6\u76e7\u6bd4\u7b26\u865f",
"turkish lira sign": "\u571f\u8033\u5176\u91cc\u62c9\u7b26\u865f",
"nordic mark sign": "\u5317\u6b50\u99ac\u514b\u7b26\u865f",
"manat sign": "\u4e9e\u585e\u62dc\u7136\u5e63\u7b26\u865f",
"ruble sign": "\u76e7\u5e03\u7b26\u865f",
"yen character": "\u65e5\u5713\u7b26\u865f",
"yuan character": "\u4eba\u6c11\u5e63\u7b26\u865f",
"yuan character, in hong kong and taiwan": "\u6e2f\u5143\u8207\u53f0\u5e63\u7b26\u865f",
"yen\/yuan character variant one": "\u65e5\u5713\/\u4eba\u6c11\u5e63\u7b26\u865f\u8b8a\u5316\u578b",
"Loading emoticons...": "\u8f09\u5165\u8868\u60c5\u7b26\u865f\u2026",
"Could not load emoticons": "\u7121\u6cd5\u8f09\u5165\u8868\u60c5\u7b26\u865f",
"People": "\u4eba",
"Animals and Nature": "\u52d5\u7269\u8207\u81ea\u7136",
"Food and Drink": "\u98f2\u98df",
"Activity": "\u6d3b\u52d5",
"Travel and Places": "\u65c5\u884c\u8207\u5730\u9ede",
"Objects": "\u7269\u4ef6",
"Flags": "\u65d7\u6a19",
"Characters": "\u5b57\u5143",
"Characters (no spaces)": "\u5b57\u5143\uff08\u7121\u7a7a\u683c\uff09",
"{0} characters": "{0}\u5b57\u5143",
"Error: Form submit field collision.": "\u932f\u8aa4\uff1a\u8868\u683c\u905e\u4ea4\u6b04\u4f4d\u885d\u7a81\u3002",
"Error: No form element found.": "\u932f\u8aa4\uff1a\u627e\u4e0d\u5230\u8868\u683c\u5143\u7d20\u3002",
"Update": "\u66f4\u65b0",
"Color swatch": "\u8272\u5f69\u6a23\u672c",
"Turquoise": "\u571f\u8033\u5176\u85cd",
"Green": "\u7da0\u8272",
"Blue": "\u85cd\u8272",
"Purple": "\u7d2b\u8272",
"Navy Blue": "\u6df1\u85cd\u8272",
"Dark Turquoise": "\u6df1\u571f\u8033\u5176\u85cd",
"Dark Green": "\u6df1\u7da0\u8272",
"Medium Blue": "\u4e2d\u85cd\u8272",
"Medium Purple": "\u4e2d\u7d2b\u8272",
"Midnight Blue": "\u9ed1\u85cd\u8272",
"Yellow": "\u9ec3\u8272",
"Orange": "\u6a59\u8272",
"Red": "\u7d05\u8272",
"Light Gray": "\u6dfa\u7070\u8272",
"Gray": "\u7070\u8272",
"Dark Yellow": "\u6df1\u9ec3\u8272",
"Dark Orange": "\u6df1\u6a59\u8272",
"Dark Red": "\u6697\u7d05\u8272",
"Medium Gray": "\u4e2d\u7070\u8272",
"Dark Gray": "\u6df1\u7070\u8272",
"Light Green": "\u6de1\u7da0\u8272",
"Light Yellow": "\u6dfa\u9ec3\u8272",
"Light Red": "\u6dfa\u7d05\u8272",
"Light Purple": "\u6dfa\u7d2b\u8272",
"Light Blue": "\u6dfa\u85cd\u8272",
"Dark Purple": "\u6df1\u7d2b\u8272",
"Dark Blue": "\u6df1\u85cd\u8272",
"Black": "\u9ed1\u8272",
"White": "\u767d\u8272",
"Switch to or from fullscreen mode": "\u8f49\u63db\u81ea\/\u81f3\u5168\u87a2\u5e55\u6a21\u5f0f",
"Open help dialog": "\u958b\u555f\u5354\u52a9\u5c0d\u8a71",
"history": "\u6b77\u53f2",
"styles": "\u6a23\u5f0f",
"formatting": "\u683c\u5f0f",
"alignment": "\u5c0d\u9f4a",
"indentation": "\u7e2e\u6392",
"permanent pen": "\u6c38\u4e45\u6027\u7b46",
"comments": "\u8a3b\u89e3",
"Format Painter": "\u8907\u88fd\u683c\u5f0f",
"Insert\/edit iframe": "\u63d2\u5165\/\u7de8\u8f2fiframe",
"Capitalization": "\u5927\u5beb",
"lowercase": "\u5c0f\u5beb",
"UPPERCASE": "\u5927\u5beb",
"Title Case": "\u5b57\u9996\u5927\u5beb",
"Permanent Pen Properties": "\u6c38\u4e45\u6a19\u8a18\u5c6c\u6027",
"Permanent pen properties...": "\u6c38\u4e45\u6a19\u8a18\u5c6c\u6027......",
"Font": "\u5b57\u578b",
"Size": "\u5b57\u5f62\u5927\u5c0f",
"More...": "\u66f4\u591a\u8cc7\u8a0a......",
"Spellcheck Language": "\u62fc\u5beb\u8a9e\u8a00",
"Select...": "\u9078\u64c7......",
"Preferences": "\u9996\u9078\u9805",
"Yes": "\u662f",
"No": "\u5426",
"Keyboard Navigation": "\u9375\u76e4\u5c0e\u822a",
"Version": "\u7248\u672c",
"Anchor": "\u52a0\u5165\u9328\u9ede",
"Special character": "\u7279\u6b8a\u5b57\u5143",
"Code sample": "\u7a0b\u5f0f\u78bc\u7bc4\u4f8b",
"Color": "\u984f\u8272",
"Emoticons": "\u8868\u60c5",
"Document properties": "\u6587\u4ef6\u7684\u5c6c\u6027",
"Image": "\u5716\u7247",
"Insert link": "\u63d2\u5165\u9023\u7d50",
"Target": "\u958b\u555f\u65b9\u5f0f",
"Link": "\u9023\u7d50",
"Poster": "\u9810\u89bd\u5716\u7247",
"Media": "\u5a92\u9ad4",
"Print": "\u5217\u5370",
"Prev": "\u4e0a\u4e00\u500b",
"Find and replace": "\u5c0b\u627e\u53ca\u53d6\u4ee3",
"Whole words": "\u6574\u500b\u55ae\u5b57",
"Spellcheck": "\u62fc\u5b57\u6aa2\u67e5",
"Caption": "\u8868\u683c\u6a19\u984c",
"Insert template": "\u63d2\u5165\u6a23\u7248"
});

@ -1,7 +0,0 @@
/**
* 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{background-color:#2f3742;color:#dfe0e4;font-family:-apple-system,BlinkMacSystemFont,'Segoe UI',Roboto,Oxygen,Ubuntu,Cantarell,'Open Sans','Helvetica Neue',sans-serif;line-height:1.4;margin:1rem}a{color:#4099ff}table{border-collapse:collapse}table:not([cellpadding]) td,table:not([cellpadding]) th{padding:.4rem}table[border]:not([border="0"]):not([style*=border-width]) td,table[border]:not([border="0"]):not([style*=border-width]) th{border-width:1px}table[border]:not([border="0"]):not([style*=border-style]) td,table[border]:not([border="0"]):not([style*=border-style]) th{border-style:solid}table[border]:not([border="0"]):not([style*=border-color]) td,table[border]:not([border="0"]):not([style*=border-color]) th{border-color:#6d737b}figure{display:table;margin:1rem auto}figure figcaption{color:#8a8f97;display:block;margin-top:.25rem;text-align:center}hr{border-color:#6d737b;border-style:solid;border-width:1px 0 0 0}code{background-color:#6d737b;border-radius:3px;padding:.1rem .2rem}.mce-content-body:not([dir=rtl]) blockquote{border-left:2px solid #6d737b;margin-left:1.5rem;padding-left:1rem}.mce-content-body[dir=rtl] blockquote{border-right:2px solid #6d737b;margin-right:1.5rem;padding-right:1rem}

@ -1,7 +0,0 @@
/**
* 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:not([cellpadding]) td,table:not([cellpadding]) th{padding:.4rem}table[border]:not([border="0"]):not([style*=border-width]) td,table[border]:not([border="0"]):not([style*=border-width]) th{border-width:1px}table[border]:not([border="0"]):not([style*=border-style]) td,table[border]:not([border="0"]):not([style*=border-style]) th{border-style:solid}table[border]:not([border="0"]):not([style*=border-color]) td,table[border]:not([border="0"]):not([style*=border-color]) th{border-color:#ccc}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}

@ -1,7 +0,0 @@
/**
* 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/
*/
@media screen{html{background:#f4f4f4;min-height:100%}}body{font-family:-apple-system,BlinkMacSystemFont,'Segoe UI',Roboto,Oxygen,Ubuntu,Cantarell,'Open Sans','Helvetica Neue',sans-serif}@media screen{body{background-color:#fff;box-shadow:0 0 4px rgba(0,0,0,.15);box-sizing:border-box;margin:1rem auto 0;max-width:820px;min-height:calc(100vh - 1rem);padding:4rem 6rem 6rem 6rem}}table{border-collapse:collapse}table:not([cellpadding]) td,table:not([cellpadding]) th{padding:.4rem}table[border]:not([border="0"]):not([style*=border-width]) td,table[border]:not([border="0"]):not([style*=border-width]) th{border-width:1px}table[border]:not([border="0"]):not([style*=border-style]) td,table[border]:not([border="0"]):not([style*=border-style]) th{border-style:solid}table[border]:not([border="0"]):not([style*=border-color]) td,table[border]:not([border="0"]):not([style*=border-color]) th{border-color:#ccc}figure figcaption{color:#999;margin-top:.25rem;text-align:center}hr{border-color:#ccc;border-style:solid;border-width:1px 0 0 0}.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}

@ -1,7 +0,0 @@
/**
* 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 auto;max-width:900px}table{border-collapse:collapse}table:not([cellpadding]) td,table:not([cellpadding]) th{padding:.4rem}table[border]:not([border="0"]):not([style*=border-width]) td,table[border]:not([border="0"]):not([style*=border-width]) th{border-width:1px}table[border]:not([border="0"]):not([style*=border-style]) td,table[border]:not([border="0"]):not([style*=border-style]) th{border-style:solid}table[border]:not([border="0"]):not([style*=border-color]) td,table[border]:not([border="0"]):not([style*=border-color]) th{border-color:#ccc}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}

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

@ -1,7 +0,0 @@
/**
* 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/
*/
.tinymce-mobile-unfocused-selections .tinymce-mobile-unfocused-selection{background-color:green;display:inline-block;opacity:.5;position:absolute}body{-webkit-text-size-adjust:none}body img{max-width:96vw}body table img{max-width:95%}body{font-family:sans-serif}table{border-collapse:collapse}

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

@ -1,7 +0,0 @@
/**
* 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.tox-dialog__disable-scroll{overflow:hidden}.tox-fullscreen{border:0;height:100%;left:0;margin:0;overflow:hidden;-ms-scroll-chaining:none;overscroll-behavior:none;padding:0;position:fixed;top:0;touch-action:pinch-zoom;width:100%}.tox.tox-tinymce.tox-fullscreen .tox-statusbar__resize-handle{display:none}.tox.tox-tinymce.tox-fullscreen{background-color:transparent;z-index:1200}.tox-shadowhost.tox-fullscreen{z-index:1200}.tox-fullscreen .tox.tox-tinymce-aux,.tox-fullscreen~.tox.tox-tinymce-aux{z-index:1201}

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

@ -1,7 +0,0 @@
/**
* 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/
*/
.tinymce-mobile-unfocused-selections .tinymce-mobile-unfocused-selection{background-color:green;display:inline-block;opacity:.5;position:absolute}body{-webkit-text-size-adjust:none}body img{max-width:96vw}body table img{max-width:95%}body{font-family:sans-serif}table{border-collapse:collapse}

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

@ -1,7 +0,0 @@
/**
* 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.tox-dialog__disable-scroll{overflow:hidden}.tox-fullscreen{border:0;height:100%;left:0;margin:0;overflow:hidden;-ms-scroll-chaining:none;overscroll-behavior:none;padding:0;position:fixed;top:0;touch-action:pinch-zoom;width:100%}.tox.tox-tinymce.tox-fullscreen .tox-statusbar__resize-handle{display:none}.tox.tox-tinymce.tox-fullscreen{background-color:transparent;z-index:1200}.tox-shadowhost.tox-fullscreen{z-index:1200}.tox-fullscreen .tox.tox-tinymce-aux,.tox-fullscreen~.tox.tox-tinymce-aux{z-index:1201}

@ -0,0 +1,5 @@
import axios from '@/utils/request';
export const systemBuyerAdd = async (data: Record<string, any>): Promise<any> => (await axios.post('/product/systemBuyer/add', data)).data;
export const systemBuyerFind = async (): Promise<any> => (await axios.post('/product/systemBuyer/details')).data;
export const systemBuyerUpdate = async (data: Record<string, any>): Promise<any> => (await axios.post('/product/systemBuyer/update', data)).data;

@ -1,30 +0,0 @@
import axios from '@/utils/request';
export const queryChannelList = async (params?: Record<string, any>): Promise<any> => (await axios.get('/backend/core/channel', { params })).data;
export const queryChannel = async (id: number): Promise<any> => (await axios.get(`/backend/core/channel/${id}`)).data;
export const createChannel = async (data: Record<string, any>): Promise<any> => (await axios.post('/backend/core/channel', data)).data;
export const updateChannel = async (data: Record<string, any>): Promise<any> => (await axios.post('/backend/core/channel?_method=put', data)).data;
export const updateChannelOrder = async (data: number[]): Promise<any> => (await axios.post('/backend/core/channel/order?_method=put', data)).data;
export const deleteChannel = async (data: number[]): Promise<any> => (await axios.post('/backend/core/channel?_method=delete', data)).data;
export const queryChannelTemplates = async (): Promise<any> => (await axios.get('/backend/core/channel/channel-templates')).data;
export const queryArticleTemplates = async (): Promise<any> => (await axios.get('/backend/core/channel/article-templates')).data;
export const queryArticlePage = async (params?: Record<string, any>): Promise<any> => (await axios.get('/backend/core/article', { params })).data;
export const queryArticle = async (id: number): Promise<any> => (await axios.get(`/backend/core/article/${id}`)).data;
export const createArticle = async (data: Record<string, any>): Promise<any> => (await axios.post('/backend/core/article', data)).data;
export const updateArticle = async (data: Record<string, any>): Promise<any> => (await axios.post('/backend/core/article?_method=put', data)).data;
export const deleteArticle = async (data: number[]): Promise<any> => (await axios.post('/backend/core/article?_method=delete', data)).data;
export const queryBlockItemList = async (params?: Record<string, any>): Promise<any> => (await axios.get('/backend/core/block-item', { params })).data;
export const queryBlockItem = async (id: number): Promise<any> => (await axios.get(`/backend/core/block-item/${id}`)).data;
export const createBlockItem = async (data: Record<string, any>): Promise<any> => (await axios.post('/backend/core/block-item', data)).data;
export const updateBlockItem = async (data: Record<string, any>): Promise<any> => (await axios.post('/backend/core/block-item?_method=put', data)).data;
export const updateBlockItemOrder = async (data: number[]): Promise<any> => (await axios.post('/backend/core/block-item/order?_method=put', data)).data;
export const deleteBlockItem = async (data: number[]): Promise<any> => (await axios.post('/backend/core/block-item?_method=delete', data)).data;
export const fulltextReindexAll = async (): Promise<any> => (await axios.post('/backend/core/generator/fulltext-reindex-all')).data;
export const fulltextReindexSite = async (): Promise<any> => (await axios.post('/backend/core/generator/fulltext-reindex-site')).data;
export const htmlAll = async (): Promise<any> => (await axios.post('/backend/core/generator/html-all')).data;
export const htmlHome = async (): Promise<any> => (await axios.post('/backend/core/generator/html-home')).data;
export const htmlChannel = async (): Promise<any> => (await axios.post('/backend/core/generator/html-channel')).data;
export const htmlArticle = async (): Promise<any> => (await axios.post('/backend/core/generator/html-article')).data;

@ -11,7 +11,7 @@
</div> </div>
</template> </template>
<script setup lang="ts"> <script setup lang="ts">
import { defineProps, PropType, ref } from 'vue'; import { PropType, ref } from 'vue';
defineProps({ defineProps({
name: { type: String, required: true }, name: { type: String, required: true },

@ -1,12 +1,12 @@
<template> <template>
{{ label ?? $t(message) }} {{ label ?? $t(message) }}
<el-tooltip :content="tooltip ?? $t(message + '.tooltip')" placement="top"> <el-tooltip :content="tooltip ?? $t(message + '.tooltip')"
placement="top">
<el-icon class="text-base align-text-top"><question-filled /></el-icon> <el-icon class="text-base align-text-top"><question-filled /></el-icon>
</el-tooltip> </el-tooltip>
</template> </template>
<script setup lang="ts"> <script setup lang="ts">
import { defineProps } from 'vue';
import { QuestionFilled } from '@element-plus/icons-vue'; import { QuestionFilled } from '@element-plus/icons-vue';
defineProps({ defineProps({

@ -1,14 +1,21 @@
<template> <template>
<el-button-group> <el-button-group>
<el-button :disabled="disabled" :icon="Top" @click="$emit('move', 'top')">{{ $t('moveTop') }}</el-button> <el-button :disabled="disabled"
<el-button :disabled="disabled" :icon="ArrowUp" @click="$emit('move', 'up')">{{ $t('moveUp') }}</el-button> :icon="Top"
<el-button :disabled="disabled" :icon="ArrowDown" @click="$emit('move', 'down')">{{ $t('moveDown') }}</el-button> @click="$emit('move', 'top')">{{ $t('moveTop') }}</el-button>
<el-button :disabled="disabled" :icon="Bottom" @click="$emit('move', 'bottom')">{{ $t('moveBottom') }}</el-button> <el-button :disabled="disabled"
:icon="ArrowUp"
@click="$emit('move', 'up')">{{ $t('moveUp') }}</el-button>
<el-button :disabled="disabled"
:icon="ArrowDown"
@click="$emit('move', 'down')">{{ $t('moveDown') }}</el-button>
<el-button :disabled="disabled"
:icon="Bottom"
@click="$emit('move', 'bottom')">{{ $t('moveBottom') }}</el-button>
</el-button-group> </el-button-group>
</template> </template>
<script setup lang="ts"> <script setup lang="ts">
import { defineProps, defineEmits } from 'vue';
import { Top, Bottom, ArrowUp, ArrowDown } from '@element-plus/icons-vue'; import { Top, Bottom, ArrowUp, ArrowDown } from '@element-plus/icons-vue';
defineProps({ defineProps({

@ -19,7 +19,7 @@
</template> </template>
<script setup lang="ts"> <script setup lang="ts">
import { defineProps, defineEmits, useSlots, provide, computed, ref, toRefs } from 'vue'; import { defineEmits, useSlots, provide, computed, ref, toRefs } from 'vue';
import { Plus, Minus, Search, Refresh } from '@element-plus/icons-vue'; import { Plus, Minus, Search, Refresh } from '@element-plus/icons-vue';
import QueryInput from './QueryInput.vue'; import QueryInput from './QueryInput.vue';

@ -1,25 +1,26 @@
<template> <template>
<slot> <slot>
<div v-if="type === 'number'" class="inline-block"> <div v-if="type === 'number'"
<el-input-number v-model="params[first]" :placeholder="$t('begin.number')" class="w-48"></el-input-number> class="inline-block">
<el-input-number v-model="params[second]" :placeholder="$t('end.number')" class="w-48"></el-input-number> <el-input-number v-model="params[first]"
:placeholder="$t('begin.number')"
class="w-48"></el-input-number>
<el-input-number v-model="params[second]"
:placeholder="$t('end.number')"
class="w-48"></el-input-number>
</div> </div>
<el-date-picker <el-date-picker v-else-if="type === 'date'"
v-else-if="type === 'date'" v-model="params[name]"
v-model="params[name]" type="daterange"
type="daterange" :start-placeholder="$t('begin.date')"
:start-placeholder="$t('begin.date')" :end-placeholder="$t('end.date')"
:end-placeholder="$t('end.date')" class="w-96"></el-date-picker>
class="w-96" <el-date-picker v-else-if="type === 'datetime'"
></el-date-picker> v-model="params[name]"
<el-date-picker type="datetimerange"
v-else-if="type === 'datetime'" :start-placeholder="$t('begin.date')"
v-model="params[name]" :end-placeholder="$t('end.date')"
type="datetimerange" class="w-96">
:start-placeholder="$t('begin.date')"
:end-placeholder="$t('end.date')"
class="w-96"
>
</el-date-picker> </el-date-picker>
<!-- <!--
<div v-else-if="type === 'date'" class="inline-block"> <div v-else-if="type === 'date'" class="inline-block">
@ -31,14 +32,22 @@
<el-date-picker v-model="params[second]" type="datetime" class="w-48"></el-date-picker> <el-date-picker v-model="params[second]" type="datetime" class="w-48"></el-date-picker>
</div> </div>
--> -->
<el-select v-else-if="options" v-model="params[name]" multiple class="w-96"> <el-select v-else-if="options"
<el-option v-for="item in options" :key="item.value" :label="item.label" :value="item.value"></el-option> v-model="params[name]"
multiple
class="w-96">
<el-option v-for="item in options"
:key="item.value"
:label="item.label"
:value="item.value"></el-option>
</el-select> </el-select>
<el-input v-else v-model="params[name]" class="w-96"></el-input> <el-input v-else
v-model="params[name]"
class="w-96"></el-input>
</slot> </slot>
</template> </template>
<script setup lang="ts"> <script setup lang="ts">
import { inject, defineProps, PropType, ref, toRefs } from 'vue'; import { inject, PropType, ref, toRefs } from 'vue';
const props = defineProps({ const props = defineProps({
label: { type: String, required: true }, label: { type: String, required: true },

@ -3,7 +3,7 @@
<input type="text" <input type="text"
placeholder="搜索" placeholder="搜索"
maxlength="20" maxlength="20"
v-model="modelValue" /> v-model="val" />
<img src="@/assets/images/search.png" <img src="@/assets/images/search.png"
alt="" alt=""
class="icon" /> class="icon" />
@ -11,22 +11,35 @@
</template> </template>
<script setup lang="ts"> <script setup lang="ts">
import { watch, toRef, ref } from 'vue'; import { watch, computed, ref } from 'vue';
const props = defineProps({ const props = defineProps({
modelValue: { type: String, required: true }, modelValue: { type: String, default: '' },
}); });
const timer = ref<any>(null); const timer = ref<any>(null);
const emit = defineEmits({ 'update:modelValue': null }); const emit = defineEmits({ 'update:modelValue': null });
watch( const val = computed({
() => props.modelValue, get: () => props.modelValue,
(prop: val) => { set: (value) => {
clearTimeout(timer.value); clearTimeout(timer.value);
timer.value = setTimeout(() => { timer.value = setTimeout(() => {
emit('update:modelValue', prop); emit('update:modelValue', value);
}, 500); }, 500);
// emit('update:modelValue', value)
}, },
); });
// watch(
// () => props.modelValue,
// (val) => {
// clearTimeout(timer.value);
// timer.value = setTimeout(() => {
// emit('update:modelValue', val);
// }, 500);
// },
// {
// deep: true,
// },
// );
</script> </script>
<style lang="scss" scoped> <style lang="scss" scoped>

@ -1,14 +1,22 @@
<template> <template>
<el-dropdown class="align-middle" trigger="click" :hide-on-click="false"> <el-dropdown class="align-middle"
<el-tooltip :content="$t('table.columnsSetting')" placement="top"> trigger="click"
<el-icon class="text-base"><setting /></el-icon> :hide-on-click="false">
<el-tooltip :content="$t('table.columnsSetting')"
placement="top">
<el-icon class="text-base">
<setting />
</el-icon>
</el-tooltip> </el-tooltip>
<template #dropdown> <template #dropdown>
<el-dropdown-menu> <el-dropdown-menu>
<el-dropdown-item> <el-dropdown-item>
<el-button @click="resetColumns" type="text">{{ $t('table.columnsReset') }}</el-button> <el-button @click="resetColumns"
type="text">{{ $t('table.columnsReset') }}</el-button>
</el-dropdown-item> </el-dropdown-item>
<el-dropdown-item v-for="(column, index) in settings" :key="column.title" :divided="index === 0"> <el-dropdown-item v-for="(column, index) in settings"
:key="column.title"
:divided="index === 0">
<el-checkbox v-model="column.display">{{ column.title }}</el-checkbox> <el-checkbox v-model="column.display">{{ column.title }}</el-checkbox>
</el-dropdown-item> </el-dropdown-item>
</el-dropdown-menu> </el-dropdown-menu>
@ -17,7 +25,7 @@
</template> </template>
<script setup lang="ts"> <script setup lang="ts">
import { defineProps, toRefs, watch } from 'vue'; import { toRefs, watch } from 'vue';
import { Setting } from '@element-plus/icons-vue'; import { Setting } from '@element-plus/icons-vue';
import { getColumnOrigins, getColumnSettings, mergeColumns, storeColumnSettings } from './useColumns'; import { getColumnOrigins, getColumnSettings, mergeColumns, storeColumnSettings } from './useColumns';

@ -1,53 +1,82 @@
<template> <template>
<div class="w-full"> <div class="w-full">
<el-upload <el-upload :action="fileUploadUrl"
:action="fileUploadUrl" :headers="{ ...getAuthHeaders(), ...getSiteHeaders() }"
:headers="{ ...getAuthHeaders(), ...getSiteHeaders() }" :accept="accept"
:accept="accept" :before-upload="beforeUpload"
:before-upload="beforeUpload" :on-success="(res) => fileList.push({ name: res.name, url: res.url, length: res.size })"
:on-success="(res) => fileList.push({ name: res.name, url: res.url, length: res.size })" :on-progress="(event, file) => (progressFile = file)"
:on-progress="(event, file) => (progressFile = file)" :show-file-list="false"
:show-file-list="false" multiple>
multiple
>
<!-- <!--
action="https://jsonplaceholder.typicode.com/posts/" action="https://jsonplaceholder.typicode.com/posts/"
--> -->
<el-button type="primary">{{ $t('clickToUpload') }}</el-button> <el-button type="primary">{{ $t('clickToUpload') }}</el-button>
</el-upload> </el-upload>
<el-progress v-if="progressFile.status === 'uploading'" :percentage="parseInt(progressFile.percentage, 10)"></el-progress> <el-progress v-if="progressFile.status === 'uploading'"
<transition-group tag="ul" :class="['el-upload-list', 'el-upload-list--text', { 'is-disabled': disabled }]" name="el-list"> :percentage="parseInt(progressFile.percentage, 10)"></el-progress>
<li v-for="file in fileList" :key="file.url" class="el-upload-list__item is-success"> <transition-group tag="ul"
<a class="el-upload-list__item-name" @click="handlePreview(file)"> :class="['el-upload-list', 'el-upload-list--text', { 'is-disabled': disabled }]"
<el-icon class="el-icon--document"><Document /></el-icon>{{ file.name }} name="el-list">
<li v-for="file in fileList"
:key="file.url"
class="el-upload-list__item is-success">
<a class="el-upload-list__item-name"
@click="handlePreview(file)">
<el-icon class="el-icon--document">
<Document />
</el-icon>{{ file.name }}
</a> </a>
<label class="el-upload-list__item-status-label"> <label class="el-upload-list__item-status-label">
<el-icon class="el-icon--upload-success el-icon--circle-check"><CircleCheck /></el-icon> <el-icon class="el-icon--upload-success el-icon--circle-check">
<CircleCheck />
</el-icon>
</label> </label>
<el-icon v-if="!disabled" class="el-icon--close" @click="fileList.splice(fileList.indexOf(file), 1)"><Close /></el-icon> <el-icon v-if="!disabled"
class="el-icon--close"
@click="fileList.splice(fileList.indexOf(file), 1)">
<Close />
</el-icon>
</li> </li>
</transition-group> </transition-group>
<el-dialog :title="$t('article.fileList.attribute')" v-model="previewVisible" top="5vh" :width="768" append-to-body> <el-dialog :title="$t('article.fileList.attribute')"
<el-form ref="form" :model="previewFile" label-width="150px"> v-model="previewVisible"
<el-form-item prop="name" :label="$t('name')" :rules="{ required: true, message: () => $t('v.required') }"> top="5vh"
<el-input v-model="previewFile.name" maxlength="100"></el-input> :width="768"
append-to-body>
<el-form ref="form"
:model="previewFile"
label-width="150px">
<el-form-item prop="name"
:label="$t('name')"
:rules="{ required: true, message: () => $t('v.required') }">
<el-input v-model="previewFile.name"
maxlength="100"></el-input>
</el-form-item> </el-form-item>
<el-form-item prop="length" :label="$t('size')" :rules="{ required: true, message: () => $t('v.required') }"> <el-form-item prop="length"
<el-input v-model="previewFile.length" maxlength="19"> :label="$t('size')"
:rules="{ required: true, message: () => $t('v.required') }">
<el-input v-model="previewFile.length"
maxlength="19">
<template #append>Byte</template> <template #append>Byte</template>
</el-input> </el-input>
</el-form-item> </el-form-item>
<el-form-item prop="url" label="URL" :rules="{ required: true, message: () => $t('v.required') }"> <el-form-item prop="url"
<el-input v-model="previewFile.url" maxlength="255"></el-input> label="URL"
:rules="{ required: true, message: () => $t('v.required') }">
<el-input v-model="previewFile.url"
maxlength="255"></el-input>
</el-form-item> </el-form-item>
<el-button @click.prevent="handleSubmit()" type="primary" native-type="submit">{{ $t('submit') }}</el-button> <el-button @click.prevent="handleSubmit()"
type="primary"
native-type="submit">{{ $t('submit') }}</el-button>
</el-form> </el-form>
</el-dialog> </el-dialog>
</div> </div>
</template> </template>
<script setup lang="ts"> <script setup lang="ts">
import { defineProps, defineEmits, onMounted, ref, toRefs, computed } from 'vue'; import { onMounted, ref, toRefs, computed } from 'vue';
import { ElMessage } from 'element-plus'; import { ElMessage } from 'element-plus';
import { Close, Document, CircleCheck } from '@element-plus/icons-vue'; import { Close, Document, CircleCheck } from '@element-plus/icons-vue';
import { useI18n } from 'vue-i18n'; import { useI18n } from 'vue-i18n';

@ -2,56 +2,83 @@
<div> <div>
<!-- <transition-group tag="ul" :class="['el-upload-list', 'el-upload-list--picture-card', { 'is-disabled': disabled }]" name="el-list"> --> <!-- <transition-group tag="ul" :class="['el-upload-list', 'el-upload-list--picture-card', { 'is-disabled': disabled }]" name="el-list"> -->
<ul :class="['el-upload-list', 'el-upload-list--picture-card', { 'is-disabled': disabled }]"> <ul :class="['el-upload-list', 'el-upload-list--picture-card', { 'is-disabled': disabled }]">
<li v-for="file in fileList" :key="file.url" class="el-upload-list__item is-success"> <li v-for="file in fileList"
:key="file.url"
class="el-upload-list__item is-success">
<div class="w-full h-full bg-gray-50 flex justify-center items-center"> <div class="w-full h-full bg-gray-50 flex justify-center items-center">
<img class="max-w-full max-h-full block" :src="file.url" alt="" /> <img class="max-w-full max-h-full block"
<div class="full-flex-center absolute rounded-md cursor-default bg-black bg-opacity-50 opacity-0 hover:opacity-100 space-x-4" @click.stop> :src="file.url"
<el-icon class="image-action" @click="(cropperVisible = true), (currentFile = file)" :title="$t('cropImage')"><Crop /></el-icon> alt="" />
<el-icon class="image-action" @click="handlePreview(file)" :title="$t('previewImage')"><View /></el-icon> <div class="full-flex-center absolute rounded-md cursor-default bg-black bg-opacity-50 opacity-0 hover:opacity-100 space-x-4"
<el-icon class="image-action" @click="fileList.splice(fileList.indexOf(file), 1)" :title="$t('deleteImage')"><Delete /></el-icon> @click.stop>
<el-icon class="image-action"
@click="(cropperVisible = true), (currentFile = file)"
:title="$t('cropImage')">
<Crop />
</el-icon>
<el-icon class="image-action"
@click="handlePreview(file)"
:title="$t('previewImage')">
<View />
</el-icon>
<el-icon class="image-action"
@click="fileList.splice(fileList.indexOf(file), 1)"
:title="$t('deleteImage')">
<Delete />
</el-icon>
</div> </div>
</div> </div>
</li> </li>
</ul> </ul>
<!-- </transition-group> --> <!-- </transition-group> -->
<el-upload <el-upload :action="imageUploadUrl"
:action="imageUploadUrl" :headers="{ ...getAuthHeaders(), ...getSiteHeaders() }"
:headers="{ ...getAuthHeaders(), ...getSiteHeaders() }" :data="getData()"
:data="getData()" :accept="accept"
:accept="accept" :before-upload="beforeUpload"
:before-upload="beforeUpload" :on-success="(res, file) => fileList.push({ name: res.name, url: res.url })"
:on-success="(res, file) => fileList.push({ name: res.name, url: res.url })" :on-progress="(event, file) => (progressFile = file)"
:on-progress="(event, file) => (progressFile = file)" :show-file-list="false"
:show-file-list="false" multiple
multiple class="inline-block">
class="inline-block" <el-progress v-if="progressFile.status === 'uploading'"
> type="circle"
<el-progress v-if="progressFile.status === 'uploading'" type="circle" :percentage="parseInt(progressFile.percentage, 10)" /> :percentage="parseInt(progressFile.percentage, 10)" />
<div v-else class="el-upload--picture-card"> <div v-else
<el-icon><Plus /></el-icon> class="el-upload--picture-card">
<el-icon>
<Plus />
</el-icon>
</div> </div>
</el-upload> </el-upload>
<div> <div>
<el-dialog v-model="previewVisible" top="5vh" :width="768"> <el-dialog v-model="previewVisible"
<el-input v-model="previewFile.url" maxlength="255"> top="5vh"
:width="768">
<el-input v-model="previewFile.url"
maxlength="255">
<template #prepend>URL</template> <template #prepend>URL</template>
</el-input> </el-input>
<el-input v-model="previewFile.description" type="textarea" :rows="2" :placeholder="$t('article.imageList.description')" class="mt-1"></el-input> <el-input v-model="previewFile.description"
<img :src="previewFile.url" alt="" class="mt-1 border border-gray-300" /> type="textarea"
:rows="2"
:placeholder="$t('article.imageList.description')"
class="mt-1"></el-input>
<img :src="previewFile.url"
alt=""
class="mt-1 border border-gray-300" />
</el-dialog> </el-dialog>
</div> </div>
<image-cropper <image-cropper v-model="cropperVisible"
v-model="cropperVisible" :src="currentFile.url"
:src="currentFile.url" :thumbnailWidth="thumbnailWidth"
:thumbnailWidth="thumbnailWidth" :thumbnailHeight="thumbnailHeight"
:thumbnailHeight="thumbnailHeight" @success="(url) => (currentFile.url = url)"></image-cropper>
@success="(url) => (currentFile.url = url)"
></image-cropper>
</div> </div>
</template> </template>
<script setup lang="ts"> <script setup lang="ts">
import { defineProps, defineEmits, onMounted, ref, toRefs, computed } from 'vue'; import { onMounted, ref, toRefs, computed } from 'vue';
import { ElMessage } from 'element-plus'; import { ElMessage } from 'element-plus';
import { Plus, Crop, View, Delete } from '@element-plus/icons-vue'; import { Plus, Crop, View, Delete } from '@element-plus/icons-vue';
import { useI18n } from 'vue-i18n'; import { useI18n } from 'vue-i18n';

@ -1,44 +1,72 @@
<template> <template>
<el-upload <el-upload :action="imageUploadUrl"
:action="imageUploadUrl" :headers="{ ...getAuthHeaders(), ...getSiteHeaders() }"
:headers="{ ...getAuthHeaders(), ...getSiteHeaders() }" :accept="accept"
:accept="accept" :before-upload="beforeUpload"
:before-upload="beforeUpload" :data="data"
:data="data" :show-file-list="false"
:show-file-list="false" :on-success="(res) => ((src = res.url), (cropperVisible = mode === 'manual'))"
:on-success="(res) => ((src = res.url), (cropperVisible = mode === 'manual'))" :on-progress="(event, file) => (progressFile = file)">
:on-progress="(event, file) => (progressFile = file)"
>
<!-- <!--
// //
action="https://jsonplaceholder.typicode.com/posts/" action="https://jsonplaceholder.typicode.com/posts/"
--> -->
<div v-if="src" class="full-flex-center rounded-border relative hover:border-opacity-0"> <div v-if="src"
<img :src="src" class="max-w-full max-h-full block" /> class="full-flex-center rounded-border relative hover:border-opacity-0">
<div class="full-flex-center absolute rounded-md cursor-default bg-black bg-opacity-50 opacity-0 hover:opacity-100 space-x-4" @click.stop> <img :src="src"
<el-icon class="image-action" @click="cropperVisible = true" :title="$t('cropImage')"><Crop /></el-icon> class="max-w-full max-h-full block" />
<el-icon class="image-action" @click="previewVisible = true" :title="$t('previewImage')"><View /></el-icon> <div class="full-flex-center absolute rounded-md cursor-default bg-black bg-opacity-50 opacity-0 hover:opacity-100 space-x-4"
<el-icon class="image-action" @click="src = undefined" :title="$t('deleteImage')"><Delete /></el-icon> @click.stop>
<el-icon class="image-action"
@click="cropperVisible = true"
:title="$t('cropImage')">
<Crop />
</el-icon>
<el-icon class="image-action"
@click="previewVisible = true"
:title="$t('previewImage')">
<View />
</el-icon>
<el-icon class="image-action"
@click="src = undefined"
:title="$t('deleteImage')">
<Delete />
</el-icon>
</div> </div>
</div> </div>
<el-progress v-else-if="progressFile.status === 'uploading'" type="circle" :percentage="parseInt(progressFile.percentage, 10)" /> <el-progress v-else-if="progressFile.status === 'uploading'"
<div v-else class="el-upload--picture-card"> type="circle"
<el-icon><plus /></el-icon> :percentage="parseInt(progressFile.percentage, 10)" />
<div v-else
class="el-upload--picture-card">
<el-icon>
<plus />
</el-icon>
</div> </div>
</el-upload> </el-upload>
<div> <div>
<el-dialog v-model="previewVisible" top="5vh" :width="768" append-to-body destroy-on-close> <el-dialog v-model="previewVisible"
top="5vh"
:width="768"
append-to-body
destroy-on-close>
<el-input v-model="src"> <el-input v-model="src">
<template #prepend>URL</template> <template #prepend>URL</template>
</el-input> </el-input>
<img :src="src" alt="" class="mt-1 border border-gray-300" /> <img :src="src"
alt=""
class="mt-1 border border-gray-300" />
</el-dialog> </el-dialog>
</div> </div>
<image-cropper v-model="cropperVisible" :src="src" :width="width" :height="height" @success="(url) => (src = url)"></image-cropper> <image-cropper v-model="cropperVisible"
:src="src"
:width="width"
:height="height"
@success="(url) => (src = url)"></image-cropper>
</template> </template>
<script setup lang="ts"> <script setup lang="ts">
import { defineProps, defineEmits, computed, onMounted, ref, toRefs } from 'vue'; import { computed, onMounted, ref, toRefs } from 'vue';
import { ElMessage } from 'element-plus'; import { ElMessage } from 'element-plus';
import { Plus, Crop, View, Delete } from '@element-plus/icons-vue'; import { Plus, Crop, View, Delete } from '@element-plus/icons-vue';
import { useI18n } from 'vue-i18n'; import { useI18n } from 'vue-i18n';

@ -31,21 +31,11 @@ import { appState, toggleSidebar } from '@/store/useAppState';
import Logo from './Logo.vue'; import Logo from './Logo.vue';
const router = useRouter(); const router = useRouter();
const siteId = ref<number | null>(getSessionSiteId());
const siteList = ref<any[]>([]);
const site = computed(() => siteList.value.find((item) => item.id === siteId.value));
const fetchSiteList = async () => {
// siteList.value = flatTree(toTree(await querySiteList()));
// if (siteId.value == null) {
// siteId.value = siteList.value[0]?.id;
// }
};
const switchRole = (type: number) => { const switchRole = (type: number) => {
router.push(`/product?type=0&i=1&role=${type}`); router.push(`/product?type=0&i=1&role=${type}`);
}; };
onMounted(() => { onMounted(() => {});
// fetchSiteList();
});
const handleLogout = () => { const handleLogout = () => {
logout(); logout();

@ -74,7 +74,7 @@
</template> </template>
<script setup lang="ts"> <script setup lang="ts">
import { computed, defineProps, ref, toRefs } from 'vue'; import { computed, ref, toRefs } from 'vue';
import { useRouter, useRoute } from 'vue-router'; import { useRouter, useRoute } from 'vue-router';
import { isShowMenu } from '@/store/useCurrentUser'; import { isShowMenu } from '@/store/useCurrentUser';

@ -32,7 +32,6 @@ export default defineComponent({
() => route.path, () => route.path,
(val: any) => { (val: any) => {
hideNav.value = Setting.hideNavPath.includes(val); hideNav.value = Setting.hideNavPath.includes(val);
console.log(33, hideNav.value);
}, },
{ {
immediate: true, immediate: true,

@ -1,6 +1,5 @@
import { createApp } from 'vue'; import { createApp } from 'vue';
import ElementPlus from 'element-plus'; import ElementPlus from 'element-plus';
import { initRefreshInterval } from '@/store/useCurrentUser';
import App from './App.vue'; import App from './App.vue';
import router from './router'; import router from './router';
import i18n from './i18n'; import i18n from './i18n';
@ -10,9 +9,6 @@ import '@/styles/tailwind.scss';
import '@/styles/element-plus.scss'; import '@/styles/element-plus.scss';
import '@/styles/index.scss'; import '@/styles/index.scss';
// 初始化RefreshToken自动刷新
initRefreshInterval();
const app = createApp(App) const app = createApp(App)
.use(router) .use(router)
// tinymce 对话框的层级太低,必须调低 ElementPlus 的 对话框层级(默认为2000) // tinymce 对话框的层级太低,必须调低 ElementPlus 的 对话框层级(默认为2000)

@ -1,21 +1,7 @@
import { reactive, readonly } from 'vue'; import { reactive, readonly } from 'vue';
import { RouteRecordRaw } from 'vue-router'; import { RouteRecordRaw } from 'vue-router';
import { accountLogin, accountRefreshToken, LoginParam, queryCurrentUser } from '@/api/login'; import { accountLogin, accountRefreshToken, LoginParam, queryCurrentUser } from '@/api/login';
import { import { setAccessToken, removeAccessToken, setAccessAt, setSessionTimeout, removeSessionTimeout } from '@/utils/auth';
setAccessToken,
removeAccessToken,
getRefreshToken,
setRefreshToken,
getRefreshAt,
setRefreshAt,
getAccessAt,
setAccessAt,
getSessionTimeout,
setSessionTimeout,
removeSessionTimeout,
removeRefreshToken,
removeRefreshAt,
} from '@/utils/auth';
export interface CurrentUser { export interface CurrentUser {
username?: string; username?: string;
@ -39,61 +25,18 @@ export const login = async (params: LoginParam): Promise<any> => {
const { result } = data; const { result } = data;
const now = new Date().getTime(); const now = new Date().getTime();
setAccessToken(result.accessToken); setAccessToken(result.accessToken);
setRefreshToken(result.refreshToken);
setSessionTimeout(result.sessionTimeout); setSessionTimeout(result.sessionTimeout);
setAccessAt(now); setAccessAt(now);
setRefreshAt(now);
} }
return data; return data;
}; };
export const logout = (): void => { export const logout = (): void => {
removeRefreshAt();
removeAccessToken(); removeAccessToken();
removeRefreshToken();
removeSessionTimeout(); removeSessionTimeout();
setCurrentUser({}); setCurrentUser({});
}; };
// 刷新间隔时间。默认 5 分钟。
const interval = 5 * 60 * 1000;
let refreshInterval: any;
/**
* RefreshToken
*
* 1.
* 2. 访30
*/
const runRefreshToken = async () => {
const refreshToken = getRefreshToken();
// refreshToken不存在,不刷新。
if (!refreshToken) return;
const accessAt = getAccessAt();
const now = new Date().getTime();
// 超过时间没有访问,退出登录。默认为 30 分钟。
if (now - accessAt > getSessionTimeout() * 60 * 1000) {
logout();
return;
}
// 记录刷新时间,用于重新加载页面时,初始化Interval。
setRefreshAt(now);
const data = await accountRefreshToken({ refreshToken });
if (data.status !== 0) return;
const { result } = data;
setAccessToken(result.accessToken);
setRefreshToken(result.refreshToken);
};
export const initRefreshInterval = (): void => {
let afterTime = getRefreshAt() + interval - new Date().getTime();
if (afterTime < 0) afterTime = 0;
setTimeout(() => {
runRefreshToken();
if (!refreshInterval) refreshInterval = setInterval(runRefreshToken, interval);
}, afterTime);
};
export const fetchCurrentUser = async (): Promise<any> => { export const fetchCurrentUser = async (): Promise<any> => {
const user = await queryCurrentUser(); const user = await queryCurrentUser();
if (user) { if (user) {

@ -2,8 +2,6 @@ import Cookies from 'js-cookie';
const SAND_ACCESS_TOKEN = 'sand-token'; const SAND_ACCESS_TOKEN = 'sand-token';
const SAND_ACCESS_AT = 'jwt-access-at'; const SAND_ACCESS_AT = 'jwt-access-at';
const SAND_REFRESH_TOKEN = 'jwt-refresh-token';
const SAND_REFRESH_AT = 'jwt-refresh-at';
const SAND_SESSION_TIMEOUT = 'jwt-session-timeout'; const SAND_SESSION_TIMEOUT = 'jwt-session-timeout';
export const getAccessToken = (): string | undefined => Cookies.get(SAND_ACCESS_TOKEN); export const getAccessToken = (): string | undefined => Cookies.get(SAND_ACCESS_TOKEN);
@ -12,25 +10,6 @@ export const setAccessToken = (token: string): void => {
}; };
export const removeAccessToken = (): void => Cookies.remove(SAND_ACCESS_TOKEN); export const removeAccessToken = (): void => Cookies.remove(SAND_ACCESS_TOKEN);
export const getRefreshToken = (): string | undefined => Cookies.get(SAND_REFRESH_TOKEN);
export const setRefreshToken = (token: string): void => {
Cookies.set(SAND_REFRESH_TOKEN, token);
};
export const removeRefreshToken = (): void => {
Cookies.remove(SAND_REFRESH_TOKEN);
};
export const getRefreshAt = (): number => {
const refreshAt = Cookies.get(SAND_REFRESH_AT);
return refreshAt ? Number(refreshAt) : 0;
};
export const setRefreshAt = (refreshAt: number): void => {
Cookies.set(SAND_REFRESH_AT, String(refreshAt));
};
export const removeRefreshAt = (): void => {
Cookies.remove(SAND_REFRESH_AT);
};
export const getAccessAt = (): number => { export const getAccessAt = (): number => {
const accessAt = Cookies.get(SAND_ACCESS_AT); const accessAt = Cookies.get(SAND_ACCESS_AT);
return accessAt ? Number(accessAt) : 0; return accessAt ? Number(accessAt) : 0;

@ -115,25 +115,19 @@
<script setup lang="ts"> <script setup lang="ts">
import { ref, onMounted } from 'vue'; import { ref, onMounted } from 'vue';
import { ElMessage } from 'element-plus'; import { ElMessage } from 'element-plus';
import { primaryTypeOfGuarantee, bankingProductsList } from '@/api/bank'; import { systemBuyerAdd, systemBuyerFind } from '@/api/config';
defineProps({ modelValue: { type: Object, required: true } });
defineEmits({ 'update:form': null });
const list = ref<Array<any>>([]); const list = ref<Array<any>>([]);
const form = ref<Object>({}); const form = ref<Object>({});
// //
const getGuarantee = async () => { const getInfo = async () => {
try { const { process } = await systemBuyerFind();
const { data } = await primaryTypeOfGuarantee(); config.value = process;
guarantees.value = data;
} finally {
}
}; };
onMounted(() => { onMounted(() => {
// getGuarantee(); getInfo();
// fetchData();
}); });
</script> </script>

@ -1,12 +1,17 @@
<template> <template>
<div class="block"> <div class="block">
<el-tabs v-model="curTab" @tab-click="tabChange"> <el-tabs v-model="curTab"
<el-tab-pane label="系统买方" name="tab1"> @tab-click="tabChange">
<el-tab-pane label="系统买方"
name="tab1">
<buyer></buyer> <buyer></buyer>
</el-tab-pane> </el-tab-pane>
<el-tab-pane label="金融市场" name="tab2"> </el-tab-pane> <el-tab-pane label="金融市场"
<el-tab-pane label="扫单配置" name="tab3"> </el-tab-pane> name="tab2"> </el-tab-pane>
<el-tab-pane label="渠道广告" name="tab4"> </el-tab-pane> <el-tab-pane label="扫单配置"
name="tab3"> </el-tab-pane>
<el-tab-pane label="渠道广告"
name="tab4"> </el-tab-pane>
</el-tabs> </el-tabs>
</div> </div>
</template> </template>
@ -15,7 +20,6 @@
import { ref, onMounted } from 'vue'; import { ref, onMounted } from 'vue';
import { ElMessage } from 'element-plus'; import { ElMessage } from 'element-plus';
import type { TabsPaneContext } from 'element-plus'; import type { TabsPaneContext } from 'element-plus';
import { primaryTypeOfGuarantee, bankingProductsList } from '@/api/bank';
import Buyer from './Buyer.vue'; import Buyer from './Buyer.vue';
defineProps({ modelValue: { type: Object, required: true } }); defineProps({ modelValue: { type: Object, required: true } });
@ -27,14 +31,6 @@ const curTab = ref<string>('tab1');
const tabChange = (tab: TabsPaneContext, event: Event) => { const tabChange = (tab: TabsPaneContext, event: Event) => {
console.log(tab, event); console.log(tab, event);
}; };
//
const getGuarantee = async () => {
try {
const { data } = await primaryTypeOfGuarantee();
guarantees.value = data;
} finally {
}
};
onMounted(() => { onMounted(() => {
// getGuarantee(); // getGuarantee();
// fetchData(); // fetchData();

@ -150,7 +150,6 @@
import { ref, onMounted } from 'vue'; import { ref, onMounted } from 'vue';
import { ElMessage } from 'element-plus'; import { ElMessage } from 'element-plus';
import { Plus } from '@element-plus/icons-vue'; import { Plus } from '@element-plus/icons-vue';
import { primaryTypeOfGuarantee, bankingProductsList } from '@/api/bank';
import Search from '@/components/Search.vue'; import Search from '@/components/Search.vue';
import Back from '@/components/Back.vue'; import Back from '@/components/Back.vue';
import { pageSizes, pageLayout, toParams, resetParams } from '@/utils/common'; import { pageSizes, pageLayout, toParams, resetParams } from '@/utils/common';
@ -170,14 +169,6 @@ const loading = ref<boolean>(false);
const showProduct = async () => { const showProduct = async () => {
productVisible.value = true; productVisible.value = true;
}; };
//
const getGuarantee = async () => {
try {
const { data } = await primaryTypeOfGuarantee();
guarantees.value = data;
} finally {
}
};
onMounted(() => { onMounted(() => {
// getGuarantee(); // getGuarantee();
// fetchData(); // fetchData();

@ -6,12 +6,10 @@
</div> </div>
<div class="inline-flex items-center"> <div class="inline-flex items-center">
<ul class="types inline-flex items-center mr-5"> <ul class="types inline-flex items-center mr-5">
<li v-for="(item, i) in types" <li v-for="(item, i) in types" :key="i">{{ item.name }}</li>
:key="i">{{ item.name }}</li>
</ul> </ul>
<ul class="times inline-flex items-center"> <ul class="times inline-flex items-center">
<li v-for="(item, i) in times" <li v-for="(item, i) in times" :key="i">{{ item.name }}</li>
:key="i">{{ item.name }}</li>
</ul> </ul>
</div> </div>
</div> </div>
@ -19,9 +17,7 @@
<div class="flex"> <div class="flex">
<div class="wrap"> <div class="wrap">
<div class="header"> <div class="header">
<img src="@/assets/images/armory/7.png" <img src="@/assets/images/armory/7.png" alt="" class="mr-2" />
alt=""
class="mr-2" />
收益排行 收益排行
</div> </div>
<ul class="c-table table-header"> <ul class="c-table table-header">
@ -33,9 +29,7 @@
<ul class="c-table table-body"> <ul class="c-table table-body">
<div class="line"> <div class="line">
<li> <li>
<img src="@/assets/images/armory/icon1.png" <img src="@/assets/images/armory/icon1.png" alt="" class="mx-auto" />
alt=""
class="mx-auto" />
</li> </li>
<li>周转易</li> <li>周转易</li>
<li>刘物语</li> <li>刘物语</li>
@ -45,9 +39,7 @@
</div> </div>
<div class="wrap"> <div class="wrap">
<div class="header"> <div class="header">
<img src="@/assets/images/armory/8.png" <img src="@/assets/images/armory/8.png" alt="" class="mr-2" />
alt=""
class="mr-2" />
总资产排行 总资产排行
</div> </div>
<ul class="c-table table-header"> <ul class="c-table table-header">
@ -59,9 +51,7 @@
<ul class="c-table table-body"> <ul class="c-table table-body">
<div class="line"> <div class="line">
<li> <li>
<img src="@/assets/images/armory/icon1.png" <img src="@/assets/images/armory/icon1.png" alt="" class="mx-auto" />
alt=""
class="mx-auto" />
</li> </li>
<li>周转易</li> <li>周转易</li>
<li>刘物语</li> <li>刘物语</li>
@ -71,9 +61,7 @@
</div> </div>
<div class="wrap"> <div class="wrap">
<div class="header"> <div class="header">
<img src="@/assets/images/armory/9.png" <img src="@/assets/images/armory/9.png" alt="" class="mr-2" />
alt=""
class="mr-2" />
交易订单排行 交易订单排行
</div> </div>
<ul class="c-table table-header"> <ul class="c-table table-header">
@ -85,9 +73,7 @@
<ul class="c-table table-body"> <ul class="c-table table-body">
<div class="line"> <div class="line">
<li> <li>
<img src="@/assets/images/armory/icon1.png" <img src="@/assets/images/armory/icon1.png" alt="" class="mx-auto" />
alt=""
class="mx-auto" />
</li> </li>
<li>周转易</li> <li>周转易</li>
<li>刘物语</li> <li>刘物语</li>
@ -102,7 +88,6 @@
import { ref, onMounted } from 'vue'; import { ref, onMounted } from 'vue';
import { ElMessage } from 'element-plus'; import { ElMessage } from 'element-plus';
import { Plus } from '@element-plus/icons-vue'; import { Plus } from '@element-plus/icons-vue';
import { primaryTypeOfGuarantee, bankingProductsList } from '@/api/bank';
const form = ref<Object>({}); const form = ref<Object>({});
const types = ref<Array<any>>([ const types = ref<Array<any>>([
@ -151,14 +136,6 @@ const loading = ref<boolean>(false);
const showProduct = async () => { const showProduct = async () => {
productVisible.value = true; productVisible.value = true;
}; };
//
const getGuarantee = async () => {
try {
const { data } = await primaryTypeOfGuarantee();
guarantees.value = data;
} finally {
}
};
onMounted(() => { onMounted(() => {
// getGuarantee(); // getGuarantee();
// fetchData(); // fetchData();

@ -74,20 +74,11 @@
import { ref, onMounted } from 'vue'; import { ref, onMounted } from 'vue';
import { ElMessage } from 'element-plus'; import { ElMessage } from 'element-plus';
import { Plus } from '@element-plus/icons-vue'; import { Plus } from '@element-plus/icons-vue';
import { primaryTypeOfGuarantee, bankingProductsList } from '@/api/bank';
import Search from '@/components/Search.vue'; import Search from '@/components/Search.vue';
import Back from '@/components/Back.vue'; import Back from '@/components/Back.vue';
const form = ref<Object>({}); const form = ref<Object>({});
//
const getGuarantee = async () => {
try {
const { data } = await primaryTypeOfGuarantee();
guarantees.value = data;
} finally {
}
};
onMounted(() => { onMounted(() => {
// getGuarantee(); // getGuarantee();
// fetchData(); // fetchData();

@ -65,7 +65,6 @@
import { ref, onMounted } from 'vue'; import { ref, onMounted } from 'vue';
import { ElMessage } from 'element-plus'; import { ElMessage } from 'element-plus';
import { Plus } from '@element-plus/icons-vue'; import { Plus } from '@element-plus/icons-vue';
import { primaryTypeOfGuarantee, bankingProductsList } from '@/api/bank';
import Search from '@/components/Search.vue'; import Search from '@/components/Search.vue';
import Back from '@/components/Back.vue'; import Back from '@/components/Back.vue';
import { pageSizes, pageLayout, toParams, resetParams } from '@/utils/common'; import { pageSizes, pageLayout, toParams, resetParams } from '@/utils/common';
@ -107,14 +106,6 @@ const loading = ref<boolean>(false);
const showProduct = async () => { const showProduct = async () => {
productVisible.value = true; productVisible.value = true;
}; };
//
const getGuarantee = async () => {
try {
const { data } = await primaryTypeOfGuarantee();
guarantees.value = data;
} finally {
}
};
onMounted(() => { onMounted(() => {
// getGuarantee(); // getGuarantee();
// fetchData(); // fetchData();

@ -131,7 +131,6 @@
import { ref, onMounted } from 'vue'; import { ref, onMounted } from 'vue';
import { ElMessage } from 'element-plus'; import { ElMessage } from 'element-plus';
import { Plus } from '@element-plus/icons-vue'; import { Plus } from '@element-plus/icons-vue';
import { primaryTypeOfGuarantee, bankingProductsList } from '@/api/bank';
import Search from '@/components/Search.vue'; import Search from '@/components/Search.vue';
import Back from '@/components/Back.vue'; import Back from '@/components/Back.vue';
import { pageSizes, pageLayout, toParams, resetParams } from '@/utils/common'; import { pageSizes, pageLayout, toParams, resetParams } from '@/utils/common';
@ -151,14 +150,6 @@ const loading = ref<boolean>(false);
const showProduct = async () => { const showProduct = async () => {
productVisible.value = true; productVisible.value = true;
}; };
//
const getGuarantee = async () => {
try {
const { data } = await primaryTypeOfGuarantee();
guarantees.value = data;
} finally {
}
};
onMounted(() => { onMounted(() => {
// getGuarantee(); // getGuarantee();
// fetchData(); // fetchData();

@ -132,8 +132,6 @@
import { computed, onMounted, ref, reactive, watch } from 'vue'; import { computed, onMounted, ref, reactive, watch } from 'vue';
import { ElMessage } from 'element-plus'; import { ElMessage } from 'element-plus';
import { useI18n } from 'vue-i18n'; import { useI18n } from 'vue-i18n';
import dayjs from 'dayjs';
import { perm } from '@/store/useCurrentUser';
import { pageSizes, pageLayout, toParams, resetParams } from '@/utils/common'; import { pageSizes, pageLayout, toParams, resetParams } from '@/utils/common';
import { getProcessInformationBasedOnRoles } from '@/api/judgment'; import { getProcessInformationBasedOnRoles } from '@/api/judgment';
import { bankingProductsList, batchDeletion } from '@/api/bank'; import { bankingProductsList, batchDeletion } from '@/api/bank';

@ -1,46 +1,57 @@
<template> <template>
<dialog-form <dialog-form ref="form"
ref="form" :name="$t('menu.user.role')"
:name="$t('menu.user.role')" :queryBean="queryRole"
:queryBean="queryRole" :createBean="createRole"
:createBean="createRole" :updateBean="updateRole"
:updateBean="updateRole" :deleteBean="deleteRole"
:deleteBean="deleteRole" :beanId="beanId"
:beanId="beanId" :beanIds="beanIds"
:beanIds="beanIds" :focus="focus"
:focus="focus" :initValues="() => ({})"
:initValues="() => ({})" :toValues="(bean) => ({ ...bean })"
:toValues="(bean) => ({ ...bean })" :disableDelete="(bean) => bean.id <= 1"
:disableDelete="(bean) => bean.id <= 1" perms="role"
perms="role" :model-value="modelValue"
:model-value="modelValue" @update:model-value="$emit('update:modelValue', $event)"
@update:model-value="$emit('update:modelValue', $event)" @finished="$emit('finished')"
@finished="$emit('finished')" @beanChange="(bean) => tree?.setCheckedKeys(bean.permission?.split(',') ?? [])"
@beanChange="(bean) => tree?.setCheckedKeys(bean.permission?.split(',') ?? [])" @beforeSubmit="
@beforeSubmit="
(values) => (values) =>
(values.permission = [...tree.getHalfCheckedNodes(), ...tree.getCheckedNodes()] (values.permission = [...tree.getHalfCheckedNodes(), ...tree.getCheckedNodes()]
.filter((item) => item.perms) .filter((item) => item.perms)
.map((item) => item.perms?.join(',')) .map((item) => item.perms?.join(','))
.join(',')) .join(','))
" ">
>
<template #default="{ values }"> <template #default="{ values }">
<el-form-item prop="name" :label="$t('role.name')" :rules="{ required: true, message: () => $t('v.required') }"> <el-form-item prop="name"
<el-input v-model="values.name" ref="focus" maxlength="50"></el-input> :label="$t('role.name')"
:rules="{ required: true, message: () => $t('v.required') }">
<el-input v-model="values.name"
ref="focus"
maxlength="50"></el-input>
</el-form-item> </el-form-item>
<el-form-item prop="description" :label="$t('role.description')"> <el-form-item prop="description"
<el-input v-model="values.description" maxlength="255"></el-input> :label="$t('role.description')">
<el-input v-model="values.description"
maxlength="255"></el-input>
</el-form-item> </el-form-item>
<el-form-item prop="permission" :label="$t('role.permission')"> <el-form-item prop="permission"
<el-tree ref="tree" :data="perms" node-key="key" @check="form.setUnsaved(true)" show-checkbox default-expand-all check-on-click-node /> :label="$t('role.permission')">
<el-tree ref="tree"
:data="perms"
node-key="key"
@check="form.setUnsaved(true)"
show-checkbox
default-expand-all
check-on-click-node />
</el-form-item> </el-form-item>
</template> </template>
</dialog-form> </dialog-form>
</template> </template>
<script setup lang="ts"> <script setup lang="ts">
import { defineProps, defineEmits, ref } from 'vue'; import { ref } from 'vue';
import { queryRole, createRole, updateRole, deleteRole } from '@/api/user'; import { queryRole, createRole, updateRole, deleteRole } from '@/api/user';
import { getPermsTreeData } from '@/data'; import { getPermsTreeData } from '@/data';
import DialogForm from '@/components/DialogForm.vue'; import DialogForm from '@/components/DialogForm.vue';

@ -221,7 +221,7 @@
</template> </template>
<script setup lang="ts"> <script setup lang="ts">
import { defineProps, defineEmits, onMounted, ref } from 'vue'; import { onMounted, ref } from 'vue';
import { queryUser, createUser, updateUser, deleteUser, usernameValidation, emailValidation, mobileValidation, queryGroupList, queryOrgList, queryRoleList } from '@/api/user'; import { queryUser, createUser, updateUser, deleteUser, usernameValidation, emailValidation, mobileValidation, queryGroupList, queryOrgList, queryRoleList } from '@/api/user';
import { toTree } from '@/utils/tree'; import { toTree } from '@/utils/tree';
import DialogForm from '@/components/DialogForm.vue'; import DialogForm from '@/components/DialogForm.vue';

Loading…
Cancel
Save