提交 a6311d60 编写于 作者: ibizdev's avatar ibizdev

ibizdev提交

上级 2bd27459
*2020-3-7*
初始化
module.exports = {
presets: [
'@vue/cli-plugin-babel/preset'
]
}
{
"pluginsFile": "tests/e2e/plugins/index.js"
}
module.exports = {
preset: '@vue/cli-plugin-unit-jest/presets/typescript-and-babel'
}
{
"name": "app",
"version": "0.1.0",
"private": true,
"scripts": {
"serve": "node --max_old_space_size=8102 ./node_modules/@vue/cli-service/bin/vue-cli-service serve --mode production",
"dev-serve": "node --max_old_space_size=8102 ./node_modules/@vue/cli-service/bin/vue-cli-service serve --mode development",
"build": "node --max_old_space_size=8102 ./node_modules/@vue/cli-service/bin/vue-cli-service build",
"dev-build": "node --max_old_space_size=8102 ./node_modules/@vue/cli-service/bin/vue-cli-service build --mode development",
"test:unit": "vue-cli-service test:unit",
"test:e2e": "vue-cli-service test:e2e",
"lint": "vue-cli-service lint"
},
"dependencies": {
"axios": "^0.19.1",
"core-js": "^3.4.4",
"element-ui": "^2.13.0",
"font-awesome": "^4.7.0",
"path-to-regexp": "^6.1.0",
"qs": "^6.9.1",
"rxjs": "^6.5.4",
"tinymce": "4.8.5",
"view-design": "^4.1.0",
"vue": "^2.6.10",
"vue-class-component": "^7.0.2",
"vue-i18n": "^8.15.3",
"vue-property-decorator": "^8.3.0",
"vue-router": "^3.1.3",
"vuex": "^3.1.2"
},
"devDependencies": {
"@types/jest": "^24.0.19",
"@types/mockjs": "^1.0.2",
"@types/qs": "^6.9.0",
"@vue/cli-plugin-babel": "^4.1.0",
"@vue/cli-plugin-e2e-cypress": "^4.1.0",
"@vue/cli-plugin-router": "^4.1.0",
"@vue/cli-plugin-typescript": "^4.1.0",
"@vue/cli-plugin-unit-jest": "^4.1.0",
"@vue/cli-plugin-vuex": "^4.1.0",
"@vue/cli-service": "^4.1.0",
"@vue/test-utils": "1.0.0-beta.29",
"axios-mock-adapter": "^1.17.0",
"less": "^3.0.4",
"less-loader": "^5.0.0",
"mockjs": "^1.1.0",
"typescript": "~3.5.3",
"vue-template-compiler": "^2.6.10"
}
}
tinymce.addI18n('en_GB',{
"Cut": "Cut",
"Heading 5": "Heading 5",
"Header 2": "Header 2",
"Your browser doesn't support direct access to the clipboard. Please use the Ctrl+X\/C\/V keyboard shortcuts instead.": "Your browser doesn't support direct access to the clipboard. Please use the Ctrl+X\/C\/V keyboard shortcuts instead.",
"Heading 4": "Heading 4",
"Div": "Div",
"Heading 2": "Heading 2",
"Paste": "Paste",
"Close": "Close",
"Font Family": "Font Family",
"Pre": "Pre",
"Align right": "Align right",
"New document": "New document",
"Blockquote": "Blockquote",
"Numbered list": "Numbered list",
"Heading 1": "Heading 1",
"Headings": "Headings",
"Increase indent": "Increase indent",
"Formats": "Formats",
"Headers": "Headers",
"Select all": "Select all",
"Header 3": "Header 3",
"Blocks": "Blocks",
"Undo": "Undo",
"Strikethrough": "Strike-through",
"Bullet list": "Bullet list",
"Header 1": "Header 1",
"Superscript": "Superscript",
"Clear formatting": "Clear formatting",
"Font Sizes": "Font Sizes",
"Subscript": "Subscript",
"Header 6": "Header 6",
"Redo": "Redo",
"Paragraph": "Paragraph",
"Ok": "Ok",
"Bold": "Bold",
"Code": "Code",
"Italic": "Italic",
"Align center": "Align centre",
"Header 5": "Header 5",
"Heading 6": "Heading 6",
"Heading 3": "Heading 3",
"Decrease indent": "Decrease indent",
"Header 4": "Header 4",
"Paste is now in plain text mode. Contents will now be pasted as plain text until you toggle this option off.": "Paste is now in plain text mode. Contents will now be pasted as plain text until you toggle this option off.",
"Underline": "Underline",
"Cancel": "Cancel",
"Justify": "Justify",
"Inline": "Inline",
"Copy": "Copy",
"Align left": "Align left",
"Visual aids": "Visual aids",
"Lower Greek": "Lower Greek",
"Square": "Square",
"Default": "Default",
"Lower Alpha": "Lower Alpha",
"Circle": "Circle",
"Disc": "Disc",
"Upper Alpha": "Upper Alpha",
"Upper Roman": "Upper Roman",
"Lower Roman": "Lower Roman",
"Id should start with a letter, followed only by letters, numbers, dashes, dots, colons or underscores.": "ID should start with a letter, followed only by letters, numbers, dashes, dots, colons or underscores.",
"Name": "Name",
"Anchor": "Anchor",
"Id": "ID",
"You have unsaved changes are you sure you want to navigate away?": "You have unsaved changes are you sure you want to navigate away?",
"Restore last draft": "Restore last draft",
"Special character": "Special character",
"Source code": "Source code",
"Language": "Language",
"Insert\/Edit code sample": "Insert\/Edit code sample",
"B": "B",
"R": "R",
"G": "G",
"Color": "Colour",
"Right to left": "Right to left",
"Left to right": "Left to right",
"Emoticons": "Emoticons",
"Robots": "Robots",
"Document properties": "Document properties",
"Title": "Title",
"Keywords": "Keywords",
"Encoding": "Encoding",
"Description": "Description",
"Author": "Author",
"Fullscreen": "Full-screen",
"Horizontal line": "Horizontal line",
"Horizontal space": "Horizontal space",
"Insert\/edit image": "Insert\/edit image",
"General": "General",
"Advanced": "Advanced",
"Source": "Source",
"Border": "Border",
"Constrain proportions": "Constrain proportions",
"Vertical space": "Vertical space",
"Image description": "Image description",
"Style": "Style",
"Dimensions": "Dimensions",
"Insert image": "Insert image",
"Image": "Image",
"Zoom in": "Zoom in",
"Contrast": "Contrast",
"Back": "Back",
"Gamma": "Gamma",
"Flip horizontally": "Flip horizontally",
"Resize": "Resize",
"Sharpen": "Sharpen",
"Zoom out": "Zoom out",
"Image options": "Image options",
"Apply": "Apply",
"Brightness": "Brightness",
"Rotate clockwise": "Rotate clockwise",
"Rotate counterclockwise": "Rotate counterclockwise",
"Edit image": "Edit image",
"Color levels": "Colour levels",
"Crop": "Crop",
"Orientation": "Orientation",
"Flip vertically": "Flip vertically",
"Invert": "Invert",
"Date\/time": "Date\/time",
"Insert date\/time": "Insert date\/time",
"Remove link": "Remove link",
"Url": "URL",
"Text to display": "Text to display",
"Anchors": "Anchors",
"Insert link": "Insert link",
"Link": "Link",
"New window": "New window",
"None": "None",
"The URL you entered seems to be an external link. Do you want to add the required http:\/\/ prefix?": "The URL you entered seems to be an external link. Do you want to add the required http:\/\/ prefix?",
"Paste or type a link": "Paste or type a link",
"Target": "Target",
"The URL you entered seems to be an email address. Do you want to add the required mailto: prefix?": "The URL you entered seems to be an email address. Do you want to add the required mailto: prefix?",
"Insert\/edit link": "Insert\/edit link",
"Insert\/edit video": "Insert\/edit video",
"Media": "Media",
"Alternative source": "Alternative source",
"Paste your embed code below:": "Paste your embed code below:",
"Insert video": "Insert video",
"Poster": "Poster",
"Insert\/edit media": "Insert\/edit media",
"Embed": "Embed",
"Nonbreaking space": "Non-breaking space",
"Page break": "Page break",
"Paste as text": "Paste as text",
"Preview": "Preview",
"Print": "Print",
"Save": "Save",
"Could not find the specified string.": "Could not find the specified string.",
"Replace": "Replace",
"Next": "Next",
"Whole words": "Whole words",
"Find and replace": "Find and replace",
"Replace with": "Replace with",
"Find": "Find",
"Replace all": "Replace all",
"Match case": "Match case",
"Prev": "Prev",
"Spellcheck": "Spell-check",
"Finish": "Finish",
"Ignore all": "Ignore all",
"Ignore": "Ignore",
"Add to Dictionary": "Add to Dictionary",
"Insert row before": "Insert row before",
"Rows": "Rows",
"Height": "Height",
"Paste row after": "Paste row after",
"Alignment": "Alignment",
"Border color": "Border colour",
"Column group": "Column group",
"Row": "Row",
"Insert column before": "Insert column before",
"Split cell": "Split cell",
"Cell padding": "Cell padding",
"Cell spacing": "Cell spacing",
"Row type": "Row type",
"Insert table": "Insert table",
"Body": "Body",
"Caption": "Caption",
"Footer": "Footer",
"Delete row": "Delete row",
"Paste row before": "Paste row before",
"Scope": "Scope",
"Delete table": "Delete table",
"H Align": "H Align",
"Top": "Top",
"Header cell": "Header cell",
"Column": "Column",
"Row group": "Row group",
"Cell": "Cell",
"Middle": "Middle",
"Cell type": "Cell type",
"Copy row": "Copy row",
"Row properties": "Row properties",
"Table properties": "Table properties",
"Bottom": "Bottom",
"V Align": "V Align",
"Header": "Header",
"Right": "Right",
"Insert column after": "Insert column after",
"Cols": "Cols",
"Insert row after": "Insert row after",
"Width": "Width",
"Cell properties": "Cell properties",
"Left": "Left",
"Cut row": "Cut row",
"Delete column": "Delete column",
"Center": "Centre",
"Merge cells": "Merge cells",
"Insert template": "Insert template",
"Templates": "Templates",
"Background color": "Background colour",
"Custom...": "Custom...",
"Custom color": "Custom colour",
"No color": "No colour",
"Text color": "Text colour",
"Table of Contents": "Table of Contents",
"Show blocks": "Show blocks",
"Show invisible characters": "Show invisible characters",
"Words: {0}": "Words: {0}",
"Insert": "Insert",
"File": "File",
"Edit": "Edit",
"Rich Text Area. Press ALT-F9 for menu. Press ALT-F10 for toolbar. Press ALT-0 for help": "Rich Text Area. Press ALT-F9 for menu. Press ALT-F10 for toolbar. Press ALT-0 for help",
"Tools": "Tools",
"View": "View",
"Table": "Table",
"Format": "Format"
});
\ No newline at end of file
此差异已折叠。
/* PrismJS 1.14.0
https://prismjs.com/download.html#themes=prism&languages=markup+css+clike+javascript */
/**
* prism.js default theme for JavaScript, CSS and HTML
* Based on dabblet (http://dabblet.com)
* @author Lea Verou
*/
code[class*="language-"],
pre[class*="language-"] {
color: black;
background: none;
text-shadow: 0 1px white;
font-family: Consolas, Monaco, 'Andale Mono', 'Ubuntu Mono', monospace;
text-align: left;
white-space: pre;
word-spacing: normal;
word-break: normal;
word-wrap: normal;
line-height: 1.5;
-moz-tab-size: 4;
-o-tab-size: 4;
tab-size: 4;
-webkit-hyphens: none;
-moz-hyphens: none;
-ms-hyphens: none;
hyphens: none;
}
pre[class*="language-"]::-moz-selection, pre[class*="language-"] ::-moz-selection,
code[class*="language-"]::-moz-selection, code[class*="language-"] ::-moz-selection {
text-shadow: none;
background: #b3d4fc;
}
pre[class*="language-"]::selection, pre[class*="language-"] ::selection,
code[class*="language-"]::selection, code[class*="language-"] ::selection {
text-shadow: none;
background: #b3d4fc;
}
@media print {
code[class*="language-"],
pre[class*="language-"] {
text-shadow: none;
}
}
/* Code blocks */
pre[class*="language-"] {
padding: 1em;
margin: .5em 0;
overflow: auto;
}
:not(pre) > code[class*="language-"],
pre[class*="language-"] {
background: #f5f2f0;
}
/* Inline code */
:not(pre) > code[class*="language-"] {
padding: .1em;
border-radius: .3em;
white-space: normal;
}
.token.comment,
.token.prolog,
.token.doctype,
.token.cdata {
color: slategray;
}
.token.punctuation {
color: #999;
}
.namespace {
opacity: .7;
}
.token.property,
.token.tag,
.token.boolean,
.token.number,
.token.constant,
.token.symbol,
.token.deleted {
color: #905;
}
.token.selector,
.token.attr-name,
.token.string,
.token.char,
.token.builtin,
.token.inserted {
color: #690;
}
.token.operator,
.token.entity,
.token.url,
.language-css .token.string,
.style .token.string {
color: #9a6e3a;
background: hsla(0, 0%, 100%, .5);
}
.token.atrule,
.token.attr-value,
.token.keyword {
color: #07a;
}
.token.function,
.token.class-name {
color: #DD4A68;
}
.token.regex,
.token.important,
.token.variable {
color: #e90;
}
.token.important,
.token.bold {
font-weight: bold;
}
.token.italic {
font-style: italic;
}
.token.entity {
cursor: help;
}
.word-wrap{word-wrap:break-word;-ms-word-break:break-all;word-break:break-all;word-break:break-word;-ms-hyphens:auto;-moz-hyphens:auto;-webkit-hyphens:auto;hyphens:auto}.mce-content-body .mce-reset{margin:0;padding:0;border:0;outline:0;vertical-align:top;background:transparent;text-decoration:none;color:black;font-family:Arial;font-size:11px;text-shadow:none;float:none;position:static;width:auto;height:auto;white-space:nowrap;cursor:inherit;line-height:normal;font-weight:normal;text-align:left;-webkit-tap-highlight-color:transparent;-moz-box-sizing:content-box;-webkit-box-sizing:content-box;box-sizing:content-box;direction:ltr;max-width:none}.mce-object{border:1px dotted #3A3A3A;background:#D5D5D5 url(img/object.gif) no-repeat center}.mce-preview-object{display:inline-block;position:relative;margin:0 2px 0 2px;line-height:0;border:1px solid gray}.mce-preview-object[data-mce-selected="2"] .mce-shim{display:none}.mce-preview-object .mce-shim{position:absolute;top:0;left:0;width:100%;height:100%;background:url(data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7)}figure.align-left{float:left}figure.align-right{float:right}figure.image.align-center{display:table;margin-left:auto;margin-right:auto}figure.image{display:inline-block;border:1px solid gray;margin:0 2px 0 1px;background:#f5f2f0}figure.image img{margin:8px 8px 0 8px}figure.image figcaption{margin:6px 8px 6px 8px;text-align:center}.mce-toc{border:1px solid gray}.mce-toc h2{margin:4px}.mce-toc li{list-style-type:none}.mce-pagebreak{cursor:default;display:block;border:0;width:100%;height:5px;border:1px dashed #666;margin-top:15px;page-break-before:always}@media print{.mce-pagebreak{border:0}}.mce-item-anchor{cursor:default;display:inline-block;-webkit-user-select:all;-webkit-user-modify:read-only;-moz-user-select:all;-moz-user-modify:read-only;user-select:all;user-modify:read-only;width:9px !important;height:9px !important;border:1px dotted #3A3A3A;background:#D5D5D5 url(img/anchor.gif) no-repeat center}.mce-nbsp,.mce-shy{background:#AAA}.mce-shy::after{content:'-'}.mce-match-marker{background:#AAA;color:#fff}.mce-match-marker-selected{background:#3399ff;color:#fff}.mce-spellchecker-word{border-bottom:2px solid rgba(208,2,27,0.5);cursor:default}.mce-spellchecker-grammar{border-bottom:2px solid #008000;cursor:default}.mce-item-table,.mce-item-table td,.mce-item-table th,.mce-item-table caption{border:1px dashed #BBB}td[data-mce-selected],th[data-mce-selected]{background-color:#2276d2 !important}.mce-edit-focus{outline:1px dotted #333}.mce-content-body *[contentEditable=false] *[contentEditable=true]:focus{outline:2px solid #2276d2}.mce-content-body *[contentEditable=false] *[contentEditable=true]:hover{outline:2px solid #2276d2}.mce-content-body *[contentEditable=false][data-mce-selected]{outline:2px solid #2276d2}.mce-content-body.mce-content-readonly *[contentEditable=true]:focus,.mce-content-body.mce-content-readonly *[contentEditable=true]:hover{outline:none}.mce-content-body *[data-mce-selected="inline-boundary"]{background:#bfe6ff}.mce-content-body .mce-item-anchor[data-mce-selected]{background:#D5D5D5 url(img/anchor.gif) no-repeat center}.mce-content-body hr{cursor:default}.mce-content-body table{-webkit-nbsp-mode:normal}.ephox-snooker-resizer-bar{background-color:#2276d2;opacity:0}.ephox-snooker-resizer-cols{cursor:col-resize}.ephox-snooker-resizer-rows{cursor:row-resize}.ephox-snooker-resizer-bar.ephox-snooker-resizer-bar-dragging{opacity:.2}.mce-content-body{line-height:1.3}
\ No newline at end of file
body{background-color:#FFFFFF;color:#000000;font-family:Verdana,Arial,Helvetica,sans-serif;font-size:14px;line-height:1.3;scrollbar-3dlight-color:#F0F0EE;scrollbar-arrow-color:#676662;scrollbar-base-color:#F0F0EE;scrollbar-darkshadow-color:#DDDDDD;scrollbar-face-color:#E0E0DD;scrollbar-highlight-color:#F0F0EE;scrollbar-shadow-color:#F0F0EE;scrollbar-track-color:#F5F5F5}td,th{font-family:Verdana,Arial,Helvetica,sans-serif;font-size:14px}.word-wrap{word-wrap:break-word;-ms-word-break:break-all;word-break:break-all;word-break:break-word;-ms-hyphens:auto;-moz-hyphens:auto;-webkit-hyphens:auto;hyphens:auto}.mce-content-body .mce-reset{margin:0;padding:0;border:0;outline:0;vertical-align:top;background:transparent;text-decoration:none;color:black;font-family:Arial;font-size:11px;text-shadow:none;float:none;position:static;width:auto;height:auto;white-space:nowrap;cursor:inherit;line-height:normal;font-weight:normal;text-align:left;-webkit-tap-highlight-color:transparent;-moz-box-sizing:content-box;-webkit-box-sizing:content-box;box-sizing:content-box;direction:ltr;max-width:none}.mce-object{border:1px dotted #3A3A3A;background:#D5D5D5 url(img/object.gif) no-repeat center}.mce-preview-object{display:inline-block;position:relative;margin:0 2px 0 2px;line-height:0;border:1px solid gray}.mce-preview-object[data-mce-selected="2"] .mce-shim{display:none}.mce-preview-object .mce-shim{position:absolute;top:0;left:0;width:100%;height:100%;background:url(data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7)}figure.align-left{float:left}figure.align-right{float:right}figure.image.align-center{display:table;margin-left:auto;margin-right:auto}figure.image{display:inline-block;border:1px solid gray;margin:0 2px 0 1px;background:#f5f2f0}figure.image img{margin:8px 8px 0 8px}figure.image figcaption{margin:6px 8px 6px 8px;text-align:center}.mce-toc{border:1px solid gray}.mce-toc h2{margin:4px}.mce-toc li{list-style-type:none}.mce-pagebreak{cursor:default;display:block;border:0;width:100%;height:5px;border:1px dashed #666;margin-top:15px;page-break-before:always}@media print{.mce-pagebreak{border:0}}.mce-item-anchor{cursor:default;display:inline-block;-webkit-user-select:all;-webkit-user-modify:read-only;-moz-user-select:all;-moz-user-modify:read-only;user-select:all;user-modify:read-only;width:9px !important;height:9px !important;border:1px dotted #3A3A3A;background:#D5D5D5 url(img/anchor.gif) no-repeat center}.mce-nbsp,.mce-shy{background:#AAA}.mce-shy::after{content:'-'}.mce-match-marker{background:#AAA;color:#fff}.mce-match-marker-selected{background:#3399ff;color:#fff}.mce-spellchecker-word{border-bottom:2px solid rgba(208,2,27,0.5);cursor:default}.mce-spellchecker-grammar{border-bottom:2px solid #008000;cursor:default}.mce-item-table,.mce-item-table td,.mce-item-table th,.mce-item-table caption{border:1px dashed #BBB}td[data-mce-selected],th[data-mce-selected]{background-color:#2276d2 !important}.mce-edit-focus{outline:1px dotted #333}.mce-content-body *[contentEditable=false] *[contentEditable=true]:focus{outline:2px solid #2276d2}.mce-content-body *[contentEditable=false] *[contentEditable=true]:hover{outline:2px solid #2276d2}.mce-content-body *[contentEditable=false][data-mce-selected]{outline:2px solid #2276d2}.mce-content-body.mce-content-readonly *[contentEditable=true]:focus,.mce-content-body.mce-content-readonly *[contentEditable=true]:hover{outline:none}.mce-content-body *[data-mce-selected="inline-boundary"]{background:#bfe6ff}.mce-content-body .mce-item-anchor[data-mce-selected]{background:#D5D5D5 url(img/anchor.gif) no-repeat center}.mce-content-body hr{cursor:default}.mce-content-body table{-webkit-nbsp-mode:normal}.ephox-snooker-resizer-bar{background-color:#2276d2;opacity:0}.ephox-snooker-resizer-cols{cursor:col-resize}.ephox-snooker-resizer-rows{cursor:row-resize}.ephox-snooker-resizer-bar.ephox-snooker-resizer-bar-dragging{opacity:.2}
\ No newline at end of file
.tinymce-mobile-unfocused-selections .tinymce-mobile-unfocused-selection{position:absolute;display:inline-block;background-color:green;opacity:.5}body{-webkit-text-size-adjust:none}body img{max-width:96vw}body table img{max-width:95%}
\ No newline at end of file
<template>
<div id='app'>
<router-view/>
</div>
</template>
import { ViewTool } from './utils/view-tool/view-tool';
import { UIActionTool } from './utils/uiaction-tool/uiaction-tool';
import { Verify } from './utils/verify/verify';
import { Util } from './utils/util/util';
import { Http } from './utils/http/http';
import { AppPopover } from './utils/app-popover/app-popover';
import { AppModal } from './utils/app-modal/app-modal';
import { AppDrawer } from './utils/app-drawer/app-drawer';
import InputBox from './components/input-box/input-box.vue'
import AppKeepAlive from './components/app-keep-alive/app-keep-alive.vue'
import TabPageExp from './components/tab-page-exp/tab-page-exp.vue'
import AppLang from './components/app-lang/app-lang.vue'
import AppTheme from './components/app-theme/app-theme.vue'
import AppUser from './components/app-user/app-user.vue'
import AppForm from './components/app-form/app-form.vue'
import APPAutocomplete from './components/app-autocomplete/app-autocomplete.vue'
import AppFormDruipart from './components/app-form-druipart/app-form-druipart.vue'
import DropdownList from './components/dropdown-list/dropdown-list.vue'
import UploadFile from './components/upload-file/upload-file.vue'
import ContextMenuContainer from './components/context-menu-container/context-menu-container.vue'
import AppCheckboxList from './components/app-checkbox-list/app-checkbox-list.vue'
import AppRadioGroup from './components/app-radio-group/app-radio-group.vue'
import AppEmbedPicker from './components/app-embed-picker/app-embed-picker.vue'
import AppTreePicker from './components/app-tree-picker/app-tree-picker.vue'
import AppRichTextEditor from './components/app-rich-text-editor/app-rich-text-editor.vue'
import AppFileUpload from './components/app-file-upload/app-file-upload.vue'
import AppImageUpload from './components/app-image-upload/app-image-upload.vue'
import PropertyLayout from './components/property-layout/property-layout.vue'
import AppRangeEditor from './components/app-range-editor/app-range-editor.vue'
import AppExportExcel from './components/app-export-excel/app-export-excel.vue'
import AppFormGroup from './components/app-form-group/app-form-group.vue'
import AppFormItem from './components/app-form-item/app-form-item.vue'
import AppPicker from './components/app-picker/app-picker.vue'
import AppMpicker from './components/app-mpicker/app-mpicker.vue'
import AppFormGroup2 from './components/app-form-group2/app-form-group2.vue'
import AppFormItem2 from './components/app-form-item2/app-form-item2.vue'
import CodeList from './components/codelist/codelist.vue'
import AppQuickMenus from './components/app-quick-menus/app-quick-menus.vue'
import AppCheckbox from './components/app-checkbox/app-checkbox.vue'
import AppColumnRender from './components/app-column-render/app-column-render.vue'
import AppPickerSelectView from './components/app-picker-select-view/app-picker-select-view.vue'
import AppSiderMenus from './components/app-sider-menus/app-sider-menus.vue'
import AppSpan from './components/app-span/app-span.vue'
import AppAddressSelection from './components/app-address-selection/app-address-selection.vue'
import DropdownListMpicker from './components/dropdown-list-mpicker/dropdown-list-mpicker.vue'
import AppRate from './components/app-rate/app-rate.vue'
import appInputNumber from './components/app-input-number/app-input-number.vue'
import AppSwitch from './components/app-switch/app-switch.vue'
import AppFileUploadDrag from './components/app-file-upload-drag/app-file-upload-drag.vue'
export const AppComponents = {
install(v: any, opt: any) {
v.prototype.$appdrawer = AppDrawer.getInstance();
v.prototype.$appmodal = AppModal.getInstance();
v.prototype.$apppopover = AppPopover.getInstance();
v.prototype.$http = Http.getInstance();
v.prototype.$util = Util;
v.prototype.$verify = Verify;
v.prototype.$viewTool = ViewTool;
v.prototype.$uiActionTool = UIActionTool;
v.component('input-box', InputBox);
v.component('app-keep-alive',AppKeepAlive);
v.component('tab-page-exp',TabPageExp);
v.component('app-lang',AppLang);
v.component('app-theme',AppTheme);
v.component('app-user',AppUser);
v.component('app-form', AppForm);
v.component('app-autocomplete', APPAutocomplete);
v.component('app-form-druipart', AppFormDruipart);
v.component('dropdown-list', DropdownList);
v.component('upload-file', UploadFile);
v.component('context-menu-container', ContextMenuContainer);
v.component('app-checkbox-list',AppCheckboxList);
v.component('app-radio-group',AppRadioGroup);
v.component('app-embed-picker', AppEmbedPicker);
v.component('app-tree-picker', AppTreePicker);
v.component('app-rich-text-editor',AppRichTextEditor);
v.component('app-file-upload',AppFileUpload);
v.component('app-image-upload',AppImageUpload);
v.component('property-layout',PropertyLayout);
v.component('app-range-editor',AppRangeEditor);
v.component('app-export-excel',AppExportExcel);
v.component('app-form-group',AppFormGroup);
v.component('app-form-item',AppFormItem);
v.component('app-picker', AppPicker);
v.component('app-mpicker', AppMpicker);
v.component('app-form-group2', AppFormGroup2);
v.component('app-form-item2', AppFormItem2);
v.component('codelist', CodeList);
v.component('app-quick-menus', AppQuickMenus);
v.component('app-checkbox',AppCheckbox);
v.component('app-column-render',AppColumnRender);
v.component('app-picker-select-view',AppPickerSelectView);
v.component('app-sider-menus',AppSiderMenus);
v.component('app-span', AppSpan);
v.component('app-address-selection', AppAddressSelection);
v.component('dropdown-list-mpicker', DropdownListMpicker);
v.component('app-rate', AppRate);
v.component('app-input-number', appInputNumber);
v.component('app-switch', AppSwitch);
v.component('app-file-upload-drag', AppFileUploadDrag);
},
};
\ No newline at end of file
此差异已折叠。
html, body {
height: 100%;
}
.app-error-view {
height: 100%;
width: 100%;
position: relative;
.app-error-container {
height: 380px;
width: 670px;
position: absolute;
top: calc((100% - 400px) / 2);
left: calc((100% - 670px) / 2);
display: flex;
align-items: center;
.error-text {
padding-left: 20px;
.error-text1 {
font-size: 20px;
margin-bottom: 20px;
}
.error-text2 {
font-size: 14px;
}
}
}
}
\ No newline at end of file
<template>
<div class="app-error-view">
<div class="app-error-container">
<img src="/assets/img/404.png" />
<div class="error-text">
<div class="error-text1">抱歉,您访问的页面不存在!</div>
<div class="error-text2">您要找的页面存在,请返回 <a on-click={this.gotoIndexView}>首页</a> 继续浏览</div>
</div>
</div>
</div>
</template>
<script lang="ts">
import { Vue, Component } from 'vue-property-decorator';
@Component({})
export default class Error404 extends Vue {
/**
* 跳转首页
*
* @memberof Error404
*/
public gotoIndexView() {
this.$router.push('/');
}
}
</script>
<style lang='less'>
@import './404.less';
</style>
\ No newline at end of file
html, body {
height: 100%;
}
.app-error-view {
height: 100%;
width: 100%;
position: relative;
.app-error-container {
height: 380px;
width: 670px;
position: absolute;
top: calc((100% - 400px) / 2);
left: calc((100% - 670px) / 2);
display: flex;
align-items: center;
.error-text {
padding-left: 20px;
.error-text1 {
font-size: 20px;
margin-bottom: 20px;
}
.error-text2 {
font-size: 14px;
}
}
}
}
\ No newline at end of file
<template>
<div class="app-error-view">
<div class="app-error-container">
<img src="/assets/img/500.png" />
<div class="error-text">
<div class="error-text1">抱歉,服务器出错了!</div>
<div class="error-text2">服务器出错了,请返回 <a on-click={this.gotoIndexView}>首页</a> 继续浏览</div>
</div>
</div>
</div>
</template>
<script lang="ts">
import { Vue, Component } from 'vue-property-decorator';
@Component({})
export default class Error404 extends Vue {
/**
* 跳转首页
*
* @memberof Error404
*/
public gotoIndexView() {
this.$router.push('/');
}
}
</script>
<style lang='less'>
@import './500.less';
</style>
\ No newline at end of file
<template>
<div class="appAddressSelection">
<el-cascader
:disabled="disabled"
size ="medium"
v-model="CurrentVal"
:options="city">
</el-cascader>
</div>
</template>
<script lang='ts'>
import { Component, Vue, Prop, Model, Watch } from 'vue-property-decorator';
import { Subject } from 'rxjs';
import { debounceTime, distinctUntilChanged } from 'rxjs/operators';
import axios from 'axios';
@Component({})
export default class AppAddressSelection extends Vue {
/**
* 传入值
* @type {any}
* @memberof AppAddressSelection
*/
@Prop() public value?:any;
/**
* 是否禁用
* @type {boolean}
* @memberof AppAddressSelection
*/
@Prop() public disabled?: boolean;
/**
* 当前值
*
* @memberof AppAddressSelection
*/
get CurrentVal() {
return this.value;
}
/**
* 值变化
*
* @memberof AppAddressSelection
*/
set CurrentVal(val: any) {
this.$emit("change", val);
}
/**
* 城市数据
*
* @memberof AppAddressSelection
*/
public city :any = [];
/**
* 获取城市数据
*
* @memberof AppAddressSelection
*/
public getcity() {
axios.get("../../assets/json/city_code.json").then((response: any) => {
this.format(response.data);
}).catch((response: any) => {
console.log("城市数据加载失败");
});
}
/**
* 生命周期
*
* @memberof AppAddressSelection
*/
public created() {
this.getcity();
}
/**
* 数据格式化
*
* @memberof AppAddressSelection
*/
public format(data :any) {
let data1 = JSON.parse(JSON.stringify(data).replace(/city/g, 'children'))
let data2 = JSON.parse(JSON.stringify(data1).replace(/name/g, 'label'))
let data3 = JSON.parse(JSON.stringify(data2).replace(/area/g, 'children'))
let data4 = JSON.parse(JSON.stringify(data3).replace(/code/g, 'value'))
this.city = data4;
}
}
</script>
<style lang='less'>
@import './app-address-selection.less';
</style>
\ No newline at end of file
.ivu-auto-complete {
.ivu-select-dropdown-list {
height: 300px;
}
}
<template>
<el-autocomplete
class='text-value'
:value-key="deMajorField"
:disabled="disabled"
v-model="curvalue"
size='small'
:trigger-on-focus="true"
:fetch-suggestions="onSearch"
@select="onACSelect"
@input="onInput"
@blur="onBlur"
style='width:100%;'>
<template v-slot:suffix>
<i v-if="curvalue && !disabled" class='el-icon-circle-close' @click="onClear"></i>
<i class="el-icon-arrow-down"></i>
</template>
</el-autocomplete>
</template>
<script lang='ts'>
import { Component, Vue, Prop, Model, Watch } from 'vue-property-decorator';
import { Subject } from 'rxjs';
import { debounceTime, distinctUntilChanged } from 'rxjs/operators';
@Component({})
export default class AppAutocomplete extends Vue {
/**
* 表单数据
*
* @type {*}
* @memberof AppAutocomplete
*/
@Prop() public data: any;
/**
* 视图上下文
*
* @type {*}
* @memberof AppAutocomplete
*/
@Prop() public context!: any;
/**
* 视图参数
*
* @type {*}
* @memberof AppFormDRUIPart
*/
@Prop() public viewparams!: any;
/**
* AC参数
*
* @type {*}
* @memberof AppFormDRUIPart
*/
@Prop({default: {}}) public acParams?: any;
/**
* 表单服务
*
* @type {*}
* @memberof AppFormDRUIPart
*/
@Prop() public service?: any;
/**
* 应用实体主信息属性名称
*
* @type {string}
* @memberof AppAutocomplete
*/
@Prop({default: 'srfmajortext'}) public deMajorField!: string;
/**
* 应用实体主键属性名称
*
* @type {string}
* @memberof AppAutocomplete
*/
@Prop({default: 'srfkey'}) public deKeyField!: string;
/**
* 是否启用
*
* @type {boolean}
* @memberof AppAutocomplete
*/
@Prop() public disabled?: boolean;
/**
* 属性项名称
*
* @type {string}
* @memberof AppAutocomplete
*/
@Prop() public name!: string;
/**
* 编辑器参数
*
* @type {string}
* @memberof AppAutocomplete
*/
@Prop() public itemParam?: any;
/**
* 值项名称
*
* @type {string}
* @memberof AppAutocomplete
*/
@Prop() public valueitem?: string;
/**
* 值
*
* @type {*}
* @memberof AppPicker
*/
@Model('change') public value?: any;
/**
* 当前值
*
* @type {string}
* @memberof AppPicker
*/
public curvalue: string = '';
/**
* 远程请求url 地址
*
* @type {string}
* @memberof AppAutocomplete
*/
@Prop() public url?: string;
/**
* 数组
*
* @type {any[]}
* @memberof AppAutocomplete
*/
public items: any[] = [];
/**
* 输入状态
*
* @type {boolean}
* @memberof AppAutocomplete
*/
public inputState: boolean = false;
/**
* 值变化
*
* @param {*} newVal
* @param {*} oldVal
* @memberof AppPicker
*/
@Watch('value')
public onValueChange(newVal: any, oldVal: any) {
this.curvalue = newVal;
}
/**
* 执行搜索数据
* @param query
* @param callback
*/
public onSearch(query: any, callback: any): void {
// 处理搜索参数
query = !query ? '' : query;
if (!this.inputState && Object.is(query, this.value)) {
query = '';
}
this.inputState = false;
// 合并视图上下文参数和视图参数
let param: any = JSON.parse(JSON.stringify(this.viewparams));
let context: any = JSON.parse(JSON.stringify(this.context));
Object.assign(param, { query: query });
// 附加参数处理
if (this.itemParam.context) {
let _context = this.$util.formatData(this.data,this.itemParam.context);
Object.assign(context,_context);
}
if (this.itemParam.param) {
let _param = this.$util.formatData(this.data,this.itemParam.param);
Object.assign(param,_param);
}
if (this.itemParam.parentdata) {
let _parentdata = this.$util.formatData(this.data,this.itemParam.parentdata);
Object.assign(param,_parentdata);
}
if(!this.service){
this.$Notice.error({ title: '错误', desc: '缺少参数service' });
} else if(!this.acParams.serviceName) {
this.$Notice.error({ title: '错误', desc: '缺少参数serviceName' });
} else if(!this.acParams.interfaceName) {
this.$Notice.error({ title: '错误', desc: '缺少参数interfaceName' });
} else {
this.service.getItems(this.acParams.serviceName,this.acParams.interfaceName, context, param).then((response: any) => {
if (!response) {
this.$Notice.error({ title: '错误', desc: '请求异常' });
} else {
this.items = [...response];
}
if (callback) {
callback(this.items);
}
}).catch((error: any) => {
if (callback) {
callback([]);
}
});
}
}
/**
* 选中数据回调
* @param item
*/
public onACSelect(item: any): void {
if (this.name) {
this.$emit('formitemvaluechange', { name: this.name, value: item[this.deMajorField] });
}
if (this.valueitem) {
this.$emit('formitemvaluechange', { name: this.valueitem, value: item[this.deKeyField] });
}
}
/**
* 输入过程中
*
* @memberof AppAutocomplete
*/
public onInput($event: any) {
if (Object.is($event, this.value)) {
this.inputState = true;
}
}
/**
* 失去焦点事件
* @param e
*/
public onBlur(e: any): void {
let val: string = e.target.value;
if (!Object.is(val, this.value)) {
this.onACSelect({ [this.deMajorField]: val, [this.deKeyField]: '' });
}
this.$forceUpdate();
}
/**
* 清除
*/
public onClear($event: any): void {
if (this.name) {
this.$emit('formitemvaluechange', { name: this.name, value: '' });
}
if (this.valueitem) {
this.$emit('formitemvaluechange', { name: this.valueitem, value: '' });
}
this.$forceUpdate();
}
}
</script>
<style lang='less'>
@import './app-autocomplete.less';
</style>
\ No newline at end of file
.app-checkbox-list {
overflow: auto;
}
\ No newline at end of file
<template>
<checkbox-group class="app-checkbox-list" v-model="selectArray">
<checkbox v-for="(item,index) in items" :key="index" :label="item.value" :disabled="isDisabled || item.disabled">
<span>{{item.text}}</span>
</checkbox>
</checkbox-group >
</template>
<script lang="ts">
import { Component, Vue, Prop, Model } from 'vue-property-decorator';
import CodeListService from "@service/app/codelist-service";
@Component({})
export default class AppCheckBox extends Vue {
/**
* 代码表服务对象
*
* @type {CodeListService}
* @memberof AppCheckBox
*/
public codeListService:CodeListService = new CodeListService({ $store: this.$store });
/**
* 代码表标识
*
* @type {string}
* @memberof AppCheckBox
*/
@Prop() public tag?: string;
/**
* 代码表类型
*
* @type {string}
* @memberof AppCheckBox
*/
@Prop() public codelistType?: string;
/**
* 是否禁用
*
* @type {boolean}
* @memberof AppCheckBox
*/
@Prop() disabled?: boolean;
/**
* 获取启用禁用状态
*
* @readonly
* @memberof AppCheckBox
*/
get isDisabled() {
if (this.disabled) {
return true;
} else {
return false;
}
}
/**
* 属性名称
*
* @type {*}
* @memberof AppCheckBox
*/
@Prop() name?: any;
/**
* 模式(数字或者字符串)
*
* @type {*}
* @memberof AppCheckBox
*/
@Prop() mode: any;
/**
* 当前模式
*
* @readonly
* @memberof AppCheckBox
*/
get currentmode() {
if (this.mode) {
return this.mode;
} else {
return 'str';
}
}
/**
* 分隔符
*
* @type {*}
* @memberof AppCheckBox
*/
@Prop() separator: any;
/**
* 获取分隔符
*
* @readonly
* @memberof AppCheckBox
*/
get currentseparator() {
if (this.separator) {
return this.separator;
} else {
return ';';
}
}
/**
* 选中值
*
* @type {*}
* @memberof AppCheckBox
*/
@Model('change') selects?: any;
/**
* 选中数组
*
* @memberof AppCheckBox
*/
get selectArray() {
if (this.selects) {
if (Object.is(this.currentmode, 'num') && this.items) {
let selectsArray: Array<any> = [];
let num: number = parseInt(this.selects, 10);
this.items.forEach((item: any) => {
if ((num & item.value) == item.value) {
selectsArray.push(item.value);
}
});
return selectsArray;
} else if (Object.is(this.currentmode, 'str')) {
if (this.selects !== '') {
return this.selects.split(this.currentseparator);
}
}
} else {
return [];
}
}
/**
* 设置选中
*
* @memberof AppCheckBox
*/
set selectArray(val: any) {
let value: null | string | number = null;
if (Object.is(this.currentmode, 'num')) {
let temp: number = 0;
val.forEach((item: any) => {
temp = temp | parseInt(item, 10);
});
value = temp;
} else if (Object.is(this.currentmode, 'str')) {
let _datas: string[] = [];
this.items.forEach((item: any) => {
const index = val.findIndex((_key: any) => Object.is(item.value, _key));
if (index === -1) {
return;
}
_datas.push(item.value);
});
value = _datas.join(this.currentseparator);
}
this.$emit('change', value);
}
/**
* 代码表数组
*
* @type {any[]}
* @memberof AppCheckBox
*/
public items: any[] = [];
/**
* vue 生命周期
*
* @memberof AppCheckBox
*/
public created() {
if(this.tag){
if (Object.is(this.codelistType,"STATIC")) {
const codelist = this.$store.getters.getCodeList(this.tag);
if (codelist) {
this.items = [...JSON.parse(JSON.stringify(codelist.items))];
} else {
console.log(`----${this.tag}----代码表不存在`);
}
} else if (Object.is(this.codelistType,"DYNAMIC")) {
this.codeListService.getItems(this.tag).then((res:any) => {
this.items = res;
}).catch((error:any) => {
console.log(`----${this.tag}----代码表不存在`);
});
}
}
}
}
</script>
<style lang='less'>
@import './app-checkbox-list.less';
</style>
\ No newline at end of file
.app-checkbox-list {
overflow: auto;
}
\ No newline at end of file
<template>
<div class="checkbox">
<checkbox v-model="CurrentVal" :disabled="disabled"></checkbox>
</div>
</template>
<script lang="ts">
import { Vue, Component, Prop, Model, Emit } from "vue-property-decorator";
import { Subject } from "rxjs";
import { debounceTime, distinctUntilChanged } from "rxjs/operators";
@Component({})
export default class AppCheckbox extends Vue {
/**
* 传入值
* @type {any}
* @memberof checkbox
*/
@Prop() public value?:any;
/**
* 是否禁用
* @type {boolean}
* @memberof checkbox
*/
@Prop() public disabled?: boolean;
/**
* 当前值
*
* @memberof checkbox
*/
get CurrentVal() {
if(this.value == 0){
return false;
}else if(this.value ==1){
return true;
}
}
/**
* 值变化
*
* @memberof checkbox
*/
set CurrentVal(val: any) {
this.$emit("change", val?1:0);
}
}
</script>
<style lang='less'>
@import "./app-checkbox.less";
</style>
\ No newline at end of file
.column-render{
.input-unit{
display: inline-block;
}
}
\ No newline at end of file
<template>
<div class="column-render">
{{textValue}}
<template v-if="Object.is(type,'input')">
<input-box :disabled="disabled" v-model="editorvalue" @change="($event)=>{onEditorValueChange($event)}"></input-box>
</template>
<template v-else-if="Object.is(type,'dropdown')">
<i-select v-model="editorvalue" :disabled="disabled" :clearable="true" placeholder='请选择...' >
<i-option v-for="(item, index) in codelist" :key="index" :value="item.value">{{item.text}}</i-option>
</i-select>
</template>
<template v-else>
<span>{{type}}不支持</span>
</template>
</div>
</template>
<script lang="ts">
import { Vue, Component, Prop, Model, Emit, Watch } from "vue-property-decorator";
import { Subject } from "rxjs";
import { debounceTime, distinctUntilChanged } from "rxjs/operators";
@Component({})
export default class AppColumnRender extends Vue {
/**
* 值
* @type {any}
* @memberof AppColumnRender
*/
@Prop() public value?: any;
/**
* 是否禁用
* @type {boolean}
* @memberof AppColumnRender
*/
@Prop() public disabled?: boolean;
/**
* 列字段名称
*
* @type {string}
* @memberof AppColumnRender
*/
@Prop() public name?: string;
/**
* 表格行数据
*
* @type {string}
* @memberof AppColumnRender
*/
@Prop() public row?: any;
/**
* 自定义样式
*
* @type {string}
* @memberof AppColumnRender
*/
@Prop() public customStyle?: string;
/**
* 文本信息
* @type {String}
* @memberof AppColumnRender
*/
public textValue: string = "";
/**
* 编辑器类型
* @type {String}
* @memberof AppColumnRender
*/
public type: string = "";
/**
* 值项名称
*
* @type {string}
* @memberof AppColumnRender
*/
public valueitem: string = "";
/**
* 编辑器值
* @type {any}
* @memberof AppColumnRender
*/
public editorvalue: any = "";
/**
* 代码表选项数组
* @memberof AppColumnRender
*/
public codelist: any = [];
public created(){
this.onValueChange(this.value,"");
}
/**
* 自定义列值监控
*
* @param {*} newVal
* @param {*} oldVal
* @memberof AppColumnRender
*/
@Watch('value')
onValueChange(newVal: any, oldVal: any) {
if (newVal) {
let arrs = newVal.split("%");
this.textValue = arrs[0];
let params = [];
if(arrs[1]){
(arrs[1].split(";")).forEach((item:any)=>{
let temp = item.split("=");
if(Object.is(temp[0], "type")){
this.type = temp[1];
} else if(Object.is(temp[0], "value")) {
this.valueitem = temp[1];
if(this.valueitem && this.row[this.valueitem]){
this.editorvalue = this.row[this.valueitem];
}
} else if(Object.is(temp[0], "codelist")) {
this.codelist = temp[1];
}
});
}
}
}
/**
* 编辑器值变化回调
* @param item
*/
public onEditorValueChange(item: any): void {
if (this.name) {
// this.$emit('griditemvaluechange', { name: this.name, value: item });
}
if (this.valueitem) {
this.$emit('griditemvaluechange', { name: this.valueitem, value: item });
}
}
}
</script>
<style lang='less'>
@import "./app-column-render.less";
</style>
\ No newline at end of file
.app-embed-picker {
.app-embed-value, .app-embed-placeholder {
line-height: 32px;
height: 32px;
}
.app-embed-placeholder {
color: #c1c1c1;
}
> .ivu-card {
> .ivu-card-body {
> .content-container {
margin: 0;
}
}
}
}
\ No newline at end of file
<template>
<div v-if="refviewname" class="app-embed-picker">
<div :style="{ height: placeholder ? 'calc(100% - 32px)' : '100%' }">
<component
:is="refviewname"
:viewdata="viewdata"
:viewparam="viewparam"
:viewDefaultUsage="false"
@viewdataschange="setValue(args)"
style="height:100%;">
</component>
</div>
<template v-if="placeholder">
<div v-if="value" class="app-embed-value">{this.value}</div>
<div v-else class="app-embed-placeholder">{this.placeholder}</div>
</template>
</div>
<div v-else>{{emptyText}}</div>
</template>
<script lang="ts">
import { Vue, Component, Prop, Watch } from 'vue-property-decorator';
import { CreateElement } from 'vue';
import { Subject, Subscription } from 'rxjs';
@Component({})
export default class AppEmbedPicker extends Vue {
/**
* 视图上下文
*
* @type {*}
* @memberof AppFormDRUIPart
*/
@Prop() public context!: any;
/**
* 视图参数
*
* @type {*}
* @memberof AppFormDRUIPart
*/
@Prop() public viewparams!: any;
/**
* 视图参数
*
* @type {string}
* @memberof AppTreePicker
*/
public viewparam: any = JSON.stringify(this.viewparams);;
/**
* 视图参数
*
* @type {string}
* @memberof AppTreePicker
*/
public viewdata: any = JSON.stringify(this.context);
/**
* 表单数据
*
* @type {*}
* @memberof AppPicker
*/
@Prop() public data!: any;
/**
* 值
*
* @type {*}
* @memberof AppEmbedPicker
*/
@Prop() public value: any;
/**
* 表单状态
*
* @type {Subject<any>}
* @memberof AppEmbedPicker
*/
@Prop() public formState!: Subject<any>
/**
* 视图状态事件
*
* @protected
* @type {(Subscription | undefined)}
* @memberof SelectType
*/
protected formStateEvent: Subscription | undefined;
/**
* 值项名称
*
* @type {string}
* @memberof AppPicker
*/
@Prop() public valueItem?: string;
/**
* 关联视图名称
*
* @type {string}
* @memberof AppPicker
*/
@Prop() public refviewname?: string;
/**
* 提示信息
*
* @type {string}
* @memberof AppEmbedPicker
*/
@Prop() public placeholder!: string;
/**
* 空值文本
*
* @type {string}
* @memberof EmbedPicker
*/
@Prop() public emptyText?: string;
/**
* 属性项名称
*
* @type {string}
* @memberof AppPicker
*/
@Prop() public name!: string;
/**
* 关联视图参数
*
* @type {*}
* @memberof AppEmbedPicker
*/
@Prop() public itemParam: any;
/**
* 是否忽略之变化
*
* @type {boolean}
* @memberof AppEmbedPicker
*/
@Prop() public ignorefieldvaluechange!: boolean;
/**
* 重置项
*
* @type {string}
* @memberof AppEmbedPicker
*/
@Prop() public refreshitems?: string;
/**
* 设置视图参数
*
* @memberof AppEmbedPicker
*/
public setViewParam(activeData: any) {
if (!this.itemParam || !activeData) {
return;
}
let arg: any = {};
// 合并视图上下文参数和视图参数
let param: any = JSON.parse(JSON.stringify(this.viewparams));
let context: any = JSON.parse(JSON.stringify(this.context));
// 附加参数处理
if (this.itemParam.context) {
let _context = this.$util.formatData(activeData,this.itemParam.context);
Object.assign(context,_context);
}
if (this.itemParam.param) {
let _param = this.$util.formatData(activeData,this.itemParam.param);
Object.assign(param,_param);
}
if (this.itemParam.parentdata) {
let _parentdata = this.$util.formatData(activeData,this.itemParam.parentdata);
Object.assign(param,_parentdata);
}
this.viewdata = JSON.stringify(context);
this.viewparam = JSON.stringify(param);
}
/**
* 监控值
*
* @param {*} newVal
* @param {*} oldVal
* @memberof AppFormDRUIPart
*/
@Watch('data')
onActivedataChange(newVal: any, oldVal: any) {
const newFormData: any = JSON.parse(newVal);
const oldDormData: any = JSON.parse(oldVal);
this.setViewParam(newFormData);
if (!this.refreshitems || this.ignorefieldvaluechange) {
return;
}
if(Object.is(newFormData[this.refreshitems], oldDormData[this.refreshitems])) {
return;
}
this.setValue([{srfmajortext: null, srfkey: null}]);
}
/**
* 生命周期
*
* @memberof AppEmbedPicker
*/
public created() {
if(this.formState) {
this.formStateEvent = this.formState.subscribe(({ tag, action, data }) => {
if (Object.is('load', action)) {
this.setViewParam(JSON.parse(this.data));
}
});
}
}
/**
* vue 生命周期
*
* @memberof SelectType
*/
public destroyed() {
if (this.formStateEvent) {
this.formStateEvent.unsubscribe();
}
}
/**
* 设置值
*
* @param {*} item
* @memberof AppEmbedPicker
*/
public setValue(item: any) {
if (this.valueItem) {
this.$emit('formitemvaluechange', { name: this.valueItem, value: item[0].srfkey });
}
if (this.name) {
this.$emit('formitemvaluechange', { name: this.name, value: item[0].srfmajortext });
}
}
}
</script>
<style lang='less'>
@import './app-embed-picker.less';
</style>
\ No newline at end of file
<template>
<dropdown v-if="itemLevel === 0" :transfer="true" trigger='click'>
<i-button :disabled="item.disabled">
<i class='fa fa-file-excel-o'></i>
<span class='caption'>{{item.caption}}</span>
</i-button>
<dropdown-menu slot='list'>
<dropdown-item>
<p @click="exportExcel($event, 'maxRowCount')">
{{item.caption}}全部(最大{{item.caption}}{{item.MaxRowCount}}行)
</p>
</dropdown-item>
<dropdown-item>
<p @click="exportExcel($event, 'activatedPage')">
{{this.item.caption}}当前页
</p>
</dropdown-item>
</dropdown-menu>
</dropdown>
</template>
<script lang="ts">
import { Vue, Component, Prop, Watch } from 'vue-property-decorator';
/**
* 数据导出组件
*
* @export
* @class AppExportExcel
* @extends {Vue}
*/
@Component({})
export default class AppExportExcel extends Vue {
/**
* 工具栏项
*
* @type {*}
* @memberof AppExportExcel
*/
@Prop() public item?: any;
/**
* 工具栏项层级
*
* @type {number}
* @memberof AppExportExcel
*/
@Prop({ default: 0 }) public itemLevel!: number;
/**
* 起始页
*
* @type {(string | null)}
* @memberof AppExportExcel
*/
public startPage: string | null = null;
/**
* 结束页
*
* @type {(string | null)}
* @memberof AppExportExcel
*/
public endPage: string | null = null;
/**
* 是否显示下拉菜单
*
* @type {boolean}
* @memberof AppExportExcel
*/
public visible: boolean = false;
/**
* 点击触发相似
*
* @memberof AppExportExcel
*/
public clickVisible(): void {
this.visible = !this.visible
}
/**
* 导出数据
*
* @param {*} $event
* @param {string} type
* @returns {void}
* @memberof AppExportExcel
*/
public exportExcel($event: any, type: string): void {
const exportparms: any = { type: type };
if (Object.is(type, 'maxRowCount')) {
Object.assign(exportparms, { maxRowCount: this.item.MaxRowCount })
this.visible = false;
} else if (Object.is(type, 'activatedPage')) {
this.visible = false;
} else if (Object.is(type, 'custom')) {
if (!this.startPage || !this.endPage) {
this.$Notice.warning({ title: '警告', desc: '请输入起始页' });
return;
}
const startPage: any = Number.parseInt(this.startPage, 10);
const endPage: any = Number.parseInt(this.endPage, 10);
if (Number.isNaN(startPage) || Number.isNaN(endPage)) {
this.$Notice.warning({ title: '警告', desc: '请输入有效的起始页' });
return;
}
if (startPage < 1 || endPage < 1 || startPage > endPage) {
this.$Notice.warning({ title: '警告', desc: '请输入有效的起始页' });
return;
}
this.startPage = null;
this.endPage = null;
Object.assign(exportparms, { startPage: startPage, endPage: endPage });
this.visible = false;
}
if (!this.visible) {
Object.assign($event, { exportparms: exportparms });
this.$emit('exportexcel', $event);
}
}
}
</script>
<style lang='less'>
@import './app-export-excel.less';
</style>
\ No newline at end of file
<template>
<el-upload
class="upload-demo"
:disabled="disabled"
:file-list="files"
:action="uploadUrl"
:headers="{}"
:before-upload="beforeUpload"
:before-remove="onRemove"
:on-success="onSuccess"
:on-error="onError"
:on-preview="onDownload"
drag
>
<i class="el-icon-upload"></i>
<div class="el-upload__text">将文件拖到此处,或<em>点击上传</em></div>
</el-upload>
</template>
<script lang="ts">
import { Component, Vue, Prop, Watch } from 'vue-property-decorator';
import { Environment } from '@/environments/environment';
import { CreateElement } from 'vue';
import { Subject, Unsubscribable } from 'rxjs';
@Component({})
export default class AppFileUploadDrag extends Vue {
/**
* 表单状态
*
* @type {Subject<any>}
* @memberof AppFileUploadDrag
*/
@Prop() public formState?: Subject<any>
/**
* 是否忽略表单项书香值变化
*
* @type {boolean}
* @memberof AppFileUploadDrag
*/
@Prop() public ignorefieldvaluechange?: boolean;
/**
* 表单状态事件
*
* @private
* @type {(Unsubscribable | undefined)}
* @memberof AppFileUploadDrag
*/
private formStateEvent: Unsubscribable | undefined;
/**
* 表单数据
*
* @type {string}
* @memberof AppFileUploadDrag
*/
@Prop() public data!: string;
/**
* 初始化值
*
* @type {*}
* @memberof AppFileUploadDrag
*/
@Prop() public value?: any;
/**
* 数据值变化
*
* @param {*} newval
* @param {*} val
* @memberof AppFileUploadDrag
*/
@Watch('value')
onValueChange(newval: any, val: any) {
if (this.ignorefieldvaluechange) {
return;
}
if (newval) {
this.files = JSON.parse(newval);
this.dataProcess();
} else {
this.files = [];
}
}
/**
* 所属表单项名称
*
* @type {string}
* @memberof AppFileUploadDrag
*/
@Prop() public name!: string;
/**
* 是否禁用
*
* @type {boolean}
* @memberof AppFileUploadDrag
*/
@Prop() public disabled?: boolean;
/**
* 上传参数
*
* @type {string}
* @memberof AppFileUploadDrag
*/
@Prop() public uploadparams?: string;
/**
* 下载参数
*
* @type {string}
* @memberof AppFileUploadDrag
*/
@Prop() public exportparams?: string;
/**
* 自定义参数
*
* @type {*}
* @memberof AppFileUploadDrag
*/
@Prop() public customparams?: any;
/**
* 上传文件路径
*
* @memberof AppFileUploadDrag
*/
public uploadUrl = Environment.BaseUrl + Environment.UploadFile;
/**
* 下载文件路径
*
* @memberof AppFileUploadDrag
*/
public downloadUrl = Environment.BaseUrl + Environment.ExportFile;
/**
* 文件列表
*
* @memberof AppFileUploadDrag
*/
public files = [];
/**
* 上传keys
*
* @type {Array<any>}
* @memberof AppFileUploadDrag
*/
public upload_keys: Array<any> = [];
/**
* 导出keys
*
* @type {Array<any>}
* @memberof AppFileUploadDrag
*/
public export_keys: Array<any> = [];
/**
* 自定义数组
*
* @type {Array<any>}
* @memberof AppFileUploadDrag
*/
public custom_arr: Array<any> = [];
/**
* 应用参数
*
* @type {*}
* @memberof AppFileUploadDrag
*/
public appData: any;
/**
* 数据处理
*
* @private
* @memberof AppFileUploadDrag
*/
private dataProcess(): void {
let upload_arr: Array<string> = [];
let export_arr: Array<string> = [];
const _data: any = JSON.parse(this.data);
this.upload_keys.forEach((key: string) => {
upload_arr.push(`${key}=${_data[key]}`);
});
this.export_keys.forEach((key: string) => {
export_arr.push(`${key}=${_data[key]}`);
});
let _url = `${Environment.BaseUrl}${Environment.UploadFile}`;
if (upload_arr.length > 0 || this.custom_arr.length > 0) {
_url = `${_url}?${upload_arr.join('&')}${upload_arr.length > 0 ? '&' : ''}${this.custom_arr.join('&')}`;
}
this.uploadUrl = _url;
this.files.forEach((file: any) => {
let url = `${this.downloadUrl}/${file.id}`;
if (upload_arr.length > 0 || this.custom_arr.length > 0) {
url = `${url}?${upload_arr.join('&')}${upload_arr.length > 0 ? '&' : ''}${this.custom_arr.join('&')}`;
}
file.url = url;
});
}
/**
* vue 生命周期
*
* @memberof AppFileUploadDrag
*/
public created() {
if (this.formState) {
this.formStateEvent = this.formState.subscribe(($event: any) => {
// 表单加载完成
if (Object.is($event.type, 'load')) {
if (this.value) {
this.files = JSON.parse(this.value);
}
this.dataProcess();
}
});
}
}
/**
* vue 生命周期
*
* @returns
* @memberof AppFileUploadDrag
*/
public mounted() {
this.appData = this.$store.getters.getAppData();
let uploadparams: string = '';
let exportparams: string = '';
if (this.uploadparams && !Object.is(this.uploadparams, '')) {
uploadparams = this.uploadparams;
}
if (this.exportparams && !Object.is(this.exportparams, '')) {
exportparams = this.exportparams;
}
let upload_keys: Array<string> = uploadparams.split(';');
let export_keys: Array<string> = exportparams.split(';');
let custom_arr: Array<string> = [];
if (this.customparams && !Object.is(this.customparams, '')) {
Object.keys(this.customparams).forEach((name: string) => {
custom_arr.push(`${name}=${this.customparams[name]}`);
});
}
this.upload_keys = upload_keys;
this.export_keys = export_keys;
this.custom_arr = custom_arr;
if (this.value) {
this.files = JSON.parse(this.value);
}
this.dataProcess();
}
/**
* 组件销毁
*
* @memberof AppFileUploadDrag
*/
public destroyed(): void {
if (this.formStateEvent) {
this.formStateEvent.unsubscribe();
}
}
/**
* 上传之前
*
* @param {*} file
* @memberof AppFileUploadDrag
*/
public beforeUpload(file: any) {
// console.log('上传之前');
}
/**
* 上传成功回调
*
* @param {*} response
* @param {*} file
* @param {*} fileList
* @memberof AppFileUploadDrag
*/
public onSuccess(response: any, file: any, fileList: any) {
if (!response) {
return;
}
const data = { name: response.name, id: response.id };
let arr: Array<any> = [];
this.files.forEach((_file:any) => {
arr.push({name: _file.name, id: _file.id})
});
arr.push(data);
let value: any = arr.length > 0 ? JSON.stringify(arr) : null;
this.$emit('formitemvaluechange', { name: this.name, value: value });
}
/**
* 上传失败回调
*
* @param {*} error
* @param {*} file
* @param {*} fileList
* @memberof AppFileUploadDrag
*/
public onError(error: any, file: any, fileList: any) {
this.$Notice.error({ title: '上传失败' });
}
/**
* 删除文件
*
* @param {*} file
* @param {*} fileList
* @memberof AppFileUploadDrag
*/
public onRemove(file: any, fileList: any) {
let arr: Array<any> = [];
fileList.forEach((f: any) => {
if (f.id != file.id) {
arr.push({ name: f.name, id: f.id });
}
});
let value: any = arr.length > 0 ? JSON.stringify(arr) : null;
this.$emit('formitemvaluechange', { name: this.name, value: value });
}
/**
* 下载文件
*
* @param {*} file
* @memberof AppFileUploadDrag
*/
public onDownload(file: any) {
window.open(file.url);
}
}
</script>
<style lang='less'>
@import './app-file-upload-drag.less';
</style>
\ No newline at end of file
<template>
<el-upload
:disabled="disabled"
:file-list="files"
:action="uploadUrl"
:headers="{}"
:before-upload="beforeUpload"
:before-remove="onRemove"
:on-success="onSuccess"
:on-error="onError"
:on-preview="onDownload">
<el-button size='small' icon='el-icon-upload' :disabled="disabled">{{this.$t('app.fileUpload.caption')}}</el-button>
</el-upload>
</template>
<script lang="ts">
import { Component, Vue, Prop, Watch } from 'vue-property-decorator';
import { Environment } from '@/environments/environment';
import { CreateElement } from 'vue';
import { Subject, Unsubscribable } from 'rxjs';
@Component({})
export default class AppFileUpload extends Vue {
/**
* 表单状态
*
* @type {Subject<any>}
* @memberof AppFileUpload
*/
@Prop() public formState?: Subject<any>
/**
* 是否忽略表单项书香值变化
*
* @type {boolean}
* @memberof AppFileUpload
*/
@Prop() public ignorefieldvaluechange?: boolean;
/**
* 表单状态事件
*
* @private
* @type {(Unsubscribable | undefined)}
* @memberof AppFileUpload
*/
private formStateEvent: Unsubscribable | undefined;
/**
* 表单数据
*
* @type {string}
* @memberof AppFileUpload
*/
@Prop() public data!: string;
/**
* 初始化值
*
* @type {*}
* @memberof AppFileUpload
*/
@Prop() public value?: any;
/**
* 数据值变化
*
* @param {*} newval
* @param {*} val
* @memberof AppFileUpload
*/
@Watch('value')
onValueChange(newval: any, val: any) {
if (this.ignorefieldvaluechange) {
return;
}
if (newval) {
this.files = JSON.parse(newval);
this.dataProcess();
} else {
this.files = [];
}
}
/**
* 所属表单项名称
*
* @type {string}
* @memberof AppFileUpload
*/
@Prop() public name!: string;
/**
* 是否禁用
*
* @type {boolean}
* @memberof AppFileUpload
*/
@Prop() public disabled?: boolean;
/**
* 上传参数
*
* @type {string}
* @memberof AppFileUpload
*/
@Prop() public uploadparams?: string;
/**
* 下载参数
*
* @type {string}
* @memberof AppFileUpload
*/
@Prop() public exportparams?: string;
/**
* 自定义参数
*
* @type {*}
* @memberof AppFileUpload
*/
@Prop() public customparams?: any;
/**
* 上传文件路径
*
* @memberof AppFileUpload
*/
public uploadUrl = Environment.BaseUrl + Environment.UploadFile;
/**
* 下载文件路径
*
* @memberof AppFileUpload
*/
public downloadUrl = Environment.BaseUrl + Environment.ExportFile;
/**
* 文件列表
*
* @memberof AppFileUpload
*/
public files = [];
/**
* 上传keys
*
* @type {Array<any>}
* @memberof AppFileUpload
*/
public upload_keys: Array<any> = [];
/**
* 导出keys
*
* @type {Array<any>}
* @memberof AppFileUpload
*/
public export_keys: Array<any> = [];
/**
* 自定义数组
*
* @type {Array<any>}
* @memberof AppFileUpload
*/
public custom_arr: Array<any> = [];
/**
* 应用参数
*
* @type {*}
* @memberof AppImageUpload
*/
public appData: any;
/**
* 数据处理
*
* @private
* @memberof AppFileUpload
*/
private dataProcess(): void {
let upload_arr: Array<string> = [];
let export_arr: Array<string> = [];
const _data: any = JSON.parse(this.data);
this.upload_keys.forEach((key: string) => {
upload_arr.push(`${key}=${_data[key]}`);
});
this.export_keys.forEach((key: string) => {
export_arr.push(`${key}=${_data[key]}`);
});
let _url = `${Environment.BaseUrl}${Environment.UploadFile}`;
if (upload_arr.length > 0 || this.custom_arr.length > 0) {
_url = `${_url}?${upload_arr.join('&')}${upload_arr.length > 0 ? '&' : ''}${this.custom_arr.join('&')}`;
}
this.uploadUrl = _url;
this.files.forEach((file: any) => {
let url = `${this.downloadUrl}/${file.id}`;
if (upload_arr.length > 0 || this.custom_arr.length > 0) {
url = `${url}?${upload_arr.join('&')}${upload_arr.length > 0 ? '&' : ''}${this.custom_arr.join('&')}`;
}
file.url = url;
});
}
/**
* vue 生命周期
*
* @memberof AppFileUpload
*/
public created() {
if (this.formState) {
this.formStateEvent = this.formState.subscribe(($event: any) => {
// 表单加载完成
if (Object.is($event.type, 'load')) {
if (this.value) {
this.files = JSON.parse(this.value);
}
this.dataProcess();
}
});
}
}
/**
* vue 生命周期
*
* @returns
* @memberof AppFileUpload
*/
public mounted() {
this.appData = this.$store.getters.getAppData();
let uploadparams: string = '';
let exportparams: string = '';
if (this.uploadparams && !Object.is(this.uploadparams, '')) {
uploadparams = this.uploadparams;
}
if (this.exportparams && !Object.is(this.exportparams, '')) {
exportparams = this.exportparams;
}
let upload_keys: Array<string> = uploadparams.split(';');
let export_keys: Array<string> = exportparams.split(';');
let custom_arr: Array<string> = [];
if (this.customparams && !Object.is(this.customparams, '')) {
Object.keys(this.customparams).forEach((name: string) => {
custom_arr.push(`${name}=${this.customparams[name]}`);
});
}
this.upload_keys = upload_keys;
this.export_keys = export_keys;
this.custom_arr = custom_arr;
if (this.value) {
this.files = JSON.parse(this.value);
}
this.dataProcess();
}
/**
* 组件销毁
*
* @memberof AppFileUpload
*/
public destroyed(): void {
if (this.formStateEvent) {
this.formStateEvent.unsubscribe();
}
}
/**
* 上传之前
*
* @param {*} file
* @memberof AppFileUpload
*/
public beforeUpload(file: any) {
// console.log('上传之前');
}
/**
* 上传成功回调
*
* @param {*} response
* @param {*} file
* @param {*} fileList
* @memberof AppFileUpload
*/
public onSuccess(response: any, file: any, fileList: any) {
if (!response) {
return;
}
const data = { name: response.name, id: response.id };
let arr: Array<any> = [];
this.files.forEach((_file:any) => {
arr.push({name: _file.name, id: _file.id})
});
arr.push(data);
let value: any = arr.length > 0 ? JSON.stringify(arr) : null;
this.$emit('formitemvaluechange', { name: this.name, value: value });
}
/**
* 上传失败回调
*
* @param {*} error
* @param {*} file
* @param {*} fileList
* @memberof AppFileUpload
*/
public onError(error: any, file: any, fileList: any) {
this.$Notice.error({ title: '上传失败' });
}
/**
* 删除文件
*
* @param {*} file
* @param {*} fileList
* @memberof AppFileUpload
*/
public onRemove(file: any, fileList: any) {
let arr: Array<any> = [];
fileList.forEach((f: any) => {
if (f.id != file.id) {
arr.push({ name: f.name, id: f.id });
}
});
let value: any = arr.length > 0 ? JSON.stringify(arr) : null;
this.$emit('formitemvaluechange', { name: this.name, value: value });
}
/**
* 下载文件
*
* @param {*} file
* @memberof AppFileUpload
*/
public onDownload(file: any) {
window.open(file.url);
}
}
</script>
<style lang='less'>
@import './app-file-upload.less';
</style>
\ No newline at end of file
.form-druipart {
position: relative;
}
\ No newline at end of file
<template>
<div class='form-druipart'>
<component
:is="viewname"
class="viewcontainer2"
:viewdata ="JSON.stringify(this.viewdata)"
:viewDefaultUsage="false"
:formDruipart="formDruipart"
@mditemsload="mditemsload"
@drdatasaved="drdatasaved"
@drdatachange="drdatachange"
@viewdataschange="viewdataschange"
@viewload="viewload">
</component>
<spin v-if="blockUI" class='app-druipart-spin' fix >{{ blockUITipInfo }}</spin>
</div>
</template>
<script lang = 'ts'>
import { Vue, Component, Prop, Watch } from 'vue-property-decorator';
import { Subject, Unsubscribable } from 'rxjs';
@Component({})
export default class AppFormDRUIPart extends Vue {
/**
* 表单数据
*
* @type {string}
* @memberof AppFormDRUIPart
*/
@Prop() public data!: string;
/**
* 关联视图
*
* @type {string}
* @memberof AppFormDRUIPart
*/
@Prop() public viewname?: string;
/**
* 刷新关系项
*
* @type {string}
* @memberof AppFormDRUIPart
*/
@Prop({ default: '' }) public refreshitems!: string;
/**
* 关系视图类型
*
* @type {string}
* @memberof AppFormDRUIPart
*/
@Prop() public refviewtype?: string;
/**
* 父数据
*
* @type {*}
* @memberof AppFormDRUIPart
*/
@Prop() public parentdata!: any;
/**
* 传入参数项名称
*
* @type {string}
* @memberof AppFormDRUIPart
*/
@Prop() public paramItem!: string;
/**
* 是否忽略表单项值变化
*
* @type {boolean}
* @memberof AppFormDRUIPart
*/
@Prop() public ignorefieldvaluechange!: boolean;
/**
* 表单状态
*
* @type {Subject<any>}
* @memberof AppFormDRUIPart
*/
@Prop() public formState!: Subject<any>;
/**
* 视图参数
*
* @type {any[]}
* @memberof AppFormDRUIPart
*/
@Prop() public parameters!: any[];
/**
* 视图参数
*
* @type {*}
* @memberof AppFormDRUIPart
*/
@Prop() public viewParam!: any;
/**
* 应用实体参数名称
*
* @type {string}
* @memberof AppFormDRUIPart
*/
@Prop() public parameterName!: string;
/**
* 关系界面向视图下发指令对象
*
* @private
* @type {Subject<any>}
* @memberof AppFormDRUIPart
*/
private formDruipart: Subject<any> = new Subject<any>();
/**
* 表单状态事件
*
* @private
* @type {(Unsubscribable | undefined)}
* @memberof AppFormDRUIPart
*/
private formStateEvent: Unsubscribable | undefined;
/**
* 监控值
*
* @param {*} newVal
* @param {*} oldVal
* @memberof AppFormDRUIPart
*/
@Watch('data')
onActivedataChange(newVal: any, oldVal: any) {
if (this.ignorefieldvaluechange) {
return;
}
if (Object.is(newVal, oldVal)) {
return;
}
const newFormData: any = JSON.parse(newVal);
const oldDormData: any = JSON.parse(oldVal);
let refreshRefview = false;
this.hookItems.some((_hookItem: any) => {
if (!Object.is(newFormData[_hookItem], oldDormData[_hookItem])) {
refreshRefview = true;
return refreshRefview;
}
return refreshRefview;
});
if (refreshRefview) {
this.refreshDRUIPart();
}
}
/**
* 是否启用遮罩
*
* @type {boolean}
* @memberof AppFormDRUIPart
*/
public blockUI: boolean = false;
/**
* 遮罩提示信息
*
* @type {string}
* @memberof AppFormDRUIPart
*/
public blockUITipInfo: string = '请先保存主数据';
/**
* 是否刷新关系数据
*
* @private
* @type {boolean}
* @memberof AppFormDRUIPart
*/
private isRelationalData: boolean = true;
/**
* 刷新节点
*
* @private
* @type {string[]}
* @memberof AppFormDRUIPart
*/
private hookItems: string[] = [];
/**
* 父数据
*
* @type {*}
* @memberof AppFormDRUIPart
*/
public viewdata: any = {};
/**
* 刷新关系页面
*
* @private
* @returns {void}
* @memberof AppFormDRUIPart
*/
private refreshDRUIPart(data?:any): void {
if (Object.is(this.parentdata.SRFPARENTTYPE, 'CUSTOM')) {
this.isRelationalData = false;
}
const formData: any = data?data:JSON.parse(this.data);
const _paramitem = formData[this.paramItem];
this.viewdata = {};
Object.assign(this.viewdata, this.parentdata);
Object.assign(this.viewdata, this.$viewTool.getIndexViewParam());
const _parameters: any[] = [...this.$viewTool.getIndexParameters(), ...this.parameters];
_parameters.forEach((parameter: any) => {
const { pathName, parameterName }: { pathName: string, parameterName: string } = parameter;
if (this.viewParam[parameterName] && !Object.is(this.viewParam[parameterName], '')) {
Object.assign(this.viewdata, { [parameterName]: this.viewParam[parameterName] });
}
});
Object.assign(this.viewdata, { [this.paramItem]: _paramitem });
//设置顶层视图唯一标识
Object.assign(this.viewdata,{srfsessionid:this.viewParam.srfsessionid});
if (this.isRelationalData) {
if (!_paramitem || _paramitem == null || Object.is(_paramitem, '')) {
this.blockUIStart();
return;
} else {
this.blockUIStop();
}
}
this.formDruipart.next({action:'load',data:[]});
// this.$forceUpdate();
}
/**
* vue 生命周期
*
* @memberof AppFormDRUIPart
*/
public created(): void {
this.hookItems = [...this.refreshitems.split(';')];
if (!this.formState) {
return;
}
if (!Object.is(this.paramItem, this.parameterName)) {
this.hookItems.push(this.paramItem);
}
this.formStateEvent = this.formState.subscribe(($event: any) => {
// 表单加载完成
if (Object.is($event.type, 'load')) {
this.refreshDRUIPart($event.data);
}
// 表单保存之前
if (Object.is($event.type, 'beforesave')) {
if(Object.is(this.refviewtype,'DEMEDITVIEW9') || Object.is(this.refviewtype,'DEGRIDVIEW9')){
this.formDruipart.next({action:'save',data:$event.data});
} else {
// 不需要保存的界面也要抛出事件,供计数器计算
this.$emit('drdatasaved',$event);
}
}
// 表单保存完成
if (Object.is($event.type, 'save')) {
this.refreshDRUIPart($event.data);
}
// 表单项更新
if (Object.is($event.type, 'updateformitem')) {
if (!$event.data) {
return;
}
let refreshRefview = false;
Object.keys($event.data).some((name: string) => {
const index = this.hookItems.findIndex((_name: string) => Object.is(_name, name));
refreshRefview = index !== -1 ? true : false;
return refreshRefview;
});
if (refreshRefview) {
this.refreshDRUIPart();
}
}
});
this.refreshDRUIPart();
}
/**
* 部件销毁
*
* @memberof AppFormDRUIPart
*/
public destroyed(): void {
if (this.formStateEvent) {
this.formStateEvent.unsubscribe();
}
}
/**
* 开启遮罩
*
* @private
* @memberof AppFormDRUIPart
*/
private blockUIStart(): void {
this.blockUI = true;
}
/**
* 关闭遮罩
*
* @private
* @memberof AppFormDRUIPart
*/
private blockUIStop(): void {
this.blockUI = false;
}
/**
* 多数据视图加载完成
*
* @public
* @memberof AppFormDRUIPart
*/
public mditemsload(){
console.log('多数据视图加载完成,触发后续表单项更新');
}
/**
* DEMEDITVIEW9 关系数据保存完成
*
* @public
* @memberof AppFormDRUIPart
*/
public drdatasaved($event:any){
this.$emit('drdatasaved',$event);
console.log(this.viewname+'关系数据保存完成');
}
/**
* DEMEDITVIEW9 关系数据值变化
*
* @public
* @memberof AppFormDRUIPart
*/
public drdatachange(){
console.log('DEMEDITVIEW9 关系数据值变化');
}
/**
* 视图数据变化
*
* @public
* @memberof AppFormDRUIPart
*/
public viewdataschange(){
console.log('视图数据变化');
}
/**
* 视图加载完成
*
* @public
* @memberof AppFormDRUIPart
*/
public viewload(){
console.log('视图加载完成');
}
}
</script>
<style lang = "less">
@import './app-form-druipart.less';
</style>
\ No newline at end of file
.app-form-group {
>.ivu-card-head {
>p {
>i {
margin-right: 8px;
cursor: pointer;
}
}
}
>.ivu-card-extra {
.item-extract-mode {
.item {
margin-left: 12px;
}
}
}
}
.app-form-group.app-group-collapse-contant {
.ivu-card-body {
display: none;
}
}
.app-group-flex {
height: 100%;
overflow: auto;
> .ivu-card-body {
height: calc(100% - 51px);
overflow: auto;
}
}
\ No newline at end of file
<template>
<div class="app-form-group">
<div v-if="uiStyle=='STYLE2'">
<app-form-group2
:caption="caption"
:uiStyle="uiStyle"
:layoutType="layoutType"
:isShowCaption="isShowCaption"
:uiActionGroup="uiActionGroup"
:titleBarCloseMode="titleBarCloseMode">
<slot></slot>
</app-form-group2>
</div>
<div v-else>
<card v-if="isShowCaption === true" :bordered="false" :dis-hover="true" :class="classes">
<p class='' slot='title'>
<icon v-if="titleBarCloseMode !== 0" :type="collapseContant ? 'ios-arrow-dropright-circle' : 'ios-arrow-dropdown-circle'"
@click="clickCollapse"></icon>
<span :class="titleClass">{{caption}}</span>
</p>
<template v-if="uiActionGroup">
<a slot='extra'>
<template v-if="uiActionGroup.extractMode && Object.is(uiActionGroup.extractMode, 'ITEMS')">
<dropdown :transfer="true" trigger='click'>
<a href='javascript:void(0)'>
{{uiActionGroup.caption}}
</a>
<dropdown-menu slot='list' v-if="uiActionGroup.details && Array.isArray(uiActionGroup.details)">
<dropdown-item v-for="(detail,index) in (uiActionGroup.details)" :key="index" :name="detail.name">
<span class='item' @click="doUIAction($event, detail)">
<template v-if="detail.icon && !Object.is(detail.icon, '')">
<i :class="detail.icon" ></i>
</template>
<template v-if="!(detail.icon && !Object.is(detail.icon, ''))">
<div v-if="detail.img && !Object.is(detail.img, '')">
<img :src="detail.img" />
</div>
</template>
&nbsp;
<span>
<template v-if="uiActionGroup.langbase && !Object.is(uiActionGroup.langbase, '') && detail.uiactiontag && !Object.is(detail.uiactiontag, '')">
{{$t(`${uiActionGroup.langbase}.uiactions.${detail.uiactiontag}`)}}
</template>
<template v-if="!(uiActionGroup.langbase && !Object.is(uiActionGroup.langbase, '') && detail.uiactiontag && !Object.is(detail.uiactiontag, ''))">
{{detail.caption}}
</template>
</span>
</span>
</dropdown-item>
</dropdown-menu>
</dropdown>
</template>
<template v-if="!(uiActionGroup.extractMode && Object.is(uiActionGroup.extractMode, 'ITEMS'))">
<span class='item-extract-mode'>
<template v-if="uiActionGroup.details && Array.isArray(uiActionGroup.details)">
<div v-for="(detail,index) in uiActionGroup.details" :key="index">
<span class='item' @click="doUIAction($event, detail)">
<template v-if="detail.icon && !Object.is(detail.icon, '')">
<i :class="detail.icon" ></i>
</template>
<template v-if="!(detail.icon && !Object.is(detail.icon, ''))">
<div v-if="detail.img && !Object.is(detail.img, '')">
<img :src="detail.img" />
</div>
</template>
&nbsp;
<span>
<template v-if="uiActionGroup.langbase && !Object.is(uiActionGroup.langbase, '') && detail.uiactiontag && !Object.is(detail.uiactiontag, '')">
{{$t(`${uiActionGroup.langbase}.uiactions.${detail.uiactiontag}`)}}
</template>
<template v-if="!(uiActionGroup.langbase && !Object.is(uiActionGroup.langbase, '') && detail.uiactiontag && !Object.is(detail.uiactiontag, ''))">
{{detail.caption}}
</template>
</span>
</span>
</div>
</template>
</span>
</template>
</a >
</template>
<div v-if="Object.is(layoutType, 'FLEX')">
<slot></slot>
</div>
<div v-if="!Object.is(layoutType, 'FLEX')">
<row :gutter="10"><slot></slot></row>
</div>
</card>
<row v-if="isShowCaption === false" :class="classes">
<slot></slot>
</row>
</div>
</div>
</template>
<script lang="ts">
import { Vue, Component, Prop } from 'vue-property-decorator';
@Component({})
export default class AppFormGroup extends Vue {
/**
* 标题
*
* @type {string}
* @memberof AppFormGroup
*/
@Prop() public caption?: string;
/**
* 内置界面样式
*
* @type {string}
* @memberof AppFormGroup
*/
@Prop() public uiStyle?: string;
/**
* 布局模式
*
* @type {string}
* @memberof AppFormGroup
*/
@Prop() public layoutType?: string;
/**
* 标题样式
*
* @type {string}
* @memberof AppFormGroup
*/
@Prop() public titleStyle?:string;
/**
* 是否显示标题
*
* @type {boolean}
* @memberof AppFormGroup
*/
@Prop({ default: true }) public isShowCaption!: boolean;
/**
* 信息面板模式
*
* @type {boolean}
* @memberof AppFormGroup
*/
@Prop({ default: false }) public isInfoGroupMode!: boolean;
/**
* 界面行为组
*
* @type {*}
* @memberof AppFormGroup
*/
@Prop() public uiActionGroup?: any;
/**
* 标题栏关闭模式
* 0: 不支持关闭
* 1: 默认打开
* 2: 默认关闭
*
* @type {(number | 0 | 1 | 2)}
* @memberof AppFormGroup
*/
@Prop({ default: 0 }) public titleBarCloseMode!: number | 0 | 1 | 2;
/**
* 收缩内容
*
* @type {boolean}
* @memberof AppFormGroup
*/
public collapseContant: boolean = false;
/**
* 计算样式
*
* @readonly
* @type {string[]}
* @memberof AppFormGroup
*/
get classes(): string[] {
return [
'app-form-group',
this.isShowCaption && this.collapseContant ? 'app-group-collapse-contant' : '',
this.isInfoGroupMode ? 'app-info-group-mode' : '',
Object.is(this.layoutType, 'FLEX') ? 'app-group-flex': ''
];
}
/**
* 标题样式
*
* @readonly
* @type {string}
* @memberof AppFormGroup
*/
get titleClass():string{
return this.titleStyle?this.titleStyle:'';
}
/**
* vue 生命周期
*
* @memberof AppFormGroup
*/
public created() {
this.collapseContant = this.titleBarCloseMode === 2 ? true : false;
}
/**
* 触发收缩
*
* @memberof AppFormGroup
*/
public clickCollapse(): void {
this.collapseContant = !this.collapseContant;
}
/**
* 执行界面行
*
* @param {*} $event
* @memberof AppFormGroup
*/
public doUIAction($event: any, item: any): void {
this.$emit('groupuiactionclick', { event: $event, item: item });
}
}
</script>
<style lang='less'>
@import './app-form-group.less';
</style>
\ No newline at end of file
<template>
<span>未实现</span>
</template>
<script lang="ts">
import { Vue, Component, Prop, } from 'vue-property-decorator';
@Component({})
export default class AppFormGroup2 extends Vue {
/**
* 标题
*
* @type {string}
* @memberof AppFormGroup2
*/
@Prop() public caption?: string;
/**
* 内置界面样式
*
* @type {string}
* @memberof AppFormGroup2
*/
@Prop() public uiStyle?: string;
/**
* 布局模式
*
* @type {string}
* @memberof AppFormGroup2
*/
@Prop() public layoutType?: string;
/**
* 是否显示标题
*
* @type {boolean}
* @memberof AppFormGroup2
*/
@Prop({ default: true }) public isShowCaption!: boolean;
/**
* 界面行为组
*
* @type {*}
* @memberof AppFormGroup2
*/
@Prop() public uiActionGroup?: any;
/**
* 标题栏关闭模式
* 0: 不支持关闭
* 1: 默认打开
* 2: 默认关闭
*
* @type {(number | 0 | 1 | 2)}
* @memberof AppFormGroup2
*/
@Prop({ default: 0 }) public titleBarCloseMode!: number | 0 | 1 | 2;
}
</script>
<style lang="less">
@import './app-form-group2.less';
</style>
\ No newline at end of file
.app-form-item {
// margin-bottom: 16px;
>.ivu-form-item-label {
text-decoration: none;
display: block;
overflow: hidden;
white-space: nowrap;
}
>.ivu-form-item-content {
min-height: 36px;
}
}
.app-form-item-label-top {
>.ivu-form-item-label {
float: none;
display: inline-block;
padding: 0 0 10px;
}
}
\ No newline at end of file
<template>
<div>
<div v-if="this.uiStyle === 'STYLE2'">
<app-form-item2
:caption="caption"
:labelStyle="labelStyle"
:error="error"
:labelPos="labelPos"
:labelWidth="labelWidth"
:isShowCaption="isShowCaption"
:isEmptyCaption="isEmptyCaption"
:name="name"
:uiStyle="uiStyle"
:itemRules="itemRules">
<slot></slot>
</app-form-item2>
</div>
<div v-if="this.uiStyle !== 'STYLE2'">
<form-item
:prop="name"
:error="error"
:required="required"
:rules="rules"
:class="classes"
:label-width="this.isShowCaption ? !Object.is(this.labelPos, 'TOP') ? this.labelWidth : null : 0">
<span slot='label' v-if="this.isShowCaption && this.labelWidth > 0" :class="labelclasses">
{{this.isEmptyCaption ? '' : this.caption}}
</span>
<slot></slot>
</form-item>
</div>
</div>
</template>
<script lang="ts">
import { Vue, Component, Prop, Watch } from 'vue-property-decorator';
@Component({})
export default class AppFormItem extends Vue {
/**
* 名称
*
* @type {string}
* @memberof AppFormItem
*/
@Prop() public caption!: string;
/**
* 错误信息
*
* @type {string}
* @memberof AppFormItem
*/
@Prop() public error?: string;
/**
* label样式
*
* @type {string}
* @memberof AppFormItem
*/
@Prop() public labelStyle?: string;
/**
* 标签位置
*
* @type {(string | 'BOTTOM' | 'LEFT' | 'NONE' | 'RIGHT' | 'TOP')}
* @memberof AppFormItem
*/
@Prop() public labelPos?: string | 'BOTTOM' | 'LEFT' | 'NONE' | 'RIGHT' | 'TOP';
/**
* 标签宽度
*
* @type {number}
* @memberof AppFormItem
*/
@Prop({}) public labelWidth!: number;
/**
* 是否显示标题
*
* @type {boolean}
* @memberof AppFormItem
*/
@Prop() public isShowCaption?: boolean;
/**
* 标签是否空白
*
* @type {boolean}
* @memberof AppFormItem
*/
@Prop() public isEmptyCaption?: boolean;
/**
* 表单项名称
*
* @type {string}
* @memberof AppFormItem
*/
@Prop() public name!: string;
/**
* 内置样式
*
* @type {string}
* @memberof AppFormItem
*/
@Prop() public uiStyle?: string;
/**
* 表单项值规则
*
* @type {string}
* @memberof AppFormItem
*/
@Prop() public itemRules!: any;
/**
* 值规则数组
*
* @type {any[]}
* @memberof AppFormItem
*/
public rules: any[] = [];
/**
* 是否必填
*
* @type {boolean}
* @memberof AppFormItem
*/
public required: boolean = false;
/**
* 表单项值规则监控
*
* @param {*} newVal
* @param {*} oldVal
* @memberof AppFormItem
*/
@Watch('itemRules',{deep:true})
onItemRulesChange(newVal: any, oldVal: any) {
if (newVal) {
try {
this.rules = [];
const _rules: any[] = newVal;
this.rules = [..._rules];
this.rules.some((rule: any) => {
if (rule.hasOwnProperty('required')) {
this.required = rule.required;
return true;
}
return false;
});
} catch (error) {
}
}
}
/**
* 计算样式
*
* @readonly
* @type {string []}
* @memberof AppFormItem
*/
get classes(): string[] {
return [
'app-form-item',
Object.is(this.labelPos, 'TOP') ? 'app-form-item-label-top' : ''
];
}
/**
* label样式
*
* @readonly
* @type {string}
* @memberof AppFormItem
*/
get labelclasses():string{
return this.labelStyle?this.labelStyle:'';
}
/**
* vue 生命周期
*
* @memberof AppFormItem
*/
public mounted() {
if (this.itemRules) {
try {
const _rules: any[] = this.itemRules;
this.rules = [..._rules];
this.rules.some((rule: any) => {
if (rule.hasOwnProperty('required')) {
this.required = rule.required;
return true;
}
return false;
});
} catch (error) {
}
}
}
}
</script>
<style lang='less'>
@import './app-form-item.less';
</style>
\ No newline at end of file
.app-form-item2 {
// margin-bottom: 16px;
>.ivu-form-item-label {
text-decoration: none;
display: block;
overflow: hidden;
white-space: nowrap;
}
>.ivu-form-item-content {
min-height: 36px;
display: flex;
.app-editor-contant {
flex-grow: 1;
}
.app-error-tip {
width: 20px;
}
}
.ivu-form-item-error-tip {
display: none;
}
}
.app-form-item-label-top {
>.ivu-form-item-label {
float: none;
display: inline-block;
padding: 0 0 10px;
}
}
\ No newline at end of file
<template>
<div>
<form-item
:prop="name"
:error="error"
:required="required"
:rules="rules"
:class="classes"
:label-width="isShowCaption ? !Object.is(labelPos, 'TOP') ? labelWidth : null : 0"
:ref="name"
>
<span
v-if="isShowCaption && labelWidth > 0"
slot="label" :class="labelclasses"
>{{isEmptyCaption ? '' : caption}}</span>
<div class="app-editor-contant">{{$slots.default}}</div>
<div
v-if="_formitem && _formitem.validateState && Object.is(_formitem.validateState, 'error')"
class="app-error-tip"
>
<poptip trigger="hover" placement="left" width="300" word-wrap="true" transfer="true">
<icon type="ios-information-circle-outline" color="#ed4014" size="20"></icon>
<div slot="content" class="app-form-item-error-info">
<div class="icon">
<icon type="ios-information-circle-outline" color="#ed4014" size="20"></icon>
</div>
<div class="contant">{{_formitem.validateMessage}}</div>
</div>
</poptip>
</div>
</form-item>
</div>
</template>
<script lang="ts">
import { Vue, Component, Prop, Watch } from "vue-property-decorator";
@Component({})
export default class AppFormItem2 extends Vue {
/**
* 名称
*
* @type {string}
* @memberof AppFormItem2
*/
@Prop() public caption!: string;
/**
* 错误信息
*
* @type {string}
* @memberof AppFormItem2
*/
@Prop() public error?: string;
/**
* label样式
*
* @type {string}
* @memberof AppFormItem2
*/
@Prop() public labelStyle?: string;
/**
* 标签位置
*
* @type {(string | 'BOTTOM' | 'LEFT' | 'NONE' | 'RIGHT' | 'TOP')}
* @memberof AppFormItem2
*/
@Prop() public labelPos?:
| string
| "BOTTOM"
| "LEFT"
| "NONE"
| "RIGHT"
| "TOP";
/**
* 标签宽度
*
* @type {number}
* @memberof AppFormItem2
*/
@Prop({}) public labelWidth!: number;
/**
* 是否显示标题
*
* @type {boolean}
* @memberof AppFormItem2
*/
@Prop() public isShowCaption?: boolean;
/**
* 标签是否空白
*
* @type {boolean}
* @memberof AppFormItem2
*/
@Prop() public isEmptyCaption?: boolean;
/**
* 表单项名称
*
* @type {string}
* @memberof AppFormItem2
*/
@Prop() public name!: string;
/**
* 内置样式
*
* @type {string}
* @memberof AppFormItem2
*/
@Prop() public uiStyle?: string;
/**
* 表单项值规则
*
* @type {string}
* @memberof AppFormItem2
*/
@Prop() public itemRules!: any;
/**
* 值规则数组
*
* @type {any[]}
* @memberof AppFormItem2
*/
public rules: any[] = [];
/**
* 是否必填
*
* @type {boolean}
* @memberof AppFormItem2
*/
public required: boolean = false;
/**
* 表单项值规则监控
*
* @param {*} newVal
* @param {*} oldVal
* @memberof AppFormItem2
*/
@Watch("itemRules")
onItemRulesChange(newVal: any, oldVal: any) {
if (newVal) {
try {
this.rules = [];
const _rules: any[] = newVal;
this.rules = [..._rules];
this.rules.some((rule: any) => {
if (rule.hasOwnProperty("required")) {
this.required = rule.required;
return true;
}
return false;
});
} catch (error) {}
}
}
/**
* 计算样式
*
* @readonly
* @type {string[]}
* @memberof AppFormItem2
*/
get classes(): string[] {
return [
"app-form-item2",
Object.is(this.labelPos, "TOP") ? "app-form-item-label-top" : ""
];
}
/**
* label样式
*
* @readonly
* @type {string}
* @memberof AppFormItem2
*/
get labelclasses():string{
return this.labelStyle?this.labelStyle:'';
}
/**
* vue 生命周期
*
* @memberof AppFormItem2
*/
public mounted() {
if (this.itemRules) {
try {
const _rules: any[] = this.itemRules;
this.rules = [..._rules];
this.rules.some((rule: any) => {
if (rule.hasOwnProperty("required")) {
this.required = rule.required;
return true;
}
return false;
});
} catch (error) {}
}
}
}
</script>
<style lang="less">
@import "./app-form-item2.less";
</style>
\ No newline at end of file
.form-detail-show {
display: block;
}
.form-detail-hidden {
display: none;
}
.app-form {
height: 100%;
> .ivu-row {
height: 100%;
> .ivu-tabs {
height: 100%;
> .ivu-tabs-content {
height: calc(100% - 50px);
overflow: auto;
> .ivu-tabs-tabpane {
height: 100%;
overflow: auto;
}
}
}
> .el-tabs {
height: 100%;
> .el-tabs__content {
height: calc(100% - 51px);
> .el-tab-pane {
height: 100%;
overflow: auto;
}
}
.el-tabs__header {
.el-tabs__nav-wrap::after {
background-color: var(--app-border-content);
height: 1px;
}
.el-tabs__item {
height: 36px;
}
}
}
}
}
\ No newline at end of file
<template>
<i-form form="form">
<row >
<slot></slot>
</row>
</i-form>
</template>
<script lang = 'ts'>
import { Component, Vue, Prop } from 'vue-property-decorator';
@Component({})
export default class AppForm extends Vue {
/**
* 表单数据对象
*
* @type {*}
* @memberof Form
*/
@Prop() public form?: any;
/**
* 表单名称
*
* @type {string}
* @memberof Form
*/
@Prop() public name?: string;
}
</script>
<style lang = "less">
@import './app-form.less';
</style>
\ No newline at end of file
/*** BEGIN:图片上传 ***/
.app-picture-upload {
>div{
display: inline;
}
.el-upload-disabled {
.el-upload {
cursor: not-allowed;
}
}
.el-image {
.image-slot {
display: flex;
justify-content: center;
align-items: center;
width: 100%;
height: 100%;
background: #f5f7fa;
color: #909399;
font-size: 30px;
}
}
}
.app-image-upload-model {
.el-image {
width: 100%;
height: 100%;
.image-slot {
display: flex;
justify-content: center;
align-items: center;
width: 100%;
height: 300px;
background: #f5f7fa;
color: #909399;
font-size: 30px;
}
}
}
/*** END:图片上传 ***/
\ No newline at end of file
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
Markdown 格式
0% or
您添加了 0 到此讨论。请谨慎行事。
先完成此消息的编辑!
想要评论请 注册