mirror of https://gitee.com/xiaonuobase/snowy
				
				
				
			【更新】优化前端代码,更改模块坞名称、删除无用的工具类、操作日志增加IP跟IP地址显示、修复文件上传组件
							parent
							
								
									2573c7a1ed
								
							
						
					
					
						commit
						9c0a63b9fd
					
				| 
						 | 
				
			
			@ -36,6 +36,7 @@
 | 
			
		|||
	import tool from '@/utils/tool'
 | 
			
		||||
	import sysConfig from '@/config/index'
 | 
			
		||||
	const fileList = ref([])
 | 
			
		||||
	const emit = defineEmits({ uploadDone: null })
 | 
			
		||||
	const headers = ref({
 | 
			
		||||
		token: tool.data.get('TOKEN')
 | 
			
		||||
	})
 | 
			
		||||
| 
						 | 
				
			
			@ -45,12 +46,6 @@
 | 
			
		|||
			default: '/dev/file/uploadDynamicReturnUrl',
 | 
			
		||||
			required: false
 | 
			
		||||
		},
 | 
			
		||||
		// 允许多个
 | 
			
		||||
		allowMultiple: {
 | 
			
		||||
			type: Boolean,
 | 
			
		||||
			default: false,
 | 
			
		||||
			required: false
 | 
			
		||||
		},
 | 
			
		||||
		// 上传方式 defaults || drag
 | 
			
		||||
		uploadMode: {
 | 
			
		||||
			type: String,
 | 
			
		||||
| 
						 | 
				
			
			@ -66,22 +61,16 @@
 | 
			
		|||
	})
 | 
			
		||||
	const action = sysConfig.API_URL + props.action
 | 
			
		||||
 | 
			
		||||
	const handleChange = () => {}
 | 
			
		||||
 | 
			
		||||
	// 获取上传的内容
 | 
			
		||||
	const getUploadData = () => {
 | 
			
		||||
		return fileList.value.map((item) => {
 | 
			
		||||
			return {
 | 
			
		||||
				uid: item.uid,
 | 
			
		||||
				name: item.name,
 | 
			
		||||
				status: item.status,
 | 
			
		||||
				url: item.response.data
 | 
			
		||||
	const handleChange = () => {
 | 
			
		||||
		let result = []
 | 
			
		||||
		for (let a = 0; a < props.uploadMumber; a++) {
 | 
			
		||||
			const file = fileList.value[a]
 | 
			
		||||
			if (file.status === 'done' && file.response && file.response.code === 200) {
 | 
			
		||||
				result.push(file.response.data)
 | 
			
		||||
			}
 | 
			
		||||
		})
 | 
			
		||||
		}
 | 
			
		||||
		if (result.length > 0) {
 | 
			
		||||
			emit('uploadDone', result)
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	defineExpose({
 | 
			
		||||
		getUploadData
 | 
			
		||||
	})
 | 
			
		||||
</script>
 | 
			
		||||
 | 
			
		||||
<style scoped></style>
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -36,7 +36,7 @@ const DEFAULT_CONFIG = {
 | 
			
		|||
	// 菜单是否折叠
 | 
			
		||||
	SNOWY_MENU_COLLAPSE: false,
 | 
			
		||||
 | 
			
		||||
	// 目录坞
 | 
			
		||||
	// 模块坞
 | 
			
		||||
	SNOWY_MODULE_UNFOLD_OPEN: true,
 | 
			
		||||
 | 
			
		||||
	// 是否开启多标签
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -55,7 +55,7 @@
 | 
			
		|||
			</div>
 | 
			
		||||
			<a-divider />
 | 
			
		||||
			<a-form ref="form" style="text-align: right">
 | 
			
		||||
				<a-form-item label="目录坞">
 | 
			
		||||
				<a-form-item label="模块坞">
 | 
			
		||||
					<a-switch v-model:checked="moduleUnfoldOpen" />
 | 
			
		||||
				</a-form-item>
 | 
			
		||||
				<a-form-item label="面包屑">
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -484,9 +484,11 @@
 | 
			
		|||
					: header.classList.remove('snowy-header-primary-color')
 | 
			
		||||
				// 判断是否开启了通栏
 | 
			
		||||
				const headerLogin = document.getElementById('snowyHeaderLogo')
 | 
			
		||||
				this.topHanderThemeColorSpread
 | 
			
		||||
					? headerLogin.classList.add('snowy-header-logo-primary-color')
 | 
			
		||||
					: headerLogin.classList.remove('snowy-header-logo-primary-color')
 | 
			
		||||
				try{
 | 
			
		||||
					this.topHanderThemeColorSpread
 | 
			
		||||
						? headerLogin.classList.add('snowy-header-logo-primary-color')
 | 
			
		||||
						: headerLogin.classList.remove('snowy-header-logo-primary-color')
 | 
			
		||||
				}catch (e) { }
 | 
			
		||||
				// 如果是双排菜单,吧第二排的也给渲染了
 | 
			
		||||
				if (this.layout === 'doublerow') {
 | 
			
		||||
					const snowyDoublerowSideTop = document.getElementById('snowyDoublerowSideTop')
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -14,7 +14,7 @@ import enGB from 'ant-design-vue/es/locale/en_GB'
 | 
			
		|||
import zh_cn from './lang/zh-cn.js'
 | 
			
		||||
import en from './lang/en.js'
 | 
			
		||||
import tool from '@/utils/tool'
 | 
			
		||||
import sysConfig from '@/config/index.js'
 | 
			
		||||
import sysConfig from '@/config/index'
 | 
			
		||||
 | 
			
		||||
export const messages = {
 | 
			
		||||
	'zh-cn': {
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -44,7 +44,7 @@ export default {
 | 
			
		|||
		// 顶栏主题色通栏
 | 
			
		||||
		topHanderThemeColorSpread:
 | 
			
		||||
			getCacheConfig('SNOWY_TOP_HANDER_THEME_COLOR_SPREAD'),
 | 
			
		||||
		// 目录坞
 | 
			
		||||
		// 模块坞
 | 
			
		||||
		moduleUnfoldOpen: getCacheConfig('SNOWY_MODULE_UNFOLD_OPEN'),
 | 
			
		||||
		// 主题
 | 
			
		||||
		theme: getCacheConfig('SNOWY_THEME'),
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1,156 +0,0 @@
 | 
			
		|||
/**
 | 
			
		||||
 *  Copyright [2022] [https://www.xiaonuo.vip]
 | 
			
		||||
 *	Snowy采用APACHE LICENSE 2.0开源协议,您在使用过程中,需要注意以下几点:
 | 
			
		||||
 *	1.请不要删除和修改根目录下的LICENSE文件。
 | 
			
		||||
 *	2.请不要删除和修改Snowy源码头部的版权声明。
 | 
			
		||||
 *	3.本项目代码可免费商业使用,商业使用请保留源码和相关描述文件的项目出处,作者声明等。
 | 
			
		||||
 *	4.分发源码时候,请注明软件出处 https://www.xiaonuo.vip
 | 
			
		||||
 *	5.不可二次分发开源参与同类竞品,如有想法可联系团队xiaonuobase@qq.com商议合作。
 | 
			
		||||
 *	6.若您的项目无法满足以上几点,需要更多功能代码,获取Snowy商业授权许可,请在官网购买授权,地址为 https://www.xiaonuo.vip
 | 
			
		||||
 */
 | 
			
		||||
/* eslint-disable */
 | 
			
		||||
// 打印类属性、方法定义
 | 
			
		||||
const Print = function(dom, options) {
 | 
			
		||||
  if (!(this instanceof Print)) return new Print(dom, options)
 | 
			
		||||
 | 
			
		||||
  this.options = this.extend({
 | 
			
		||||
    noPrint: '.no-print',
 | 
			
		||||
  }, options)
 | 
			
		||||
 | 
			
		||||
  if ((typeof dom) === 'string') {
 | 
			
		||||
    try {
 | 
			
		||||
      this.dom = document.querySelector(dom)
 | 
			
		||||
    }
 | 
			
		||||
    catch {
 | 
			
		||||
      const createDom = document.createElement('div')
 | 
			
		||||
      createDom.innerHTML = dom
 | 
			
		||||
      this.dom = createDom
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
  else {
 | 
			
		||||
    this.isDOM(dom)
 | 
			
		||||
    this.dom = this.isDOM(dom) ? dom : dom.$el
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  this.init()
 | 
			
		||||
}
 | 
			
		||||
Print.prototype = {
 | 
			
		||||
  init() {
 | 
			
		||||
    const content = this.getStyle() + this.getHtml()
 | 
			
		||||
    this.writeIframe(content)
 | 
			
		||||
  },
 | 
			
		||||
  extend(obj, obj2) {
 | 
			
		||||
    for (const k in obj2) {
 | 
			
		||||
      obj[k] = obj2[k]
 | 
			
		||||
    }
 | 
			
		||||
    return obj
 | 
			
		||||
  },
 | 
			
		||||
 | 
			
		||||
  getStyle() {
 | 
			
		||||
    let str = ''
 | 
			
		||||
    const styles = document.querySelectorAll('style,link')
 | 
			
		||||
    for (let i = 0; i < styles.length; i++) {
 | 
			
		||||
      str += styles[i].outerHTML
 | 
			
		||||
    }
 | 
			
		||||
    str += `<style>${ this.options.noPrint ? this.options.noPrint : '.no-print'
 | 
			
		||||
			 }{display:none;}</style>`
 | 
			
		||||
    str += '<style>html,body{background-color:#fff;}</style>'
 | 
			
		||||
    return str
 | 
			
		||||
  },
 | 
			
		||||
 | 
			
		||||
  getHtml() {
 | 
			
		||||
    const inputs = document.querySelectorAll('input')
 | 
			
		||||
    const textareas = document.querySelectorAll('textarea')
 | 
			
		||||
    const selects = document.querySelectorAll('select')
 | 
			
		||||
 | 
			
		||||
    for (let k = 0; k < inputs.length; k++) {
 | 
			
		||||
      if (inputs[k].type == 'checkbox' || inputs[k].type == 'radio') {
 | 
			
		||||
        if (inputs[k].checked == true) {
 | 
			
		||||
          inputs[k].setAttribute('checked', 'checked')
 | 
			
		||||
        }
 | 
			
		||||
        else {
 | 
			
		||||
          inputs[k].removeAttribute('checked')
 | 
			
		||||
        }
 | 
			
		||||
      }
 | 
			
		||||
      else if (inputs[k].type == 'text') {
 | 
			
		||||
        inputs[k].setAttribute('value', inputs[k].value)
 | 
			
		||||
      }
 | 
			
		||||
      else {
 | 
			
		||||
        inputs[k].setAttribute('value', inputs[k].value)
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    for (let k2 = 0; k2 < textareas.length; k2++) {
 | 
			
		||||
      if (textareas[k2].type == 'textarea') {
 | 
			
		||||
        textareas[k2].innerHTML = textareas[k2].value
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    for (let k3 = 0; k3 < selects.length; k3++) {
 | 
			
		||||
      if (selects[k3].type == 'select-one') {
 | 
			
		||||
        const child = selects[k3].children
 | 
			
		||||
        for (const i in child) {
 | 
			
		||||
          if (child[i].tagName == 'OPTION') {
 | 
			
		||||
            if (child[i].selected == true) {
 | 
			
		||||
              child[i].setAttribute('selected', 'selected')
 | 
			
		||||
            }
 | 
			
		||||
            else {
 | 
			
		||||
              child[i].removeAttribute('selected')
 | 
			
		||||
            }
 | 
			
		||||
          }
 | 
			
		||||
        }
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    return this.dom.outerHTML
 | 
			
		||||
  },
 | 
			
		||||
 | 
			
		||||
  writeIframe(content) {
 | 
			
		||||
    let w; let doc; const iframe = document.createElement('iframe')
 | 
			
		||||
    const f = document.body.appendChild(iframe)
 | 
			
		||||
    iframe.id = 'myIframe'
 | 
			
		||||
    // iframe.style = "position:absolute;width:0;height:0;top:-10px;left:-10px;";
 | 
			
		||||
    iframe.setAttribute('style', 'position:absolute;width:0;height:0;top:-10px;left:-10px;')
 | 
			
		||||
    w = f.contentWindow || f.contentDocument
 | 
			
		||||
    doc = f.contentDocument || f.contentWindow.document
 | 
			
		||||
    doc.open()
 | 
			
		||||
    doc.write(content)
 | 
			
		||||
    doc.close()
 | 
			
		||||
    const _this = this
 | 
			
		||||
    iframe.onload = function() {
 | 
			
		||||
      _this.toPrint(w)
 | 
			
		||||
      setTimeout(() => {
 | 
			
		||||
        document.body.removeChild(iframe)
 | 
			
		||||
      }, 100)
 | 
			
		||||
    }
 | 
			
		||||
  },
 | 
			
		||||
 | 
			
		||||
  toPrint(frameWindow) {
 | 
			
		||||
    try {
 | 
			
		||||
      setTimeout(() => {
 | 
			
		||||
        frameWindow.focus()
 | 
			
		||||
        try {
 | 
			
		||||
          if (!frameWindow.document.execCommand('print', false, null)) {
 | 
			
		||||
            frameWindow.print()
 | 
			
		||||
          }
 | 
			
		||||
        }
 | 
			
		||||
        catch (e) {
 | 
			
		||||
          frameWindow.print()
 | 
			
		||||
        }
 | 
			
		||||
        frameWindow.close()
 | 
			
		||||
      }, 10)
 | 
			
		||||
    }
 | 
			
		||||
    catch (err) {
 | 
			
		||||
      console.log('err', err)
 | 
			
		||||
    }
 | 
			
		||||
  },
 | 
			
		||||
  isDOM: (typeof HTMLElement === 'object')
 | 
			
		||||
    ? function(obj) {
 | 
			
		||||
      return obj instanceof HTMLElement
 | 
			
		||||
    }
 | 
			
		||||
    : function(obj) {
 | 
			
		||||
      return obj && typeof obj === 'object' && obj.nodeType === 1 && typeof obj.nodeName === 'string'
 | 
			
		||||
    },
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
export default Print
 | 
			
		||||
| 
						 | 
				
			
			@ -49,7 +49,7 @@ export default {
 | 
			
		|||
	doSm3Hash(msgString) {
 | 
			
		||||
		return sm3(msgString)
 | 
			
		||||
	},
 | 
			
		||||
	// SM4 CBC加密
 | 
			
		||||
	// SM4 加密
 | 
			
		||||
	doSm4Encrypt(msgString) {
 | 
			
		||||
		return sm4.encrypt(msgString, key)
 | 
			
		||||
	},
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -14,15 +14,9 @@
 | 
			
		|||
 * @LastEditors: yubaoshan
 | 
			
		||||
 * @LastEditTime: 2022年4月19日10:58:41
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
const tool = {}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * localStorage
 | 
			
		||||
 *
 | 
			
		||||
 * @author yubaoshan
 | 
			
		||||
 * @date 2022-05-18 22:59
 | 
			
		||||
 */
 | 
			
		||||
// localStorage
 | 
			
		||||
tool.data = {
 | 
			
		||||
	set(table, settings) {
 | 
			
		||||
		const _set = JSON.stringify(settings)
 | 
			
		||||
| 
						 | 
				
			
			@ -46,12 +40,7 @@ tool.data = {
 | 
			
		|||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * sessionStorage
 | 
			
		||||
 *
 | 
			
		||||
 * @author yubaoshan
 | 
			
		||||
 * @date 2022-05-18 22:59
 | 
			
		||||
 */
 | 
			
		||||
// sessionStorage
 | 
			
		||||
tool.session = {
 | 
			
		||||
	set(table, settings) {
 | 
			
		||||
		const _set = JSON.stringify(settings)
 | 
			
		||||
| 
						 | 
				
			
			@ -74,12 +63,7 @@ tool.session = {
 | 
			
		|||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * 千分符
 | 
			
		||||
 *
 | 
			
		||||
 * @author yubaoshan
 | 
			
		||||
 * @date 2022-05-18 22:59
 | 
			
		||||
 */
 | 
			
		||||
// 千分符
 | 
			
		||||
tool.groupSeparator = (num) => {
 | 
			
		||||
	num = `${num}`
 | 
			
		||||
	if (!num.includes('.')) num += '.'
 | 
			
		||||
| 
						 | 
				
			
			@ -91,24 +75,12 @@ tool.groupSeparator = (num) => {
 | 
			
		|||
		.replace(/\.$/, '')
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * 获取所有字典数组
 | 
			
		||||
 *
 | 
			
		||||
 * @author yubaoshan
 | 
			
		||||
 * @date 2022-04-08 01:11
 | 
			
		||||
 */
 | 
			
		||||
// 获取所有字典数组
 | 
			
		||||
tool.dictDataAll = () => {
 | 
			
		||||
	return tool.data.get('DICT_TYPE_TREE_DATA')
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * 字典翻译方法
 | 
			
		||||
 * 界面插槽使用方法 {{ $TOOL.dictType('sex', record.sex) }}
 | 
			
		||||
 *
 | 
			
		||||
 * @author yubaoshan
 | 
			
		||||
 * @date 2022-04-08 01:11
 | 
			
		||||
 */
 | 
			
		||||
// todo 每次都从localStorage获取并重新解析,会有性能问题,应该在内存中做一层缓存,后面需要优化掉
 | 
			
		||||
// 字典翻译方法,界面插槽使用方法 {{ $TOOL.dictType('sex', record.sex) }}
 | 
			
		||||
tool.dictTypeData = (dictValue, value) => {
 | 
			
		||||
	const dictTypeTree = tool.dictDataAll()
 | 
			
		||||
	if (!dictTypeTree) {
 | 
			
		||||
| 
						 | 
				
			
			@ -123,12 +95,7 @@ tool.dictTypeData = (dictValue, value) => {
 | 
			
		|||
	return dict?.name || '无此字典'
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * 获取某个code下字典的列表,多用于字典下拉框
 | 
			
		||||
 *
 | 
			
		||||
 * @author yubaoshan
 | 
			
		||||
 * @date 2022-04-08 01:11
 | 
			
		||||
 */
 | 
			
		||||
// 获取某个code下字典的列表,多用于字典下拉框
 | 
			
		||||
tool.dictTypeList = (dictValue) => {
 | 
			
		||||
	const dictTypeTree = tool.dictDataAll()
 | 
			
		||||
	if (!dictTypeTree) {
 | 
			
		||||
| 
						 | 
				
			
			@ -141,12 +108,7 @@ tool.dictTypeList = (dictValue) => {
 | 
			
		|||
	return []
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * 生成UUID
 | 
			
		||||
 *
 | 
			
		||||
 * @author yubaoshan
 | 
			
		||||
 * @date 2022-05-18 22:59
 | 
			
		||||
 */
 | 
			
		||||
// 生成UUID
 | 
			
		||||
tool.snowyUuid = () => {
 | 
			
		||||
	let uuid = 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, (c) => {
 | 
			
		||||
		let r = (Math.random() * 16) | 0,
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -9,6 +9,8 @@
 | 
			
		|||
	>
 | 
			
		||||
		<a-descriptions :column="1" size="middle" bordered class="mb-2">
 | 
			
		||||
			<a-descriptions-item label="名称">{{ formData.name }}</a-descriptions-item>
 | 
			
		||||
			<a-descriptions-item label="请求IP">{{ formData.opIp }}</a-descriptions-item>
 | 
			
		||||
			<a-descriptions-item label="IP来源">{{ formData.opAddress }}</a-descriptions-item>
 | 
			
		||||
			<a-descriptions-item label="请求地址">{{ formData.reqUrl }}</a-descriptions-item>
 | 
			
		||||
			<a-descriptions-item label="操作类">{{ formData.className }}</a-descriptions-item>
 | 
			
		||||
			<a-descriptions-item label="操作方法">{{ formData.methodName }}</a-descriptions-item>
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -87,6 +87,14 @@
 | 
			
		|||
			title: '名称',
 | 
			
		||||
			dataIndex: 'name'
 | 
			
		||||
		},
 | 
			
		||||
		{
 | 
			
		||||
			title: 'IP地址',
 | 
			
		||||
			dataIndex: 'opIp'
 | 
			
		||||
		},
 | 
			
		||||
		{
 | 
			
		||||
			title: '地址',
 | 
			
		||||
			dataIndex: 'opAddress'
 | 
			
		||||
		},
 | 
			
		||||
		{
 | 
			
		||||
			title: '类名称',
 | 
			
		||||
			dataIndex: 'className'
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
		Reference in New Issue