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

English language support #74

上级 11ebdc0f
此差异已折叠。
{
"name": "c-tool",
"version": "1.9.0",
"version": "1.9.1",
"private": true,
"scripts": {
"serve": "vue-cli-service serve --port 8081",
......@@ -27,6 +27,7 @@
"graphql": "15.5.0",
"ipinyinjs": "^1.0.0",
"jian_fan": "^1.0.3",
"jimp": "^0.16.1",
"js-base64": "^2.6.4",
"js-htmlencode": "^0.3.0",
"js-yaml": "^3.14.1",
......
<template>
<div style="position: relative;">
<slot></slot>
<div class="right-bottom">
<div :style="extraStyle">
<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>
</div>
</div>
......@@ -15,6 +15,38 @@ export default {
text: {
type: String,
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: {
......@@ -24,11 +56,3 @@ export default {
}
};
</script>
<style scoped>
.right-bottom {
position: absolute;
bottom: 4px;
right: 4px;
}
</style>
<template>
<Form inline style="padding: 10px 0" class="option-block">
<Form inline :style="style" class="option-block">
<slot></slot>
</Form>
</template>
<script>
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>
......
......@@ -14,54 +14,52 @@ const DEFAULT_COMMON_TOOL = [
]
const category = [
{'name': 'common', 'title': '常用'},
{'name': 'encryption', 'title': '加解密'},
{'name': 'conversion', 'title': '转换'},
{'name': 'serialize', 'title': '序列化'},
{'name': 'check', 'title': '校验'},
{'name': 'generate', 'title': '生成'},
{'name': 'other', 'title': '其他'},
{'name': 'common'},
{'name': 'encryption'},
{'name': 'conversion'},
{'name': 'serialize'},
{'name': 'check'},
{'name': 'generate'},
{'name': 'other'},
]
const tool = [
{
'name': 'hash',
'title': '哈希(hash)',
'cat': ['encryption']
},
{
'name': 'encrypt',
'title': '加密/解密',
'cat': ['encryption']
},
{'name': 'sign', 'title': '签名/验签', 'cat': ['encryption']},
{'name': 'base64', 'title': 'BASE64编码', 'cat': ['encryption']},
{'name': 'json', 'title': 'JSON工具', 'cat': ['conversion', 'serialize']},
{'name': 'url', 'title': 'URL编码', 'cat': ['conversion']},
{'name': 'timestamp', 'title': '时间戳', 'cat': ['conversion']},
{'name': 'qrCode', 'title': '二维码', 'cat': ['generate']},
{'name': 'barcode', 'title': '条形码', 'cat': ['generate']},
{'name': 'pinyin', 'title': '汉字转拼音', 'cat': ['conversion']},
{'name': 'ip', 'title': 'IP地址查询', 'cat': ['other']},
{'name': 'code', 'title': '代码格式化', 'cat': ['other']},
{'name': 'unicode', 'title': 'Unicode', 'cat': ['conversion']},
{'name': 'decimalConvert', 'title': '进制转换', 'cat': ['conversion']},
{'name': 'regex', 'title': '正则表达式', 'cat': ['check']},
{'name': 'randomString', 'title': '随机字符生成', 'cat': ['generate']},
{'name': 'serializeConversion', 'title': '序列化转换', 'cat': ['conversion', 'serialize']},
{'name': 'diffs', 'title': '文本差异化对比', 'cat': ['check']},
{'name': 'crontab', 'title': 'crontab校验', 'cat': ['check']},
{'name': 'websocket', 'title': 'websocket调试', 'cat': ['other']},
{'name': 'unit', 'title': '单位换算', 'cat': ['other']},
{'name': 'time', 'title': '时间计算器', 'cat': ['other']},
{'name': 'uuid', 'title': 'UUID生成', 'cat': ['generate']},
{'name': 'jsonToObject', 'title': 'JSON转实体类', 'cat': ['conversion', 'serialize']},
{'name': 'ascii', 'title': 'ASCII转换', 'cat': ['conversion']},
{'name': 'variableConversion', 'title': '变量名转换', 'cat': ['conversion']},
{'name': 'jwt', 'title': 'JWT解码', 'cat': ['conversion']},
{'name': 'hexString', 'title': 'Hex/String转换', 'cat': ['conversion']},
{'name': 'text', 'title': '文本处理', 'cat': ['other']},
{'name': 'html', 'title': 'html编码', 'cat': ['conversion']},
{'name': 'sign', 'cat': ['encryption','check']},
{'name': 'base64', 'cat': ['encryption']},
{'name': 'json', 'cat': ['conversion', 'serialize']},
{'name': 'url', 'cat': ['conversion']},
{'name': 'timestamp', 'cat': ['conversion']},
{'name': 'qrCode', 'cat': ['generate']},
{'name': 'barcode', 'cat': ['generate']},
{'name': 'pinyin', 'cat': ['conversion']},
{'name': 'ip', 'cat': ['other']},
{'name': 'code', 'cat': ['other']},
{'name': 'unicode', 'cat': ['conversion']},
{'name': 'decimalConvert', 'cat': ['conversion']},
{'name': 'regex', 'cat': ['check']},
{'name': 'randomString', 'cat': ['generate']},
{'name': 'serializeConversion', 'cat': ['conversion', 'serialize']},
{'name': 'diffs', 'cat': ['check']},
{'name': 'crontab', 'cat': ['check']},
{'name': 'websocket', 'cat': ['other']},
{'name': 'unit', 'cat': ['other']},
{'name': 'time', 'cat': ['other']},
{'name': 'uuid', 'cat': ['generate']},
{'name': 'jsonToObject', 'cat': ['conversion', 'serialize']},
{'name': 'ascii', 'cat': ['conversion']},
{'name': 'variableConversion', 'cat': ['conversion']},
{'name': 'jwt', 'cat': ['conversion']},
{'name': 'hexString', 'cat': ['conversion']},
{'name': 'text', 'cat': ['other']},
{'name': 'html', 'cat': ['conversion']},
]
// 工具类功能配置
......
locales/build.json
locales/build.js
......@@ -53,7 +53,7 @@ const getLocale = (code) => {
message: config[key],
}
if (placeholders.length > 0) {
locale["placeholders"] = placeholders
locale[`${type}_${key}`]["placeholders"] = placeholders
}
});
}
......@@ -107,7 +107,7 @@ module.exports = {
},
// 生成运行时语言包
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) {
let locales = ALL_LOCALE['detail']
......
......@@ -2,11 +2,10 @@ import VueI18n from 'vue-i18n'
import Vue from 'vue'
import {getMessage as chromiumGetMessage} from "../adapter/chromium/helper"
import {isChromium} from "../helper";
import locales from "./locales/build.js";
Vue.use(VueI18n)
const locales = require('./locales/build.json')
// 区域列表
export const LOCALE_LISTS = locales.lists
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 @@
"ui_views": "View",
"ui_load":"Loading",
"ui_close": "Close",
"ui_copy_text_ok":"Result Copied ^o^",
"ui_copy_image_ok":"Image Copied ^o^",
// views
"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 @@
"ui_setting": "设置",
"ui_views": "查看",
"ui_load":"加载",
"ui_close": "管理",
"ui_close": "关闭",
"ui_copy_text_ok":"结果已复制 ^o^",
"ui_copy_image_ok":"图片已复制 ^o^",
// 界面
"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'
import cache from './tool/cache'
import setting from './tool/setting'
import App from './tool.vue'
import {isUtools,setDisplayMode} from './helper'
import {isUtools,setDisplayMode,isWeb} from './helper'
import {setCurrentLocale,i18n} from "./i18n";
const run = () => {
......@@ -37,8 +37,7 @@ const run = () => {
}
(function () {
if (document.body.clientWidth > 900 || isUtools) {
console.log('调整窗口大小')
if (document.body.clientWidth > 900 || isUtools || isWeb) {
const page = document.getElementById('page')
page.style.width = 'auto'
page.style.height = 'auto'
......
<template>
<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;">
<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]">
......@@ -31,7 +31,7 @@
</template>
</MenuItem>
</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">
<Badge v-if="badgeToolIsShow(tool.name)" dot :offset="[5,-5]">
{{ $t('main_tool_'+tool.name) }}
......
......@@ -53,11 +53,12 @@ const debounceSaveToolDataMethod = _.debounce(function () {
export const plugin = {
install: function (Vue) {
Vue.prototype.$getToolData = function (clipboardField = '') {
Vue.prototype.$getToolData = function (clipboardField = '',clipboardFieldRegex = "") {
let data = history(model.getCurrentTool()).current()
if (clipboardField) {
let inputData = "";
if (fixeInputData) { // 使用固定输入数据
data[clipboardField] = fixeInputData
inputData = fixeInputData
fixeInputData = ""
} else if (setting.autoReadCopy()) {
let paste = clipboard.paste()
......@@ -65,27 +66,42 @@ export const plugin = {
if (setting.autoReadCopyFilter()) {
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
}
Vue.prototype.$saveToolData = function (data) {
debounceSaveToolData = {tool:model.getCurrentTool(),data:_.cloneDeep(data)}
Vue.prototype.$saveToolData = function (data, ignoreDebounce = false) {
if (ignoreDebounce) {
return history(model.getCurrentTool()).push(_.cloneDeep(data))
}
debounceSaveToolData = {tool: model.getCurrentTool(), data: _.cloneDeep(data)}
debounceSaveToolDataMethod()
}
Vue.prototype.$clipboardCopy = function (data, force = false) {
if ((setting.autoSaveCopy() || force) && 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) {
if ((setting.autoSaveCopy() || force) && data) {
clipboard.copyImage(data, () => {
this.$Message.success('图片已复制 ^o^')
this.$Message.success(this.$t('main_ui_copy_image_ok').toString())
})
}
}
......
......@@ -9,7 +9,7 @@
<Row :gutter="10">
<Col span="12">
<Form :label-width="80">
<FormItem label="内容">
<FormItem :label="$t('barcode_content')">
<Input v-model="current.text">
<Select v-model="current.format" slot="append" style="width: 100px">
<Option v-for="type in barcodeFormat" :key="type" :value="type">{{ type }}</Option>
......@@ -18,17 +18,17 @@
</FormItem>
<Row>
<Col span="12">
<FormItem label="背景">
<FormItem :label="$t('barcode_background')">
<ColorPicker recommend v-model="current.background"/>
</FormItem>
</Col>
<Col span="12">
<FormItem label="线条颜色">
<FormItem :label="$t('barcode_line_color')">
<ColorPicker recommend v-model="current.lineColor"/>
</FormItem>
</Col>
</Row>
<FormItem label="条码宽">
<FormItem :label="$t('barcode_bar_width')">
<Row>
<Col span="21">
<Slider v-model="current.width" :min="1" :max="4"></Slider>
......@@ -38,7 +38,7 @@
</Col>
</Row>
</FormItem>
<FormItem label="条码高">
<FormItem :label="$t('barcode_height')">
<Row>
<Col span="21">
<Slider v-model="current.height" :min="10" :max="150"></Slider>
......@@ -48,7 +48,7 @@
</Col>
</Row>
</FormItem>
<FormItem label="外边距">
<FormItem :label="$t('barcode_margin')">
<Row>
<Col span="21">
<Slider v-model="current.margin" :min="0" :max="25"></Slider>
......@@ -62,33 +62,33 @@
</Col>
<Col span="12">
<Form :label-width="80">
<FormItem label="文本显示">
<FormItem :label="$t('barcode_show_text')">
<RadioGroup v-model="current.textPosition" type="button">
<Radio label="close">
<span>隐藏</span>
<span>{{ $t('barcode_hide') }}</span>
</Radio>
<Radio label="top">
<span>上方</span>
<span>{{ $t('barcode_top') }}</span>
</Radio>
<Radio label="bottom">
<span>下方</span>
<span>{{ $t('barcode_bottom') }}</span>
</Radio>
</RadioGroup>
</FormItem>
<FormItem label="水平位置">
<FormItem :label="$t('barcode_text_align')">
<RadioGroup v-model="current.textAlign" type="button">
<Radio :disabled="!showText" label="left">
<span>居左</span>
<span>{{ $t('barcode_left') }}</span>
</Radio>
<Radio :disabled="!showText" label="center">
<span>居中</span>
<span>{{ $t('barcode_center') }}</span>
</Radio>
<Radio :disabled="!showText" label="right">
<span>居右</span>
<span>{{ $t('barcode_right') }}</span>
</Radio>
</RadioGroup>
</FormItem>
<FormItem label="字体">
<FormItem :label="$t('barcode_font')">
<Row :gutter="10">
<Col span="12">
<Select :disabled="!showText" v-model="current.font">
......@@ -98,16 +98,16 @@
<Col span="12">
<CheckboxGroup v-model="current.fontOptions">
<Checkbox :disabled="!showText" label="bold">
<span>粗体</span>
<span>{{ $t('barcode_bold') }}</span>
</Checkbox>
<Checkbox :disabled="!showText" label="italic">
<span>斜体</span>
<span>{{ $t('barcode_italic') }}</span>
</Checkbox>
</CheckboxGroup>
</Col>
</Row>
</FormItem>
<FormItem label="大小">
<FormItem :label="$t('barcode_font_size')">
<Row>
<Col span="22">
<Slider :disabled="!showText" v-model="current.fontSize" :min="8"
......@@ -118,7 +118,7 @@
</Col>
</Row>
</FormItem>
<FormItem label="外边距">
<FormItem :label="$t('barcode_text_margin')">
<Row>
<Col span="22">
<Slider :disabled="!showText" v-model="current.textMargin" :min="-15"
......@@ -190,7 +190,7 @@ export default {
fontSize: this.current.fontSize,
textMargin: this.current.textMargin,
valid: (valid) => {
this.validStr = !valid ? `"${barcodeContent}" 无效的条码内容` : "";
this.validStr = !valid ? `"${barcodeContent}" ${this.$t('barcode_invalid_content').toString()}` : "";
if (!this.validStr && this.current.text) {
this.$saveToolData(this.current)
}
......
<template>
<div>
<Input v-model="current.input" :rows="7" type="textarea" :placeholder="$t('base64_input')"></Input>
<option-block>
<heightResize ignore :append="['.page-option-block']" @resize="resize">
<input-block bottom="0px" right="10px">
<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>
<ButtonGroup>
<Button type="primary" @click="handle('encode')">{{ $t('base64_encode') }}</Button>
......@@ -11,21 +16,27 @@
<FormItem>
<Checkbox v-model="current.isUriSafe">{{ $t('base64_url_safe') }}</Checkbox>
</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>
<Input v-model="current.output" :rows="7" type="textarea" :placeholder="$t('base64_output') "></Input>
</div>
<input-block right="10px">
<pasteClipboardFlie @on-paste-file="handleUpload">
<autoHeightTextarea :height="height2" :value="current.output" :placeholder="$t('base64_output')" />
</pasteClipboardFlie>
</input-block>
</heightResize>
</template>
<script>
import {Base64} from 'js-base64'
import mimeType from 'mime-types'
import moment from "moment";
import pasteClipboardFlie from "./components/pasteClipboardFlie";
import heightResize from "./components/heightResize";
import autoHeightTextarea from "./components/autoHeightTextarea";
export default {
components: {
pasteClipboardFlie,
heightResize,
autoHeightTextarea
},
created() {
this.current = Object.assign(this.current, this.$getToolData('input'))
},
......@@ -65,6 +76,10 @@ export default {
aEle.click();
aEle.remove();
window.URL.revokeObjectURL(objectUrl);
},
resize(height){
this.height1 = Math.min(160,Math.ceil(height/2))
this.height2 = height - this.height1
}
},
data() {
......@@ -75,6 +90,8 @@ export default {
operation: '',
isUriSafe: false,
},
height1:100,
height2:100
}
},
}
......
<template>
<div>
<div style="border: 1px solid #dcdee2; border-radius: 4px">
<code-editor ref="editor" v-model="current.content" :auto-height="220" :language="this.current.lang"></code-editor>
</div>
<option-block>
<heightResize :append="['.page-option-block']">
<code-editor ref="editor" v-model="current.content" :language="this.current.lang"></code-editor>
</heightResize>
<option-block class="page-option-block">
<FormItem>
<ButtonGroup>
<Button
......@@ -16,20 +16,20 @@
</ButtonGroup>
</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>
</Select>
</FormItem>
<FormItem>
<Select placeholder="代码缩进" v-model="current.tab">
<Option :value="2">缩进 Tab 2</Option>
<Option :value="4">缩进 Tab 4</Option>
<Option :value="6">缩进 Tab 6</Option>
<Option :value="8">缩进 Tab 8</Option>
<Select :placeholder="$t('code_indent')" v-model="current.tab">
<Option :value="2">{{ $t('code_indent_width',[2]) }}</Option>
<Option :value="4">{{ $t('code_indent_width',[4]) }}</Option>
<Option :value="6">{{ $t('code_indent_width',[6]) }}</Option>
<Option :value="8">{{ $t('code_indent_width',[8]) }}</Option>
</Select>
</FormItem>
<FormItem>
<Checkbox v-model="current.isCompress">压缩</Checkbox>
<Checkbox v-model="current.isCompress">{{ $t('code_compress') }}</Checkbox>
</FormItem>
</option-block>
</div>
......@@ -37,10 +37,11 @@
<script>
import _ from "lodash";
import codeEditor from "./components/codeEditor";
import heightResize from "./components/heightResize";
export default {
components: {
codeEditor,
heightResize
},
computed: {
buttonLang() {
......@@ -66,11 +67,11 @@ export default {
this.$refs.editor.compress(language);
}
this.$saveToolData(this.current);
return this.$Message.success(`${this.current.isCompress ? "压缩" : "格式化"}完成`);
return this.$Message.success(this.$t('code_complete').toString());
} catch (e) {
console.log(e)
return this.$Modal.error({
title: "格式化错误",
title: this.$t('code_error_prompt').toString(),
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>
<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>
<script>
import {format} from "../library/formatter";
......@@ -15,19 +17,37 @@ export default {
type: String,
default: ""
},
autoHeight: {
type: Number,
default: 0
enableBorder: {
type: Boolean,
default: true
},
placeholder: {
type: String,
default: ""
},
height: {
type: String,
default: "350px"
default: "100%"
},
hideLineNumbers: {
type: Boolean,
default: false
},
width: {
type: String,
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: {
value(newValue) {
if (this.editor !== null && this.editor.getValue() !== newValue) {
......@@ -40,27 +60,25 @@ export default {
}
}
},
created() {
if (this.autoHeight > 0) {
this.containerHeight = (window.innerHeight - this.autoHeight) + "px"
} else {
this.containerHeight = this.height
}
},
mounted() {
this.initEditor()
},
data() {
return {
editor: null,
containerHeight: ""
}
},
methods: {
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.setSize(null, this.containerHeight)
this.editor.on('change', editor => {
if (this.value !== editor.getValue()) {
this.$emit('input', editor.getValue())
......@@ -79,4 +97,12 @@ export default {
}
};
</script>
<style>
.CodeMirror {
height: 100%;
}
.CodeMirror pre.CodeMirror-placeholder {
color: #999;
}
</style>
<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>
<script>
import {createMerge} from "../library/editor";
......@@ -18,13 +18,9 @@ export default {
type: Boolean,
default: false
},
autoHeight: {
type: Number,
default: 0
},
height: {
type: String,
default: "350px"
default: "100%"
},
width: {
type: String,
......@@ -45,20 +41,12 @@ export default {
this.reset()
}
},
created() {
if (this.autoHeight > 0) {
this.containerHeight = (window.innerHeight - this.autoHeight) + "px"
} else {
this.containerHeight = this.height
}
},
mounted() {
this.reset()
},
data() {
return {
editor: null,
containerHeight: ""
}
},
methods: {
......@@ -68,7 +56,6 @@ export default {
},
initEditor() {
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) => {
if (original !== this.value.original || modified !== this.value.modified) {
this.value.original = original
......@@ -82,7 +69,10 @@ export default {
</script>
<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%;
}
</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 @@
<div>
<Row :gutter="16">
<Col span="12">
<Input v-model="current.input" style="margin-bottom: 16px">
<span slot="prepend">表达式</span>
<Input v-model="current.input" style="margin-bottom: 16px" class="page-option-input">
<span slot="prepend">{{ $t('crontab_expression') }}</span>
</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 span="12">
<Col span="12" class="page-option-reference">
<Tabs value="example">
<TabPane label="例子" name="example">
<Table stripe size="small" height="300" :columns="example.columns" :data="example.data"></Table>
<TabPane :label="$t('crontab_example')" name="example">
<heightResize :reduce="52" @resize="resize">
<Table stripe size="small" :height="referenceHeight" border :columns="example.columns" :data="example.data"></Table>
</heightResize>
</TabPane>
<TabPane label="格式" name="format" style="text-align: center">
<img src="../../statics/crontab.png" style="height: 300px" alt="">
<TabPane :label="$t('crontab_format')" name="format" style="text-align: center">
<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 label="特殊字符" name="special">
<TabPane :label="$t('crontab_symbol')" name="special">
<Table stripe size="small" height="300" :columns="special.columns" :data="special.data"></Table>
</TabPane>
</Tabs>
......@@ -24,21 +29,30 @@
</div>
</template>
<script>
import cronstrue from 'cronstrue/i18n';
import parser from 'cron-parser';
import moment from "moment"
export default {
import cronstrue from 'cronstrue/i18n';
import parser from 'cron-parser';
import moment from "moment"
import {getCurrentLocale} from "../../i18n";
import heightResize from "./components/heightResize";
import autoHeightTextarea from "./components/autoHeightTextarea";
export default {
components: {
heightResize,
autoHeightTextarea
},
computed: {
locale() {
return getCurrentLocale()
},
output() {
if (!this.current.input) return "";
let list = [];
try {
list.push(cronstrue.toString(this.current.input, {locale: "zh_CN"}));
list.push("\n最近10次执行时间");
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(`第${i}次: ` + moment(interval.next().toString()).format("YYYY-MM-DD HH:mm:ss"))
list.push(this.$t('crontab_no', [i, moment(interval.next().toString()).format("YYYY-MM-DD HH:mm:ss")]))
}
this.$saveToolData(this.current);
} catch (err) {
......@@ -50,66 +64,81 @@
},
created() {
this.current = Object.assign(this.current, this.$getToolData())
this.example.data = this.example.data.map((item) => {
return {
example: item,
text: this.conversion(item)
}
})
},
methods: {
conversion(input) {
return cronstrue.toString(input, {locale: this.locale})
},
resize(height){
this.referenceHeight = height
}
},
data() {
return {
referenceHeight:101,
current: {
input: "2 */5 * * 2-5",
operation: "check"
},
special: {
columns: [
{title: '特殊字符', key: 'name', width: 100},
{title: '代表意义', key: 'text'},
{title: this.$t('crontab_symbol'), key: 'name', width: 100},
{title: this.$t('crontab_description'), key: 'text'},
],
data: [
{
name: "*(星号)",
text: "代表任何时刻都接受的意思。举例来说,范例一内那个日、月、周都是*,就代表着不论何月、何日的礼拜几的12:00都执行后续命令的意思。"
name: "*",
text: this.$t('crontab_symbol_description_1')
},
{
name: ",(逗号)",
text: "代表分隔时段的意思。举例来说,如果要执行的工作是3:00与6:00时,就会是:0 3,6 * * * command时间还是有五列,不过第二列是 3,6 ,代表3与6都适用"
name: ",",
text: this.$t('crontab_symbol_description_2')
},
{
name: "-(减号)",
text: "代表一段时间范围内,举例来说,8点到12点之间的每小时的20分都进行一项工作:20 8-12 * * * command仔细看到第二列变成8-12.代表 8,9,10,11,12 都适用的意思"
name: "-",
text: this.$t('crontab_symbol_description_3')
},
{
name: "/n(斜线)",
text: "那个n代表数字,即是每隔n单位间隔的意思,例如每五分钟进行一次,则:*/5 * * * * command用*与/5来搭配,也可以写成0-59/5,意思相同"
name: "/n",
text: this.$t('crontab_symbol_description_4')
}
]
},
example: {
columns: [
{title: '例子', key: 'example', width: 120},
{title: '说明', key: 'text'},
{title: this.$t('crontab_example'), key: 'example', width: 120},
{title: this.$t('crontab_description'), key: 'text'},
],
data: [
{example: "*/1 * * * *", text: "每1分钟执行"},
{example: "* * * * *", text: "每1分钟执行"},
{example: "*/5 * * * *", text: "每5分钟执行"},
{example: "0 * * * *", text: "每小时执行"},
{example: "0 */1 * * *", text: "每小时执行"},
{example: "0 7 * * *", text: "每天上午7点执行"},
{example: "10 7 * * *", text: "每天上午7点10分执行"},
{example: "0 0 * * *", text: "每天定时执行一次"},
{example: "0 0 * * 0", text: "每周定时执行一次"},
{example: "0 0 1 * *", text: "每月定时执行一次"},
{example: "0 0 1 1 *", text: "每年定时执行一次"},
{example: "5 * * * *", text: "指定每小时的第5分钟执行一次命令"},
{example: "30 5 * * *", text: "指定每天的 5:30 执行命令"},
{example: "30 7 8 * *", text: "指定每月8号的7:30分执行命令"},
{example: "30 5 8 6 *", text: "指定每年的6月8日5:30执行命令"},
{example: "30 6 * * 0", text: "指定每星期日的6:30执行命令"},
{example: "30 3 10,20 * *", text: "每月10号及20号的3:30执行命令[注:“,”用来连接多个不连续的时段]"},
{example: "25 8-11 * * *", text: "每天8-11点的第25分钟执行命令[注:“-”用来连接连续的时段"},
{example: "*/15 * * * *", text: "每15分钟执行一次命令 [即每个小时的第0 15 30 45 60分钟执行命令]"},
{example: "30 6 */10 * *", text: "每个月中,每隔10天6:30执行一次命令[即每月的1、11、21、31日是的6:30执行一次命令。]"}
"*/1 * * * *",
"* * * * *",
"*/5 * * * *",
"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>
<template>
<div style="padding: 0 70px">
<option-block>
<Input v-model="current.input" placeholder="请输入待转换数字">
<div slot="prepend" style="width: 70px"><strong>转换数字</strong></div>
<Input v-model="current.input" :placeholder="$t('decimalConvert_input_placeholder')">
<div slot="prepend" style="width: 70px"><strong>{{ $t('decimalConvert_input') }}</strong></div>
<Select v-model="current.decimal" slot="append" style="width:100px">
<OptionGroup :label="type.common.name">
<Option v-for="v in type.common.list" :value="v" :key="v">{{ v }} 进制</Option>
<OptionGroup :label="$t('decimalConvert_input_type_common')">
<Option v-for="v in type.common" :value="v" :key="v">{{ $t('decimalConvert_base',[v]) }}</Option>
</OptionGroup>
<OptionGroup :label="type.other.name">
<Option v-for="v in type.other.list" :value="v" :key="v">{{ v }} 进制</Option>
<OptionGroup :label="$t('decimalConvert_input_type_other')">
<Option v-for="v in type.other" :value="v" :key="v">{{ $t('decimalConvert_base',[v]) }}</Option>
</OptionGroup>
</Select>
</Input>
</option-block>
<option-block v-for="n in [1,2,3,4,5,6]" :key="n">
<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">
<OptionGroup :label="type.common.name">
<Option v-for="v in type.common.list" :value="v" :key="v">{{ v }} 进制</Option>
<OptionGroup :label="$t('decimalConvert_input_type_common')">
<Option v-for="v in type.common" :value="v" :key="v">{{ $t('decimalConvert_base',[v]) }}</Option>
</OptionGroup>
<OptionGroup :label="type.other.name">
<Option v-for="v in type.other.list" :value="v" :key="v">{{ v }} 进制</Option>
<OptionGroup :label="$t('decimalConvert_input_type_other')">
<Option v-for="v in type.other" :value="v" :key="v">{{ $t('decimalConvert_base',[v]) }}</Option>
</OptionGroup>
</Select>
</Input>
</option-block>
<option-block>
<Input v-model="current.alphabet">
<div slot="prepend" style="width: 70px">64位字母表</div>
<Button slot="append" @click="current.alphabet=alphabet" :disabled="current.alphabet===alphabet">恢复默认
<div slot="prepend">{{ $t('decimalConvert_alphabet') }}</div>
<Button slot="append" @click="current.alphabet=alphabet" :disabled="current.alphabet===alphabet">
{{ $t('decimalConvert_reset') }}
</Button>
</Input>
</option-block>
......@@ -46,7 +47,7 @@ export default {
watch: {
convert: function (val) {
if (val.alphabet.length !== 64) {
return this.$Message.error("转换字母表必须是64位长度");
return this.$Message.error(this.$t('decimalConvert_alphabet_length_error').toString());
}
if (!val.input) {
return;
......@@ -74,17 +75,11 @@ export default {
},
type() {
let type = {
common: {
name: "常用进制",
list: [2, 8, 10, 16]
},
other: {
name: "其他进制",
list: []
}
common: [2, 8, 10, 16],
other: []
}
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
}
......
<template>
<div>
<div style="border: 1px solid #dcdee2; border-radius: 4px">
<diffEditor ref="editor" :collapse="current.collapse" v-model="current.diff" :language="current.language"
:auto-height="220"/>
<heightResize :append="['.page-option-block']">
<div style="border: 1px solid #dcdee2; border-radius: 4px;height: 100%;">
<diff-editor ref="editor" :collapse="current.collapse" v-model="current.diff" :language="current.language" />
</div>
<option-block>
</heightResize>
<option-block class="page-option-block">
<FormItem>
<ButtonGroup>
<Button
......@@ -17,12 +18,12 @@
</ButtonGroup>
</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>
</Select>
</FormItem>
<FormItem>
<Checkbox v-model="current.collapse">折叠相同</Checkbox>
<Checkbox v-model="current.collapse">{{ $t('diffs_collapse') }}</Checkbox>
</FormItem>
</option-block>
</div>
......@@ -31,6 +32,7 @@
import diffEditor from "./components/diffEditor";
import {allLang} from "./library/editor";
import _ from "lodash";
import heightResize from "./components/heightResize";
const COMMON_LANG = [
"text",
......@@ -46,6 +48,7 @@ const COMMON_LANG = [
export default {
components: {
diffEditor,
heightResize
},
computed: {
allLang() {
......
<template>
<div>
<Input v-model="current.input" :rows="7" type="textarea" placeholder="内容"></Input>
<option-block>
<heightResize ignore :append="['.page-option-block']" @resize="resize">
<autoHeightTextarea v-model="current.input" :height="inputHeight" :placeholder="$t('encrypt_input')"/>
<option-block class="page-option-block">
<FormItem>
<Select v-model="current.type" style="width:200px">
<Option v-for="v in type" :value="v" :key="v">{{ v }}</Option>
</Select>
</FormItem>
<FormItem>
<Input v-model="current.password" placeholder="密码/秘钥"></Input>
<Input v-model="current.password" :placeholder="$t('encrypt_password')"></Input>
</FormItem>
<FormItem v-if="current.type === 'SM2'">
<Select v-model="current.sm2CipherMode" style="width:100px">
......@@ -18,25 +18,35 @@
</FormItem>
<FormItem>
<ButtonGroup>
<Button type="primary" @click="handle('encrypt')">加密</Button>
<Button type="primary" @click="handle('decrypt')">解密</Button>
<Button type="primary" @click="sm2Generate()" v-if="current.type === 'SM2'">生成密钥对</Button>
<Button type="primary" @click="handle('encrypt')">{{ $t('encrypt_encrypt') }}</Button>
<Button type="primary" @click="handle('decrypt')">{{ $t('encrypt_decrypt') }}</Button>
<Button type="primary" @click="sm2Generate()" v-if="current.type === 'SM2'">
{{ $t('encrypt_generate_secret_key') }}
</Button>
</ButtonGroup>
</FormItem>
</option-block>
<Input v-model="current.output" :rows="7" type="textarea" placeholder="结果"></Input>
</div>
<autoHeightTextarea :value="current.output" :height="outputHeight" :placeholder="$t('encrypt_output')"/>
</heightResize>
</template>
<script>
import crypto from "crypto-js"
export default {
import crypto from "crypto-js"
import heightResize from "./components/heightResize";
import autoHeightTextarea from "./components/autoHeightTextarea";
export default {
components: {
heightResize,
autoHeightTextarea
},
created() {
this.current = Object.assign(this.current,this.$getToolData("input"))
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) {
case "AES":
case "DES":
......@@ -48,8 +58,7 @@
this.current.input,
this.current.password
).toString();
}
else{
} else {
this.current.output = crypto[this.current.type].decrypt(
this.current.input,
this.current.password
......@@ -58,14 +67,13 @@
break;
case "SM2":
if (v === "encrypt") {
this.current.output =sm2.doEncrypt(
this.current.output = sm2.doEncrypt(
this.current.input,
this.current.password,
this.current.sm2CipherMode
);
}
else{
this.current.output =sm2.doDecrypt(
} else {
this.current.output = sm2.doDecrypt(
this.current.input,
this.current.password,
this.current.sm2CipherMode
......@@ -75,43 +83,59 @@
default:
return;
}
} catch (e) {
return this.$Message.error(
this.$t('encrypt_failed', [e.message]).toString()
)
}
this.current.operation = v;
this.$clipboardCopy(this.current.output);
this.$saveToolData(this.current);
}
},
sm2Generate(){
sm2Generate() {
const sm2 = require('sm-crypto').sm2
let keypair = sm2.generateKeyPairHex()
let string = "公钥:\n"+keypair.publicKey+"\n"+"私钥:\n"+keypair.privateKey+"\n\n"+
"请及时保存秘钥对, 关闭对话框后无法恢复当前秘钥数据"
let string = [
this.$t('encrypt_public_key'),
keypair.publicKey,
this.$t('encrypt_private_key'),
keypair.privateKey, '',
this.$t('encrypt_secret_key_prompt')
].join("\n");
this.$Modal.info({
render: (h) => {
return h('Input', {
props: {
value: string,
type:"textarea",
rows:9
type: "textarea",
rows: 9
}
})
},
okText:"关闭",
width:600
okText: this.$t('encrypt_close'),
width: 600
})
},
resize(height) {
this.inputHeight = Math.min(160, Math.ceil(height / 2))
this.outputHeight = height - this.inputHeight
}
},
data() {
return {
current:{
current: {
input: "",
password:"",
sm2CipherMode:"C1C3C2",
password: "",
sm2CipherMode: "C1C3C2",
output: "",
type:"AES",
operation:""
type: "AES",
operation: ""
},
type: ["AES","DES","RC4","Rabbit","TripleDes","SM2"],
type: ["AES", "DES", "RC4", "Rabbit", "TripleDes", "SM2"],
inputHeight: 100,
outputHeight: 100
}
},
}
}
</script>
......@@ -2,7 +2,7 @@
<div id="tool-hash">
<Row :gutter="10">
<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>
<Checkbox slot="extra" v-model="current.isUppercase">{{ $t('hash_uppercase') }}</Checkbox>
</input-block>
......
<template>
<div>
<Input v-model="current.input" :rows="7" type="textarea" placeholder="内容"></Input>
<option-block>
<heightResize ignore :append="['.page-option-block']" @resize="resize">
<autoHeightTextarea v-model="current.input" :height="inputHeight" :placeholder="$t('hexString_input')"/>
<option-block class="page-option-block">
<FormItem>
<ButtonGroup>
<Button type="primary" @click="handle('hex')">String -> Hex</Button>
......@@ -9,15 +9,21 @@
</ButtonGroup>
</FormItem>
<FormItem>
<Checkbox v-model="current.isUppercase">大写字母</Checkbox>
<Checkbox v-model="current.isUppercase">{{ $t('hexString_uppercase') }}</Checkbox>
</FormItem>
</option-block>
<Input v-model="current.output" :rows="7" type="textarea" placeholder="结果"></Input>
</div>
<autoHeightTextarea :value="current.output" :height="outputHeight" :placeholder="$t('hexString_output')"/>
</heightResize>
</template>
<script>
import heightResize from "./components/heightResize";
import autoHeightTextarea from "./components/autoHeightTextarea";
export default {
components: {
heightResize,
autoHeightTextarea
},
created() {
this.current = Object.assign(this.current, this.$getToolData("input"))
},
......@@ -42,6 +48,10 @@ export default {
this.$clipboardCopy(this.current.output);
this.$saveToolData(this.current);
}
},
resize(height) {
this.inputHeight = Math.min(160, Math.ceil(height / 2))
this.outputHeight = height - this.inputHeight
}
},
data() {
......@@ -51,7 +61,9 @@ export default {
isUppercase: false,
output: "",
operation: ""
}
},
inputHeight: 100,
outputHeight: 100
}
},
}
......
<template>
<div>
<Input v-model="current.input" :rows="7" type="textarea" placeholder="内容"></Input>
<option-block>
<heightResize ignore :append="['.page-option-block']" @resize="resize">
<autoHeightTextarea v-model="current.input" :height="inputHeight" :placeholder="$t('html_input')"/>
<option-block class="page-option-block">
<FormItem>
<ButtonGroup>
<Button type="primary" @click="handle('encode')">编码</Button>
<Button type="primary" @click="handle('decode')">解密</Button>
<Button type="primary" @click="handle('encode')">{{ $t('html_encode') }}</Button>
<Button type="primary" @click="handle('decode')">{{ $t('html_decode') }}</Button>
</ButtonGroup>
</FormItem>
</option-block>
<Input v-model="current.output" :rows="7" type="textarea" placeholder="结果"></Input>
</div>
<autoHeightTextarea :value="current.output" :height="outputHeight" :placeholder="$t('html_output')"/>
</heightResize>
</template>
<script>
import heightResize from "./components/heightResize";
import autoHeightTextarea from "./components/autoHeightTextarea";
export default {
components: {
heightResize,
autoHeightTextarea
},
created() {
this.current = Object.assign(this.current, this.$getToolData("input"))
},
......@@ -30,6 +36,10 @@ export default {
this.$clipboardCopy(this.current.output);
this.$saveToolData(this.current);
}
},
resize(height) {
this.inputHeight = Math.min(160, Math.ceil(height / 2))
this.outputHeight = height - this.inputHeight
}
},
data() {
......@@ -38,7 +48,9 @@ export default {
input: "",
output: "",
operation: ""
}
},
inputHeight: 100,
outputHeight: 100
}
},
}
......
<template>
<div>
<option-block>
<option-block class="page-option-block" style="padding: 0 0 0 5px">
<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>
<ButtonGroup>
<Button type="primary" @click="handle()">查询</Button>
<Button type="primary" @click="local()">本地IP</Button>
<Button type="primary" @click="handle()">{{ $t('ip_query') }}</Button>
<Button type="primary" @click="local()">{{ $t('ip_local') }}</Button>
</ButtonGroup>
</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>
</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>
</div>
</heightResize>
</div>
</template>
<script>
import axios from "axios"
import _ from "lodash"
import codeEditor from "./components/codeEditor";
import jsonFormatter from "./library/formatter/json";
import heightResize from "./components/heightResize";
export default {
components: {
codeEditor,
heightResize
},
created() {
this.current = Object.assign(this.current, this.$getToolData("input"))
......@@ -38,11 +41,13 @@ export default {
url: 'https://get.geojs.io/v1/ip/geo.json',
params: this.current.input !== "localhost" ? {ip: this.current.input} : {}
}).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.$Message.success("查询成功")
this.$Message.success(this.$t('ip_ok').toString())
}).catch((error) => {
return this.$Message.error("ip地址信息查询错误:" + error);
return this.$Message.error(
this.$t('ip_error', [error.message]).toString()
)
});
}
},
......
<template>
<div>
<div style="border: 1px solid #dcdee2;border-radius: 4px;">
<code-editor v-model="current.content" :auto-height="220" language="json"></code-editor>
</div>
<option-block :style="{textAlign:'center'}">
<heightResize :append="['.page-option-block']">
<code-editor :placeholder="$t('json_input')" v-model="current.content" language="json"></code-editor>
</heightResize>
<option-block center class="page-option-block">
<FormItem>
<ButtonGroup class="tool-json-button">
<Button type="primary" @click="handle(k)" v-for="(v,k) in type" :key="k">{{ v }}</Button>
......@@ -14,45 +14,40 @@
</template>
<script>
import Unicode from "./library/unicode"
import {jsonFormatter} from "./library/formatter"
import jsonFormatter from "./library/formatter/json"
import codeEditor from "./components/codeEditor";
import heightResize from "./components/heightResize";
export default {
components: {
codeEditor,
heightResize
},
created() {
this.current = Object.assign(this.current, this.$getToolData('content'))
},
methods: {
handle(v) {
if (this.current.content) {
// 保存操作前数据
this.$saveToolData(this.current)
switch (v) {
case 'format':
try {
let content = this.current.content.trim()
if (!content) {
return this.$Notice.error({title: '错误提示', desc: '请输入内容'})
if (!this.current.content.trim()) {
throw new Error(this.$t('json_content_empty').toString())
}
require('jsonlint').parse(content)
this.current.content = jsonFormatter(content)
} catch (error) {
this.$Notice.error({
title: '错误提示',
desc: error.message,
})
return
// 保存操作前数据
this.$saveToolData(this.current, true)
this.operation(v)
this.$clipboardCopy(this.current.content)
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':
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, '')
}
this.current.content = jsonFormatter.compress(this.current.content)
break
case 'escape':
this.current.content = this.current.content.trim().replace(/\\/g, '\\\\').replace(/"/g, '\\"')
......@@ -61,45 +56,21 @@ export default {
this.current.content = this.current.content.trim().replace(/\\\\/g, '\\').replace(/\\"/g, '"')
break
case 'unicode2zh':
this.current.content = this.unicode2zh()
this.current.content = this.unicode2zh(this.current.content)
break
case 'zh2unicode':
this.current.content = this.zh2unicode()
this.current.content = this.zh2unicode(this.current.content)
break
case 'get':
try {
let content = this.current.content.trim()
if (!content) {
return
}
require('jsonlint').parse(content)
require('jsonlint').parse(this.current.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'}))
this.current.content = jsonFormatter.beautify(
JSON.stringify(require('query-string').parse(this.current.content.trim(), {arrayFormat: 'bracket'}))
)
} catch (error) {
this.$Notice.error({
title: '错误提示',
desc: error.message,
})
return
}
break
case 'clear':
this.current.content = ''
......@@ -107,20 +78,16 @@ export default {
default:
return
}
this.$clipboardCopy(this.current.content)
this.$saveToolData(this.current)
}
},
unicode2zh() {
unicode2zh(content) {
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
return item.replace("\\U", "\\u");
})
)
},
zh2unicode() {
let content = this.current.content
zh2unicode(content) {
if (content) {
let newStr = ''
for (let i = 0; i < content.length; i++) {
......@@ -138,22 +105,22 @@ export default {
content: '',
},
type: {
'format': '格式化',
'compress': '压缩',
'escape': '转义',
'clearEscape': '去除转义',
'unicode2zh': 'Unicode转中文',
'zh2unicode': '中文转Unicode',
'get': '转GET',
'getToJson': 'GET转Json',
'clear': '清空',
'format': this.$t('json_format'),
'compress': this.$t('json_compress'),
'escape': this.$t('json_escape'),
'clearEscape': this.$t('json_clear_escape'),
'unicode2zh': this.$t('json_unicode_to_zh'),
'zh2unicode': this.$t('json_zh_to_unicode'),
'get': this.$t('json_to_get'),
'getToJson': this.$t('json_get_to_json'),
'clear': this.$t('json_clear'),
},
}
},
}
</script>
<style scoped>
.tool-json-button .ivu-btn{
.tool-json-button .ivu-btn {
padding: 0 10px;
}
</style>
<template>
<Row :gutter="10">
<Col span="10">
<Card :padding="0">
<p slot="title">JSON内容</p>
<code-editor v-model="current.json" :auto-height="330" language="json"></code-editor>
</Card>
<option-block>
<FormItem>
<div class="page-option-block">
<option-block style="padding: 0 0">
<Input v-model="current.package">
<div slot="prepend">namespace/package</div>
</Input>
</FormItem>
</option-block>
<option-block>
<FormItem>
<Input v-model="current.class">
<div slot="prepend">class/struct</div>
</Input>
</FormItem>
</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 span="14">
<Card :padding="0">
<p slot="title">转换结果</p>
<input-block top="10px" right="10px">
<heightResize>
<code-editor :placeholder="$t('jsonToObject_output')" :value="output" :language="languages[current.type]"/>
</heightResize>
<template slot="extra">
<Button style="margin-right: 5px" size="small" v-for="(item,key) in type" :key="key" type="primary"
@click="handle(item)">{{ item }}
</Button>
<RadioGroup v-model="current.type" type="button" button-style="solid">
<Radio :label="type" v-for="(type) in types" :key="type">
<span>{{ type }}</span>
</Radio>
</RadioGroup>
</template>
<code-editor v-model="current.output" :auto-height="220" :language="languages[current.type]"></code-editor>
</Card>
</input-block>
</Col>
</Row>
</template>
<script>
import codeEditor from "./components/codeEditor";
import json2Go from './library/json2Go'
import jsonFormatter from './library/formatter/json'
import json2CSharp from './library/json2CSharp'
import json2Java from './library/json2Java'
import json2Dart from './library/json2Dart'
import heightResize from "./components/heightResize";
export default {
components: {
codeEditor,
heightResize
},
created() {
this.current = Object.assign(this.current, this.$getToolData())
},
methods: {
handle(type) {
try {
require('jsonlint').parse(this.current.json)
if (!this.type.includes(type)) {
throw new Error("转换类型错误")
computed: {
output() {
if (!this.current.input.trim()) {
return "";
}
this.current.type = type;
switch (type) {
try {
let result = "";
require('jsonlint').parse(this.current.input)
switch (this.current.type) {
case "Go":
this.current.output = json2Go(this.current.json, this.current.class, this.current.package).go
break;
result = json2Go(this.current.input, this.current.class, this.current.package).go
break
case "Java":
this.current.output = json2Java(JSON.parse(this.current.json), this.current.class, this.current.package)
break;
result = json2Java(JSON.parse(this.current.input), this.current.class, this.current.package)
break
case "Dart":
this.current.output = json2Dart(JSON.parse(this.current.json), this.current.class)
break;
result = json2Dart(JSON.parse(this.current.input), this.current.class)
break
case "C#":
this.current.output = json2CSharp.convert(JSON.parse(this.current.json), this.current.class, this.current.package)
break;
result = json2CSharp.convert(JSON.parse(this.current.input), this.current.class, this.current.package)
break
default:
throw new Error(this.$t('jsonToObject_type_error').toString())
}
this.$saveToolData(this.current)
return result;
} catch (error) {
this.$Notice.error({
title: '错误提示',
desc: error.message,
})
return
return this.$t('jsonToObject_error', [error.message]).toString()
}
},
types(){
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() {
return {
current: {
json: "",
input: "",
type: "Java",
package: "pag",
class: "RootName",
output: "",
},
type: ["Java", "C#", "Go",'Dart'],
languages: {
"Java": "java",
"Dart": "dart",
......
<template>
<div>
<Input v-model="current.input" :rows="7" type="textarea" placeholder="内容"></Input>
<option-block>
<FormItem>
<ButtonGroup>
<Button type="primary" @click="handle('decode')">解码</Button>
</ButtonGroup>
</FormItem>
<FormItem>
<heightResize @resize="resize">
<Row :gutter="10">
<Col span="12">
<input-block top="4px">
<code-editor :height="editorheight" :placeholder="$t('jwt_input')" hideLineNumbers v-model="current.input"></code-editor>
<template slot="extra">
<Checkbox v-model="current.header">header</Checkbox>
<Checkbox v-model="current.payload">payload</Checkbox>
</FormItem>
</option-block>
<Input v-model="current.output" :rows="7" type="textarea" placeholder="结果"></Input>
</div>
</template>
</input-block>
</Col>
<Col span="12">
<code-editor :height="editorheight" :placeholder="$t('jwt_output')" :value="output" language="json"></code-editor>
</Col>
</Row>
</heightResize>
</template>
<script>
import jwtDecode from "jwt-decode"
import codeEditor from "./components/codeEditor";
import jsonFormatter from "./library/formatter/json";
import heightResize from "./components/heightResize";
export default {
components: {
codeEditor,
heightResize
},
created() {
this.current = Object.assign(this.current, this.$getToolData("input"))
},
methods: {
handle(v) {
if (this.current.input) {
computed: {
output() {
if(!this.current.input.trim()){
return ""
}
try {
let data = {};
if (this.current.header) {
......@@ -33,29 +43,28 @@ export default {
if (this.current.payload) {
data.payload = jwtDecode(this.current.input)
}
this.current.output = JSON.stringify(
this.$saveToolData(this.current);
return jsonFormatter.objectBeautify(
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)
return this.$t('jwt_decode_fail',[e.message])
}
}
},
methods:{
resize(height){
this.editorheight = height+"px"
}
},
data() {
return {
current: {
input: "",
output: "",
header: false,
payload: true,
operation: ""
}
},
editorheight:"100%",
}
},
}
......
......@@ -7,6 +7,7 @@ import "codemirror/addon/fold/comment-fold";
import "codemirror/addon/fold/foldgutter.css";
import 'codemirror/addon/merge/merge'
import 'codemirror/addon/merge/merge.css'
import "codemirror/addon/display/placeholder";
import "codemirror/mode/javascript/javascript.js";
import "codemirror/mode/htmlmixed/htmlmixed.js";
import "codemirror/mode/css/css.js";
......@@ -103,12 +104,6 @@ export const createMerge = (data, container, lang, option = {}) => {
editor.right.orig.setValue(modified)
}
}
editor['customSetSize'] = (width, height) => {
editor.edit.setSize(width, height)
editor.right.orig.setSize(width, height)
}
editor['customChange'] = (callback) => {
editor.edit.on('change', () => {
callback && callback(editor.edit.getValue(), editor.right.orig.getValue())
......
......@@ -45,9 +45,5 @@ export const format = (code, lang, isCompress = false, options = {}) => {
return methods[lang][method](code,options)
};
export const jsonFormatter = (code) => {
return format(code, 'json')
}
export default format
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
export const compress = (code, options = {}) => {
try {
return JSON.stringify(JSON.parse(code.trim()), null, 0)
} catch (e) {
return code.replace(/\n/g, '').replace(/\r/g, '')
}
}
export default {
beautify, compress
beautify, compress,objectBeautify
}
......@@ -40,7 +40,7 @@ class serializeConversion {
break;
}
} catch (e) {
throw new Error("源数据转换异常:" + e.message);
throw new Error("source error:" + e.message);
}
}
......@@ -64,7 +64,7 @@ class serializeConversion {
return this.getProperties();
}
} catch (e) {
throw new Error("目标数据转换错误:" + e.message);
throw new Error("target error:" + e.message);
}
}
......
......@@ -40,6 +40,9 @@ class TextHandle {
// 行首大写
upperLineStart() {
return this.text.split(/\r?\n/).map((str) => {
if (str.length < 1){
return "";
}
return str[0].toUpperCase() + str.substr(1)
}).join("\n");
}
......@@ -47,6 +50,9 @@ class TextHandle {
// 行首小写
lowerLineStart() {
return this.text.split(/\r?\n/).map((str) => {
if (str.length < 1){
return "";
}
return str[0].toLowerCase() + str.substr(1)
}).join("\n");
}
......@@ -77,7 +83,7 @@ class TextHandle {
replace(search = [], replace = []) {
let text = this.text;
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] : ""));
}
}
......
......@@ -21,7 +21,7 @@ export default {
try {
return callback && callback()
} catch (e) {
throw new Error(`${item} 解码异常:${e.message}`)
throw new Error(`${item} decode error:${e.message}`)
}
}
......@@ -55,7 +55,7 @@ export default {
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) {
let code = []
......@@ -97,7 +97,7 @@ export default {
code.push(`\\${hexRepairStr}`);
break;
default:
throw new Error("编码类型异常")
throw new Error("encode type error")
}
}
return code.join("");
......
此差异已折叠。
<template>
<div>
<Input v-model="current.input" :rows="7" type="textarea" placeholder="内容"></Input>
<option-block>
<heightResize :append="['.page-option-block']" ignore @resize="resize">
<autoHeightTextarea :height="inputHeight" v-model="current.input" :placeholder="$t('pinyin_input')" />
<option-block class="page-option-block">
<FormItem>
<ButtonGroup>
<Button type="primary" @click="handle('normal')">无声调</Button>
<Button type="primary" @click="handle('tone')">有声调</Button>
<Button type="primary" @click="handle('abbr')">首字母</Button>
</ButtonGroup>
<RadioGroup v-model="current.operation" type="button" button-style="solid">
<Radio label="normal">{{ $t('pinyin_normal') }}</Radio>
<Radio label="tone">{{ $t('pinyin_tone') }}</Radio>
<Radio label="abbr">{{ $t('pinyin_abbr') }}</Radio>
</RadioGroup>
</FormItem>
<FormItem>
<Select v-model="current.delimiter" style="width:200px">
......@@ -15,14 +15,16 @@
</Select>
</FormItem>
</option-block>
<Input v-model="current.output" :rows="7" type="textarea" placeholder="结果"></Input>
</div>
<autoHeightTextarea :height="outputHeight" :value="output" :placeholder="$t('pinyin_output')" />
</heightResize>
</template>
<script>
import "./pinyin/dict"
import "ipinyinjs"
import "./pinyin/dict"
import "ipinyinjs"
import heightResize from "./components/heightResize";
import autoHeightTextarea from "./components/autoHeightTextarea";
function py (type, str, delimiter) {
function py(type, str, delimiter) {
let pinyin = {
abbr: function (str, delimiter) {
return window.pinyinUtil.getFirstLetter(str).split('').join(delimiter);
......@@ -39,41 +41,54 @@
str[i] = pinyin[type](str[i], delimiter);
}
return str.join("\n");
}
export default {
}
export default {
components:{
heightResize,
autoHeightTextarea
},
created() {
this.current = Object.assign({},this.current,this.$getToolData("input"))
this.current = Object.assign({}, this.current, this.$getToolData("input"))
},
methods: {
handle(v) {
if (this.current.input) {
this.current.output = py(
v,
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.current.operation = v;
this.$clipboardCopy(this.current.output);
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:{
current: {
input: "",
output: "",
delimiter:"null",
operation:""
delimiter: "null",
operation: "normal"
},
delimiter:[
{"n":"无分隔符","v":"null"},
{"n":"空格分隔","v":"blank"},
{"n":"'-'中划线分隔","v":"-"},
{"n":"'_'下划线分隔","v":"_"},
{"n":"'.'点分隔","v":"."}
]
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>
<div>
<Tabs v-model="current.operation">
<TabPane label="二维码生成" name="generate">
<TabPane :label="$t('qrCode_generate_title')" name="generate">
<Row :gutter="16">
<Col span="14">
<Input v-model="current.generateInput" :rows="14" type="textarea" placeholder="内容"></Input>
<option-block>
<FormItem>
<Button type="primary" @click="generate()">生成</Button>
</FormItem>
</option-block>
<Input v-model="current.generateInput" :rows="14" type="textarea" :placeholder="$t('qrCode_generate_input')"></Input>
</Col>
<Col span="10">
<div style="text-align: center" v-html="current.generateOutput"></div>
<div style="text-align: center" v-html="generateOutput"></div>
</Col>
</Row>
</TabPane>
<TabPane label="二维码解析" name="reader">
<TabPane :label="$t('qrCode_reader_title')" name="reader">
<Row :gutter="16">
<Col span="14">
<Input v-model="current.readerInput" :rows="5" type="textarea" placeholder="请输入二维码图片地址或点击下方按钮上传图片"></Input>
<option-block>
<FormItem>
<Button type="primary" @click="reader()">解析</Button>
</FormItem>
<FormItem>
<Upload action="#" :before-upload="handleUpload">
<Button icon="ios-cloud-upload-outline">上传图片</Button>
<input-block style="margin-bottom: 10px" bottom="0px" right="10px">
<pasteClipboardFlie @on-paste-image="handleUpload">
<Input v-model="current.readerInput" :rows="3" type="textarea" :placeholder="$t('qrCode_reader_input')"></Input>
</pasteClipboardFlie>
<Upload slot="extra" action="#" :before-upload="handleUpload">
<Button size="small" type="primary" icon="ios-cloud-upload-outline">{{ $t('qrCode_reader_upload') }}</Button>
</Upload>
</FormItem>
</option-block>
<Input v-model="current.readerOutput" :rows="5" type="textarea" placeholder="解析结果"></Input>
</input-block>
<Input v-model="readerOutput" :rows="8" type="textarea" :placeholder="$t('qrCode_reader_output')"></Input>
</Col>
<Col span="10" style="text-align: center" v-html="readerInputImg"></Col>
</Row>
</TabPane>
</Tabs>
</div>
</template>
<script>
import generator from 'qrcode'
import qrcodeParser from 'qrcode-parser'
import model from '../../tool/model'
import generator from 'qrcode'
import qrcodeParser from 'qrcode-parser'
import model from '../../tool/model'
import Jimp from 'jimp';
import pasteClipboardFlie from './components/pasteClipboardFlie';
export default {
export default {
components: {
pasteClipboardFlie,
},
computed: {
readerInputImg () {
readerInputImg() {
if (this.current.readerInput) {
return `<img style="width:300px" src="${this.current.readerInput}" />`
}
return ''
}
},
watch: {
"current.generateInput"() {
this.generate()
},
"current.readerInput"() {
this.reader()
}
},
created () {
created() {
let feature = model.getToolCurrentFeature('generate')
if(feature === 'generate'){
if (feature === 'generate') {
this.current = Object.assign(this.current, this.$getToolData('generateInput'))
this.current.operation = feature;
}
else if(feature === 'reader'){
} else if (feature === 'reader') {
this.current = Object.assign(this.current, this.$getToolData('readerInput'))
this.current.operation = feature;
}
else{
} else {
this.current = Object.assign(this.current, this.$getToolData())
}
},
methods: {
generate () {
if (!this.current.generateInput) return
this.generateHandle(this.current.generateInput)
generate() {
if (!this.current.generateInput) {
this.generateOutput = "";
return;
}
generator.toDataURL(this.current.generateInput, (error, url) => {
if (error) {
this.generateOutput = this.$t("qrCode_generate_error", [error]);
return;
}
this.$clipboardCopyImages(url)
this.generateOutput = `<img style="width:300px" src="${url}" />`
this.$saveToolData(this.current)
})
},
reader () {
reader() {
if (!this.current.readerInput) {
this.readerOutput = "";
return
}
qrcodeParser(this.current.readerInput).then((c) => {
this.current.readerOutput = c.data
this.getReaderImagePngBase64(this.current.readerInput).then((result) => {
this.readerOutput = result
this.$saveToolData(this.current)
this.$Message.success('解析成功')
}).catch(() => {
return this.$Message.error('图片解析错误')
}).catch(e => {
this.readerOutput = this.$t('qrCode_reader_error', [e.message])
})
},
generateHandle (str) {
generator.toDataURL(str, (error, url) => {
if (error) return this.$Message.error('二维码生成错误:' + error)
this.$clipboardCopyImages(url)
this.current.generateOutput = `<img style="width:300px" src="${url}" />`
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) {
handleUpload(file) {
if (this.current.operation !== "reader"){
return;
}
let r = new FileReader()
r.readAsDataURL(file)
r.onloadend = () => {
this.current.readerInput = r.result
this.reader()
}
return false
}
},
substr (str) {
str = str.replace(/[\r\n]/g, '').trim()
const strLength = 100
return str.length > strLength ? str.substr(0, strLength) + '...' : str
},
},
data () {
data() {
return {
readerOutput: "",
generateOutput: "",
current: {
generateInput: '',
generateOutput: '',
readerInput: '',
readerOutput: '',
operation: 'generate',
},
}
},
}
}
</script>
<template>
<div>
<div class="page-option-block">
<Row :gutter="16">
<Col span="8">
<Input v-model="current.length">
<div slot="prepend" style="width: 70px">长度</div>
<Input v-model="current.length" type="number">
<div slot="prepend" style="width: 70px">{{ $t('randomString_length') }}</div>
</Input>
</Col>
<Col span="8">
<Input v-model="current.amount">
<div slot="prepend" style="width: 70px">生成数量</div>
<Input v-model="current.amount" type="number">
<div slot="prepend" style="width: 70px">{{ $t('randomString_amount') }}</div>
</Input>
</Col>
<Col span="8">
<Input v-model="current.delimiter">
<div slot="prepend" style="width: 70px">分隔符</div>
<div slot="prepend" style="width: 70px">{{ $t('randomString_delimiter') }}</div>
</Input>
</Col>
</Row>
<option-block>
<FormItem>
<Checkbox v-model="current.isDigital">数字</Checkbox>
<Checkbox v-model="current.isDigital">{{ $t('randomString_digital') }}</Checkbox>
</FormItem>
<FormItem>
<Checkbox v-model="current.isLowercase">小写字母</Checkbox>
<Checkbox v-model="current.isLowercase">{{ $t('randomString_lowercase') }}</Checkbox>
</FormItem>
<FormItem>
<Checkbox v-model="current.isUppercase">大写字母</Checkbox>
<Checkbox v-model="current.isUppercase">{{ $t('randomString_uppercase') }}</Checkbox>
</FormItem>
<FormItem>
<Checkbox v-model="current.isSymbol">特殊符号</Checkbox>
<Checkbox v-model="current.isSymbol">{{ $t('randomString_symbol') }}</Checkbox>
</FormItem>
<FormItem>
<Checkbox v-model="current.isUnique">唯一</Checkbox>
<Checkbox v-model="current.isUnique">{{ $t('randomString_unique') }}</Checkbox>
</FormItem>
<FormItem>
<Checkbox v-model="current.isAddQuote">添加引号</Checkbox>
<Checkbox v-model="current.isAddQuote">{{ $t('randomString_add_quote') }}</Checkbox>
</FormItem>
<FormItem>
<Button type="primary" @click="handle()">生成</Button>
<Button type="primary" @click="handle()">{{ $t('randomString_generate') }}</Button>
</FormItem>
</option-block>
<Input v-model="current.output" :rows="12" type="textarea" placeholder="结果"></Input>
</div>
<heightResize :append="['.page-option-block']">
<autoHeightTextarea :value="current.output" :placeholder="$t('randomString_output')" />
</heightResize>
</div>
</template>
<script>
export default {
import heightResize from "./components/heightResize";
import autoHeightTextarea from "./components/autoHeightTextarea";
export default {
components:{
heightResize,
autoHeightTextarea
},
created() {
this.current = Object.assign(this.current,this.$getToolData())
this.current = Object.assign(this.current, this.$getToolData())
},
mounted() {
if (!this.current.output){
this.handle()
}
},
methods: {
handle() {
......@@ -55,7 +70,6 @@
if (this.current.isLowercase) chars += "abcdefghijklmnopqrstuvwxyz";
if (this.current.isUppercase) chars += "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
if (this.current.isSymbol) chars += "`~!@#$%^&*()-_=+[{]}|;:',<.>/?";
let randomStringLists = [];
for (let i = 0, l = this.current.amount; i < l; i++) {
let _chars = chars.split(""),
......@@ -74,19 +88,19 @@
},
data() {
return {
current:{
length:8,
amount:10,
delimiter:",\\n",
isDigital:true,
isLowercase:true,
isUppercase:true,
isSymbol:false,
isUnique:false,
isAddQuote:false,
current: {
length: 8,
amount: 10,
delimiter: ",\\n",
isDigital: true,
isLowercase: true,
isUppercase: true,
isSymbol: false,
isUnique: true,
isAddQuote: false,
output: "",
}
}
},
}
}
</script>
此差异已折叠。
<template>
<div>
<Input v-model="current.input" :rows="7" type="textarea" placeholder="内容"></Input>
<option-block>
<FormItem>
<Select v-model="current.source" style="width:200px">
<Option v-for="v in type" :value="v" :key="v">源数据:{{ v }}</Option>
<Row :gutter="10">
<Col span="12">
<input-block top="10px" right="15px">
<heightResize>
<code-editor v-model="current.input" :placeholder="$t('serializeConversion_input')"
:language="language[current.source]"/>
</heightResize>
<template slot="extra">
<Select v-model="current.source" style="width:100px">
<Option v-for="v in type" :value="v" :key="v">{{ v }}</Option>
</Select>
</FormItem>
<FormItem>
<Select v-model="current.target" style="width:200px">
<Option v-for="v in type" :value="v" :key="v">目标数据:{{ v }}</Option>
</template>
</input-block>
</Col>
<Col span="12">
<input-block top="10px" right="15px">
<heightResize>
<code-editor :value="output" :placeholder="$t('serializeConversion_output')" :language="language[current.target]"/>
</heightResize>
<template slot="extra">
<Select v-model="current.target" style="width:100px">
<Option v-for="v in type" :value="v" :key="v">{{ v }}</Option>
</Select>
</FormItem>
<FormItem>
<ButtonGroup>
<Button type="primary" @click="handle()">转换</Button>
</ButtonGroup>
</FormItem>
</option-block>
<Input v-model="current.output" :rows="7" type="textarea" placeholder="结果"></Input>
</div>
</template>
</input-block>
</Col>
</Row>
</template>
<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 {
components: {
codeEditor,
heightResize
},
created() {
this.current = Object.assign(this.current, this.$getToolData("input"))
},
methods: {
handle() {
computed: {
output() {
let result = "";
if (this.current.input) {
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) {
this.$Message.error(e.message);
return;
result = this.$t('serializeConversion_error', [e.message])
}
this.$clipboardCopy(this.current.output);
this.$saveToolData(this.current);
}
return result;
}
},
data() {
......@@ -51,6 +63,14 @@ export default {
target: "xml"
},
type: conversionType,
language: {
json: "json",
xml: "xml",
yaml: "yaml",
phpArray: "php",
phpSerialize: "text",
properties: "text",
}
}
},
}
......
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册