提交 11db7f6c 编写于 作者: B baiy 提交者: ninecents

English language support #74

上级 11ebdc0f
此差异已折叠。
{ {
"name": "c-tool", "name": "c-tool",
"version": "1.9.0", "version": "1.9.1",
"private": true, "private": true,
"scripts": { "scripts": {
"serve": "vue-cli-service serve --port 8081", "serve": "vue-cli-service serve --port 8081",
...@@ -27,6 +27,7 @@ ...@@ -27,6 +27,7 @@
"graphql": "15.5.0", "graphql": "15.5.0",
"ipinyinjs": "^1.0.0", "ipinyinjs": "^1.0.0",
"jian_fan": "^1.0.3", "jian_fan": "^1.0.3",
"jimp": "^0.16.1",
"js-base64": "^2.6.4", "js-base64": "^2.6.4",
"js-htmlencode": "^0.3.0", "js-htmlencode": "^0.3.0",
"js-yaml": "^3.14.1", "js-yaml": "^3.14.1",
......
<template> <template>
<div style="position: relative;"> <div style="position: relative;">
<slot></slot> <slot></slot>
<div class="right-bottom"> <div :style="extraStyle">
<slot name="extra"> <slot name="extra">
<Button v-if="text" type="primary" size="small" @click="buttonClick">{{ text }}</Button> <Button v-if="text" :type="type" size="small" @click="buttonClick">{{ text }}</Button>
</slot> </slot>
</div> </div>
</div> </div>
...@@ -15,6 +15,38 @@ export default { ...@@ -15,6 +15,38 @@ export default {
text: { text: {
type: String, type: String,
default: "" default: ""
},
bottom: {
type: String,
default: "4px"
},
top: {
type: String,
default: ""
},
left: {
type: String,
default: ""
},
right: {
type: String,
default: "4px"
},
type:{
type: String,
default: "primary"
}
},
computed:{
extraStyle(){
let css = {
fixed:"position: absolute",
zindex:"z-index:100",
vertical:this.top !== "" ? `top:${this.top}` : `bottom:${this.bottom}`,
horizontal:this.left !== "" ? `left:${this.left}` : `right:${this.right}`,
};
return Object.values(css).join(";")
} }
}, },
methods: { methods: {
...@@ -24,11 +56,3 @@ export default { ...@@ -24,11 +56,3 @@ export default {
} }
}; };
</script> </script>
<style scoped>
.right-bottom {
position: absolute;
bottom: 4px;
right: 4px;
}
</style>
<template> <template>
<Form inline style="padding: 10px 0" class="option-block"> <Form inline :style="style" class="option-block">
<slot></slot> <slot></slot>
</Form> </Form>
</template> </template>
<script> <script>
export default { export default {
name: 'optionBlock' name: 'optionBlock',
props: {
center: {
type: Boolean,
default: false
},
},
computed:{
style(){
let css = {
padding:"10px 0",
};
if (this.center){
css.textAlign = "center"
}
return css;
}
}
}; };
</script> </script>
......
...@@ -14,54 +14,52 @@ const DEFAULT_COMMON_TOOL = [ ...@@ -14,54 +14,52 @@ const DEFAULT_COMMON_TOOL = [
] ]
const category = [ const category = [
{'name': 'common', 'title': '常用'}, {'name': 'common'},
{'name': 'encryption', 'title': '加解密'}, {'name': 'encryption'},
{'name': 'conversion', 'title': '转换'}, {'name': 'conversion'},
{'name': 'serialize', 'title': '序列化'}, {'name': 'serialize'},
{'name': 'check', 'title': '校验'}, {'name': 'check'},
{'name': 'generate', 'title': '生成'}, {'name': 'generate'},
{'name': 'other', 'title': '其他'}, {'name': 'other'},
] ]
const tool = [ const tool = [
{ {
'name': 'hash', 'name': 'hash',
'title': '哈希(hash)',
'cat': ['encryption'] 'cat': ['encryption']
}, },
{ {
'name': 'encrypt', 'name': 'encrypt',
'title': '加密/解密',
'cat': ['encryption'] 'cat': ['encryption']
}, },
{'name': 'sign', 'title': '签名/验签', 'cat': ['encryption']}, {'name': 'sign', 'cat': ['encryption','check']},
{'name': 'base64', 'title': 'BASE64编码', 'cat': ['encryption']}, {'name': 'base64', 'cat': ['encryption']},
{'name': 'json', 'title': 'JSON工具', 'cat': ['conversion', 'serialize']}, {'name': 'json', 'cat': ['conversion', 'serialize']},
{'name': 'url', 'title': 'URL编码', 'cat': ['conversion']}, {'name': 'url', 'cat': ['conversion']},
{'name': 'timestamp', 'title': '时间戳', 'cat': ['conversion']}, {'name': 'timestamp', 'cat': ['conversion']},
{'name': 'qrCode', 'title': '二维码', 'cat': ['generate']}, {'name': 'qrCode', 'cat': ['generate']},
{'name': 'barcode', 'title': '条形码', 'cat': ['generate']}, {'name': 'barcode', 'cat': ['generate']},
{'name': 'pinyin', 'title': '汉字转拼音', 'cat': ['conversion']}, {'name': 'pinyin', 'cat': ['conversion']},
{'name': 'ip', 'title': 'IP地址查询', 'cat': ['other']}, {'name': 'ip', 'cat': ['other']},
{'name': 'code', 'title': '代码格式化', 'cat': ['other']}, {'name': 'code', 'cat': ['other']},
{'name': 'unicode', 'title': 'Unicode', 'cat': ['conversion']}, {'name': 'unicode', 'cat': ['conversion']},
{'name': 'decimalConvert', 'title': '进制转换', 'cat': ['conversion']}, {'name': 'decimalConvert', 'cat': ['conversion']},
{'name': 'regex', 'title': '正则表达式', 'cat': ['check']}, {'name': 'regex', 'cat': ['check']},
{'name': 'randomString', 'title': '随机字符生成', 'cat': ['generate']}, {'name': 'randomString', 'cat': ['generate']},
{'name': 'serializeConversion', 'title': '序列化转换', 'cat': ['conversion', 'serialize']}, {'name': 'serializeConversion', 'cat': ['conversion', 'serialize']},
{'name': 'diffs', 'title': '文本差异化对比', 'cat': ['check']}, {'name': 'diffs', 'cat': ['check']},
{'name': 'crontab', 'title': 'crontab校验', 'cat': ['check']}, {'name': 'crontab', 'cat': ['check']},
{'name': 'websocket', 'title': 'websocket调试', 'cat': ['other']}, {'name': 'websocket', 'cat': ['other']},
{'name': 'unit', 'title': '单位换算', 'cat': ['other']}, {'name': 'unit', 'cat': ['other']},
{'name': 'time', 'title': '时间计算器', 'cat': ['other']}, {'name': 'time', 'cat': ['other']},
{'name': 'uuid', 'title': 'UUID生成', 'cat': ['generate']}, {'name': 'uuid', 'cat': ['generate']},
{'name': 'jsonToObject', 'title': 'JSON转实体类', 'cat': ['conversion', 'serialize']}, {'name': 'jsonToObject', 'cat': ['conversion', 'serialize']},
{'name': 'ascii', 'title': 'ASCII转换', 'cat': ['conversion']}, {'name': 'ascii', 'cat': ['conversion']},
{'name': 'variableConversion', 'title': '变量名转换', 'cat': ['conversion']}, {'name': 'variableConversion', 'cat': ['conversion']},
{'name': 'jwt', 'title': 'JWT解码', 'cat': ['conversion']}, {'name': 'jwt', 'cat': ['conversion']},
{'name': 'hexString', 'title': 'Hex/String转换', 'cat': ['conversion']}, {'name': 'hexString', 'cat': ['conversion']},
{'name': 'text', 'title': '文本处理', 'cat': ['other']}, {'name': 'text', 'cat': ['other']},
{'name': 'html', 'title': 'html编码', 'cat': ['conversion']}, {'name': 'html', 'cat': ['conversion']},
] ]
// 工具类功能配置 // 工具类功能配置
......
locales/build.json locales/build.js
...@@ -53,7 +53,7 @@ const getLocale = (code) => { ...@@ -53,7 +53,7 @@ const getLocale = (code) => {
message: config[key], message: config[key],
} }
if (placeholders.length > 0) { if (placeholders.length > 0) {
locale["placeholders"] = placeholders locale[`${type}_${key}`]["placeholders"] = placeholders
} }
}); });
} }
...@@ -107,7 +107,7 @@ module.exports = { ...@@ -107,7 +107,7 @@ module.exports = {
}, },
// 生成运行时语言包 // 生成运行时语言包
generate() { generate() {
fs.writeFileSync(path.join(__dirname, 'locales/build.json'), JSON.stringify(ALL_LOCALE, null, 4)); fs.writeFileSync(path.join(__dirname, 'locales/build.js'), `export default ${JSON.stringify(ALL_LOCALE, null, 4)}`);
}, },
getMessage(code, key) { getMessage(code, key) {
let locales = ALL_LOCALE['detail'] let locales = ALL_LOCALE['detail']
......
...@@ -2,11 +2,10 @@ import VueI18n from 'vue-i18n' ...@@ -2,11 +2,10 @@ import VueI18n from 'vue-i18n'
import Vue from 'vue' import Vue from 'vue'
import {getMessage as chromiumGetMessage} from "../adapter/chromium/helper" import {getMessage as chromiumGetMessage} from "../adapter/chromium/helper"
import {isChromium} from "../helper"; import {isChromium} from "../helper";
import locales from "./locales/build.js";
Vue.use(VueI18n) Vue.use(VueI18n)
const locales = require('./locales/build.json')
// 区域列表 // 区域列表
export const LOCALE_LISTS = locales.lists export const LOCALE_LISTS = locales.lists
export const LOCALE_DETAIL = locales.detail export const LOCALE_DETAIL = locales.detail
......
{
"content": "Content",
"background": "Background",
"line_color": "Line Color",
"bar_width": "Bar Width",
"height": "Height",
"margin": "Margin",
"show_text": "Show Text",
"hide": "Hide",
"top": "Top",
"bottom": "Bottom",
"text_align": "Text Align",
"left": "Left",
"center": "Center",
"right": "Right",
"font": "Font",
"bold": "Bold",
"italic": "Italic",
"font_size": "Size",
"text_margin": "Margin",
"invalid_content": "Invalid content"
}
{
"more": "More Languages",
"indent": "Code Indent",
"indent_width": "Indent Space {0}",
"compress": "Compress",
"complete": "Operation Complete",
"error_prompt": "Error Prompt"
}
{
"expression": "Expression",
"execute_time": "Execute Time",
"example": "Example",
"format": "Format",
"execute_time_list": "Execute Time List",
"no": "{0}: {1}",
"symbol": "Symbol",
"description": "Description",
"symbol_description_1": "any value",
"symbol_description_2": "value list separator",
"symbol_description_3": "range of values",
"symbol_description_4": "step values",
}
{
"input_placeholder": "Please enter the number to be converted",
"input": "Input",
"input_type_common": "Common",
"input_type_other": "Other",
"base": "Base-{0}",
"result": "Result {0}",
"alphabet": "64 Alphabet",
"reset": "Reset Default",
"alphabet_length_error": "The conversion alphabet must be 64 bits in length"
}
{
"more": "More Languages",
"collapse":"Collapse Identical"
}
{
"input": "Input",
"password":"Password/Secret Key",
"encrypt": "Encrypt",
"decrypt":"Decrypt",
"generate_secret_key": "Generate Secret Key",
"output":"Output",
"public_key": "Public Key:",
"private_key":"Private Key:",
"secret_key_prompt": "Please save the key pair in time, the current key data cannot be restored after closing the dialog",
"close":"Close",
"failed": "Operation failed with error:{0}"
}
{
"input": "Input",
"output": "Output",
"uppercase": "Uppercase",
}
{
"input": "Input",
"encode":"Encode",
"decode": "Decode",
"output":"Output"
}
{
"input": "Please enter IP address",
"query":"Query",
"local": "Local IP",
"info_source":"IP information source",
"ok": "Query Success",
"error":"Query Fail:{0}"
}
{
"input": "Input",
"content_empty": "Please enter content",
"error": "Exception:{0}",
"format": "Format",
"compress": "Compress",
"escape": "Escape",
"clear_escape": "Unescape",
"unicode_to_zh": "Unicode->Zh",
"zh_to_unicode": "Zh->Unicode",
"to_get": "To Get",
"get_to_json": "Get=>Json",
"clear": "Clear"
}
{
"input": "Input",
"output":"Output",
"type_error": "Conversion type error",
"format": "Beautify",
"error":"Error:{0}"
}
{
"input": "Input",
"decode":"Decode",
"output": "Output",
"decode_fail":"Decode Fail:{0}"
}
...@@ -4,6 +4,8 @@ ...@@ -4,6 +4,8 @@
"ui_views": "View", "ui_views": "View",
"ui_load":"Loading", "ui_load":"Loading",
"ui_close": "Close", "ui_close": "Close",
"ui_copy_text_ok":"Result Copied ^o^",
"ui_copy_image_ok":"Image Copied ^o^",
// views // views
"setting_language": "Language", "setting_language": "Language",
......
{
"input": "Input",
"normal":"No Tone",
"tone": "Have Tone",
"abbr":"First Letter",
"output": "Output",
"delimiter_null":"No Delimiter",
"delimiter_space": "Space Delimiter",
"delimiter_1":"'-' Delimiter",
"delimiter_2": "'_' Delimiter",
"delimiter_3":"'.' Delimiter"
}
{
"generate_title": "Generate",
"generate_input": "Input",
"generate_error": "Generate Error:{0}",
"reader_title": "Reader",
"reader_input": "Please enter the QR code image url or click the button below to upload the image",
"reader_upload": "Upload Image",
"reader_output": "Output",
"reader_error": "Reader Error:{0}",
"reader_parsing_failure": "Image parsing failure",
}
{
"length": "Length",
"amount": "Number of strings",
"delimiter": "Delimiter",
"digital": "Digital",
"lowercase": "Lowercase",
"uppercase": "Uppercase",
"symbol": "Symbol",
"unique": "Unique",
"add_quote": "Add Quote",
"generate": "Generate",
"output": "Output"
}
{
"reference": "Reference",
"expression": "Expression",
"replace_content": "Replace Content",
"delete": "Delete",
"input": "Input",
"global": "Global",
"ignore_case": "Ignore Case",
"output": "Output",
"output_count": "{0} Total Matches",
"output_emty": "No match result, please check expression",
"error": "Error:{0}",
"reference_url": "https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Regular_Expressions",
"type_zh": "Chinese",
"type_complex": "Double-byte characters (including Chinese characters)",
"type_blank": "Blank lines",
"type_email": "Email",
"type_url": "URL",
"type_cn_mobile": "China Mobile Phone Number",
"type_ip": "IP",
"type_cn_tel": "China Phone Number",
"type_tencent_qq": "Tencent QQ",
"type_cn_postcode": "China Postcode",
"type_date": "Data (YYYY-MM-DD)",
"type_positive_integer": "Positive Integer",
"type_negative_integer": "Negative Integer",
"type_integer": "Integer",
"type_non_negative_integer": "Non Negative Integer",
"type_non_positive_integer": "Non Positive Integer",
"type_positive_float": "Positive Float",
"type_negative_float": "Negative Float"
}
{
"input": "Input",
"output":"output",
"error": "Error:"
}
{
"sign_data": "Sign Data/Verify data",
"verify_code": "Signature after Base64 encoding",
"sign": "Sign",
"verify": "Verify",
"generate_keypair": "Generate Keypair",
"public_key": "PEM Public Key",
"private_key": "PEM Private Key",
"keypair_type": "Type",
"keypair_length": "Length",
"generate_cancel": "Cancel",
"generate_in": "Generate in progress",
"generate": "Generate",
"error_sign_content_empty": "Sign Data/Private Key Required",
"error": "error:{0}",
"error_verify_content_empty": "Base64 Sign/Public Key Required",
"verify_fail": "Verify Fail",
"verify_ok": "Verify Success",
}
{
"content": "Text Content",
"input": "Input",
"resume": "Resume",
"case_conversion": "Case Converter",
"upper_all": "Upper",
"lower_all": "Lower",
"upper_line_start": "Upper Line Start",
"lower_line_start": "lower Line Start",
"upper_word_start": "Upper Word Start",
"lower_word_start": "Lower Word Start",
"punctuation": "Punctuation",
"cn": "CN",
"en": "EN",
"simplified_traditional": "Chinese",
"simplified": "Simplified",
"traditional": "Traditional",
"replace": "Replace",
"line_remove_duplicate": "Line Remove Duplicate",
"line_number": "Line Number",
"line_number_add": "Add",
"line_number_remove": "Remove",
"line_sort": "Line Sort",
"line_sort_asc": "Asc",
"line_sort_desc": "Desc",
"filter": "Filter",
"filter_trim": "(trim) Removes whitespace from both ends of a string",
"filter_blank_line": "Filter blank line",
"stat": "Stat",
"stat_explain": "Explain",
"replace_search": "Search",
"replace_replace": "Replace",
"replace_explain": "You can enter multiple lines, batch replace by line",
"cancel": "Cancel",
"submit": "Submit",
"string_length": "String",
"byte_length": "byte(utf8/gbk)",
"word_length": "Word",
"line_length": "Line",
"zh_length": "(Cn)Char/Punctuation",
"en_length": "(En)Char/Word/Punctuation",
"int_length": "(Number)Char/word",
"ok": "Complete",
"error": "Error:{0}",
"item": "Item",
"explain": "Explain",
"explain_byte_length_utf8_name": "byte utf8",
"explain_byte_length_utf8_info": "Cn Char Length:3",
"explain_byte_length_gbk_name": "byte gbk",
"explain_byte_length_gbk_info": "Cn Char Length:2",
"explain_string_length_name": "String Length",
"explain_string_length_info": "Cn/En Char Length:1 Line Break Length:0",
"explain_word_length_name": "Word",
"explain_word_length_info": "Cn+En Word+punctuation+Number word",
"explain_int_length_name": "Number Char",
"explain_int_length_info": "Number Char Count. For example:'a1024 1024' result:8",
"explain_int_word_length_name": "Number Word",
"explain_int_word_length_info": "For example:'a1024 1024' result:1",
"explain_blank_line_length_name": "Line Length",
"explain_blank_line_length_info": "Blank lines are also included in the number of lines",
"value": "value",
"stat_show": "Word:{1} UTF-8:{1} GBK:{2}"
}
{
"diff_tool": "Difference Calculator",
"and": "And",
"diff": "Diff",
"operation": "Time Operation",
"add": "Add",
"reduce": "Reduce",
"after": "After",
"is": "Is",
"error": "error:{0}",
"error_duration_length": "The year/month interval can only be an integer",
"current_time": "Current Time",
"current_date": "Current Date",
"current_month_date": "Current Month Date",
"current_year_date": "Current Year Date",
"year": "Year",
"month": "Month",
"week": "Week",
"day": "Day",
"hour": "Hour",
"minute": "Minute",
"second": "Second"
}
{
"input": "Input",
"get":"Get Current",
"normal_second": "Normal Second",
"normal_millisecond":"Normal Millisecond",
"unix_second": "Unix Timestamp Second",
"unix_millisecond":"Unix Timestamp Millisecond",
"output": "Output",
"copy":"Copy",
"error_format": "Input Format Error",
"error":"error:{0}",
"format": "Format",
"value":"Value"
}
{
"input": "Input",
"encode": "Encode",
"decode": "Decode",
"mode_default": "Unicode Default",
"mode_wide": "Unicode Wide",
"mode_wide_bracket": "Unicode Wide(Has Bracket)",
"mode_number": "Unicode Number",
"mode_html_10": "HTML-code(Base-10)",
"mode_html_16": "HTML-code(Base-16)",
"mode_css_16": "Css-code(Base-16)",
"ignore_ascii": "Ignore Ascii",
"output": "Output",
"error": "error:{0}"
}
{
"length": "Length",
"area": "Area",
"volume": "Volume",
"weight": "Weight",
"temperature": "Temperature",
"pressure": "Pressure",
"power": "Power",
"work": "Work",
"density": "Density",
"strength": "Strength",
"time": "Time",
"speed": "Speed",
"byte": "Byte",
"angle": "Angle",
"length_km": "kilometres",
"length_m": "metre",
"length_dm": "decimetre",
"length_cm": "centimetre",
"length_mm": "millimetre",
"length_um": "Micrometre",
"length_nm": "Nanometre",
"length_pm": "Picometre",
"length_ly": "Light year",
"length_au": "Astronomical unit",
"length_in": "Inch",
"length_ft": "Foot",
"length_yd": "Yard",
"length_mi": "Mile",
"length_nmi": "Nautical mile",
"length_fm": "Fathom",
"length_fur": "furlong",
"length_cn_li": "lǐ",
"length_cn_zhang": "zhàng",
"length_cn_chi": "chǐ",
"length_cn_cun": "cùn",
"length_cn_fen": "fēn",
"length_cn_li2": "lí",
"length_cn_hao": "háo",
"area_km_2": "Square kilometre",
"area_ha": "Hectare",
"area_are": "Hectare Are",
"area_m_2": "Square metre",
"area_dm_2": "square decimetre",
"area_cm_2": "Square centimetre",
"area_mm_2": "Square millimeter",
"area_acre": "Acre",
"area_mi_2": "Square Acre",
"area_yd_2": "Square Yard",
"area_ft_2": "Square foot",
"area_in_2": "Square inch",
"area_rd_2": "Square rod",
"area_cn_qing": "qǐng",
"area_cn_mu": "mǔ",
"area_cn_fen": "fēn",
"area_cn_chi_2": "Square chǐ",
"area_cn_cun_2": "Square cùn",
"volume_m_3": "Cubic metre",
"volume_dm_3": "cubic decimeter",
"volume_cm_3": "Cubic centimeter",
"volume_mm_3": "Cubic millimeter",
"volume_l": "Litre",
"volume_dl": "deciliter",
"volume_ml": "milliliter",
"volume_cl": "centiliter",
"volume_uL": "microliter",
"volume_hl": "hectolitre",
"volume_ft_3": "Cubic feet",
"volume_in_3": "Cubic inch",
"volume_yd_3": "Cubic yards",
"volume_acre_ft": "acre foot",
"volume_uk_gal": "Uk gallon",
"volume_us_gal": "Us gallon",
"volume_uk_oz": "Uk ounce",
"volume_us_oz": "Us ounce",
"weight_kg": "kilogram",
"weight_g": "gram",
"weight_mg": "Milligrams",
"weight_ug": "microgram",
"weight_t": "Ton",
"weight_q": "Quintal",
"weight_ct": "carat",
"weight_lb": "Pound",
"weight_oz": "ounce",
"weight_gr": "Grain",
"weight_lt": "British long ton",
"weight_st1": "US short ton",
"weight_st2": "Stone",
"weight_uk_cwt": "British long hundredweight",
"weight_us_cwt": "US short hundredweight",
"weight_dr": "Dram",
"weight_cn_dan": "dān",
"weight_cn_jin": "jīn",
"weight_cn_liang": "liǎng",
"weight_cn_qian": "qián",
"temperature_c": "Celsius",
"temperature_f": "Fahrenheit",
"temperature_k": "Kelvin",
"temperature_r": "Rankine_scale",
"temperature_re": "Réaumur_scale",
"pressure_pa": "Pascal",
"pressure_kpa": "KPa",
"pressure_hpa": "HPa",
"pressure_atm": "Standard atmospheric pressure",
"pressure_mmhg": "MmHg",
"pressure_in_hg": "Inch mercury",
"pressure_bar": "bar",
"pressure_mbar": "millibar",
"pressure_psf": "Pounds per square feet",
"pressure_psi": "Pounds per square inch",
"pressure_mmwg": "mmH2O",
"pressure_kgf_cm_2": "Kgf/square centimeter",
"pressure_kgf_m_2": "Kgf/Square meter",
"pressure_mpa": "MPa",
"power_w": "watt",
"power_kw": "kilowatt",
"power_hp": "Imperial horsepower",
"power_ps": "Metric horsepower",
"power_kg_m_s": "Kg·m/sec",
"power_kcal_s": "Kcal/s",
"power_btu_s": "British Thermal Unit/sec",
"power_ft_lb_s": "Feet·lbs/sec",
"power_j_s": "Joule/sec",
"power_n_m_s": "Newton m/s",
"work_j": "joule",
"work_kg_m": "Kg·m",
"work_ps_h": "Metric horsepower·hour",
"work_hp_h": "British horsepower·hour",
"work_kw_h": "Kilowatt hour",
"work_kw_h_": "Spend",
"work_cal": "Card",
"work_kcal": "Kcal",
"work_btu": "British Thermal Unit",
"work_ft_lb": "Foot pound",
"work_kj": "Kilojoule",
"density_kg_cm_3": "Kg/Cubic centimeter",
"density_kg_dm_3": "Kg/cubic decimeter",
"density_kg_m_3": "Kg/Cubic metre",
"density_g_cm_3": "g/Cubic centimeter",
"density_g_dm_3": "g/cubic decimeter",
"density_g_m_3": "g/Cubic metre",
"strength_n": "Newton",
"strength_kn": "Kilogram Newton",
"strength_kgf": "Kilogram force",
"strength_gf": "Keli 克力",
"strength_tf": "Metric ton force",
"strength_lbf": "Pound force",
"strength_kip": "Kilopound force",
"strength_dyn": "Dyne",
"time_yr": "year",
"time_week": "week",
"time_d": "Day",
"time_h": "Hour",
"time_min": "Minute",
"time_s": "Second",
"time_ms": "millisecond",
"time_us": "Microseconds",
"time_ns": "Nanosecond",
"speed_m_s": "metre/Sec",
"speed_km_s": "kilometer/Sec",
"speed_km_h": "kilometer/Hour",
"speed_c": "Speed of light",
"speed_mach": "Maher",
"speed_mile_h": "Mile/hour",
"speed_in_s": "Inch/Sec",
"byte_bit": "Bit",
"byte_b": "byte",
"byte_kb": "Kilobytes",
"byte_mb": "Megabyte",
"byte_gb": "Gigabytes",
"byte_tb": "Terabyte",
"byte_pb": "Petabytes",
"byte_eb": "Exabytes",
"angle_circle": "circle",
"angle_angle": "angle",
"angle_gon": "grade",
"angle_degree": "degree",
"angle_min": "Minute",
"angle_s": "Second",
"angle_rad": "radian",
"angle_mrad": "Milliradian",
"metric_system": "Metric System",
"imperial_units": "Imperial Units",
"chinese_units": "Chinese Units",
"angle_units": "Angle Units",
"radian_units": "Radian Units",
"all": "All"
}
{
"input": "Input",
"encode": "Encode",
"decode": "Decode",
"output": "Output"
}
{
"amount": "Amount",
"delimiter": "Delimiter",
"hyphens": "Hyphens(-)",
"is_upper": "Upper",
"is_add_quote": "Add Quote",
"uint8_array": "Uint8 Array",
"output": "Output"
}
{
"input": "Input",
"input_placeholder":"A line of one"
}
{
"connect": "Connect",
"close": "Close",
"send_content": "Send Content",
"log_content": "Request/Response/Log Content",
"send": "Send",
"copy": "Copy",
"clear": "Clear",
"you": "You",
"server": "Server",
"error_connect": "Ws is not connected yet, or the connection fails, please check",
"error_content": "Send content cannot be empty",
"connect_ok": "Connect Success",
"close_ok": "Close Success",
"error": "error:{0}",
"connect_start": "Connecting:{0}",
"close_start": "Closing:{0}"
}
{
"content": "内容",
"background": "背景",
"line_color": "线条颜色",
"bar_width": "条码宽",
"height": "条码高",
"margin": "外边距",
"show_text": "文本显示",
"hide": "隐藏",
"top": "上方",
"bottom": "下方",
"text_align": "水平位置",
"left": "居左",
"center": "居中",
"right": "居右",
"font": "字体",
"bold": "粗体",
"italic": "斜体",
"font_size": "大小",
"text_margin": "外边距",
"invalid_content": "无效条码内容"
}
{
"more": "更多语言",
"indent": "代码缩进",
"indent_width": "缩进 空格 {0}",
"compress": "压缩",
"complete": "操作完成",
"error_prompt": "错误提示"
}
{
"expression": "表达式",
"execute_time": "最近执行时间",
"example": "例子",
"format": "格式",
"execute_time_list": "最近10次执行时间",
"no": "第{0}次: {1}",
"symbol": "特殊符号",
"description": "描述",
"symbol_description_1": "代表任何时刻都接受的意思。举例来说,范例一内那个日、月、周都是*,就代表着不论何月、何日的礼拜几的12:00都执行后续命令的意思。",
"symbol_description_2": "代表分隔时段的意思。举例来说,如果要执行的工作是3:00与6:00时,就会是:0 3,6 * * * command时间还是有五列,不过第二列是 3,6 ,代表3与6都适用",
"symbol_description_3": "代表一段时间范围内,举例来说,8点到12点之间的每小时的20分都进行一项工作:20 8-12 * * * command仔细看到第二列变成8-12.代表 8,9,10,11,12 都适用的意思",
"symbol_description_4": "那个n代表数字,即是每隔n单位间隔的意思,例如每五分钟进行一次,则:*/5 * * * * command用*与/5来搭配,也可以写成0-59/5,意思相同",
}
{
"input_placeholder": "请输入待转换数字",
"input": "转换数字",
"input_type_common": "常用",
"input_type_other": "其他",
"base": "{0} 进制",
"result": "转换结果 {0}",
"alphabet": "64位字母表",
"reset": "恢复默认",
"alphabet_length_error": "转换字母表必须是64位长度"
}
{
"more": "更多语言",
"collapse":"折叠相同"
}
{
"input": "输入",
"password":"密码/密钥",
"encrypt": "加密",
"decrypt":"解密",
"generate_secret_key": "生成密钥对",
"output":"输出",
"public_key": "公钥:",
"private_key":"私钥:",
"secret_key_prompt": "请及时保存秘钥对, 关闭对话框后无法恢复当前秘钥数据",
"close":"关闭",
"failed": "操作失败:{0}"
}
{
"input": "输入",
"output": "输出",
"uppercase": "大写字母",
}
{
"input": "输入",
"encode":"编码",
"decode": "解码",
"output":"输出"
}
{
"input": "请输入IP地址",
"query":"查询",
"local": "本地IP",
"info_source":"IP 信息来源",
"ok": "查询成功",
"error":"查询异常:{0}"
}
{
"input": "输入",
"content_empty": "请输入内容",
"error":"异常:{0}",
"format": "格式化",
"compress":"压缩",
"escape": "转移",
"clear_escape":"去除转移",
"unicode_to_zh": "Unicode转中文",
"zh_to_unicode":"中文转Unicode",
"to_get": "转Get参数",
"get_to_json":"Get参数转Json",
"clear": "清空"
}
{
"input": "输入",
"output":"输出",
"type_error": "转换类型错误",
"format": "格式化",
"error":"错误:{0}"
}
{
"input": "输入",
"decode":"解码",
"output": "输出",
"decode_fail":"解码失败:{0}"
}
...@@ -3,7 +3,9 @@ ...@@ -3,7 +3,9 @@
"ui_setting": "设置", "ui_setting": "设置",
"ui_views": "查看", "ui_views": "查看",
"ui_load":"加载", "ui_load":"加载",
"ui_close": "管理", "ui_close": "关闭",
"ui_copy_text_ok":"结果已复制 ^o^",
"ui_copy_image_ok":"图片已复制 ^o^",
// 界面 // 界面
"setting_language": "语言", "setting_language": "语言",
......
{
"input": "输入",
"normal":"无声调",
"tone": "有声调",
"abbr":"首字母",
"output": "输出",
"delimiter_null":"无分隔符",
"delimiter_space": "空格分隔",
"delimiter_1":"'-'中划线分隔",
"delimiter_2": "'_'下划线分隔",
"delimiter_3":"'.'点分隔"
}
{
"generate_title": "二维码生成",
"generate_input": "输入",
"generate_error": "生成错误:{0}",
"reader_title": "二维码解析",
"reader_input": "请输入二维码图片地址或点击下方按钮上传图片",
"reader_upload": "上传图片",
"reader_output": "输出",
"reader_error": "解析错误:{0}",
"reader_parsing_failure": "图片解析失败",
}
{
"length": "长度",
"amount":"数量",
"delimiter": "分隔符",
"digital":"数字",
"lowercase": "小写字母",
"uppercase":"大写字母",
"symbol": "特殊符号",
"unique":"唯一",
"add_quote": "添加引号",
"generate":"生成",
"output": "输出"
}
{
"reference": "参考",
"expression": "正则表达式",
"replace_content": "替换内容",
"delete": "删除",
"input": "输入待处理内容",
"global": "全局搜索",
"ignore_case": "忽略大小写",
"output": "输出",
"output_count": "共 {0} 个匹配项",
"output_emty": "没有匹配结果,请检查正则",
"error": "错误:{0}",
"reference_url": "https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Guide/Regular_Expressions",
"type_zh": "中文字符",
"type_complex": "双字节字符(包括汉字在内)",
"type_blank": "空白行",
"type_email": "Email地址",
"type_url": "网址URL",
"type_cn_mobile": "手机",
"type_ip": "IP地址",
"type_cn_tel": "国内电话号码",
"type_tencent_qq": "腾讯QQ号",
"type_cn_postcode": "中国邮政编码",
"type_date": "(年-月-日)格式日期",
"type_positive_integer": "正整数",
"type_negative_integer": "负整数",
"type_integer": "整数",
"type_non_negative_integer": "非负整数(正整数 + 0)",
"type_non_positive_integer": "非正整数(负整数 + 0)",
"type_positive_float": "正浮点数",
"type_negative_float": "负浮点数"
}
{
"input": "输入",
"output":"输出",
"error": "错误:{0}"
}
{
"sign_data": "待签名内容/验签数据",
"verify_code": "Base64编码后签名",
"sign": "签名",
"verify": "验签",
"generate_keypair": "生成公钥/私钥",
"public_key": "PEM格式公钥",
"private_key": "PEM格式私钥",
"keypair_type": "密钥格式",
"keypair_length": "密钥长度",
"generate_cancel": "取消",
"generate_in": "生成中",
"generate": "生成",
"error_sign_content_empty": "待签名内容/PEM格式私钥 必填",
"error": "错误:{0}",
"error_verify_content_empty": "Base64编码后签名/PEM格式公钥 必填",
"verify_fail": "验签失败",
"verify_ok": "验签成功",
}
{
"content": "文本内容",
"input": "输入",
"resume": "恢复",
"case_conversion": "大小写转换",
"upper_all": "全部大写",
"lower_all": "全部小写",
"upper_line_start": "行首大写",
"lower_line_start": "行首小写",
"upper_word_start": "词首大写",
"lower_word_start": "词首小写",
"punctuation": "中英标点转换",
"cn": "中文",
"en": "英文",
"simplified_traditional": "简繁转换",
"simplified": "简体",
"traditional": "繁体",
"replace": "替换",
"line_remove_duplicate": "行去重",
"line_number": "行号",
"line_number_add": "添加",
"line_number_remove": "移除",
"line_sort": "行排序",
"line_sort_asc": "升序",
"line_sort_desc": "降序",
"filter": "过滤",
"filter_trim": "过滤行首尾不可见字符(trim)",
"filter_blank_line": "过滤多余空行",
"stat": "统计",
"stat_explain": "统计说明",
"replace_search": "查找",
"replace_replace": "替换",
"replace_explain": "可输入多行, 按行进行批量替换",
"cancel": "取消",
"submit": "提交",
"string_length": "字符数",
"byte_length": "字节数(utf8/gbk)",
"word_length": "字数",
"line_length": "行数",
"zh_length": "(中文)字数/标点",
"en_length": "(英文)字母/单词/标点",
"int_length": "(数字)字符/单词",
"ok": "完成",
"error": "错误:{0}",
"item": "项目",
"explain": "说明",
"explain_byte_length_utf8_name": "字节数utf8",
"explain_byte_length_utf8_info": "中文字符计3个长度",
"explain_byte_length_gbk_name": "字节数gbk",
"explain_byte_length_gbk_info": "中文字符计2个长度",
"explain_string_length_name": "字符数",
"explain_string_length_info": "中/英文字符均计1个长度 换行符不计入长度",
"explain_word_length_name": "字数",
"explain_word_length_info": "中文字数+英文单词数+中文标点数+英文标点数+数字单词数",
"explain_int_length_name": "数字字符",
"explain_int_length_info": "统计单个数字出现次数 例如:'a1024 1024' 结果为:8",
"explain_int_word_length_name": "数字单词",
"explain_int_word_length_info": "例如:'a1024 1024' 结果为:1 其中:'a1024' 为英文单词 '1024' 为数字单词",
"explain_blank_line_length_name": "行数",
"explain_blank_line_length_info": "空行也会计入行数",
"value": "值",
"stat_show": "字数:{0} UTF-8:{1} GBK:{2}",
}
{
"diff_tool": "差值计算器",
"and": "与",
"diff": "相差",
"operation": "时间操作",
"add": "添加",
"reduce": "减少",
"after": "后",
"is": "为",
"error": "错误:{0}",
"error_duration_length": "年/月间隔只能是整数",
"current_time": "当前时间",
"current_date": "当前日期",
"current_month_date": "当月日期",
"current_year_date": "当年日期",
"year": "年",
"month": "月",
"week": "周",
"day": "日",
"hour": "小时",
"minute": "分钟",
"second": "秒"
}
{
"input": "输入",
"get":"获取当前",
"normal_second": "标准时间(秒)",
"normal_millisecond":"标准时间(毫秒)",
"unix_second": "Unix时间戳(秒)",
"unix_millisecond":"Unix时间戳(秒)",
"output": "输出",
"copy":"复制",
"error_format": "输入时间格式异常",
"error":"错误:{0}",
"format": "格式",
"value":"值"
}
{
"input": "输入",
"encode": "编码",
"decode": "解码",
"mode_default": "Unicode 默认模式",
"mode_wide": "Unicode 宽字符模式",
"mode_wide_bracket": "Unicode 宽字符模式(带大括号)",
"mode_number": "Unicode 编码模式",
"mode_html_10": "Html 实体(10进制)",
"mode_html_16": "Html 实体(16进制)",
"mode_css_16": "Css 实体(16进制)",
"ignore_ascii": "忽略 Ascii 字符",
"output": "输出",
"error": "错误:{0}"
}
{
"length": "长度",
"area": "面积",
"volume": "体积",
"weight": "质量",
"temperature": "温度",
"pressure": "压力",
"power": "功率",
"work": "功/能/热",
"density": "密度",
"strength": "力",
"time": "时间",
"speed": "速度",
"byte": "数据存储",
"angle": "角度",
"length_km": "千米",
"length_m": "米",
"length_dm": "分米",
"length_cm": "厘米",
"length_mm": "毫米",
"length_um": "微米",
"length_nm": "纳米",
"length_pm": "皮米",
"length_ly": "光年",
"length_au": "天文单位",
"length_in": "英寸",
"length_ft": "英尺",
"length_yd": "码",
"length_mi": "英里",
"length_nmi": "海里",
"length_fm": "英寻",
"length_fur": "弗隆",
"length_cn_li": "里",
"length_cn_zhang": "丈",
"length_cn_chi": "尺",
"length_cn_cun": "寸",
"length_cn_fen": "分",
"length_cn_li2": "厘",
"length_cn_hao": "毫",
"area_km_2": "平方千米",
"area_ha": "公顷",
"area_are": "公亩",
"area_m_2": "平方米",
"area_dm_2": "平方分米",
"area_cm_2": "平方厘米",
"area_mm_2": "平方毫米",
"area_acre": "英亩",
"area_mi_2": "平方英里",
"area_yd_2": "平方码",
"area_ft_2": "平方英尺",
"area_in_2": "平方英寸",
"area_rd_2": "平方竿",
"area_cn_qing": "顷",
"area_cn_mu": "亩",
"area_cn_fen": "分",
"area_cn_chi_2": "平方尺",
"area_cn_cun_2": "平方寸",
"volume_m_3": "立方米",
"volume_dm_3": "立方分米",
"volume_cm_3": "立方厘米",
"volume_mm_3": "立方毫米",
"volume_l": "升",
"volume_dl": "分升",
"volume_ml": "毫升",
"volume_cl": "厘升",
"volume_uL": "微升",
"volume_hl": "公石",
"volume_ft_3": "立方英尺",
"volume_in_3": "立方英寸",
"volume_yd_3": "立方码",
"volume_acre_ft": "亩英尺",
"volume_uk_gal": "英制加仑",
"volume_us_gal": "美制加仑",
"volume_uk_oz": "英制液体盎司",
"volume_us_oz": "美制液体盎司",
"weight_kg": "千克",
"weight_g": "克",
"weight_mg": "毫克",
"weight_ug": "微克",
"weight_t": "吨",
"weight_q": "公担",
"weight_ct": "克拉",
"weight_lb": "磅",
"weight_oz": "盎司",
"weight_gr": "格令",
"weight_lt": "长吨",
"weight_st1": "短吨",
"weight_st2": "英石",
"weight_uk_cwt": "英担",
"weight_us_cwt": "美担",
"weight_dr": "打兰",
"weight_cn_dan": "担",
"weight_cn_jin": "斤",
"weight_cn_liang": "两",
"weight_cn_qian": "钱",
"temperature_c": "摄氏度",
"temperature_f": "华氏度",
"temperature_k": "开氏度",
"temperature_r": "兰氏度",
"temperature_re": "列氏度",
"pressure_pa": "帕斯卡",
"pressure_kpa": "千帕",
"pressure_hpa": "百帕",
"pressure_atm": "标准大气压",
"pressure_mmhg": "毫米汞柱",
"pressure_in_hg": "英寸汞柱",
"pressure_bar": "巴",
"pressure_mbar": "毫巴",
"pressure_psf": "磅力/平方英尺",
"pressure_psi": "磅力/平方英寸",
"pressure_mmwg": "毫米水柱",
"pressure_kgf_cm_2": "公斤力/平方厘米",
"pressure_kgf_m_2": "公斤力/平方米",
"pressure_mpa": "兆帕",
"power_w": "瓦",
"power_kw": "千瓦",
"power_hp": "英制马力",
"power_ps": "米制马力",
"power_kg_m_s": "公斤·米/秒",
"power_kcal_s": "千卡/秒",
"power_btu_s": "英热单位/秒",
"power_ft_lb_s": "英尺·磅/秒",
"power_j_s": "焦耳/秒",
"power_n_m_s": "牛顿·米/秒",
"work_j": "焦耳",
"work_kg_m": "公斤·米",
"work_ps_h": "米制马力·时",
"work_hp_h": "英制马力·时",
"work_kw_h": "千瓦·时",
"work_kw_h_": "度",
"work_cal": "卡",
"work_kcal": "千卡",
"work_btu": "英热单位",
"work_ft_lb": "英尺·磅",
"work_kj": "千焦",
"density_kg_cm_3": "千克/立方厘米",
"density_kg_dm_3": "千克/立方分米",
"density_kg_m_3": "千克/立方米",
"density_g_cm_3": "克/立方厘米",
"density_g_dm_3": "克/立方分米",
"density_g_m_3": "克/立方米",
"strength_n": "牛",
"strength_kn": "千牛",
"strength_kgf": "千克力",
"strength_gf": "克力",
"strength_tf": "公吨力",
"strength_lbf": "磅力",
"strength_kip": "千磅力",
"strength_dyn": "达因",
"time_yr": "年",
"time_week": "周",
"time_d": "天",
"time_h": "时",
"time_min": "分",
"time_s": "秒",
"time_ms": "毫秒",
"time_us": "微秒",
"time_ns": "纳秒",
"speed_m_s": "米/秒",
"speed_km_s": "千米/秒",
"speed_km_h": "千米/时",
"speed_c": "光速",
"speed_mach": "马赫",
"speed_mile_h": "英里/时",
"speed_in_s": "英寸/秒",
"byte_bit": "比特",
"byte_b": "字节",
"byte_kb": "千字节",
"byte_mb": "兆字节",
"byte_gb": "千兆字节",
"byte_tb": "太字节",
"byte_pb": "拍字节",
"byte_eb": "艾字节",
"angle_circle": "圆周",
"angle_angle": "直角",
"angle_gon": "百分度",
"angle_degree": "度",
"angle_min": "分",
"angle_s": "秒",
"angle_rad": "弧度",
"angle_mrad": "毫弧度",
"metric_system": "公制",
"imperial_units": "英制",
"chinese_units": "市制",
"angle_units": "角度制",
"radian_units": "弧度制",
"all": "全部"
}
{
"input": "输入",
"encode": "编码",
"decode": "解码",
"output": "输出"
}
{
"amount": "数量",
"delimiter": "分隔符",
"hyphens": "连接符(-)",
"is_upper": "大写",
"is_add_quote": "添加引号",
"uint8_array": "Uint8 Array",
"output": "输出"
}
{
"input": "输入",
"input_placeholder":"一行一个"
}
{
"connect": "连接",
"close": "断开",
"send_content": "发送内容",
"log_content": "交互记录",
"send": "发送",
"copy": "复制全部",
"clear": "清空",
"you": "你",
"server": "服务端",
"error_connect": "ws还没有连接,或者连接失败,请检测",
"error_content": "发送内容不能为空",
"connect_ok": "连接成功",
"close_ok": "断开成功",
"error": "错误:{0}",
"connect_start": "开始连接:{0}",
"close_start": "开始中断:{0}"
}
...@@ -8,7 +8,7 @@ import {plugin as modelPlugin} from './tool/model' ...@@ -8,7 +8,7 @@ import {plugin as modelPlugin} from './tool/model'
import cache from './tool/cache' import cache from './tool/cache'
import setting from './tool/setting' import setting from './tool/setting'
import App from './tool.vue' import App from './tool.vue'
import {isUtools,setDisplayMode} from './helper' import {isUtools,setDisplayMode,isWeb} from './helper'
import {setCurrentLocale,i18n} from "./i18n"; import {setCurrentLocale,i18n} from "./i18n";
const run = () => { const run = () => {
...@@ -37,8 +37,7 @@ const run = () => { ...@@ -37,8 +37,7 @@ const run = () => {
} }
(function () { (function () {
if (document.body.clientWidth > 900 || isUtools) { if (document.body.clientWidth > 900 || isUtools || isWeb) {
console.log('调整窗口大小')
const page = document.getElementById('page') const page = document.getElementById('page')
page.style.width = 'auto' page.style.width = 'auto'
page.style.height = 'auto' page.style.height = 'auto'
......
<template> <template>
<div> <div>
<Menu mode="horizontal" theme="light" :active-name="currentCategory" @on-select="categorySelect" <Menu class="tool-category-menu-block" mode="horizontal" theme="light" :active-name="currentCategory" @on-select="categorySelect"
style="height: 45px;line-height: 45px;"> style="height: 45px;line-height: 45px;">
<MenuItem :style="$t('main_css_main_category_item_style')" :name="cat.name" v-for="(cat) in category" :key="cat.name"> <MenuItem :style="$t('main_css_main_category_item_style')" :name="cat.name" v-for="(cat) in category" :key="cat.name">
<Badge v-if="badgeCategoryIsShow(cat.name)" dot :offset="[15,-10]"> <Badge v-if="badgeCategoryIsShow(cat.name)" dot :offset="[15,-10]">
...@@ -31,7 +31,7 @@ ...@@ -31,7 +31,7 @@
</template> </template>
</MenuItem> </MenuItem>
</Menu> </Menu>
<RadioGroup :value="currentTool" @on-change="toolSelect" style="margin: 10px 0 10px 20px;line-height: 30px;"> <RadioGroup class="tool-select-block" :value="currentTool" @on-change="toolSelect" style="margin: 10px 0 10px 20px;line-height: 30px;">
<Radio :label="tool.name" v-for="(tool) in tools" :key="tool.name"> <Radio :label="tool.name" v-for="(tool) in tools" :key="tool.name">
<Badge v-if="badgeToolIsShow(tool.name)" dot :offset="[5,-5]"> <Badge v-if="badgeToolIsShow(tool.name)" dot :offset="[5,-5]">
{{ $t('main_tool_'+tool.name) }} {{ $t('main_tool_'+tool.name) }}
......
...@@ -53,11 +53,12 @@ const debounceSaveToolDataMethod = _.debounce(function () { ...@@ -53,11 +53,12 @@ const debounceSaveToolDataMethod = _.debounce(function () {
export const plugin = { export const plugin = {
install: function (Vue) { install: function (Vue) {
Vue.prototype.$getToolData = function (clipboardField = '') { Vue.prototype.$getToolData = function (clipboardField = '',clipboardFieldRegex = "") {
let data = history(model.getCurrentTool()).current() let data = history(model.getCurrentTool()).current()
if (clipboardField) { if (clipboardField) {
let inputData = "";
if (fixeInputData) { // 使用固定输入数据 if (fixeInputData) { // 使用固定输入数据
data[clipboardField] = fixeInputData inputData = fixeInputData
fixeInputData = "" fixeInputData = ""
} else if (setting.autoReadCopy()) { } else if (setting.autoReadCopy()) {
let paste = clipboard.paste() let paste = clipboard.paste()
...@@ -65,27 +66,42 @@ export const plugin = { ...@@ -65,27 +66,42 @@ export const plugin = {
if (setting.autoReadCopyFilter()) { if (setting.autoReadCopyFilter()) {
paste = paste.trim() paste = paste.trim()
} }
data[clipboardField] = paste inputData = paste
}
}
if (inputData){
if (
!(clipboardFieldRegex instanceof RegExp)
||
(
clipboardFieldRegex instanceof RegExp
&& clipboardFieldRegex.test(inputData)
)
){
data[clipboardField] = inputData
} }
} }
} }
return data return data
} }
Vue.prototype.$saveToolData = function (data) { Vue.prototype.$saveToolData = function (data, ignoreDebounce = false) {
debounceSaveToolData = {tool:model.getCurrentTool(),data:_.cloneDeep(data)} if (ignoreDebounce) {
return history(model.getCurrentTool()).push(_.cloneDeep(data))
}
debounceSaveToolData = {tool: model.getCurrentTool(), data: _.cloneDeep(data)}
debounceSaveToolDataMethod() debounceSaveToolDataMethod()
} }
Vue.prototype.$clipboardCopy = function (data, force = false) { Vue.prototype.$clipboardCopy = function (data, force = false) {
if ((setting.autoSaveCopy() || force) && data) { if ((setting.autoSaveCopy() || force) && data) {
clipboard.copy(data, () => { clipboard.copy(data, () => {
this.$Message.success('结果已复制 ^o^') this.$Message.success(this.$t('main_ui_copy_text_ok').toString())
}) })
} }
} }
Vue.prototype.$clipboardCopyImages = function (data, force = false) { Vue.prototype.$clipboardCopyImages = function (data, force = false) {
if ((setting.autoSaveCopy() || force) && data) { if ((setting.autoSaveCopy() || force) && data) {
clipboard.copyImage(data, () => { clipboard.copyImage(data, () => {
this.$Message.success('图片已复制 ^o^') this.$Message.success(this.$t('main_ui_copy_image_ok').toString())
}) })
} }
} }
......
...@@ -9,7 +9,7 @@ ...@@ -9,7 +9,7 @@
<Row :gutter="10"> <Row :gutter="10">
<Col span="12"> <Col span="12">
<Form :label-width="80"> <Form :label-width="80">
<FormItem label="内容"> <FormItem :label="$t('barcode_content')">
<Input v-model="current.text"> <Input v-model="current.text">
<Select v-model="current.format" slot="append" style="width: 100px"> <Select v-model="current.format" slot="append" style="width: 100px">
<Option v-for="type in barcodeFormat" :key="type" :value="type">{{ type }}</Option> <Option v-for="type in barcodeFormat" :key="type" :value="type">{{ type }}</Option>
...@@ -18,17 +18,17 @@ ...@@ -18,17 +18,17 @@
</FormItem> </FormItem>
<Row> <Row>
<Col span="12"> <Col span="12">
<FormItem label="背景"> <FormItem :label="$t('barcode_background')">
<ColorPicker recommend v-model="current.background"/> <ColorPicker recommend v-model="current.background"/>
</FormItem> </FormItem>
</Col> </Col>
<Col span="12"> <Col span="12">
<FormItem label="线条颜色"> <FormItem :label="$t('barcode_line_color')">
<ColorPicker recommend v-model="current.lineColor"/> <ColorPicker recommend v-model="current.lineColor"/>
</FormItem> </FormItem>
</Col> </Col>
</Row> </Row>
<FormItem label="条码宽"> <FormItem :label="$t('barcode_bar_width')">
<Row> <Row>
<Col span="21"> <Col span="21">
<Slider v-model="current.width" :min="1" :max="4"></Slider> <Slider v-model="current.width" :min="1" :max="4"></Slider>
...@@ -38,7 +38,7 @@ ...@@ -38,7 +38,7 @@
</Col> </Col>
</Row> </Row>
</FormItem> </FormItem>
<FormItem label="条码高"> <FormItem :label="$t('barcode_height')">
<Row> <Row>
<Col span="21"> <Col span="21">
<Slider v-model="current.height" :min="10" :max="150"></Slider> <Slider v-model="current.height" :min="10" :max="150"></Slider>
...@@ -48,7 +48,7 @@ ...@@ -48,7 +48,7 @@
</Col> </Col>
</Row> </Row>
</FormItem> </FormItem>
<FormItem label="外边距"> <FormItem :label="$t('barcode_margin')">
<Row> <Row>
<Col span="21"> <Col span="21">
<Slider v-model="current.margin" :min="0" :max="25"></Slider> <Slider v-model="current.margin" :min="0" :max="25"></Slider>
...@@ -62,33 +62,33 @@ ...@@ -62,33 +62,33 @@
</Col> </Col>
<Col span="12"> <Col span="12">
<Form :label-width="80"> <Form :label-width="80">
<FormItem label="文本显示"> <FormItem :label="$t('barcode_show_text')">
<RadioGroup v-model="current.textPosition" type="button"> <RadioGroup v-model="current.textPosition" type="button">
<Radio label="close"> <Radio label="close">
<span>隐藏</span> <span>{{ $t('barcode_hide') }}</span>
</Radio> </Radio>
<Radio label="top"> <Radio label="top">
<span>上方</span> <span>{{ $t('barcode_top') }}</span>
</Radio> </Radio>
<Radio label="bottom"> <Radio label="bottom">
<span>下方</span> <span>{{ $t('barcode_bottom') }}</span>
</Radio> </Radio>
</RadioGroup> </RadioGroup>
</FormItem> </FormItem>
<FormItem label="水平位置"> <FormItem :label="$t('barcode_text_align')">
<RadioGroup v-model="current.textAlign" type="button"> <RadioGroup v-model="current.textAlign" type="button">
<Radio :disabled="!showText" label="left"> <Radio :disabled="!showText" label="left">
<span>居左</span> <span>{{ $t('barcode_left') }}</span>
</Radio> </Radio>
<Radio :disabled="!showText" label="center"> <Radio :disabled="!showText" label="center">
<span>居中</span> <span>{{ $t('barcode_center') }}</span>
</Radio> </Radio>
<Radio :disabled="!showText" label="right"> <Radio :disabled="!showText" label="right">
<span>居右</span> <span>{{ $t('barcode_right') }}</span>
</Radio> </Radio>
</RadioGroup> </RadioGroup>
</FormItem> </FormItem>
<FormItem label="字体"> <FormItem :label="$t('barcode_font')">
<Row :gutter="10"> <Row :gutter="10">
<Col span="12"> <Col span="12">
<Select :disabled="!showText" v-model="current.font"> <Select :disabled="!showText" v-model="current.font">
...@@ -98,16 +98,16 @@ ...@@ -98,16 +98,16 @@
<Col span="12"> <Col span="12">
<CheckboxGroup v-model="current.fontOptions"> <CheckboxGroup v-model="current.fontOptions">
<Checkbox :disabled="!showText" label="bold"> <Checkbox :disabled="!showText" label="bold">
<span>粗体</span> <span>{{ $t('barcode_bold') }}</span>
</Checkbox> </Checkbox>
<Checkbox :disabled="!showText" label="italic"> <Checkbox :disabled="!showText" label="italic">
<span>斜体</span> <span>{{ $t('barcode_italic') }}</span>
</Checkbox> </Checkbox>
</CheckboxGroup> </CheckboxGroup>
</Col> </Col>
</Row> </Row>
</FormItem> </FormItem>
<FormItem label="大小"> <FormItem :label="$t('barcode_font_size')">
<Row> <Row>
<Col span="22"> <Col span="22">
<Slider :disabled="!showText" v-model="current.fontSize" :min="8" <Slider :disabled="!showText" v-model="current.fontSize" :min="8"
...@@ -118,7 +118,7 @@ ...@@ -118,7 +118,7 @@
</Col> </Col>
</Row> </Row>
</FormItem> </FormItem>
<FormItem label="外边距"> <FormItem :label="$t('barcode_text_margin')">
<Row> <Row>
<Col span="22"> <Col span="22">
<Slider :disabled="!showText" v-model="current.textMargin" :min="-15" <Slider :disabled="!showText" v-model="current.textMargin" :min="-15"
...@@ -190,7 +190,7 @@ export default { ...@@ -190,7 +190,7 @@ export default {
fontSize: this.current.fontSize, fontSize: this.current.fontSize,
textMargin: this.current.textMargin, textMargin: this.current.textMargin,
valid: (valid) => { valid: (valid) => {
this.validStr = !valid ? `"${barcodeContent}" 无效的条码内容` : ""; this.validStr = !valid ? `"${barcodeContent}" ${this.$t('barcode_invalid_content').toString()}` : "";
if (!this.validStr && this.current.text) { if (!this.validStr && this.current.text) {
this.$saveToolData(this.current) this.$saveToolData(this.current)
} }
......
<template> <template>
<div> <heightResize ignore :append="['.page-option-block']" @resize="resize">
<Input v-model="current.input" :rows="7" type="textarea" :placeholder="$t('base64_input')"></Input> <input-block bottom="0px" right="10px">
<option-block> <autoHeightTextarea :height="height1" v-model="current.input" :placeholder="$t('base64_input')" />
<Upload slot="extra" action="#" :before-upload="handleUpload">
<Button size="small" type="primary" icon="ios-cloud-upload-outline">{{ $t('base64_upload_file') }}</Button>
</Upload>
</input-block>
<option-block class="page-option-block">
<FormItem> <FormItem>
<ButtonGroup> <ButtonGroup>
<Button type="primary" @click="handle('encode')">{{ $t('base64_encode') }}</Button> <Button type="primary" @click="handle('encode')">{{ $t('base64_encode') }}</Button>
...@@ -11,21 +16,27 @@ ...@@ -11,21 +16,27 @@
<FormItem> <FormItem>
<Checkbox v-model="current.isUriSafe">{{ $t('base64_url_safe') }}</Checkbox> <Checkbox v-model="current.isUriSafe">{{ $t('base64_url_safe') }}</Checkbox>
</FormItem> </FormItem>
<FormItem style="float: right;">
<Upload action="#" :before-upload="handleUpload">
<Button type="primary" icon="md-arrow-round-up">{{ $t('base64_upload_file') }}</Button>
</Upload>
</FormItem>
</option-block> </option-block>
<Input v-model="current.output" :rows="7" type="textarea" :placeholder="$t('base64_output') "></Input> <input-block right="10px">
</div> <pasteClipboardFlie @on-paste-file="handleUpload">
<autoHeightTextarea :height="height2" :value="current.output" :placeholder="$t('base64_output')" />
</pasteClipboardFlie>
</input-block>
</heightResize>
</template> </template>
<script> <script>
import {Base64} from 'js-base64' import {Base64} from 'js-base64'
import mimeType from 'mime-types' import mimeType from 'mime-types'
import moment from "moment"; import moment from "moment";
import pasteClipboardFlie from "./components/pasteClipboardFlie";
import heightResize from "./components/heightResize";
import autoHeightTextarea from "./components/autoHeightTextarea";
export default { export default {
components: {
pasteClipboardFlie,
heightResize,
autoHeightTextarea
},
created() { created() {
this.current = Object.assign(this.current, this.$getToolData('input')) this.current = Object.assign(this.current, this.$getToolData('input'))
}, },
...@@ -65,6 +76,10 @@ export default { ...@@ -65,6 +76,10 @@ export default {
aEle.click(); aEle.click();
aEle.remove(); aEle.remove();
window.URL.revokeObjectURL(objectUrl); window.URL.revokeObjectURL(objectUrl);
},
resize(height){
this.height1 = Math.min(160,Math.ceil(height/2))
this.height2 = height - this.height1
} }
}, },
data() { data() {
...@@ -75,6 +90,8 @@ export default { ...@@ -75,6 +90,8 @@ export default {
operation: '', operation: '',
isUriSafe: false, isUriSafe: false,
}, },
height1:100,
height2:100
} }
}, },
} }
......
<template> <template>
<div> <div>
<div style="border: 1px solid #dcdee2; border-radius: 4px"> <heightResize :append="['.page-option-block']">
<code-editor ref="editor" v-model="current.content" :auto-height="220" :language="this.current.lang"></code-editor> <code-editor ref="editor" v-model="current.content" :language="this.current.lang"></code-editor>
</div> </heightResize>
<option-block> <option-block class="page-option-block">
<FormItem> <FormItem>
<ButtonGroup> <ButtonGroup>
<Button <Button
...@@ -16,20 +16,20 @@ ...@@ -16,20 +16,20 @@
</ButtonGroup> </ButtonGroup>
</FormItem> </FormItem>
<FormItem> <FormItem>
<Select placeholder="更多语言" @on-change="(value)=>{handle(value)}"> <Select :placeholder="$t('code_more')" @on-change="(value)=>{handle(value)}">
<Option v-for="item in lang" :value="item" :key="item">{{ item }}</Option> <Option v-for="item in lang" :value="item" :key="item">{{ item }}</Option>
</Select> </Select>
</FormItem> </FormItem>
<FormItem> <FormItem>
<Select placeholder="代码缩进" v-model="current.tab"> <Select :placeholder="$t('code_indent')" v-model="current.tab">
<Option :value="2">缩进 Tab 2</Option> <Option :value="2">{{ $t('code_indent_width',[2]) }}</Option>
<Option :value="4">缩进 Tab 4</Option> <Option :value="4">{{ $t('code_indent_width',[4]) }}</Option>
<Option :value="6">缩进 Tab 6</Option> <Option :value="6">{{ $t('code_indent_width',[6]) }}</Option>
<Option :value="8">缩进 Tab 8</Option> <Option :value="8">{{ $t('code_indent_width',[8]) }}</Option>
</Select> </Select>
</FormItem> </FormItem>
<FormItem> <FormItem>
<Checkbox v-model="current.isCompress">压缩</Checkbox> <Checkbox v-model="current.isCompress">{{ $t('code_compress') }}</Checkbox>
</FormItem> </FormItem>
</option-block> </option-block>
</div> </div>
...@@ -37,10 +37,11 @@ ...@@ -37,10 +37,11 @@
<script> <script>
import _ from "lodash"; import _ from "lodash";
import codeEditor from "./components/codeEditor"; import codeEditor from "./components/codeEditor";
import heightResize from "./components/heightResize";
export default { export default {
components: { components: {
codeEditor, codeEditor,
heightResize
}, },
computed: { computed: {
buttonLang() { buttonLang() {
...@@ -66,11 +67,11 @@ export default { ...@@ -66,11 +67,11 @@ export default {
this.$refs.editor.compress(language); this.$refs.editor.compress(language);
} }
this.$saveToolData(this.current); this.$saveToolData(this.current);
return this.$Message.success(`${this.current.isCompress ? "压缩" : "格式化"}完成`); return this.$Message.success(this.$t('code_complete').toString());
} catch (e) { } catch (e) {
console.log(e) console.log(e)
return this.$Modal.error({ return this.$Modal.error({
title: "格式化错误", title: this.$t('code_error_prompt').toString(),
content: `${e.message}` content: `${e.message}`
}); });
} }
......
<template>
<Input :style="style" class="auto-height-textarea" v-model="textarea" type="textarea"
:placeholder="placeholder"></Input>
</template>
<script>
import _ from "lodash";
// 窗口高度调整 返回工具页面可操作性高度
export default {
name: 'autoHeightTextarea',
props: {
value: {
type: [String, Number],
default: ''
},
placeholder: {
type: String,
default: ''
},
height: {
type: [String, Number],
default: ''
},
},
data() {
return {
textarea: ""
}
},
computed: {
style() {
let css = [];
if (this.height) {
css.push(`height:${this.height}${_.isNumber(this.height) ? 'px' : ''}`)
}
return css.join(";")
}
},
watch: {
textarea(value) {
if (value !== this.value) {
this.$emit('input', value)
}
},
value(value) {
if (value !== this.textarea) {
this.textarea = value
}
}
},
created() {
this.textarea = this.value
}
};
</script>
<style>
.auto-height-textarea, .auto-height-textarea textarea.ivu-input {
height: 100%;
}
</style>
<template> <template>
<div ref="container" class="code-editor" :style="`height:${containerHeight};width:${width}`"></div> <div :style="style">
<div ref="container" class="code-editor" :style="`height:100%;width:${width}`"></div>
</div>
</template> </template>
<script> <script>
import {format} from "../library/formatter"; import {format} from "../library/formatter";
...@@ -15,19 +17,37 @@ export default { ...@@ -15,19 +17,37 @@ export default {
type: String, type: String,
default: "" default: ""
}, },
autoHeight: { enableBorder: {
type: Number, type: Boolean,
default: 0 default: true
},
placeholder: {
type: String,
default: ""
}, },
height: { height: {
type: String, type: String,
default: "350px" default: "100%"
},
hideLineNumbers: {
type: Boolean,
default: false
}, },
width: { width: {
type: String, type: String,
default: "100%" default: "100%"
}, },
}, },
computed: {
style() {
let css = [`height:${this.height}`];
if (this.enableBorder) {
css.push("border: 1px solid #dcdee2")
css.push("border-radius: 4px")
}
return css.join(";")
}
},
watch: { watch: {
value(newValue) { value(newValue) {
if (this.editor !== null && this.editor.getValue() !== newValue) { if (this.editor !== null && this.editor.getValue() !== newValue) {
...@@ -40,27 +60,25 @@ export default { ...@@ -40,27 +60,25 @@ export default {
} }
} }
}, },
created() {
if (this.autoHeight > 0) {
this.containerHeight = (window.innerHeight - this.autoHeight) + "px"
} else {
this.containerHeight = this.height
}
},
mounted() { mounted() {
this.initEditor() this.initEditor()
}, },
data() { data() {
return { return {
editor: null, editor: null,
containerHeight: ""
} }
}, },
methods: { methods: {
initEditor() { initEditor() {
this.editor = create(this.$refs.container, this.language); this.editor = create(
this.$refs.container,
this.language,
{
lineNumbers: !this.hideLineNumbers,
placeholder: this.placeholder
}
);
this.editor.setValue(this.value) this.editor.setValue(this.value)
this.editor.setSize(null, this.containerHeight)
this.editor.on('change', editor => { this.editor.on('change', editor => {
if (this.value !== editor.getValue()) { if (this.value !== editor.getValue()) {
this.$emit('input', editor.getValue()) this.$emit('input', editor.getValue())
...@@ -79,4 +97,12 @@ export default { ...@@ -79,4 +97,12 @@ export default {
} }
}; };
</script> </script>
<style>
.CodeMirror {
height: 100%;
}
.CodeMirror pre.CodeMirror-placeholder {
color: #999;
}
</style>
<template> <template>
<div ref="container" class="diff-editor" :style="`height:${containerHeight};width:${width}`"></div> <div ref="container" class="diff-editor" :style="`height:${height};width:${width}`"></div>
</template> </template>
<script> <script>
import {createMerge} from "../library/editor"; import {createMerge} from "../library/editor";
...@@ -18,13 +18,9 @@ export default { ...@@ -18,13 +18,9 @@ export default {
type: Boolean, type: Boolean,
default: false default: false
}, },
autoHeight: {
type: Number,
default: 0
},
height: { height: {
type: String, type: String,
default: "350px" default: "100%"
}, },
width: { width: {
type: String, type: String,
...@@ -45,20 +41,12 @@ export default { ...@@ -45,20 +41,12 @@ export default {
this.reset() this.reset()
} }
}, },
created() {
if (this.autoHeight > 0) {
this.containerHeight = (window.innerHeight - this.autoHeight) + "px"
} else {
this.containerHeight = this.height
}
},
mounted() { mounted() {
this.reset() this.reset()
}, },
data() { data() {
return { return {
editor: null, editor: null,
containerHeight: ""
} }
}, },
methods: { methods: {
...@@ -68,7 +56,6 @@ export default { ...@@ -68,7 +56,6 @@ export default {
}, },
initEditor() { initEditor() {
this.editor = createMerge(this.value, this.$refs.container, this.language, {collapseIdentical: this.collapse ? 2 : false}) this.editor = createMerge(this.value, this.$refs.container, this.language, {collapseIdentical: this.collapse ? 2 : false})
this.editor.customSetSize(null, this.containerHeight)
this.editor.customChange((original, modified) => { this.editor.customChange((original, modified) => {
if (original !== this.value.original || modified !== this.value.modified) { if (original !== this.value.original || modified !== this.value.modified) {
this.value.original = original this.value.original = original
...@@ -82,7 +69,10 @@ export default { ...@@ -82,7 +69,10 @@ export default {
</script> </script>
<style> <style>
.diff-editor .CodeMirror-merge, .diff-editor .CodeMirror-merge .CodeMirror { .diff-editor .CodeMirror-merge{
border: none;
}
.diff-editor .CodeMirror-merge,.diff-editor .CodeMirror-merge-pane, .diff-editor .CodeMirror-merge .CodeMirror {
height: 100%; height: 100%;
} }
</style> </style>
......
<template>
<div :style="`height:${height}`">
<slot></slot>
</div>
</template>
<script>
function getAbsoluteHeight(select) {
let el = document.querySelector(select)
if (el === null) {
return 0;
}
let styles = window.getComputedStyle(el);
let margin = parseFloat(styles['marginTop']) +
parseFloat(styles['marginBottom']);
return Math.ceil(el.offsetHeight + margin);
}
// 窗口高度调整 返回工具页面可操作高度
export default {
name: 'heightResize',
props: {
append: {
type: Array,
default: function () {
return [];
}
},
reduce: {
type: Number,
default: 0
},
remove: {
type: Array,
default: function () {
return [];
}
},
ignore: {
type: Boolean,
default: false
},
},
data() {
return {
height: "auto",
}
},
methods: {
reportWindowSize() {
this.resize()
},
resize() {
let height = window.innerHeight;
let defaultBlock = [".tool-select-block", ".tool-category-menu-block", ".ctool-bottom"]
const filterBlock = defaultBlock.filter((item) => {
return !this.remove.includes(item)
}).concat(this.append)
for (let block of filterBlock) {
height = height - getAbsoluteHeight(block)
}
if (this.reduce > 0){
height = height - this.reduce
}
if (height > 100) {
height = height - 5
}
if (!this.ignore) {
this.height = height + "px"
}
this.$emit('resize', height);
}
},
destroyed() {
window.removeEventListener("resize", this.reportWindowSize);
},
mounted() {
window.addEventListener("resize", this.reportWindowSize);
this.resize();
}
};
</script>
<template>
<div>
<slot></slot>
</div>
</template>
<script>
// 粘贴时 获取剪贴板图片
export default {
name: 'pasteClipboardFlie',
methods: {
reader(event) {
if (!("clipboardData" in event)){
return
}
let items = event.clipboardData && event.clipboardData.items;
let types = event.clipboardData.types || [];
if (items && items.length) {
for (let i = 0; i < items.length; i++) {
if( types[i] === 'Files' ){
// 触发粘贴文件事件
this.$emit('on-paste-file', items[i].getAsFile());
if (items[i].type.indexOf('image') !== -1) {
// 触发粘贴文件事件 输出图片base64
this.$emit('on-paste-image', items[i].getAsFile());
}
return
}
}
}
}
},
destroyed() {
window.removeEventListener("paste", this.reader);
},
mounted() {
window.addEventListener("paste", this.reader);
}
};
</script>
...@@ -2,20 +2,25 @@ ...@@ -2,20 +2,25 @@
<div> <div>
<Row :gutter="16"> <Row :gutter="16">
<Col span="12"> <Col span="12">
<Input v-model="current.input" style="margin-bottom: 16px"> <Input v-model="current.input" style="margin-bottom: 16px" class="page-option-input">
<span slot="prepend">表达式</span> <span slot="prepend">{{ $t('crontab_expression') }}</span>
</Input> </Input>
<Input :value="output" :rows="14" type="textarea" placeholder="最近执行时间"></Input> <heightResize :append="['.page-option-input']">
<autoHeightTextarea :value="output" :placeholder="$t('crontab_execute_time')" />
</heightResize>
</Col> </Col>
<Col span="12"> <Col span="12" class="page-option-reference">
<Tabs value="example"> <Tabs value="example">
<TabPane label="例子" name="example"> <TabPane :label="$t('crontab_example')" name="example">
<Table stripe size="small" height="300" :columns="example.columns" :data="example.data"></Table> <heightResize :reduce="52" @resize="resize">
<Table stripe size="small" :height="referenceHeight" border :columns="example.columns" :data="example.data"></Table>
</heightResize>
</TabPane> </TabPane>
<TabPane label="格式" name="format" style="text-align: center"> <TabPane :label="$t('crontab_format')" name="format" style="text-align: center">
<img src="../../statics/crontab.png" style="height: 300px" alt=""> <img v-if="locale === 'zh_CN'" src="../../statics/crontab_cn.png" style="height: 300px" alt="">
<img v-else src="../../statics/crontab_en.png" style="height: 300px" alt="">
</TabPane> </TabPane>
<TabPane label="特殊字符" name="special"> <TabPane :label="$t('crontab_symbol')" name="special">
<Table stripe size="small" height="300" :columns="special.columns" :data="special.data"></Table> <Table stripe size="small" height="300" :columns="special.columns" :data="special.data"></Table>
</TabPane> </TabPane>
</Tabs> </Tabs>
...@@ -24,92 +29,116 @@ ...@@ -24,92 +29,116 @@
</div> </div>
</template> </template>
<script> <script>
import cronstrue from 'cronstrue/i18n'; import cronstrue from 'cronstrue/i18n';
import parser from 'cron-parser'; import parser from 'cron-parser';
import moment from "moment" import moment from "moment"
import {getCurrentLocale} from "../../i18n";
export default { import heightResize from "./components/heightResize";
computed: { import autoHeightTextarea from "./components/autoHeightTextarea";
output() { export default {
if (!this.current.input) return ""; components: {
let list = []; heightResize,
try { autoHeightTextarea
list.push(cronstrue.toString(this.current.input, {locale: "zh_CN"})); },
list.push("\n最近10次执行时间"); computed: {
let interval = parser.parseExpression(this.current.input); locale() {
for (let i = 1; i <= 10; i++) { return getCurrentLocale()
list.push(`第${i}次: ` + moment(interval.next().toString()).format("YYYY-MM-DD HH:mm:ss")) },
} output() {
this.$saveToolData(this.current); if (!this.current.input) return "";
} catch (err) { let list = [];
list.push(err) try {
list.push(this.conversion(this.current.input));
list.push(`\n${this.$t('crontab_execute_time_list')}`);
let interval = parser.parseExpression(this.current.input);
for (let i = 1; i <= 10; i++) {
list.push(this.$t('crontab_no', [i, moment(interval.next().toString()).format("YYYY-MM-DD HH:mm:ss")]))
} }
this.$saveToolData(this.current);
} catch (err) {
list.push(err)
}
return list.join("\n"); return list.join("\n");
},
},
created() {
this.current = Object.assign(this.current, this.$getToolData())
}, },
data() { },
created() {
this.current = Object.assign(this.current, this.$getToolData())
this.example.data = this.example.data.map((item) => {
return { return {
current: { example: item,
input: "2 */5 * * 2-5", text: this.conversion(item)
operation: "check" }
}, })
special: { },
columns: [ methods: {
{title: '特殊字符', key: 'name', width: 100}, conversion(input) {
{title: '代表意义', key: 'text'}, return cronstrue.toString(input, {locale: this.locale})
], },
data: [ resize(height){
{ this.referenceHeight = height
name: "*(星号)", }
text: "代表任何时刻都接受的意思。举例来说,范例一内那个日、月、周都是*,就代表着不论何月、何日的礼拜几的12:00都执行后续命令的意思。" },
}, data() {
{ return {
name: ",(逗号)", referenceHeight:101,
text: "代表分隔时段的意思。举例来说,如果要执行的工作是3:00与6:00时,就会是:0 3,6 * * * command时间还是有五列,不过第二列是 3,6 ,代表3与6都适用" current: {
}, input: "2 */5 * * 2-5",
{ operation: "check"
name: "-(减号)", },
text: "代表一段时间范围内,举例来说,8点到12点之间的每小时的20分都进行一项工作:20 8-12 * * * command仔细看到第二列变成8-12.代表 8,9,10,11,12 都适用的意思" special: {
}, columns: [
{ {title: this.$t('crontab_symbol'), key: 'name', width: 100},
name: "/n(斜线)", {title: this.$t('crontab_description'), key: 'text'},
text: "那个n代表数字,即是每隔n单位间隔的意思,例如每五分钟进行一次,则:*/5 * * * * command用*与/5来搭配,也可以写成0-59/5,意思相同" ],
} data: [
] {
}, name: "*",
example: { text: this.$t('crontab_symbol_description_1')
columns: [ },
{title: '例子', key: 'example', width: 120}, {
{title: '说明', key: 'text'}, name: ",",
], text: this.$t('crontab_symbol_description_2')
data: [ },
{example: "*/1 * * * *", text: "每1分钟执行"}, {
{example: "* * * * *", text: "每1分钟执行"}, name: "-",
{example: "*/5 * * * *", text: "每5分钟执行"}, text: this.$t('crontab_symbol_description_3')
{example: "0 * * * *", text: "每小时执行"}, },
{example: "0 */1 * * *", text: "每小时执行"}, {
{example: "0 7 * * *", text: "每天上午7点执行"}, name: "/n",
{example: "10 7 * * *", text: "每天上午7点10分执行"}, text: this.$t('crontab_symbol_description_4')
{example: "0 0 * * *", text: "每天定时执行一次"}, }
{example: "0 0 * * 0", text: "每周定时执行一次"}, ]
{example: "0 0 1 * *", text: "每月定时执行一次"}, },
{example: "0 0 1 1 *", text: "每年定时执行一次"}, example: {
{example: "5 * * * *", text: "指定每小时的第5分钟执行一次命令"}, columns: [
{example: "30 5 * * *", text: "指定每天的 5:30 执行命令"}, {title: this.$t('crontab_example'), key: 'example', width: 120},
{example: "30 7 8 * *", text: "指定每月8号的7:30分执行命令"}, {title: this.$t('crontab_description'), key: 'text'},
{example: "30 5 8 6 *", text: "指定每年的6月8日5:30执行命令"}, ],
{example: "30 6 * * 0", text: "指定每星期日的6:30执行命令"}, data: [
{example: "30 3 10,20 * *", text: "每月10号及20号的3:30执行命令[注:“,”用来连接多个不连续的时段]"}, "*/1 * * * *",
{example: "25 8-11 * * *", text: "每天8-11点的第25分钟执行命令[注:“-”用来连接连续的时段"}, "* * * * *",
{example: "*/15 * * * *", text: "每15分钟执行一次命令 [即每个小时的第0 15 30 45 60分钟执行命令]"}, "*/5 * * * *",
{example: "30 6 */10 * *", text: "每个月中,每隔10天6:30执行一次命令[即每月的1、11、21、31日是的6:30执行一次命令。]"} "0 * * * *",
] "0 */1 * * *",
} "0 7 * * *",
"10 7 * * *",
"0 0 * * *",
"0 0 * * 0",
"0 0 1 * *",
"0 0 1 1 *",
"5 * * * *",
"30 5 * * *",
"30 7 8 * *",
"30 5 8 6 *",
"30 6 * * 0",
"30 3 10,20 * *",
"25 8-11 * * *",
"*/15 * * * *",
"30 6 */10 * *"
]
} }
} }
} }
</script> }
\ No newline at end of file </script>
<template> <template>
<div style="padding: 0 70px"> <div style="padding: 0 70px">
<option-block> <option-block>
<Input v-model="current.input" placeholder="请输入待转换数字"> <Input v-model="current.input" :placeholder="$t('decimalConvert_input_placeholder')">
<div slot="prepend" style="width: 70px"><strong>转换数字</strong></div> <div slot="prepend" style="width: 70px"><strong>{{ $t('decimalConvert_input') }}</strong></div>
<Select v-model="current.decimal" slot="append" style="width:100px"> <Select v-model="current.decimal" slot="append" style="width:100px">
<OptionGroup :label="type.common.name"> <OptionGroup :label="$t('decimalConvert_input_type_common')">
<Option v-for="v in type.common.list" :value="v" :key="v">{{ v }} 进制</Option> <Option v-for="v in type.common" :value="v" :key="v">{{ $t('decimalConvert_base',[v]) }}</Option>
</OptionGroup> </OptionGroup>
<OptionGroup :label="type.other.name"> <OptionGroup :label="$t('decimalConvert_input_type_other')">
<Option v-for="v in type.other.list" :value="v" :key="v">{{ v }} 进制</Option> <Option v-for="v in type.other" :value="v" :key="v">{{ $t('decimalConvert_base',[v]) }}</Option>
</OptionGroup> </OptionGroup>
</Select> </Select>
</Input> </Input>
</option-block> </option-block>
<option-block v-for="n in [1,2,3,4,5,6]" :key="n"> <option-block v-for="n in [1,2,3,4,5,6]" :key="n">
<Input v-model="current['resultOutput'+n]" readonly> <Input v-model="current['resultOutput'+n]" readonly>
<div slot="prepend" style="width: 70px">转换结果{{ n }}</div> <div slot="prepend" style="width: 70px">{{ $t('decimalConvert_result',[n]) }}</div>
<Select slot="append" v-model="current['resultDecimal'+n]" style="width:100px"> <Select slot="append" v-model="current['resultDecimal'+n]" style="width:100px">
<OptionGroup :label="type.common.name"> <OptionGroup :label="$t('decimalConvert_input_type_common')">
<Option v-for="v in type.common.list" :value="v" :key="v">{{ v }} 进制</Option> <Option v-for="v in type.common" :value="v" :key="v">{{ $t('decimalConvert_base',[v]) }}</Option>
</OptionGroup> </OptionGroup>
<OptionGroup :label="type.other.name"> <OptionGroup :label="$t('decimalConvert_input_type_other')">
<Option v-for="v in type.other.list" :value="v" :key="v">{{ v }} 进制</Option> <Option v-for="v in type.other" :value="v" :key="v">{{ $t('decimalConvert_base',[v]) }}</Option>
</OptionGroup> </OptionGroup>
</Select> </Select>
</Input> </Input>
</option-block> </option-block>
<option-block> <option-block>
<Input v-model="current.alphabet"> <Input v-model="current.alphabet">
<div slot="prepend" style="width: 70px">64位字母表</div> <div slot="prepend">{{ $t('decimalConvert_alphabet') }}</div>
<Button slot="append" @click="current.alphabet=alphabet" :disabled="current.alphabet===alphabet">恢复默认 <Button slot="append" @click="current.alphabet=alphabet" :disabled="current.alphabet===alphabet">
{{ $t('decimalConvert_reset') }}
</Button> </Button>
</Input> </Input>
</option-block> </option-block>
...@@ -46,7 +47,7 @@ export default { ...@@ -46,7 +47,7 @@ export default {
watch: { watch: {
convert: function (val) { convert: function (val) {
if (val.alphabet.length !== 64) { if (val.alphabet.length !== 64) {
return this.$Message.error("转换字母表必须是64位长度"); return this.$Message.error(this.$t('decimalConvert_alphabet_length_error').toString());
} }
if (!val.input) { if (!val.input) {
return; return;
...@@ -74,17 +75,11 @@ export default { ...@@ -74,17 +75,11 @@ export default {
}, },
type() { type() {
let type = { let type = {
common: { common: [2, 8, 10, 16],
name: "常用进制", other: []
list: [2, 8, 10, 16]
},
other: {
name: "其他进制",
list: []
}
} }
for (let i = 2; i <= 64; i++) { for (let i = 2; i <= 64; i++) {
type.common.list.includes(i) || type.other.list.push(i); type.common.includes(i) || type.other.push(i);
} }
return type return type
} }
......
<template> <template>
<div> <div>
<div style="border: 1px solid #dcdee2; border-radius: 4px"> <heightResize :append="['.page-option-block']">
<diffEditor ref="editor" :collapse="current.collapse" v-model="current.diff" :language="current.language" <div style="border: 1px solid #dcdee2; border-radius: 4px;height: 100%;">
:auto-height="220"/> <diff-editor ref="editor" :collapse="current.collapse" v-model="current.diff" :language="current.language" />
</div> </div>
<option-block> </heightResize>
<option-block class="page-option-block">
<FormItem> <FormItem>
<ButtonGroup> <ButtonGroup>
<Button <Button
...@@ -17,12 +18,12 @@ ...@@ -17,12 +18,12 @@
</ButtonGroup> </ButtonGroup>
</FormItem> </FormItem>
<FormItem> <FormItem>
<Select placeholder="更多语言" @on-change="(value)=>{setLanguage(value)}"> <Select :placeholder="$t('diffs_more')" @on-change="(value)=>{setLanguage(value)}">
<Option v-for="item in allLang" :value="item" :key="item">{{ item }}</Option> <Option v-for="item in allLang" :value="item" :key="item">{{ item }}</Option>
</Select> </Select>
</FormItem> </FormItem>
<FormItem> <FormItem>
<Checkbox v-model="current.collapse">折叠相同</Checkbox> <Checkbox v-model="current.collapse">{{ $t('diffs_collapse') }}</Checkbox>
</FormItem> </FormItem>
</option-block> </option-block>
</div> </div>
...@@ -31,6 +32,7 @@ ...@@ -31,6 +32,7 @@
import diffEditor from "./components/diffEditor"; import diffEditor from "./components/diffEditor";
import {allLang} from "./library/editor"; import {allLang} from "./library/editor";
import _ from "lodash"; import _ from "lodash";
import heightResize from "./components/heightResize";
const COMMON_LANG = [ const COMMON_LANG = [
"text", "text",
...@@ -46,6 +48,7 @@ const COMMON_LANG = [ ...@@ -46,6 +48,7 @@ const COMMON_LANG = [
export default { export default {
components: { components: {
diffEditor, diffEditor,
heightResize
}, },
computed: { computed: {
allLang() { allLang() {
......
<template> <template>
<div> <heightResize ignore :append="['.page-option-block']" @resize="resize">
<Input v-model="current.input" :rows="7" type="textarea" placeholder="内容"></Input> <autoHeightTextarea v-model="current.input" :height="inputHeight" :placeholder="$t('encrypt_input')"/>
<option-block> <option-block class="page-option-block">
<FormItem> <FormItem>
<Select v-model="current.type" style="width:200px"> <Select v-model="current.type" style="width:200px">
<Option v-for="v in type" :value="v" :key="v">{{ v }}</Option> <Option v-for="v in type" :value="v" :key="v">{{ v }}</Option>
</Select> </Select>
</FormItem> </FormItem>
<FormItem> <FormItem>
<Input v-model="current.password" placeholder="密码/秘钥"></Input> <Input v-model="current.password" :placeholder="$t('encrypt_password')"></Input>
</FormItem> </FormItem>
<FormItem v-if="current.type === 'SM2'"> <FormItem v-if="current.type === 'SM2'">
<Select v-model="current.sm2CipherMode" style="width:100px"> <Select v-model="current.sm2CipherMode" style="width:100px">
...@@ -18,25 +18,35 @@ ...@@ -18,25 +18,35 @@
</FormItem> </FormItem>
<FormItem> <FormItem>
<ButtonGroup> <ButtonGroup>
<Button type="primary" @click="handle('encrypt')">加密</Button> <Button type="primary" @click="handle('encrypt')">{{ $t('encrypt_encrypt') }}</Button>
<Button type="primary" @click="handle('decrypt')">解密</Button> <Button type="primary" @click="handle('decrypt')">{{ $t('encrypt_decrypt') }}</Button>
<Button type="primary" @click="sm2Generate()" v-if="current.type === 'SM2'">生成密钥对</Button> <Button type="primary" @click="sm2Generate()" v-if="current.type === 'SM2'">
{{ $t('encrypt_generate_secret_key') }}
</Button>
</ButtonGroup> </ButtonGroup>
</FormItem> </FormItem>
</option-block> </option-block>
<Input v-model="current.output" :rows="7" type="textarea" placeholder="结果"></Input> <autoHeightTextarea :value="current.output" :height="outputHeight" :placeholder="$t('encrypt_output')"/>
</div> </heightResize>
</template> </template>
<script> <script>
import crypto from "crypto-js" import crypto from "crypto-js"
export default { import heightResize from "./components/heightResize";
created() { import autoHeightTextarea from "./components/autoHeightTextarea";
this.current = Object.assign(this.current,this.$getToolData("input"))
}, export default {
methods: { components: {
handle(v) { heightResize,
const sm2 = require('sm-crypto').sm2 autoHeightTextarea
if (this.current.input) { },
created() {
this.current = Object.assign(this.current, this.$getToolData("input"))
},
methods: {
handle(v) {
const sm2 = require('sm-crypto').sm2
if (this.current.input) {
try {
switch (this.current.type) { switch (this.current.type) {
case "AES": case "AES":
case "DES": case "DES":
...@@ -48,8 +58,7 @@ ...@@ -48,8 +58,7 @@
this.current.input, this.current.input,
this.current.password this.current.password
).toString(); ).toString();
} } else {
else{
this.current.output = crypto[this.current.type].decrypt( this.current.output = crypto[this.current.type].decrypt(
this.current.input, this.current.input,
this.current.password this.current.password
...@@ -58,14 +67,13 @@ ...@@ -58,14 +67,13 @@
break; break;
case "SM2": case "SM2":
if (v === "encrypt") { if (v === "encrypt") {
this.current.output =sm2.doEncrypt( this.current.output = sm2.doEncrypt(
this.current.input, this.current.input,
this.current.password, this.current.password,
this.current.sm2CipherMode this.current.sm2CipherMode
); );
} } else {
else{ this.current.output = sm2.doDecrypt(
this.current.output =sm2.doDecrypt(
this.current.input, this.current.input,
this.current.password, this.current.password,
this.current.sm2CipherMode this.current.sm2CipherMode
...@@ -75,43 +83,59 @@ ...@@ -75,43 +83,59 @@
default: default:
return; return;
} }
this.current.operation = v; } catch (e) {
this.$clipboardCopy(this.current.output); return this.$Message.error(
this.$saveToolData(this.current); this.$t('encrypt_failed', [e.message]).toString()
)
} }
}, this.current.operation = v;
sm2Generate(){ this.$clipboardCopy(this.current.output);
const sm2 = require('sm-crypto').sm2 this.$saveToolData(this.current);
let keypair = sm2.generateKeyPairHex() }
let string = "公钥:\n"+keypair.publicKey+"\n"+"私钥:\n"+keypair.privateKey+"\n\n"+
"请及时保存秘钥对, 关闭对话框后无法恢复当前秘钥数据"
this.$Modal.info({
render: (h) => {
return h('Input', {
props: {
value: string,
type:"textarea",
rows:9
}
})
},
okText:"关闭",
width:600
})
},
}, },
data() { sm2Generate() {
return { const sm2 = require('sm-crypto').sm2
current:{ let keypair = sm2.generateKeyPairHex()
input: "", let string = [
password:"", this.$t('encrypt_public_key'),
sm2CipherMode:"C1C3C2", keypair.publicKey,
output: "", this.$t('encrypt_private_key'),
type:"AES", keypair.privateKey, '',
operation:"" this.$t('encrypt_secret_key_prompt')
].join("\n");
this.$Modal.info({
render: (h) => {
return h('Input', {
props: {
value: string,
type: "textarea",
rows: 9
}
})
}, },
type: ["AES","DES","RC4","Rabbit","TripleDes","SM2"], okText: this.$t('encrypt_close'),
} width: 600
})
}, },
} resize(height) {
</script> this.inputHeight = Math.min(160, Math.ceil(height / 2))
\ No newline at end of file this.outputHeight = height - this.inputHeight
}
},
data() {
return {
current: {
input: "",
password: "",
sm2CipherMode: "C1C3C2",
output: "",
type: "AES",
operation: ""
},
type: ["AES", "DES", "RC4", "Rabbit", "TripleDes", "SM2"],
inputHeight: 100,
outputHeight: 100
}
},
}
</script>
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
<div id="tool-hash"> <div id="tool-hash">
<Row :gutter="10"> <Row :gutter="10">
<Col span="8"> <Col span="8">
<input-block :text="$t('hash_content')"> <input-block>
<Input v-model="current.input" :rows="18" type="textarea" :placeholder="$t('hash_content')"></Input> <Input v-model="current.input" :rows="18" type="textarea" :placeholder="$t('hash_content')"></Input>
<Checkbox slot="extra" v-model="current.isUppercase">{{ $t('hash_uppercase') }}</Checkbox> <Checkbox slot="extra" v-model="current.isUppercase">{{ $t('hash_uppercase') }}</Checkbox>
</input-block> </input-block>
......
<template> <template>
<div> <heightResize ignore :append="['.page-option-block']" @resize="resize">
<Input v-model="current.input" :rows="7" type="textarea" placeholder="内容"></Input> <autoHeightTextarea v-model="current.input" :height="inputHeight" :placeholder="$t('hexString_input')"/>
<option-block> <option-block class="page-option-block">
<FormItem> <FormItem>
<ButtonGroup> <ButtonGroup>
<Button type="primary" @click="handle('hex')">String -> Hex</Button> <Button type="primary" @click="handle('hex')">String -> Hex</Button>
...@@ -9,15 +9,21 @@ ...@@ -9,15 +9,21 @@
</ButtonGroup> </ButtonGroup>
</FormItem> </FormItem>
<FormItem> <FormItem>
<Checkbox v-model="current.isUppercase">大写字母</Checkbox> <Checkbox v-model="current.isUppercase">{{ $t('hexString_uppercase') }}</Checkbox>
</FormItem> </FormItem>
</option-block> </option-block>
<Input v-model="current.output" :rows="7" type="textarea" placeholder="结果"></Input> <autoHeightTextarea :value="current.output" :height="outputHeight" :placeholder="$t('hexString_output')"/>
</div> </heightResize>
</template> </template>
<script> <script>
import heightResize from "./components/heightResize";
import autoHeightTextarea from "./components/autoHeightTextarea";
export default { export default {
components: {
heightResize,
autoHeightTextarea
},
created() { created() {
this.current = Object.assign(this.current, this.$getToolData("input")) this.current = Object.assign(this.current, this.$getToolData("input"))
}, },
...@@ -42,6 +48,10 @@ export default { ...@@ -42,6 +48,10 @@ export default {
this.$clipboardCopy(this.current.output); this.$clipboardCopy(this.current.output);
this.$saveToolData(this.current); this.$saveToolData(this.current);
} }
},
resize(height) {
this.inputHeight = Math.min(160, Math.ceil(height / 2))
this.outputHeight = height - this.inputHeight
} }
}, },
data() { data() {
...@@ -51,8 +61,10 @@ export default { ...@@ -51,8 +61,10 @@ export default {
isUppercase: false, isUppercase: false,
output: "", output: "",
operation: "" operation: ""
} },
inputHeight: 100,
outputHeight: 100
} }
}, },
} }
</script> </script>
\ No newline at end of file
<template> <template>
<div> <heightResize ignore :append="['.page-option-block']" @resize="resize">
<Input v-model="current.input" :rows="7" type="textarea" placeholder="内容"></Input> <autoHeightTextarea v-model="current.input" :height="inputHeight" :placeholder="$t('html_input')"/>
<option-block> <option-block class="page-option-block">
<FormItem> <FormItem>
<ButtonGroup> <ButtonGroup>
<Button type="primary" @click="handle('encode')">编码</Button> <Button type="primary" @click="handle('encode')">{{ $t('html_encode') }}</Button>
<Button type="primary" @click="handle('decode')">解密</Button> <Button type="primary" @click="handle('decode')">{{ $t('html_decode') }}</Button>
</ButtonGroup> </ButtonGroup>
</FormItem> </FormItem>
</option-block> </option-block>
<Input v-model="current.output" :rows="7" type="textarea" placeholder="结果"></Input> <autoHeightTextarea :value="current.output" :height="outputHeight" :placeholder="$t('html_output')"/>
</div> </heightResize>
</template> </template>
<script> <script>
import heightResize from "./components/heightResize";
import autoHeightTextarea from "./components/autoHeightTextarea";
export default { export default {
components: {
heightResize,
autoHeightTextarea
},
created() { created() {
this.current = Object.assign(this.current, this.$getToolData("input")) this.current = Object.assign(this.current, this.$getToolData("input"))
}, },
...@@ -30,6 +36,10 @@ export default { ...@@ -30,6 +36,10 @@ export default {
this.$clipboardCopy(this.current.output); this.$clipboardCopy(this.current.output);
this.$saveToolData(this.current); this.$saveToolData(this.current);
} }
},
resize(height) {
this.inputHeight = Math.min(160, Math.ceil(height / 2))
this.outputHeight = height - this.inputHeight
} }
}, },
data() { data() {
...@@ -38,7 +48,9 @@ export default { ...@@ -38,7 +48,9 @@ export default {
input: "", input: "",
output: "", output: "",
operation: "" operation: ""
} },
inputHeight: 100,
outputHeight: 100
} }
}, },
} }
......
<template> <template>
<div> <div>
<option-block> <option-block class="page-option-block" style="padding: 0 0 0 5px">
<FormItem> <FormItem>
<Input v-model="current.input" placeholder="请输入ip地址" style="width:200px"></Input> <Input v-model="current.input" :placeholder="$t('ip_input')" style="width:200px"></Input>
</FormItem> </FormItem>
<FormItem> <FormItem>
<ButtonGroup> <ButtonGroup>
<Button type="primary" @click="handle()">查询</Button> <Button type="primary" @click="handle()">{{ $t('ip_query') }}</Button>
<Button type="primary" @click="local()">本地IP</Button> <Button type="primary" @click="local()">{{ $t('ip_local') }}</Button>
</ButtonGroup> </ButtonGroup>
</FormItem> </FormItem>
<FormItem> <FormItem>
<Alert>ip信息来源 <a href="https://get.geojs.io/" target="_blank">https://get.geojs.io/</a></Alert> <Alert>{{ $t('ip_info_source') }} <a href="https://get.geojs.io/" target="_blank">https://get.geojs.io/</a></Alert>
</FormItem> </FormItem>
</option-block> </option-block>
<div style="border: 1px solid #dcdee2;border-radius: 4px;"> <heightResize :append="['.page-option-block']">
<code-editor v-model="current.output" language="json"></code-editor> <code-editor v-model="current.output" language="json"></code-editor>
</div> </heightResize>
</div> </div>
</template> </template>
<script> <script>
import axios from "axios" import axios from "axios"
import _ from "lodash" import _ from "lodash"
import codeEditor from "./components/codeEditor"; import codeEditor from "./components/codeEditor";
import jsonFormatter from "./library/formatter/json";
import heightResize from "./components/heightResize";
export default { export default {
components: { components: {
codeEditor, codeEditor,
heightResize
}, },
created() { created() {
this.current = Object.assign(this.current, this.$getToolData("input")) this.current = Object.assign(this.current, this.$getToolData("input"))
...@@ -38,11 +41,13 @@ export default { ...@@ -38,11 +41,13 @@ export default {
url: 'https://get.geojs.io/v1/ip/geo.json', url: 'https://get.geojs.io/v1/ip/geo.json',
params: this.current.input !== "localhost" ? {ip: this.current.input} : {} params: this.current.input !== "localhost" ? {ip: this.current.input} : {}
}).then(({data}) => { }).then(({data}) => {
this.current.output = JSON.stringify(_.isArray(data) && data.length < 2 ? data[0] : data,null, 4); this.current.output = jsonFormatter.objectBeautify(_.isArray(data) && data.length < 2 ? data[0] : data);
this.$saveToolData(this.current); this.$saveToolData(this.current);
this.$Message.success("查询成功") this.$Message.success(this.$t('ip_ok').toString())
}).catch((error) => { }).catch((error) => {
return this.$Message.error("ip地址信息查询错误:" + error); return this.$Message.error(
this.$t('ip_error', [error.message]).toString()
)
}); });
} }
}, },
......
<template> <template>
<div> <div>
<div style="border: 1px solid #dcdee2;border-radius: 4px;"> <heightResize :append="['.page-option-block']">
<code-editor v-model="current.content" :auto-height="220" language="json"></code-editor> <code-editor :placeholder="$t('json_input')" v-model="current.content" language="json"></code-editor>
</div> </heightResize>
<option-block :style="{textAlign:'center'}"> <option-block center class="page-option-block">
<FormItem> <FormItem>
<ButtonGroup class="tool-json-button"> <ButtonGroup class="tool-json-button">
<Button type="primary" @click="handle(k)" v-for="(v,k) in type" :key="k">{{ v }}</Button> <Button type="primary" @click="handle(k)" v-for="(v,k) in type" :key="k">{{ v }}</Button>
...@@ -14,113 +14,80 @@ ...@@ -14,113 +14,80 @@
</template> </template>
<script> <script>
import Unicode from "./library/unicode" import Unicode from "./library/unicode"
import {jsonFormatter} from "./library/formatter" import jsonFormatter from "./library/formatter/json"
import codeEditor from "./components/codeEditor"; import codeEditor from "./components/codeEditor";
import heightResize from "./components/heightResize";
export default { export default {
components: { components: {
codeEditor, codeEditor,
heightResize
}, },
created() { created() {
this.current = Object.assign(this.current, this.$getToolData('content')) this.current = Object.assign(this.current, this.$getToolData('content'))
}, },
methods: { methods: {
handle(v) { handle(v) {
if (this.current.content) { try {
// 保存操作前数据 if (!this.current.content.trim()) {
this.$saveToolData(this.current) throw new Error(this.$t('json_content_empty').toString())
switch (v) {
case 'format':
try {
let content = this.current.content.trim()
if (!content) {
return this.$Notice.error({title: '错误提示', desc: '请输入内容'})
}
require('jsonlint').parse(content)
this.current.content = jsonFormatter(content)
} catch (error) {
this.$Notice.error({
title: '错误提示',
desc: error.message,
})
return
}
break
case 'compress':
try {
this.current.content = JSON.stringify(JSON.parse(this.current.content.trim()))
} catch (e) {
this.current.content = this.current.content.replace(/\n/g, '').replace(/\r/g, '')
}
break
case 'escape':
this.current.content = this.current.content.trim().replace(/\\/g, '\\\\').replace(/"/g, '\\"')
break
case 'clearEscape':
this.current.content = this.current.content.trim().replace(/\\\\/g, '\\').replace(/\\"/g, '"')
break
case 'unicode2zh':
this.current.content = this.unicode2zh()
break
case 'zh2unicode':
this.current.content = this.zh2unicode()
break
case 'get':
try {
let content = this.current.content.trim()
if (!content) {
return
}
require('jsonlint').parse(content)
this.current.content = require('query-string').stringify(
JSON.parse(this.current.content), {arrayFormat: 'bracket'}
)
} catch (error) {
this.$Notice.error({
title: '错误提示',
desc: error.message,
})
return
}
break
case 'getToJson':
try {
let content = this.current.content.trim()
if (!content) {
return
}
this.current.content = jsonFormatter(
JSON.stringify(require('query-string').parse(content, {arrayFormat: 'bracket'}))
)
} catch (error) {
this.$Notice.error({
title: '错误提示',
desc: error.message,
})
return
}
break
case 'clear':
this.current.content = ''
break
default:
return
} }
// 保存操作前数据
this.$saveToolData(this.current, true)
this.operation(v)
this.$clipboardCopy(this.current.content) this.$clipboardCopy(this.current.content)
this.$saveToolData(this.current) this.$saveToolData(this.current)
} catch (e) {
return this.$Message.error(this.$t('json_error', [e.message]).toString())
}
},
operation(type) {
switch (type) {
case 'format':
require('jsonlint').parse(this.current.content)
this.current.content = jsonFormatter.beautify(this.current.content)
break
case 'compress':
this.current.content = jsonFormatter.compress(this.current.content)
break
case 'escape':
this.current.content = this.current.content.trim().replace(/\\/g, '\\\\').replace(/"/g, '\\"')
break
case 'clearEscape':
this.current.content = this.current.content.trim().replace(/\\\\/g, '\\').replace(/\\"/g, '"')
break
case 'unicode2zh':
this.current.content = this.unicode2zh(this.current.content)
break
case 'zh2unicode':
this.current.content = this.zh2unicode(this.current.content)
break
case 'get':
require('jsonlint').parse(this.current.content)
this.current.content = require('query-string').stringify(
JSON.parse(this.current.content), {arrayFormat: 'bracket'}
)
break
case 'getToJson':
this.current.content = jsonFormatter.beautify(
JSON.stringify(require('query-string').parse(this.current.content.trim(), {arrayFormat: 'bracket'}))
)
break
case 'clear':
this.current.content = ''
break
default:
return
} }
}, },
unicode2zh() { unicode2zh(content) {
return Unicode.decode( return Unicode.decode(
this.current.content.replace(/\\U[0-9a-fA-F]{4}/g, (item) => { content.replace(/\\U[0-9a-fA-F]{4}/g, (item) => {
// \Uxxxx=>\uxxxx // \Uxxxx=>\uxxxx
return item.replace("\\U", "\\u"); return item.replace("\\U", "\\u");
}) })
) )
}, },
zh2unicode() { zh2unicode(content) {
let content = this.current.content
if (content) { if (content) {
let newStr = '' let newStr = ''
for (let i = 0; i < content.length; i++) { for (let i = 0; i < content.length; i++) {
...@@ -138,22 +105,22 @@ export default { ...@@ -138,22 +105,22 @@ export default {
content: '', content: '',
}, },
type: { type: {
'format': '格式化', 'format': this.$t('json_format'),
'compress': '压缩', 'compress': this.$t('json_compress'),
'escape': '转义', 'escape': this.$t('json_escape'),
'clearEscape': '去除转义', 'clearEscape': this.$t('json_clear_escape'),
'unicode2zh': 'Unicode转中文', 'unicode2zh': this.$t('json_unicode_to_zh'),
'zh2unicode': '中文转Unicode', 'zh2unicode': this.$t('json_zh_to_unicode'),
'get': '转GET', 'get': this.$t('json_to_get'),
'getToJson': 'GET转Json', 'getToJson': this.$t('json_get_to_json'),
'clear': '清空', 'clear': this.$t('json_clear'),
}, },
} }
}, },
} }
</script> </script>
<style scoped> <style scoped>
.tool-json-button .ivu-btn{ .tool-json-button .ivu-btn {
padding: 0 10px; padding: 0 10px;
} }
</style> </style>
<template> <template>
<Row :gutter="10"> <Row :gutter="10">
<Col span="10"> <Col span="10">
<Card :padding="0"> <div class="page-option-block">
<p slot="title">JSON内容</p> <option-block style="padding: 0 0">
<code-editor v-model="current.json" :auto-height="330" language="json"></code-editor>
</Card>
<option-block>
<FormItem>
<Input v-model="current.package"> <Input v-model="current.package">
<div slot="prepend">namespace/package</div> <div slot="prepend">namespace/package</div>
</Input> </Input>
</FormItem> </option-block>
</option-block> <option-block>
<option-block>
<FormItem>
<Input v-model="current.class"> <Input v-model="current.class">
<div slot="prepend">class/struct</div> <div slot="prepend">class/struct</div>
</Input> </Input>
</FormItem> </option-block>
</option-block> </div>
<input-block top="10px" right="10px" :text="$t('jsonToObject_format')" @on-default-right-bottom-click="format">
<heightResize :append="['.page-option-block']">
<code-editor v-model="current.input" :placeholder="$t('jsonToObject_input')" language="json"/>
</heightResize>
</input-block>
</Col> </Col>
<Col span="14"> <Col span="14">
<Card :padding="0"> <input-block top="10px" right="10px">
<p slot="title">转换结果</p> <heightResize>
<code-editor :placeholder="$t('jsonToObject_output')" :value="output" :language="languages[current.type]"/>
</heightResize>
<template slot="extra"> <template slot="extra">
<Button style="margin-right: 5px" size="small" v-for="(item,key) in type" :key="key" type="primary" <RadioGroup v-model="current.type" type="button" button-style="solid">
@click="handle(item)">{{ item }} <Radio :label="type" v-for="(type) in types" :key="type">
</Button> <span>{{ type }}</span>
</Radio>
</RadioGroup>
</template> </template>
<code-editor v-model="current.output" :auto-height="220" :language="languages[current.type]"></code-editor> </input-block>
</Card>
</Col> </Col>
</Row> </Row>
</template> </template>
<script> <script>
import codeEditor from "./components/codeEditor"; import codeEditor from "./components/codeEditor";
import json2Go from './library/json2Go' import json2Go from './library/json2Go'
import jsonFormatter from './library/formatter/json'
import json2CSharp from './library/json2CSharp' import json2CSharp from './library/json2CSharp'
import json2Java from './library/json2Java' import json2Java from './library/json2Java'
import json2Dart from './library/json2Dart' import json2Dart from './library/json2Dart'
import heightResize from "./components/heightResize";
export default { export default {
components: { components: {
codeEditor, codeEditor,
heightResize
}, },
created() { created() {
this.current = Object.assign(this.current, this.$getToolData()) this.current = Object.assign(this.current, this.$getToolData())
}, },
methods: { computed: {
handle(type) { output() {
if (!this.current.input.trim()) {
return "";
}
try { try {
require('jsonlint').parse(this.current.json) let result = "";
if (!this.type.includes(type)) { require('jsonlint').parse(this.current.input)
throw new Error("转换类型错误") switch (this.current.type) {
}
this.current.type = type;
switch (type) {
case "Go": case "Go":
this.current.output = json2Go(this.current.json, this.current.class, this.current.package).go result = json2Go(this.current.input, this.current.class, this.current.package).go
break; break
case "Java": case "Java":
this.current.output = json2Java(JSON.parse(this.current.json), this.current.class, this.current.package) result = json2Java(JSON.parse(this.current.input), this.current.class, this.current.package)
break; break
case "Dart": case "Dart":
this.current.output = json2Dart(JSON.parse(this.current.json), this.current.class) result = json2Dart(JSON.parse(this.current.input), this.current.class)
break; break
case "C#": case "C#":
this.current.output = json2CSharp.convert(JSON.parse(this.current.json), this.current.class, this.current.package) result = json2CSharp.convert(JSON.parse(this.current.input), this.current.class, this.current.package)
break; break
default:
throw new Error(this.$t('jsonToObject_type_error').toString())
} }
this.$saveToolData(this.current)
return result;
} catch (error) { } catch (error) {
this.$Notice.error({ return this.$t('jsonToObject_error', [error.message]).toString()
title: '错误提示', }
desc: error.message, },
}) types(){
return return Object.keys(this.languages)
}
},
methods:{
format(){
if (this.current.input.trim()){
this.current.input = jsonFormatter.beautify(this.current.input)
} }
this.$saveToolData(this.current)
} }
}, },
data() { data() {
return { return {
current: { current: {
json: "", input: "",
type: "Java", type: "Java",
package: "pag", package: "pag",
class: "RootName", class: "RootName",
output: "",
}, },
type: ["Java", "C#", "Go",'Dart'],
languages: { languages: {
"Java": "java", "Java": "java",
"Dart": "dart", "Dart": "dart",
......
<template> <template>
<div> <heightResize @resize="resize">
<Input v-model="current.input" :rows="7" type="textarea" placeholder="内容"></Input> <Row :gutter="10">
<option-block> <Col span="12">
<FormItem> <input-block top="4px">
<ButtonGroup> <code-editor :height="editorheight" :placeholder="$t('jwt_input')" hideLineNumbers v-model="current.input"></code-editor>
<Button type="primary" @click="handle('decode')">解码</Button> <template slot="extra">
</ButtonGroup> <Checkbox v-model="current.header">header</Checkbox>
</FormItem> <Checkbox v-model="current.payload">payload</Checkbox>
<FormItem> </template>
<Checkbox v-model="current.header">header</Checkbox> </input-block>
<Checkbox v-model="current.payload">payload</Checkbox> </Col>
</FormItem> <Col span="12">
</option-block> <code-editor :height="editorheight" :placeholder="$t('jwt_output')" :value="output" language="json"></code-editor>
<Input v-model="current.output" :rows="7" type="textarea" placeholder="结果"></Input> </Col>
</div> </Row>
</heightResize>
</template> </template>
<script> <script>
import jwtDecode from "jwt-decode" import jwtDecode from "jwt-decode"
import codeEditor from "./components/codeEditor";
import jsonFormatter from "./library/formatter/json";
import heightResize from "./components/heightResize";
export default { export default {
components: {
codeEditor,
heightResize
},
created() { created() {
this.current = Object.assign(this.current, this.$getToolData("input")) this.current = Object.assign(this.current, this.$getToolData("input"))
}, },
methods: { computed: {
handle(v) { output() {
if (this.current.input) { if(!this.current.input.trim()){
try { return ""
let data = {}; }
if (this.current.header) { try {
data.header = jwtDecode(this.current.input, {header: true}) let data = {};
} if (this.current.header) {
if (this.current.payload) { data.header = jwtDecode(this.current.input, {header: true})
data.payload = jwtDecode(this.current.input) }
} if (this.current.payload) {
this.current.output = JSON.stringify( data.payload = jwtDecode(this.current.input)
Object.keys(data).length === 1 ? data[Object.keys(data)[0]] : data,
null,4
);
this.current.operation = v;
this.$clipboardCopy(this.current.output);
this.$saveToolData(this.current);
} catch (e) {
this.$Message.error("解码失败")
console.log(e)
} }
this.$saveToolData(this.current);
return jsonFormatter.objectBeautify(
Object.keys(data).length === 1 ? data[Object.keys(data)[0]] : data,
);
} catch (e) {
return this.$t('jwt_decode_fail',[e.message])
} }
} }
}, },
methods:{
resize(height){
this.editorheight = height+"px"
}
},
data() { data() {
return { return {
current: { current: {
input: "", input: "",
output: "",
header: false, header: false,
payload: true, payload: true,
operation: "" },
} editorheight:"100%",
} }
}, },
} }
</script> </script>
\ No newline at end of file
...@@ -7,6 +7,7 @@ import "codemirror/addon/fold/comment-fold"; ...@@ -7,6 +7,7 @@ import "codemirror/addon/fold/comment-fold";
import "codemirror/addon/fold/foldgutter.css"; import "codemirror/addon/fold/foldgutter.css";
import 'codemirror/addon/merge/merge' import 'codemirror/addon/merge/merge'
import 'codemirror/addon/merge/merge.css' import 'codemirror/addon/merge/merge.css'
import "codemirror/addon/display/placeholder";
import "codemirror/mode/javascript/javascript.js"; import "codemirror/mode/javascript/javascript.js";
import "codemirror/mode/htmlmixed/htmlmixed.js"; import "codemirror/mode/htmlmixed/htmlmixed.js";
import "codemirror/mode/css/css.js"; import "codemirror/mode/css/css.js";
...@@ -103,12 +104,6 @@ export const createMerge = (data, container, lang, option = {}) => { ...@@ -103,12 +104,6 @@ export const createMerge = (data, container, lang, option = {}) => {
editor.right.orig.setValue(modified) editor.right.orig.setValue(modified)
} }
} }
editor['customSetSize'] = (width, height) => {
editor.edit.setSize(width, height)
editor.right.orig.setSize(width, height)
}
editor['customChange'] = (callback) => { editor['customChange'] = (callback) => {
editor.edit.on('change', () => { editor.edit.on('change', () => {
callback && callback(editor.edit.getValue(), editor.right.orig.getValue()) callback && callback(editor.edit.getValue(), editor.right.orig.getValue())
......
...@@ -45,9 +45,5 @@ export const format = (code, lang, isCompress = false, options = {}) => { ...@@ -45,9 +45,5 @@ export const format = (code, lang, isCompress = false, options = {}) => {
return methods[lang][method](code,options) return methods[lang][method](code,options)
}; };
export const jsonFormatter = (code) => {
return format(code, 'json')
}
export default format export default format
export const beautify = (code, option = {}) => { export const beautify = (code, option = {}) => {
return JSON.stringify(JSON.parse(code.trim()), null, "tab" in option ? option.tab : 4) return objectBeautify(JSON.parse(code.trim()), option)
}
export const objectBeautify = (codeObject, option = {}) => {
return JSON.stringify(codeObject, null, "tab" in option ? option.tab : 4)
} }
// eslint-disable-next-line no-unused-vars // eslint-disable-next-line no-unused-vars
export const compress = (code, options = {}) => { export const compress = (code, options = {}) => {
return JSON.stringify(JSON.parse(code.trim()), null, 0) try {
return JSON.stringify(JSON.parse(code.trim()), null, 0)
} catch (e) {
return code.replace(/\n/g, '').replace(/\r/g, '')
}
} }
export default { export default {
beautify, compress beautify, compress,objectBeautify
} }
...@@ -40,7 +40,7 @@ class serializeConversion { ...@@ -40,7 +40,7 @@ class serializeConversion {
break; break;
} }
} catch (e) { } catch (e) {
throw new Error("源数据转换异常:" + e.message); throw new Error("source error:" + e.message);
} }
} }
...@@ -64,7 +64,7 @@ class serializeConversion { ...@@ -64,7 +64,7 @@ class serializeConversion {
return this.getProperties(); return this.getProperties();
} }
} catch (e) { } catch (e) {
throw new Error("目标数据转换错误:" + e.message); throw new Error("target error:" + e.message);
} }
} }
...@@ -97,4 +97,4 @@ class serializeConversion { ...@@ -97,4 +97,4 @@ class serializeConversion {
export const conversion = (data, source) => { export const conversion = (data, source) => {
return new serializeConversion(data, source) return new serializeConversion(data, source)
} }
\ No newline at end of file
...@@ -40,6 +40,9 @@ class TextHandle { ...@@ -40,6 +40,9 @@ class TextHandle {
// 行首大写 // 行首大写
upperLineStart() { upperLineStart() {
return this.text.split(/\r?\n/).map((str) => { return this.text.split(/\r?\n/).map((str) => {
if (str.length < 1){
return "";
}
return str[0].toUpperCase() + str.substr(1) return str[0].toUpperCase() + str.substr(1)
}).join("\n"); }).join("\n");
} }
...@@ -47,6 +50,9 @@ class TextHandle { ...@@ -47,6 +50,9 @@ class TextHandle {
// 行首小写 // 行首小写
lowerLineStart() { lowerLineStart() {
return this.text.split(/\r?\n/).map((str) => { return this.text.split(/\r?\n/).map((str) => {
if (str.length < 1){
return "";
}
return str[0].toLowerCase() + str.substr(1) return str[0].toLowerCase() + str.substr(1)
}).join("\n"); }).join("\n");
} }
...@@ -77,7 +83,7 @@ class TextHandle { ...@@ -77,7 +83,7 @@ class TextHandle {
replace(search = [], replace = []) { replace(search = [], replace = []) {
let text = this.text; let text = this.text;
for (let i in search) { for (let i in search) {
if (search[i]){ if (search[i]) {
text = text.replace(new RegExp(regExpQuote(search[i]), 'g'), (i in replace ? replace[i] : "")); text = text.replace(new RegExp(regExpQuote(search[i]), 'g'), (i in replace ? replace[i] : ""));
} }
} }
...@@ -174,4 +180,4 @@ class TextHandle { ...@@ -174,4 +180,4 @@ class TextHandle {
export default (text) => { export default (text) => {
return new TextHandle(text) return new TextHandle(text)
} }
\ No newline at end of file
...@@ -21,7 +21,7 @@ export default { ...@@ -21,7 +21,7 @@ export default {
try { try {
return callback && callback() return callback && callback()
} catch (e) { } catch (e) {
throw new Error(`${item} 解码异常:${e.message}`) throw new Error(`${item} decode error:${e.message}`)
} }
} }
...@@ -55,7 +55,7 @@ export default { ...@@ -55,7 +55,7 @@ export default {
return errorListener(item, () => String.fromCodePoint(parseInt(`0x${item.replace("\\", "").toLowerCase()}`))) return errorListener(item, () => String.fromCodePoint(parseInt(`0x${item.replace("\\", "").toLowerCase()}`)))
}); });
} }
throw new Error("解码类型异常") throw new Error("decode type error")
}, },
encode(string, type = unicode_point_default, ignore_ascii = false) { encode(string, type = unicode_point_default, ignore_ascii = false) {
let code = [] let code = []
...@@ -97,7 +97,7 @@ export default { ...@@ -97,7 +97,7 @@ export default {
code.push(`\\${hexRepairStr}`); code.push(`\\${hexRepairStr}`);
break; break;
default: default:
throw new Error("编码类型异常") throw new Error("encode type error")
} }
} }
return code.join(""); return code.join("");
...@@ -112,4 +112,4 @@ export default { ...@@ -112,4 +112,4 @@ export default {
repair(str) { repair(str) {
return str.length > 3 ? str : `${'0'.repeat(4 - str.length)}${str}`; return str.length > 3 ? str : `${'0'.repeat(4 - str.length)}${str}`;
} }
} }
\ No newline at end of file
此差异已折叠。
<template> <template>
<div> <heightResize :append="['.page-option-block']" ignore @resize="resize">
<Input v-model="current.input" :rows="7" type="textarea" placeholder="内容"></Input> <autoHeightTextarea :height="inputHeight" v-model="current.input" :placeholder="$t('pinyin_input')" />
<option-block> <option-block class="page-option-block">
<FormItem> <FormItem>
<ButtonGroup> <RadioGroup v-model="current.operation" type="button" button-style="solid">
<Button type="primary" @click="handle('normal')">无声调</Button> <Radio label="normal">{{ $t('pinyin_normal') }}</Radio>
<Button type="primary" @click="handle('tone')">有声调</Button> <Radio label="tone">{{ $t('pinyin_tone') }}</Radio>
<Button type="primary" @click="handle('abbr')">首字母</Button> <Radio label="abbr">{{ $t('pinyin_abbr') }}</Radio>
</ButtonGroup> </RadioGroup>
</FormItem> </FormItem>
<FormItem> <FormItem>
<Select v-model="current.delimiter" style="width:200px"> <Select v-model="current.delimiter" style="width:200px">
...@@ -15,65 +15,80 @@ ...@@ -15,65 +15,80 @@
</Select> </Select>
</FormItem> </FormItem>
</option-block> </option-block>
<Input v-model="current.output" :rows="7" type="textarea" placeholder="结果"></Input> <autoHeightTextarea :height="outputHeight" :value="output" :placeholder="$t('pinyin_output')" />
</div> </heightResize>
</template> </template>
<script> <script>
import "./pinyin/dict" import "./pinyin/dict"
import "ipinyinjs" import "ipinyinjs"
import heightResize from "./components/heightResize";
import autoHeightTextarea from "./components/autoHeightTextarea";
function py (type, str, delimiter) { function py(type, str, delimiter) {
let pinyin = { let pinyin = {
abbr: function (str, delimiter) { abbr: function (str, delimiter) {
return window.pinyinUtil.getFirstLetter(str).split('').join(delimiter); return window.pinyinUtil.getFirstLetter(str).split('').join(delimiter);
},
tone: function (str, delimiter) {
return window.pinyinUtil.getPinyin(str, delimiter);
},
normal: function (str, delimiter) {
return window.pinyinUtil.getPinyin(str, delimiter, false);
}
};
str = str.split("\n");
for (let i = 0; i < str.length; i++) {
str[i] = pinyin[type](str[i], delimiter);
}
return str.join("\n");
}
export default {
created() {
this.current = Object.assign({},this.current,this.$getToolData("input"))
},
methods: {
handle(v) {
if (this.current.input) {
this.current.output = py(
v,
this.current.input,
this.current.delimiter === "null" ? "" : (this.current.delimiter === "blank" ? " " : this.current.delimiter)
);
this.current.operation = v;
this.$clipboardCopy(this.current.output);
this.$saveToolData(this.current);
}
}
}, },
data() { tone: function (str, delimiter) {
return { return window.pinyinUtil.getPinyin(str, delimiter);
current:{
input: "",
output: "",
delimiter:"null",
operation:""
},
delimiter:[
{"n":"无分隔符","v":"null"},
{"n":"空格分隔","v":"blank"},
{"n":"'-'中划线分隔","v":"-"},
{"n":"'_'下划线分隔","v":"_"},
{"n":"'.'点分隔","v":"."}
]
}
}, },
normal: function (str, delimiter) {
return window.pinyinUtil.getPinyin(str, delimiter, false);
}
};
str = str.split("\n");
for (let i = 0; i < str.length; i++) {
str[i] = pinyin[type](str[i], delimiter);
} }
</script> return str.join("\n");
\ No newline at end of file }
export default {
components:{
heightResize,
autoHeightTextarea
},
created() {
this.current = Object.assign({}, this.current, this.$getToolData("input"))
},
computed: {
output() {
let result = "";
if (this.current.input.trim()) {
result = py(
this.current.operation,
this.current.input,
this.current.delimiter === "null" ? "" : (this.current.delimiter === "blank" ? " " : this.current.delimiter)
);
this.$saveToolData(this.current);
}
return result
}
},
methods:{
resize(height){
this.inputHeight = Math.min(Math.ceil(height/2),160);
this.outputHeight = height - this.inputHeight;
}
},
data() {
return {
current: {
input: "",
output: "",
delimiter: "null",
operation: "normal"
},
delimiter: [
{"n": this.$t('pinyin_delimiter_null'), "v": "null"},
{"n": this.$t('pinyin_delimiter_space'), "v": "blank"},
{"n": this.$t('pinyin_delimiter_1'), "v": "-"},
{"n": this.$t('pinyin_delimiter_2'), "v": "_"},
{"n": this.$t('pinyin_delimiter_3'), "v": "."}
],
inputHeight:100,
outputHeight:100,
}
},
}
</script>
<template> <template>
<div> <div>
<Tabs v-model="current.operation"> <Tabs v-model="current.operation">
<TabPane label="二维码生成" name="generate"> <TabPane :label="$t('qrCode_generate_title')" name="generate">
<Row :gutter="16"> <Row :gutter="16">
<Col span="14"> <Col span="14">
<Input v-model="current.generateInput" :rows="14" type="textarea" placeholder="内容"></Input> <Input v-model="current.generateInput" :rows="14" type="textarea" :placeholder="$t('qrCode_generate_input')"></Input>
<option-block> </Col>
<FormItem> <Col span="10">
<Button type="primary" @click="generate()">生成</Button> <div style="text-align: center" v-html="generateOutput"></div>
</FormItem> </Col>
</option-block> </Row>
</Col> </TabPane>
<Col span="10"> <TabPane :label="$t('qrCode_reader_title')" name="reader">
<div style="text-align: center" v-html="current.generateOutput"></div> <Row :gutter="16">
</Col> <Col span="14">
</Row> <input-block style="margin-bottom: 10px" bottom="0px" right="10px">
</TabPane> <pasteClipboardFlie @on-paste-image="handleUpload">
<TabPane label="二维码解析" name="reader"> <Input v-model="current.readerInput" :rows="3" type="textarea" :placeholder="$t('qrCode_reader_input')"></Input>
<Row :gutter="16"> </pasteClipboardFlie>
<Col span="14"> <Upload slot="extra" action="#" :before-upload="handleUpload">
<Input v-model="current.readerInput" :rows="5" type="textarea" placeholder="请输入二维码图片地址或点击下方按钮上传图片"></Input> <Button size="small" type="primary" icon="ios-cloud-upload-outline">{{ $t('qrCode_reader_upload') }}</Button>
<option-block> </Upload>
<FormItem> </input-block>
<Button type="primary" @click="reader()">解析</Button> <Input v-model="readerOutput" :rows="8" type="textarea" :placeholder="$t('qrCode_reader_output')"></Input>
</FormItem> </Col>
<FormItem> <Col span="10" style="text-align: center" v-html="readerInputImg"></Col>
<Upload action="#" :before-upload="handleUpload"> </Row>
<Button icon="ios-cloud-upload-outline">上传图片</Button> </TabPane>
</Upload> </Tabs>
</FormItem>
</option-block> </div>
<Input v-model="current.readerOutput" :rows="5" type="textarea" placeholder="解析结果"></Input>
</Col>
<Col span="10" style="text-align: center" v-html="readerInputImg"></Col>
</Row>
</TabPane>
</Tabs>
</div>
</template> </template>
<script> <script>
import generator from 'qrcode' import generator from 'qrcode'
import qrcodeParser from 'qrcode-parser' import qrcodeParser from 'qrcode-parser'
import model from '../../tool/model' import model from '../../tool/model'
import Jimp from 'jimp';
import pasteClipboardFlie from './components/pasteClipboardFlie';
export default { export default {
computed: { components: {
readerInputImg () { pasteClipboardFlie,
if (this.current.readerInput) { },
return `<img style="width:300px" src="${this.current.readerInput}" />` computed: {
} readerInputImg() {
return '' if (this.current.readerInput) {
}, return `<img style="width:300px" src="${this.current.readerInput}" />`
},
created () {
let feature = model.getToolCurrentFeature('generate')
if(feature === 'generate'){
this.current = Object.assign(this.current, this.$getToolData('generateInput'))
this.current.operation = feature;
}
else if(feature === 'reader'){
this.current = Object.assign(this.current, this.$getToolData('readerInput'))
this.current.operation = feature;
}
else{
this.current = Object.assign(this.current, this.$getToolData())
} }
return ''
}
},
watch: {
"current.generateInput"() {
this.generate()
}, },
methods: { "current.readerInput"() {
generate () { this.reader()
if (!this.current.generateInput) return }
this.generateHandle(this.current.generateInput) },
this.$saveToolData(this.current) created() {
}, let feature = model.getToolCurrentFeature('generate')
reader () { if (feature === 'generate') {
if (!this.current.readerInput) { this.current = Object.assign(this.current, this.$getToolData('generateInput'))
return this.current.operation = feature;
} } else if (feature === 'reader') {
qrcodeParser(this.current.readerInput).then((c) => { this.current = Object.assign(this.current, this.$getToolData('readerInput'))
this.current.readerOutput = c.data this.current.operation = feature;
this.$saveToolData(this.current) } else {
this.$Message.success('解析成功') this.current = Object.assign(this.current, this.$getToolData())
}).catch(() => { }
return this.$Message.error('图片解析错误') },
}) methods: {
}, generate() {
generateHandle (str) { if (!this.current.generateInput) {
generator.toDataURL(str, (error, url) => { this.generateOutput = "";
if (error) return this.$Message.error('二维码生成错误:' + error) return;
this.$clipboardCopyImages(url) }
this.current.generateOutput = `<img style="width:300px" src="${url}" />` generator.toDataURL(this.current.generateInput, (error, url) => {
}) if (error) {
}, this.generateOutput = this.$t("qrCode_generate_error", [error]);
handleUpload (file) { return;
let r = new FileReader()
r.readAsDataURL(file)
r.onloadend = () => {
this.current.readerInput = r.result
this.reader()
} }
return false this.$clipboardCopyImages(url)
}, this.generateOutput = `<img style="width:300px" src="${url}" />`
substr (str) { this.$saveToolData(this.current)
str = str.replace(/[\r\n]/g, '').trim() })
const strLength = 100
return str.length > strLength ? str.substr(0, strLength) + '...' : str
},
}, },
data () { reader() {
return { if (!this.current.readerInput) {
current: { this.readerOutput = "";
generateInput: '', return
generateOutput: '',
readerInput: '',
readerOutput: '',
operation: 'generate',
},
} }
this.getReaderImagePngBase64(this.current.readerInput).then((result) => {
this.readerOutput = result
this.$saveToolData(this.current)
}).catch(e => {
this.readerOutput = this.$t('qrCode_reader_error', [e.message])
})
},
getReaderImagePngBase64(input) {
return new Promise((resolve, reject) => {
const xhr = new XMLHttpRequest();
xhr.open('GET', input);
xhr.responseType = 'blob';
xhr.onload = () => {
if (xhr.status >= 200 && xhr.status < 300) {
let blob = xhr.response;
const myReader = new FileReader();
myReader.readAsArrayBuffer(blob);
myReader.addEventListener('loadend', e => {
const buffer = e.target.result;
try {
Jimp.read(buffer, (err, image) => {
if (err) {
return reject(err);
}
image.getBase64Async("image/png").then((img) => {
return qrcodeParser(img)
}).then((c) => {
resolve(c.data)
}).catch((e) => {
reject(e);
})
});
} catch (e) {
reject(e);
}
});
} else {
reject(new Error(this.$t('qrCode_reader_parsing_failure').toString()));
}
};
xhr.onerror = () => reject(new Error(this.$t('qrCode_reader_parsing_failure').toString()));
xhr.send();
})
}, },
} handleUpload(file) {
if (this.current.operation !== "reader"){
return;
}
let r = new FileReader()
r.readAsDataURL(file)
r.onloadend = () => {
this.current.readerInput = r.result
}
return false
}
},
data() {
return {
readerOutput: "",
generateOutput: "",
current: {
generateInput: '',
readerInput: '',
operation: 'generate',
},
}
},
}
</script> </script>
<template> <template>
<div> <div>
<Row :gutter="16"> <div class="page-option-block">
<Col span="8"> <Row :gutter="16">
<Input v-model="current.length"> <Col span="8">
<div slot="prepend" style="width: 70px">长度</div> <Input v-model="current.length" type="number">
</Input> <div slot="prepend" style="width: 70px">{{ $t('randomString_length') }}</div>
</Col> </Input>
<Col span="8"> </Col>
<Input v-model="current.amount"> <Col span="8">
<div slot="prepend" style="width: 70px">生成数量</div> <Input v-model="current.amount" type="number">
</Input> <div slot="prepend" style="width: 70px">{{ $t('randomString_amount') }}</div>
</Col> </Input>
<Col span="8"> </Col>
<Input v-model="current.delimiter"> <Col span="8">
<div slot="prepend" style="width: 70px">分隔符</div> <Input v-model="current.delimiter">
</Input> <div slot="prepend" style="width: 70px">{{ $t('randomString_delimiter') }}</div>
</Col> </Input>
</Row> </Col>
<option-block> </Row>
<FormItem> <option-block>
<Checkbox v-model="current.isDigital">数字</Checkbox> <FormItem>
</FormItem> <Checkbox v-model="current.isDigital">{{ $t('randomString_digital') }}</Checkbox>
<FormItem> </FormItem>
<Checkbox v-model="current.isLowercase">小写字母</Checkbox> <FormItem>
</FormItem> <Checkbox v-model="current.isLowercase">{{ $t('randomString_lowercase') }}</Checkbox>
<FormItem> </FormItem>
<Checkbox v-model="current.isUppercase">大写字母</Checkbox> <FormItem>
</FormItem> <Checkbox v-model="current.isUppercase">{{ $t('randomString_uppercase') }}</Checkbox>
<FormItem> </FormItem>
<Checkbox v-model="current.isSymbol">特殊符号</Checkbox> <FormItem>
</FormItem> <Checkbox v-model="current.isSymbol">{{ $t('randomString_symbol') }}</Checkbox>
<FormItem> </FormItem>
<Checkbox v-model="current.isUnique">唯一</Checkbox> <FormItem>
</FormItem> <Checkbox v-model="current.isUnique">{{ $t('randomString_unique') }}</Checkbox>
<FormItem> </FormItem>
<Checkbox v-model="current.isAddQuote">添加引号</Checkbox> <FormItem>
</FormItem> <Checkbox v-model="current.isAddQuote">{{ $t('randomString_add_quote') }}</Checkbox>
<FormItem> </FormItem>
<Button type="primary" @click="handle()">生成</Button> <FormItem>
</FormItem> <Button type="primary" @click="handle()">{{ $t('randomString_generate') }}</Button>
</option-block> </FormItem>
<Input v-model="current.output" :rows="12" type="textarea" placeholder="结果"></Input> </option-block>
</div>
<heightResize :append="['.page-option-block']">
<autoHeightTextarea :value="current.output" :placeholder="$t('randomString_output')" />
</heightResize>
</div> </div>
</template> </template>
<script> <script>
export default { import heightResize from "./components/heightResize";
created() { import autoHeightTextarea from "./components/autoHeightTextarea";
this.current = Object.assign(this.current,this.$getToolData()) export default {
}, components:{
methods: { heightResize,
handle() { autoHeightTextarea
let chars = ""; },
if (this.current.isDigital) chars += "0123456789"; created() {
if (this.current.isLowercase) chars += "abcdefghijklmnopqrstuvwxyz"; this.current = Object.assign(this.current, this.$getToolData())
if (this.current.isUppercase) chars += "ABCDEFGHIJKLMNOPQRSTUVWXYZ"; },
if (this.current.isSymbol) chars += "`~!@#$%^&*()-_=+[{]}|;:',<.>/?"; mounted() {
if (!this.current.output){
let randomStringLists = []; this.handle()
for (let i = 0, l = this.current.amount; i < l; i++) { }
let _chars = chars.split(""), },
random_string = ""; methods: {
for (let j = 0, k = this.current.length; j < k; j++) { handle() {
if (_chars.length < 1) break; let chars = "";
let index = Math.floor(Math.random() * _chars.length); if (this.current.isDigital) chars += "0123456789";
random_string += _chars[index]; if (this.current.isLowercase) chars += "abcdefghijklmnopqrstuvwxyz";
if (this.current.isUnique) _chars.splice(index, 1); if (this.current.isUppercase) chars += "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
} if (this.current.isSymbol) chars += "`~!@#$%^&*()-_=+[{]}|;:',<.>/?";
randomStringLists.push(this.current.isAddQuote ? '"'+random_string+'"' : random_string); let randomStringLists = [];
for (let i = 0, l = this.current.amount; i < l; i++) {
let _chars = chars.split(""),
random_string = "";
for (let j = 0, k = this.current.length; j < k; j++) {
if (_chars.length < 1) break;
let index = Math.floor(Math.random() * _chars.length);
random_string += _chars[index];
if (this.current.isUnique) _chars.splice(index, 1);
} }
this.current.output = randomStringLists.join(this.current.delimiter.replace(/\\n/, "\n")); randomStringLists.push(this.current.isAddQuote ? '"'+random_string+'"' : random_string);
this.$saveToolData(this.current);
} }
}, this.current.output = randomStringLists.join(this.current.delimiter.replace(/\\n/, "\n"));
data() { this.$saveToolData(this.current);
return { }
current:{ },
length:8, data() {
amount:10, return {
delimiter:",\\n", current: {
isDigital:true, length: 8,
isLowercase:true, amount: 10,
isUppercase:true, delimiter: ",\\n",
isSymbol:false, isDigital: true,
isUnique:false, isLowercase: true,
isAddQuote:false, isUppercase: true,
output: "", isSymbol: false,
} isUnique: true,
isAddQuote: false,
output: "",
} }
}, }
} },
</script> }
\ No newline at end of file </script>
此差异已折叠。
<template> <template>
<div> <Row :gutter="10">
<Input v-model="current.input" :rows="7" type="textarea" placeholder="内容"></Input> <Col span="12">
<option-block> <input-block top="10px" right="15px">
<FormItem> <heightResize>
<Select v-model="current.source" style="width:200px"> <code-editor v-model="current.input" :placeholder="$t('serializeConversion_input')"
<Option v-for="v in type" :value="v" :key="v">源数据:{{ v }}</Option> :language="language[current.source]"/>
</Select> </heightResize>
</FormItem> <template slot="extra">
<FormItem> <Select v-model="current.source" style="width:100px">
<Select v-model="current.target" style="width:200px"> <Option v-for="v in type" :value="v" :key="v">{{ v }}</Option>
<Option v-for="v in type" :value="v" :key="v">目标数据:{{ v }}</Option> </Select>
</Select> </template>
</FormItem> </input-block>
<FormItem> </Col>
<ButtonGroup> <Col span="12">
<Button type="primary" @click="handle()">转换</Button> <input-block top="10px" right="15px">
</ButtonGroup> <heightResize>
</FormItem> <code-editor :value="output" :placeholder="$t('serializeConversion_output')" :language="language[current.target]"/>
</option-block> </heightResize>
<Input v-model="current.output" :rows="7" type="textarea" placeholder="结果"></Input> <template slot="extra">
</div> <Select v-model="current.target" style="width:100px">
<Option v-for="v in type" :value="v" :key="v">{{ v }}</Option>
</Select>
</template>
</input-block>
</Col>
</Row>
</template> </template>
<script> <script>
import {TYPE as conversionType,conversion} from "./library/serializeConversion" import {conversion, TYPE as conversionType} from "./library/serializeConversion"
import codeEditor from "./components/codeEditor";
import heightResize from "./components/heightResize";
export default { export default {
components: {
codeEditor,
heightResize
},
created() { created() {
this.current = Object.assign(this.current, this.$getToolData("input")) this.current = Object.assign(this.current, this.$getToolData("input"))
}, },
methods: { computed: {
handle() { output() {
let result = "";
if (this.current.input) { if (this.current.input) {
try { try {
this.current.output = conversion(this.current.input,this.current.source).getByTarget(this.current.target); result = conversion(this.current.input, this.current.source).getByTarget(this.current.target);
this.$saveToolData(this.current);
} catch (e) { } catch (e) {
this.$Message.error(e.message); result = this.$t('serializeConversion_error', [e.message])
return;
} }
this.$clipboardCopy(this.current.output);
this.$saveToolData(this.current);
} }
return result;
} }
}, },
data() { data() {
...@@ -51,7 +63,15 @@ export default { ...@@ -51,7 +63,15 @@ export default {
target: "xml" target: "xml"
}, },
type: conversionType, type: conversionType,
language: {
json: "json",
xml: "xml",
yaml: "yaml",
phpArray: "php",
phpSerialize: "text",
properties: "text",
}
} }
}, },
} }
</script> </script>
\ No newline at end of file
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册