')
+ dicts = []
+ } else if (dicts.filter(d => d instanceof DictData).length !== dicts.length) {
+ console.error('the type of elements in dicts must be DictData')
+ dicts = []
+ }
+ dict.type[type].splice(0, Number.MAX_SAFE_INTEGER, ...dicts)
+ dicts.forEach(d => {
+ Vue.set(dict.label[type], d.value, d.label)
+ })
+ return dicts
+ })
+}
diff --git a/oms-vue/src/utils/dict/DictConverter.js b/oms-vue/src/utils/dict/DictConverter.js
new file mode 100644
index 00000000..0cf5df86
--- /dev/null
+++ b/oms-vue/src/utils/dict/DictConverter.js
@@ -0,0 +1,17 @@
+import DictOptions from './DictOptions'
+import DictData from './DictData'
+
+export default function(dict, dictMeta) {
+ const label = determineDictField(dict, dictMeta.labelField, ...DictOptions.DEFAULT_LABEL_FIELDS)
+ const value = determineDictField(dict, dictMeta.valueField, ...DictOptions.DEFAULT_VALUE_FIELDS)
+ return new DictData(dict[label], dict[value], dict)
+}
+
+/**
+ * 确定字典字段
+ * @param {DictData} dict
+ * @param {...String} fields
+ */
+function determineDictField(dict, ...fields) {
+ return fields.find(f => Object.prototype.hasOwnProperty.call(dict, f))
+}
diff --git a/oms-vue/src/utils/dict/DictData.js b/oms-vue/src/utils/dict/DictData.js
new file mode 100644
index 00000000..afc763e8
--- /dev/null
+++ b/oms-vue/src/utils/dict/DictData.js
@@ -0,0 +1,13 @@
+/**
+ * @classdesc 字典数据
+ * @property {String} label 标签
+ * @property {*} value 标签
+ * @property {Object} raw 原始数据
+ */
+export default class DictData {
+ constructor(label, value, raw) {
+ this.label = label
+ this.value = value
+ this.raw = raw
+ }
+}
diff --git a/oms-vue/src/utils/dict/DictMeta.js b/oms-vue/src/utils/dict/DictMeta.js
new file mode 100644
index 00000000..fedc461d
--- /dev/null
+++ b/oms-vue/src/utils/dict/DictMeta.js
@@ -0,0 +1,38 @@
+import { mergeRecursive } from "@/utils/zhijian";
+import DictOptions from './DictOptions'
+
+/**
+ * @classdesc 字典元数据
+ * @property {String} type 类型
+ * @property {Function} request 请求
+ * @property {String} label 标签字段
+ * @property {String} value 值字段
+ */
+export default class DictMeta {
+ constructor(options) {
+ this.type = options.type
+ this.request = options.request
+ this.responseConverter = options.responseConverter
+ this.labelField = options.labelField
+ this.valueField = options.valueField
+ this.lazy = options.lazy === true
+ }
+}
+
+
+/**
+ * 解析字典元数据
+ * @param {Object} options
+ * @returns {DictMeta}
+ */
+DictMeta.parse= function(options) {
+ let opts = null
+ if (typeof options === 'string') {
+ opts = DictOptions.metas[options] || {}
+ opts.type = options
+ } else if (typeof options === 'object') {
+ opts = options
+ }
+ opts = mergeRecursive(DictOptions.metas['*'], opts)
+ return new DictMeta(opts)
+}
diff --git a/oms-vue/src/utils/dict/DictOptions.js b/oms-vue/src/utils/dict/DictOptions.js
new file mode 100644
index 00000000..f0e786cc
--- /dev/null
+++ b/oms-vue/src/utils/dict/DictOptions.js
@@ -0,0 +1,51 @@
+import { mergeRecursive } from "@/utils/zhijian";
+import dictConverter from './DictConverter'
+
+export const options = {
+ metas: {
+ '*': {
+ /**
+ * 字典请求,方法签名为function(dictMeta: DictMeta): Promise
+ */
+ request: (dictMeta) => {
+ console.log(`load dict ${dictMeta.type}`)
+ return Promise.resolve([])
+ },
+ /**
+ * 字典响应数据转换器,方法签名为function(response: Object, dictMeta: DictMeta): DictData
+ */
+ responseConverter,
+ labelField: 'label',
+ valueField: 'value',
+ },
+ },
+ /**
+ * 默认标签字段
+ */
+ DEFAULT_LABEL_FIELDS: ['label', 'name', 'title'],
+ /**
+ * 默认值字段
+ */
+ DEFAULT_VALUE_FIELDS: ['value', 'id', 'uid', 'key'],
+}
+
+/**
+ * 映射字典
+ * @param {Object} response 字典数据
+ * @param {DictMeta} dictMeta 字典元数据
+ * @returns {DictData}
+ */
+function responseConverter(response, dictMeta) {
+ const dicts = response.content instanceof Array ? response.content : response
+ if (dicts === undefined) {
+ console.warn(`no dict data of "${dictMeta.type}" found in the response`)
+ return []
+ }
+ return dicts.map(d => dictConverter(d, dictMeta))
+}
+
+export function mergeOptions(src) {
+ mergeRecursive(options, src)
+}
+
+export default options
diff --git a/oms-vue/src/utils/dict/index.js b/oms-vue/src/utils/dict/index.js
new file mode 100644
index 00000000..215eb9e0
--- /dev/null
+++ b/oms-vue/src/utils/dict/index.js
@@ -0,0 +1,33 @@
+import Dict from './Dict'
+import { mergeOptions } from './DictOptions'
+
+export default function(Vue, options) {
+ mergeOptions(options)
+ Vue.mixin({
+ data() {
+ if (this.$options === undefined || this.$options.dicts === undefined || this.$options.dicts === null) {
+ return {}
+ }
+ const dict = new Dict()
+ dict.owner = this
+ return {
+ dict
+ }
+ },
+ created() {
+ if (!(this.dict instanceof Dict)) {
+ return
+ }
+ options.onCreated && options.onCreated(this.dict)
+ this.dict.init(this.$options.dicts).then(() => {
+ options.onReady && options.onReady(this.dict)
+ this.$nextTick(() => {
+ this.$emit('dictReady', this.dict)
+ if (this.$options.methods && this.$options.methods.onDictReady instanceof Function) {
+ this.$options.methods.onDictReady.call(this, this.dict)
+ }
+ })
+ })
+ },
+ })
+}
diff --git a/oms-vue/src/utils/errorCode.js b/oms-vue/src/utils/errorCode.js
new file mode 100644
index 00000000..d2111ee1
--- /dev/null
+++ b/oms-vue/src/utils/errorCode.js
@@ -0,0 +1,6 @@
+export default {
+ '401': '认证失败,无法访问系统资源',
+ '403': '当前操作没有权限',
+ '404': '访问资源不存在',
+ 'default': '系统未知错误,请反馈给管理员'
+}
diff --git a/oms-vue/src/utils/generator/config.js b/oms-vue/src/utils/generator/config.js
new file mode 100644
index 00000000..7abf227d
--- /dev/null
+++ b/oms-vue/src/utils/generator/config.js
@@ -0,0 +1,438 @@
+export const formConf = {
+ formRef: 'elForm',
+ formModel: 'formData',
+ size: 'medium',
+ labelPosition: 'right',
+ labelWidth: 100,
+ formRules: 'rules',
+ gutter: 15,
+ disabled: false,
+ span: 24,
+ formBtns: true
+}
+
+export const inputComponents = [
+ {
+ label: '单行文本',
+ tag: 'el-input',
+ tagIcon: 'input',
+ placeholder: '请输入',
+ defaultValue: undefined,
+ span: 24,
+ labelWidth: null,
+ style: { width: '100%' },
+ clearable: true,
+ prepend: '',
+ append: '',
+ 'prefix-icon': '',
+ 'suffix-icon': '',
+ maxlength: null,
+ 'show-word-limit': false,
+ readonly: false,
+ disabled: false,
+ required: true,
+ regList: [],
+ changeTag: true,
+ document: 'https://element.eleme.cn/#/zh-CN/component/input'
+ },
+ {
+ label: '多行文本',
+ tag: 'el-input',
+ tagIcon: 'textarea',
+ type: 'textarea',
+ placeholder: '请输入',
+ defaultValue: undefined,
+ span: 24,
+ labelWidth: null,
+ autosize: {
+ minRows: 4,
+ maxRows: 4
+ },
+ style: { width: '100%' },
+ maxlength: null,
+ 'show-word-limit': false,
+ readonly: false,
+ disabled: false,
+ required: true,
+ regList: [],
+ changeTag: true,
+ document: 'https://element.eleme.cn/#/zh-CN/component/input'
+ },
+ {
+ label: '密码',
+ tag: 'el-input',
+ tagIcon: 'password',
+ placeholder: '请输入',
+ defaultValue: undefined,
+ span: 24,
+ 'show-password': true,
+ labelWidth: null,
+ style: { width: '100%' },
+ clearable: true,
+ prepend: '',
+ append: '',
+ 'prefix-icon': '',
+ 'suffix-icon': '',
+ maxlength: null,
+ 'show-word-limit': false,
+ readonly: false,
+ disabled: false,
+ required: true,
+ regList: [],
+ changeTag: true,
+ document: 'https://element.eleme.cn/#/zh-CN/component/input'
+ },
+ {
+ label: '计数器',
+ tag: 'el-input-number',
+ tagIcon: 'number',
+ placeholder: '',
+ defaultValue: undefined,
+ span: 24,
+ labelWidth: null,
+ min: undefined,
+ max: undefined,
+ step: undefined,
+ 'step-strictly': false,
+ precision: undefined,
+ 'controls-position': '',
+ disabled: false,
+ required: true,
+ regList: [],
+ changeTag: true,
+ document: 'https://element.eleme.cn/#/zh-CN/component/input-number'
+ }
+]
+
+export const selectComponents = [
+ {
+ label: '下拉选择',
+ tag: 'el-select',
+ tagIcon: 'select',
+ placeholder: '请选择',
+ defaultValue: undefined,
+ span: 24,
+ labelWidth: null,
+ style: { width: '100%' },
+ clearable: true,
+ disabled: false,
+ required: true,
+ filterable: false,
+ multiple: false,
+ options: [{
+ label: '选项一',
+ value: 1
+ }, {
+ label: '选项二',
+ value: 2
+ }],
+ regList: [],
+ changeTag: true,
+ document: 'https://element.eleme.cn/#/zh-CN/component/select'
+ },
+ {
+ label: '级联选择',
+ tag: 'el-cascader',
+ tagIcon: 'cascader',
+ placeholder: '请选择',
+ defaultValue: [],
+ span: 24,
+ labelWidth: null,
+ style: { width: '100%' },
+ props: {
+ props: {
+ multiple: false
+ }
+ },
+ 'show-all-levels': true,
+ disabled: false,
+ clearable: true,
+ filterable: false,
+ required: true,
+ options: [{
+ id: 1,
+ value: 1,
+ label: '选项1',
+ children: [{
+ id: 2,
+ value: 2,
+ label: '选项1-1'
+ }]
+ }],
+ dataType: 'dynamic',
+ labelKey: 'label',
+ valueKey: 'value',
+ childrenKey: 'children',
+ separator: '/',
+ regList: [],
+ changeTag: true,
+ document: 'https://element.eleme.cn/#/zh-CN/component/cascader'
+ },
+ {
+ label: '单选框组',
+ tag: 'el-radio-group',
+ tagIcon: 'radio',
+ defaultValue: undefined,
+ span: 24,
+ labelWidth: null,
+ style: {},
+ optionType: 'default',
+ border: false,
+ size: 'medium',
+ disabled: false,
+ required: true,
+ options: [{
+ label: '选项一',
+ value: 1
+ }, {
+ label: '选项二',
+ value: 2
+ }],
+ regList: [],
+ changeTag: true,
+ document: 'https://element.eleme.cn/#/zh-CN/component/radio'
+ },
+ {
+ label: '多选框组',
+ tag: 'el-checkbox-group',
+ tagIcon: 'checkbox',
+ defaultValue: [],
+ span: 24,
+ labelWidth: null,
+ style: {},
+ optionType: 'default',
+ border: false,
+ size: 'medium',
+ disabled: false,
+ required: true,
+ options: [{
+ label: '选项一',
+ value: 1
+ }, {
+ label: '选项二',
+ value: 2
+ }],
+ regList: [],
+ changeTag: true,
+ document: 'https://element.eleme.cn/#/zh-CN/component/checkbox'
+ },
+ {
+ label: '开关',
+ tag: 'el-switch',
+ tagIcon: 'switch',
+ defaultValue: false,
+ span: 24,
+ labelWidth: null,
+ style: {},
+ disabled: false,
+ required: true,
+ 'active-text': '',
+ 'inactive-text': '',
+ 'active-color': null,
+ 'inactive-color': null,
+ 'active-value': true,
+ 'inactive-value': false,
+ regList: [],
+ changeTag: true,
+ document: 'https://element.eleme.cn/#/zh-CN/component/switch'
+ },
+ {
+ label: '滑块',
+ tag: 'el-slider',
+ tagIcon: 'slider',
+ defaultValue: null,
+ span: 24,
+ labelWidth: null,
+ disabled: false,
+ required: true,
+ min: 0,
+ max: 100,
+ step: 1,
+ 'show-stops': false,
+ range: false,
+ regList: [],
+ changeTag: true,
+ document: 'https://element.eleme.cn/#/zh-CN/component/slider'
+ },
+ {
+ label: '时间选择',
+ tag: 'el-time-picker',
+ tagIcon: 'time',
+ placeholder: '请选择',
+ defaultValue: null,
+ span: 24,
+ labelWidth: null,
+ style: { width: '100%' },
+ disabled: false,
+ clearable: true,
+ required: true,
+ 'picker-options': {
+ selectableRange: '00:00:00-23:59:59'
+ },
+ format: 'HH:mm:ss',
+ 'value-format': 'HH:mm:ss',
+ regList: [],
+ changeTag: true,
+ document: 'https://element.eleme.cn/#/zh-CN/component/time-picker'
+ },
+ {
+ label: '时间范围',
+ tag: 'el-time-picker',
+ tagIcon: 'time-range',
+ defaultValue: null,
+ span: 24,
+ labelWidth: null,
+ style: { width: '100%' },
+ disabled: false,
+ clearable: true,
+ required: true,
+ 'is-range': true,
+ 'range-separator': '至',
+ 'start-placeholder': '开始时间',
+ 'end-placeholder': '结束时间',
+ format: 'HH:mm:ss',
+ 'value-format': 'HH:mm:ss',
+ regList: [],
+ changeTag: true,
+ document: 'https://element.eleme.cn/#/zh-CN/component/time-picker'
+ },
+ {
+ label: '日期选择',
+ tag: 'el-date-picker',
+ tagIcon: 'date',
+ placeholder: '请选择',
+ defaultValue: null,
+ type: 'date',
+ span: 24,
+ labelWidth: null,
+ style: { width: '100%' },
+ disabled: false,
+ clearable: true,
+ required: true,
+ format: 'yyyy-MM-dd',
+ 'value-format': 'yyyy-MM-dd',
+ readonly: false,
+ regList: [],
+ changeTag: true,
+ document: 'https://element.eleme.cn/#/zh-CN/component/date-picker'
+ },
+ {
+ label: '日期范围',
+ tag: 'el-date-picker',
+ tagIcon: 'date-range',
+ defaultValue: null,
+ span: 24,
+ labelWidth: null,
+ style: { width: '100%' },
+ type: 'daterange',
+ 'range-separator': '至',
+ 'start-placeholder': '开始日期',
+ 'end-placeholder': '结束日期',
+ disabled: false,
+ clearable: true,
+ required: true,
+ format: 'yyyy-MM-dd',
+ 'value-format': 'yyyy-MM-dd',
+ readonly: false,
+ regList: [],
+ changeTag: true,
+ document: 'https://element.eleme.cn/#/zh-CN/component/date-picker'
+ },
+ {
+ label: '评分',
+ tag: 'el-rate',
+ tagIcon: 'rate',
+ defaultValue: 0,
+ span: 24,
+ labelWidth: null,
+ style: {},
+ max: 5,
+ 'allow-half': false,
+ 'show-text': false,
+ 'show-score': false,
+ disabled: false,
+ required: true,
+ regList: [],
+ changeTag: true,
+ document: 'https://element.eleme.cn/#/zh-CN/component/rate'
+ },
+ {
+ label: '颜色选择',
+ tag: 'el-color-picker',
+ tagIcon: 'color',
+ defaultValue: null,
+ labelWidth: null,
+ 'show-alpha': false,
+ 'color-format': '',
+ disabled: false,
+ required: true,
+ size: 'medium',
+ regList: [],
+ changeTag: true,
+ document: 'https://element.eleme.cn/#/zh-CN/component/color-picker'
+ },
+ {
+ label: '上传',
+ tag: 'el-upload',
+ tagIcon: 'upload',
+ action: 'https://jsonplaceholder.typicode.com/posts/',
+ defaultValue: null,
+ labelWidth: null,
+ disabled: false,
+ required: true,
+ accept: '',
+ name: 'file',
+ 'auto-upload': true,
+ showTip: false,
+ buttonText: '点击上传',
+ fileSize: 2,
+ sizeUnit: 'MB',
+ 'list-type': 'text',
+ multiple: false,
+ regList: [],
+ changeTag: true,
+ document: 'https://element.eleme.cn/#/zh-CN/component/upload'
+ }
+]
+
+export const layoutComponents = [
+ {
+ layout: 'rowFormItem',
+ tagIcon: 'row',
+ type: 'default',
+ justify: 'start',
+ align: 'top',
+ label: '行容器',
+ layoutTree: true,
+ children: [],
+ document: 'https://element.eleme.cn/#/zh-CN/component/layout'
+ },
+ {
+ layout: 'colFormItem',
+ label: '按钮',
+ changeTag: true,
+ labelWidth: null,
+ tag: 'el-button',
+ tagIcon: 'button',
+ span: 24,
+ default: '主要按钮',
+ type: 'primary',
+ icon: 'el-icon-search',
+ size: 'medium',
+ disabled: false,
+ document: 'https://element.eleme.cn/#/zh-CN/component/button'
+ }
+]
+
+// 组件rule的触发方式,无触发方式的组件不生成rule
+export const trigger = {
+ 'el-input': 'blur',
+ 'el-input-number': 'blur',
+ 'el-select': 'change',
+ 'el-radio-group': 'change',
+ 'el-checkbox-group': 'change',
+ 'el-cascader': 'change',
+ 'el-time-picker': 'change',
+ 'el-date-picker': 'change',
+ 'el-rate': 'change'
+}
diff --git a/oms-vue/src/utils/generator/css.js b/oms-vue/src/utils/generator/css.js
new file mode 100644
index 00000000..c1c62e60
--- /dev/null
+++ b/oms-vue/src/utils/generator/css.js
@@ -0,0 +1,18 @@
+const styles = {
+ 'el-rate': '.el-rate{display: inline-block; vertical-align: text-top;}',
+ 'el-upload': '.el-upload__tip{line-height: 1.2;}'
+}
+
+function addCss(cssList, el) {
+ const css = styles[el.tag]
+ css && cssList.indexOf(css) === -1 && cssList.push(css)
+ if (el.children) {
+ el.children.forEach(el2 => addCss(cssList, el2))
+ }
+}
+
+export function makeUpCss(conf) {
+ const cssList = []
+ conf.fields.forEach(el => addCss(cssList, el))
+ return cssList.join('\n')
+}
diff --git a/oms-vue/src/utils/generator/drawingDefault.js b/oms-vue/src/utils/generator/drawingDefault.js
new file mode 100644
index 00000000..09f133ca
--- /dev/null
+++ b/oms-vue/src/utils/generator/drawingDefault.js
@@ -0,0 +1,29 @@
+export default [
+ {
+ layout: 'colFormItem',
+ tagIcon: 'input',
+ label: '手机号',
+ vModel: 'mobile',
+ formId: 6,
+ tag: 'el-input',
+ placeholder: '请输入手机号',
+ defaultValue: '',
+ span: 24,
+ style: { width: '100%' },
+ clearable: true,
+ prepend: '',
+ append: '',
+ 'prefix-icon': 'el-icon-mobile',
+ 'suffix-icon': '',
+ maxlength: 11,
+ 'show-word-limit': true,
+ readonly: false,
+ disabled: false,
+ required: true,
+ changeTag: true,
+ regList: [{
+ pattern: '/^1(3|4|5|7|8|9)\\d{9}$/',
+ message: '手机号格式错误'
+ }]
+ }
+]
diff --git a/oms-vue/src/utils/generator/html.js b/oms-vue/src/utils/generator/html.js
new file mode 100644
index 00000000..9bcc5361
--- /dev/null
+++ b/oms-vue/src/utils/generator/html.js
@@ -0,0 +1,359 @@
+/* eslint-disable max-len */
+import { trigger } from './config'
+
+let confGlobal
+let someSpanIsNot24
+
+export function dialogWrapper(str) {
+ return `
+ ${str}
+
+ 取消
+ 确定
+
+ `
+}
+
+export function vueTemplate(str) {
+ return `
+
+ ${str}
+
+ `
+}
+
+export function vueScript(str) {
+ return ``
+}
+
+export function cssStyle(cssStr) {
+ return ``
+}
+
+function buildFormTemplate(conf, child, type) {
+ let labelPosition = ''
+ if (conf.labelPosition !== 'right') {
+ labelPosition = `label-position="${conf.labelPosition}"`
+ }
+ const disabled = conf.disabled ? `:disabled="${conf.disabled}"` : ''
+ let str = `
+ ${child}
+ ${buildFromBtns(conf, type)}
+ `
+ if (someSpanIsNot24) {
+ str = `
+ ${str}
+ `
+ }
+ return str
+}
+
+function buildFromBtns(conf, type) {
+ let str = ''
+ if (conf.formBtns && type === 'file') {
+ str = `
+ 提交
+ 重置
+ `
+ if (someSpanIsNot24) {
+ str = `
+ ${str}
+ `
+ }
+ }
+ return str
+}
+
+// span不为24的用el-col包裹
+function colWrapper(element, str) {
+ if (someSpanIsNot24 || element.span !== 24) {
+ return `
+ ${str}
+ `
+ }
+ return str
+}
+
+const layouts = {
+ colFormItem(element) {
+ let labelWidth = ''
+ if (element.labelWidth && element.labelWidth !== confGlobal.labelWidth) {
+ labelWidth = `label-width="${element.labelWidth}px"`
+ }
+ const required = !trigger[element.tag] && element.required ? 'required' : ''
+ const tagDom = tags[element.tag] ? tags[element.tag](element) : null
+ let str = `
+ ${tagDom}
+ `
+ str = colWrapper(element, str)
+ return str
+ },
+ rowFormItem(element) {
+ const type = element.type === 'default' ? '' : `type="${element.type}"`
+ const justify = element.type === 'default' ? '' : `justify="${element.justify}"`
+ const align = element.type === 'default' ? '' : `align="${element.align}"`
+ const gutter = element.gutter ? `gutter="${element.gutter}"` : ''
+ const children = element.children.map(el => layouts[el.layout](el))
+ let str = `
+ ${children.join('\n')}
+ `
+ str = colWrapper(element, str)
+ return str
+ }
+}
+
+const tags = {
+ 'el-button': el => {
+ const {
+ tag, disabled
+ } = attrBuilder(el)
+ const type = el.type ? `type="${el.type}"` : ''
+ const icon = el.icon ? `icon="${el.icon}"` : ''
+ const size = el.size ? `size="${el.size}"` : ''
+ let child = buildElButtonChild(el)
+
+ if (child) child = `\n${child}\n` // 换行
+ return `<${el.tag} ${type} ${icon} ${size} ${disabled}>${child}${el.tag}>`
+ },
+ 'el-input': el => {
+ const {
+ disabled, vModel, clearable, placeholder, width
+ } = attrBuilder(el)
+ const maxlength = el.maxlength ? `:maxlength="${el.maxlength}"` : ''
+ const showWordLimit = el['show-word-limit'] ? 'show-word-limit' : ''
+ const readonly = el.readonly ? 'readonly' : ''
+ const prefixIcon = el['prefix-icon'] ? `prefix-icon='${el['prefix-icon']}'` : ''
+ const suffixIcon = el['suffix-icon'] ? `suffix-icon='${el['suffix-icon']}'` : ''
+ const showPassword = el['show-password'] ? 'show-password' : ''
+ const type = el.type ? `type="${el.type}"` : ''
+ const autosize = el.autosize && el.autosize.minRows
+ ? `:autosize="{minRows: ${el.autosize.minRows}, maxRows: ${el.autosize.maxRows}}"`
+ : ''
+ let child = buildElInputChild(el)
+
+ if (child) child = `\n${child}\n` // 换行
+ return `<${el.tag} ${vModel} ${type} ${placeholder} ${maxlength} ${showWordLimit} ${readonly} ${disabled} ${clearable} ${prefixIcon} ${suffixIcon} ${showPassword} ${autosize} ${width}>${child}${el.tag}>`
+ },
+ 'el-input-number': el => {
+ const { disabled, vModel, placeholder } = attrBuilder(el)
+ const controlsPosition = el['controls-position'] ? `controls-position=${el['controls-position']}` : ''
+ const min = el.min ? `:min='${el.min}'` : ''
+ const max = el.max ? `:max='${el.max}'` : ''
+ const step = el.step ? `:step='${el.step}'` : ''
+ const stepStrictly = el['step-strictly'] ? 'step-strictly' : ''
+ const precision = el.precision ? `:precision='${el.precision}'` : ''
+
+ return `<${el.tag} ${vModel} ${placeholder} ${step} ${stepStrictly} ${precision} ${controlsPosition} ${min} ${max} ${disabled}>${el.tag}>`
+ },
+ 'el-select': el => {
+ const {
+ disabled, vModel, clearable, placeholder, width
+ } = attrBuilder(el)
+ const filterable = el.filterable ? 'filterable' : ''
+ const multiple = el.multiple ? 'multiple' : ''
+ let child = buildElSelectChild(el)
+
+ if (child) child = `\n${child}\n` // 换行
+ return `<${el.tag} ${vModel} ${placeholder} ${disabled} ${multiple} ${filterable} ${clearable} ${width}>${child}${el.tag}>`
+ },
+ 'el-radio-group': el => {
+ const { disabled, vModel } = attrBuilder(el)
+ const size = `size="${el.size}"`
+ let child = buildElRadioGroupChild(el)
+
+ if (child) child = `\n${child}\n` // 换行
+ return `<${el.tag} ${vModel} ${size} ${disabled}>${child}${el.tag}>`
+ },
+ 'el-checkbox-group': el => {
+ const { disabled, vModel } = attrBuilder(el)
+ const size = `size="${el.size}"`
+ const min = el.min ? `:min="${el.min}"` : ''
+ const max = el.max ? `:max="${el.max}"` : ''
+ let child = buildElCheckboxGroupChild(el)
+
+ if (child) child = `\n${child}\n` // 换行
+ return `<${el.tag} ${vModel} ${min} ${max} ${size} ${disabled}>${child}${el.tag}>`
+ },
+ 'el-switch': el => {
+ const { disabled, vModel } = attrBuilder(el)
+ const activeText = el['active-text'] ? `active-text="${el['active-text']}"` : ''
+ const inactiveText = el['inactive-text'] ? `inactive-text="${el['inactive-text']}"` : ''
+ const activeColor = el['active-color'] ? `active-color="${el['active-color']}"` : ''
+ const inactiveColor = el['inactive-color'] ? `inactive-color="${el['inactive-color']}"` : ''
+ const activeValue = el['active-value'] !== true ? `:active-value='${JSON.stringify(el['active-value'])}'` : ''
+ const inactiveValue = el['inactive-value'] !== false ? `:inactive-value='${JSON.stringify(el['inactive-value'])}'` : ''
+
+ return `<${el.tag} ${vModel} ${activeText} ${inactiveText} ${activeColor} ${inactiveColor} ${activeValue} ${inactiveValue} ${disabled}>${el.tag}>`
+ },
+ 'el-cascader': el => {
+ const {
+ disabled, vModel, clearable, placeholder, width
+ } = attrBuilder(el)
+ const options = el.options ? `:options="${el.vModel}Options"` : ''
+ const props = el.props ? `:props="${el.vModel}Props"` : ''
+ const showAllLevels = el['show-all-levels'] ? '' : ':show-all-levels="false"'
+ const filterable = el.filterable ? 'filterable' : ''
+ const separator = el.separator === '/' ? '' : `separator="${el.separator}"`
+
+ return `<${el.tag} ${vModel} ${options} ${props} ${width} ${showAllLevels} ${placeholder} ${separator} ${filterable} ${clearable} ${disabled}>${el.tag}>`
+ },
+ 'el-slider': el => {
+ const { disabled, vModel } = attrBuilder(el)
+ const min = el.min ? `:min='${el.min}'` : ''
+ const max = el.max ? `:max='${el.max}'` : ''
+ const step = el.step ? `:step='${el.step}'` : ''
+ const range = el.range ? 'range' : ''
+ const showStops = el['show-stops'] ? `:show-stops="${el['show-stops']}"` : ''
+
+ return `<${el.tag} ${min} ${max} ${step} ${vModel} ${range} ${showStops} ${disabled}>${el.tag}>`
+ },
+ 'el-time-picker': el => {
+ const {
+ disabled, vModel, clearable, placeholder, width
+ } = attrBuilder(el)
+ const startPlaceholder = el['start-placeholder'] ? `start-placeholder="${el['start-placeholder']}"` : ''
+ const endPlaceholder = el['end-placeholder'] ? `end-placeholder="${el['end-placeholder']}"` : ''
+ const rangeSeparator = el['range-separator'] ? `range-separator="${el['range-separator']}"` : ''
+ const isRange = el['is-range'] ? 'is-range' : ''
+ const format = el.format ? `format="${el.format}"` : ''
+ const valueFormat = el['value-format'] ? `value-format="${el['value-format']}"` : ''
+ const pickerOptions = el['picker-options'] ? `:picker-options='${JSON.stringify(el['picker-options'])}'` : ''
+
+ return `<${el.tag} ${vModel} ${isRange} ${format} ${valueFormat} ${pickerOptions} ${width} ${placeholder} ${startPlaceholder} ${endPlaceholder} ${rangeSeparator} ${clearable} ${disabled}>${el.tag}>`
+ },
+ 'el-date-picker': el => {
+ const {
+ disabled, vModel, clearable, placeholder, width
+ } = attrBuilder(el)
+ const startPlaceholder = el['start-placeholder'] ? `start-placeholder="${el['start-placeholder']}"` : ''
+ const endPlaceholder = el['end-placeholder'] ? `end-placeholder="${el['end-placeholder']}"` : ''
+ const rangeSeparator = el['range-separator'] ? `range-separator="${el['range-separator']}"` : ''
+ const format = el.format ? `format="${el.format}"` : ''
+ const valueFormat = el['value-format'] ? `value-format="${el['value-format']}"` : ''
+ const type = el.type === 'date' ? '' : `type="${el.type}"`
+ const readonly = el.readonly ? 'readonly' : ''
+
+ return `<${el.tag} ${type} ${vModel} ${format} ${valueFormat} ${width} ${placeholder} ${startPlaceholder} ${endPlaceholder} ${rangeSeparator} ${clearable} ${readonly} ${disabled}>${el.tag}>`
+ },
+ 'el-rate': el => {
+ const { disabled, vModel } = attrBuilder(el)
+ const max = el.max ? `:max='${el.max}'` : ''
+ const allowHalf = el['allow-half'] ? 'allow-half' : ''
+ const showText = el['show-text'] ? 'show-text' : ''
+ const showScore = el['show-score'] ? 'show-score' : ''
+
+ return `<${el.tag} ${vModel} ${allowHalf} ${showText} ${showScore} ${disabled}>${el.tag}>`
+ },
+ 'el-color-picker': el => {
+ const { disabled, vModel } = attrBuilder(el)
+ const size = `size="${el.size}"`
+ const showAlpha = el['show-alpha'] ? 'show-alpha' : ''
+ const colorFormat = el['color-format'] ? `color-format="${el['color-format']}"` : ''
+
+ return `<${el.tag} ${vModel} ${size} ${showAlpha} ${colorFormat} ${disabled}>${el.tag}>`
+ },
+ 'el-upload': el => {
+ const disabled = el.disabled ? ':disabled=\'true\'' : ''
+ const action = el.action ? `:action="${el.vModel}Action"` : ''
+ const multiple = el.multiple ? 'multiple' : ''
+ const listType = el['list-type'] !== 'text' ? `list-type="${el['list-type']}"` : ''
+ const accept = el.accept ? `accept="${el.accept}"` : ''
+ const name = el.name !== 'file' ? `name="${el.name}"` : ''
+ const autoUpload = el['auto-upload'] === false ? ':auto-upload="false"' : ''
+ const beforeUpload = `:before-upload="${el.vModel}BeforeUpload"`
+ const fileList = `:file-list="${el.vModel}fileList"`
+ const ref = `ref="${el.vModel}"`
+ let child = buildElUploadChild(el)
+
+ if (child) child = `\n${child}\n` // 换行
+ return `<${el.tag} ${ref} ${fileList} ${action} ${autoUpload} ${multiple} ${beforeUpload} ${listType} ${accept} ${name} ${disabled}>${child}${el.tag}>`
+ }
+}
+
+function attrBuilder(el) {
+ return {
+ vModel: `v-model="${confGlobal.formModel}.${el.vModel}"`,
+ clearable: el.clearable ? 'clearable' : '',
+ placeholder: el.placeholder ? `placeholder="${el.placeholder}"` : '',
+ width: el.style && el.style.width ? ':style="{width: \'100%\'}"' : '',
+ disabled: el.disabled ? ':disabled=\'true\'' : ''
+ }
+}
+
+// el-buttin 子级
+function buildElButtonChild(conf) {
+ const children = []
+ if (conf.default) {
+ children.push(conf.default)
+ }
+ return children.join('\n')
+}
+
+// el-input innerHTML
+function buildElInputChild(conf) {
+ const children = []
+ if (conf.prepend) {
+ children.push(`${conf.prepend}`)
+ }
+ if (conf.append) {
+ children.push(`${conf.append}`)
+ }
+ return children.join('\n')
+}
+
+function buildElSelectChild(conf) {
+ const children = []
+ if (conf.options && conf.options.length) {
+ children.push(``)
+ }
+ return children.join('\n')
+}
+
+function buildElRadioGroupChild(conf) {
+ const children = []
+ if (conf.options && conf.options.length) {
+ const tag = conf.optionType === 'button' ? 'el-radio-button' : 'el-radio'
+ const border = conf.border ? 'border' : ''
+ children.push(`<${tag} v-for="(item, index) in ${conf.vModel}Options" :key="index" :label="item.value" :disabled="item.disabled" ${border}>{{item.label}}${tag}>`)
+ }
+ return children.join('\n')
+}
+
+function buildElCheckboxGroupChild(conf) {
+ const children = []
+ if (conf.options && conf.options.length) {
+ const tag = conf.optionType === 'button' ? 'el-checkbox-button' : 'el-checkbox'
+ const border = conf.border ? 'border' : ''
+ children.push(`<${tag} v-for="(item, index) in ${conf.vModel}Options" :key="index" :label="item.value" :disabled="item.disabled" ${border}>{{item.label}}${tag}>`)
+ }
+ return children.join('\n')
+}
+
+function buildElUploadChild(conf) {
+ const list = []
+ if (conf['list-type'] === 'picture-card') list.push('')
+ else list.push(`${conf.buttonText}`)
+ if (conf.showTip) list.push(`只能上传不超过 ${conf.fileSize}${conf.sizeUnit} 的${conf.accept}文件
`)
+ return list.join('\n')
+}
+
+export function makeUpHtml(conf, type) {
+ const htmlList = []
+ confGlobal = conf
+ someSpanIsNot24 = conf.fields.some(item => item.span !== 24)
+ conf.fields.forEach(el => {
+ htmlList.push(layouts[el.layout](el))
+ })
+ const htmlStr = htmlList.join('\n')
+
+ let temp = buildFormTemplate(conf, htmlStr, type)
+ if (type === 'dialog') {
+ temp = dialogWrapper(temp)
+ }
+ confGlobal = null
+ return temp
+}
diff --git a/oms-vue/src/utils/generator/icon.json b/oms-vue/src/utils/generator/icon.json
new file mode 100644
index 00000000..2d9999a3
--- /dev/null
+++ b/oms-vue/src/utils/generator/icon.json
@@ -0,0 +1 @@
+["platform-eleme","eleme","delete-solid","delete","s-tools","setting","user-solid","user","phone","phone-outline","more","more-outline","star-on","star-off","s-goods","goods","warning","warning-outline","question","info","remove","circle-plus","success","error","zoom-in","zoom-out","remove-outline","circle-plus-outline","circle-check","circle-close","s-help","help","minus","plus","check","close","picture","picture-outline","picture-outline-round","upload","upload2","download","camera-solid","camera","video-camera-solid","video-camera","message-solid","bell","s-cooperation","s-order","s-platform","s-fold","s-unfold","s-operation","s-promotion","s-home","s-release","s-ticket","s-management","s-open","s-shop","s-marketing","s-flag","s-comment","s-finance","s-claim","s-custom","s-opportunity","s-data","s-check","s-grid","menu","share","d-caret","caret-left","caret-right","caret-bottom","caret-top","bottom-left","bottom-right","back","right","bottom","top","top-left","top-right","arrow-left","arrow-right","arrow-down","arrow-up","d-arrow-left","d-arrow-right","video-pause","video-play","refresh","refresh-right","refresh-left","finished","sort","sort-up","sort-down","rank","loading","view","c-scale-to-original","date","edit","edit-outline","folder","folder-opened","folder-add","folder-remove","folder-delete","folder-checked","tickets","document-remove","document-delete","document-copy","document-checked","document","document-add","printer","paperclip","takeaway-box","search","monitor","attract","mobile","scissors","umbrella","headset","brush","mouse","coordinate","magic-stick","reading","data-line","data-board","pie-chart","data-analysis","collection-tag","film","suitcase","suitcase-1","receiving","collection","files","notebook-1","notebook-2","toilet-paper","office-building","school","table-lamp","house","no-smoking","smoking","shopping-cart-full","shopping-cart-1","shopping-cart-2","shopping-bag-1","shopping-bag-2","sold-out","sell","present","box","bank-card","money","coin","wallet","discount","price-tag","news","guide","male","female","thumb","cpu","link","connection","open","turn-off","set-up","chat-round","chat-line-round","chat-square","chat-dot-round","chat-dot-square","chat-line-square","message","postcard","position","turn-off-microphone","microphone","close-notification","bangzhu","time","odometer","crop","aim","switch-button","full-screen","copy-document","mic","stopwatch","medal-1","medal","trophy","trophy-1","first-aid-kit","discover","place","location","location-outline","location-information","add-location","delete-location","map-location","alarm-clock","timer","watch-1","watch","lock","unlock","key","service","mobile-phone","bicycle","truck","ship","basketball","football","soccer","baseball","wind-power","light-rain","lightning","heavy-rain","sunrise","sunrise-1","sunset","sunny","cloudy","partly-cloudy","cloudy-and-sunny","moon","moon-night","dish","dish-1","food","chicken","fork-spoon","knife-fork","burger","tableware","sugar","dessert","ice-cream","hot-water","water-cup","coffee-cup","cold-drink","goblet","goblet-full","goblet-square","goblet-square-full","refrigerator","grape","watermelon","cherry","apple","pear","orange","coffee","ice-tea","ice-drink","milk-tea","potato-strips","lollipop","ice-cream-square","ice-cream-round"]
\ No newline at end of file
diff --git a/oms-vue/src/utils/generator/js.js b/oms-vue/src/utils/generator/js.js
new file mode 100644
index 00000000..ee8668dc
--- /dev/null
+++ b/oms-vue/src/utils/generator/js.js
@@ -0,0 +1,235 @@
+import { exportDefault, titleCase } from '@/utils/index'
+import { trigger } from './config'
+
+const units = {
+ KB: '1024',
+ MB: '1024 / 1024',
+ GB: '1024 / 1024 / 1024'
+}
+let confGlobal
+const inheritAttrs = {
+ file: '',
+ dialog: 'inheritAttrs: false,'
+}
+
+
+export function makeUpJs(conf, type) {
+ confGlobal = conf = JSON.parse(JSON.stringify(conf))
+ const dataList = []
+ const ruleList = []
+ const optionsList = []
+ const propsList = []
+ const methodList = mixinMethod(type)
+ const uploadVarList = []
+
+ conf.fields.forEach(el => {
+ buildAttributes(el, dataList, ruleList, optionsList, methodList, propsList, uploadVarList)
+ })
+
+ const script = buildexport(
+ conf,
+ type,
+ dataList.join('\n'),
+ ruleList.join('\n'),
+ optionsList.join('\n'),
+ uploadVarList.join('\n'),
+ propsList.join('\n'),
+ methodList.join('\n')
+ )
+ confGlobal = null
+ return script
+}
+
+function buildAttributes(el, dataList, ruleList, optionsList, methodList, propsList, uploadVarList) {
+ buildData(el, dataList)
+ buildRules(el, ruleList)
+
+ if (el.options && el.options.length) {
+ buildOptions(el, optionsList)
+ if (el.dataType === 'dynamic') {
+ const model = `${el.vModel}Options`
+ const options = titleCase(model)
+ buildOptionMethod(`get${options}`, model, methodList)
+ }
+ }
+
+ if (el.props && el.props.props) {
+ buildProps(el, propsList)
+ }
+
+ if (el.action && el.tag === 'el-upload') {
+ uploadVarList.push(
+ `${el.vModel}Action: '${el.action}',
+ ${el.vModel}fileList: [],`
+ )
+ methodList.push(buildBeforeUpload(el))
+ if (!el['auto-upload']) {
+ methodList.push(buildSubmitUpload(el))
+ }
+ }
+
+ if (el.children) {
+ el.children.forEach(el2 => {
+ buildAttributes(el2, dataList, ruleList, optionsList, methodList, propsList, uploadVarList)
+ })
+ }
+}
+
+function mixinMethod(type) {
+ const list = []; const
+ minxins = {
+ file: confGlobal.formBtns ? {
+ submitForm: `submitForm() {
+ this.$refs['${confGlobal.formRef}'].validate(valid => {
+ if(!valid) return
+ // TODO 提交表单
+ })
+ },`,
+ resetForm: `resetForm() {
+ this.$refs['${confGlobal.formRef}'].resetFields()
+ },`
+ } : null,
+ dialog: {
+ onOpen: 'onOpen() {},',
+ onClose: `onClose() {
+ this.$refs['${confGlobal.formRef}'].resetFields()
+ },`,
+ close: `close() {
+ this.$emit('update:visible', false)
+ },`,
+ handleConfirm: `handleConfirm() {
+ this.$refs['${confGlobal.formRef}'].validate(valid => {
+ if(!valid) return
+ this.close()
+ })
+ },`
+ }
+ }
+
+ const methods = minxins[type]
+ if (methods) {
+ Object.keys(methods).forEach(key => {
+ list.push(methods[key])
+ })
+ }
+
+ return list
+}
+
+function buildData(conf, dataList) {
+ if (conf.vModel === undefined) return
+ let defaultValue
+ if (typeof (conf.defaultValue) === 'string' && !conf.multiple) {
+ defaultValue = `'${conf.defaultValue}'`
+ } else {
+ defaultValue = `${JSON.stringify(conf.defaultValue)}`
+ }
+ dataList.push(`${conf.vModel}: ${defaultValue},`)
+}
+
+function buildRules(conf, ruleList) {
+ if (conf.vModel === undefined) return
+ const rules = []
+ if (trigger[conf.tag]) {
+ if (conf.required) {
+ const type = Array.isArray(conf.defaultValue) ? 'type: \'array\',' : ''
+ let message = Array.isArray(conf.defaultValue) ? `请至少选择一个${conf.vModel}` : conf.placeholder
+ if (message === undefined) message = `${conf.label}不能为空`
+ rules.push(`{ required: true, ${type} message: '${message}', trigger: '${trigger[conf.tag]}' }`)
+ }
+ if (conf.regList && Array.isArray(conf.regList)) {
+ conf.regList.forEach(item => {
+ if (item.pattern) {
+ rules.push(`{ pattern: ${eval(item.pattern)}, message: '${item.message}', trigger: '${trigger[conf.tag]}' }`)
+ }
+ })
+ }
+ ruleList.push(`${conf.vModel}: [${rules.join(',')}],`)
+ }
+}
+
+function buildOptions(conf, optionsList) {
+ if (conf.vModel === undefined) return
+ if (conf.dataType === 'dynamic') { conf.options = [] }
+ const str = `${conf.vModel}Options: ${JSON.stringify(conf.options)},`
+ optionsList.push(str)
+}
+
+function buildProps(conf, propsList) {
+ if (conf.dataType === 'dynamic') {
+ conf.valueKey !== 'value' && (conf.props.props.value = conf.valueKey)
+ conf.labelKey !== 'label' && (conf.props.props.label = conf.labelKey)
+ conf.childrenKey !== 'children' && (conf.props.props.children = conf.childrenKey)
+ }
+ const str = `${conf.vModel}Props: ${JSON.stringify(conf.props.props)},`
+ propsList.push(str)
+}
+
+function buildBeforeUpload(conf) {
+ const unitNum = units[conf.sizeUnit]; let rightSizeCode = ''; let acceptCode = ''; const
+ returnList = []
+ if (conf.fileSize) {
+ rightSizeCode = `let isRightSize = file.size / ${unitNum} < ${conf.fileSize}
+ if(!isRightSize){
+ this.$message.error('文件大小超过 ${conf.fileSize}${conf.sizeUnit}')
+ }`
+ returnList.push('isRightSize')
+ }
+ if (conf.accept) {
+ acceptCode = `let isAccept = new RegExp('${conf.accept}').test(file.type)
+ if(!isAccept){
+ this.$message.error('应该选择${conf.accept}类型的文件')
+ }`
+ returnList.push('isAccept')
+ }
+ const str = `${conf.vModel}BeforeUpload(file) {
+ ${rightSizeCode}
+ ${acceptCode}
+ return ${returnList.join('&&')}
+ },`
+ return returnList.length ? str : ''
+}
+
+function buildSubmitUpload(conf) {
+ const str = `submitUpload() {
+ this.$refs['${conf.vModel}'].submit()
+ },`
+ return str
+}
+
+function buildOptionMethod(methodName, model, methodList) {
+ const str = `${methodName}() {
+ // TODO 发起请求获取数据
+ this.${model}
+ },`
+ methodList.push(str)
+}
+
+function buildexport(conf, type, data, rules, selectOptions, uploadVar, props, methods) {
+ const str = `${exportDefault}{
+ ${inheritAttrs[type]}
+ components: {},
+ props: [],
+ data () {
+ return {
+ ${conf.formModel}: {
+ ${data}
+ },
+ ${conf.formRules}: {
+ ${rules}
+ },
+ ${uploadVar}
+ ${selectOptions}
+ ${props}
+ }
+ },
+ computed: {},
+ watch: {},
+ created () {},
+ mounted () {},
+ methods: {
+ ${methods}
+ }
+}`
+ return str
+}
diff --git a/oms-vue/src/utils/generator/render.js b/oms-vue/src/utils/generator/render.js
new file mode 100644
index 00000000..e8640f0a
--- /dev/null
+++ b/oms-vue/src/utils/generator/render.js
@@ -0,0 +1,126 @@
+import { makeMap } from '@/utils/index'
+
+// 参考https://github.com/vuejs/vue/blob/v2.6.10/src/platforms/web/server/util.js
+const isAttr = makeMap(
+ 'accept,accept-charset,accesskey,action,align,alt,async,autocomplete,'
+ + 'autofocus,autoplay,autosave,bgcolor,border,buffered,challenge,charset,'
+ + 'checked,cite,class,code,codebase,color,cols,colspan,content,http-equiv,'
+ + 'name,contenteditable,contextmenu,controls,coords,data,datetime,default,'
+ + 'defer,dir,dirname,disabled,download,draggable,dropzone,enctype,method,for,'
+ + 'form,formaction,headers,height,hidden,high,href,hreflang,http-equiv,'
+ + 'icon,id,ismap,itemprop,keytype,kind,label,lang,language,list,loop,low,'
+ + 'manifest,max,maxlength,media,method,GET,POST,min,multiple,email,file,'
+ + 'muted,name,novalidate,open,optimum,pattern,ping,placeholder,poster,'
+ + 'preload,radiogroup,readonly,rel,required,reversed,rows,rowspan,sandbox,'
+ + 'scope,scoped,seamless,selected,shape,size,type,text,password,sizes,span,'
+ + 'spellcheck,src,srcdoc,srclang,srcset,start,step,style,summary,tabindex,'
+ + 'target,title,type,usemap,value,width,wrap'
+)
+
+function vModel(self, dataObject, defaultValue) {
+ dataObject.props.value = defaultValue
+
+ dataObject.on.input = val => {
+ self.$emit('input', val)
+ }
+}
+
+const componentChild = {
+ 'el-button': {
+ default(h, conf, key) {
+ return conf[key]
+ },
+ },
+ 'el-input': {
+ prepend(h, conf, key) {
+ return {conf[key]}
+ },
+ append(h, conf, key) {
+ return {conf[key]}
+ }
+ },
+ 'el-select': {
+ options(h, conf, key) {
+ const list = []
+ conf.options.forEach(item => {
+ list.push()
+ })
+ return list
+ }
+ },
+ 'el-radio-group': {
+ options(h, conf, key) {
+ const list = []
+ conf.options.forEach(item => {
+ if (conf.optionType === 'button') list.push({item.label})
+ else list.push({item.label})
+ })
+ return list
+ }
+ },
+ 'el-checkbox-group': {
+ options(h, conf, key) {
+ const list = []
+ conf.options.forEach(item => {
+ if (conf.optionType === 'button') {
+ list.push({item.label})
+ } else {
+ list.push({item.label})
+ }
+ })
+ return list
+ }
+ },
+ 'el-upload': {
+ 'list-type': (h, conf, key) => {
+ const list = []
+ if (conf['list-type'] === 'picture-card') {
+ list.push()
+ } else {
+ list.push({conf.buttonText})
+ }
+ if (conf.showTip) {
+ list.push(只能上传不超过 {conf.fileSize}{conf.sizeUnit} 的{conf.accept}文件
)
+ }
+ return list
+ }
+ }
+}
+
+export default {
+ render(h) {
+ const dataObject = {
+ attrs: {},
+ props: {},
+ on: {},
+ style: {}
+ }
+ const confClone = JSON.parse(JSON.stringify(this.conf))
+ const children = []
+
+ const childObjs = componentChild[confClone.tag]
+ if (childObjs) {
+ Object.keys(childObjs).forEach(key => {
+ const childFunc = childObjs[key]
+ if (confClone[key]) {
+ children.push(childFunc(h, confClone, key))
+ }
+ })
+ }
+
+ Object.keys(confClone).forEach(key => {
+ const val = confClone[key]
+ if (key === 'vModel') {
+ vModel(this, dataObject, confClone.defaultValue)
+ } else if (dataObject[key]) {
+ dataObject[key] = val
+ } else if (!isAttr(key)) {
+ dataObject.props[key] = val
+ } else {
+ dataObject.attrs[key] = val
+ }
+ })
+ return h(this.conf.tag, dataObject, children)
+ },
+ props: ['conf']
+}
diff --git a/oms-vue/src/utils/index.js b/oms-vue/src/utils/index.js
new file mode 100644
index 00000000..7d6bb43f
--- /dev/null
+++ b/oms-vue/src/utils/index.js
@@ -0,0 +1,390 @@
+import { parseTime } from './zhijian'
+
+/**
+ * 表格时间格式化
+ */
+export function formatDate(cellValue) {
+ if (cellValue == null || cellValue == "") return "";
+ var date = new Date(cellValue)
+ var year = date.getFullYear()
+ var month = date.getMonth() + 1 < 10 ? '0' + (date.getMonth() + 1) : date.getMonth() + 1
+ var day = date.getDate() < 10 ? '0' + date.getDate() : date.getDate()
+ var hours = date.getHours() < 10 ? '0' + date.getHours() : date.getHours()
+ var minutes = date.getMinutes() < 10 ? '0' + date.getMinutes() : date.getMinutes()
+ var seconds = date.getSeconds() < 10 ? '0' + date.getSeconds() : date.getSeconds()
+ return year + '-' + month + '-' + day + ' ' + hours + ':' + minutes + ':' + seconds
+}
+
+/**
+ * @param {number} time
+ * @param {string} option
+ * @returns {string}
+ */
+export function formatTime(time, option) {
+ if (('' + time).length === 10) {
+ time = parseInt(time) * 1000
+ } else {
+ time = +time
+ }
+ const d = new Date(time)
+ const now = Date.now()
+
+ const diff = (now - d) / 1000
+
+ if (diff < 30) {
+ return '刚刚'
+ } else if (diff < 3600) {
+ // less 1 hour
+ return Math.ceil(diff / 60) + '分钟前'
+ } else if (diff < 3600 * 24) {
+ return Math.ceil(diff / 3600) + '小时前'
+ } else if (diff < 3600 * 24 * 2) {
+ return '1天前'
+ }
+ if (option) {
+ return parseTime(time, option)
+ } else {
+ return (
+ d.getMonth() +
+ 1 +
+ '月' +
+ d.getDate() +
+ '日' +
+ d.getHours() +
+ '时' +
+ d.getMinutes() +
+ '分'
+ )
+ }
+}
+
+/**
+ * @param {string} url
+ * @returns {Object}
+ */
+export function getQueryObject(url) {
+ url = url == null ? window.location.href : url
+ const search = url.substring(url.lastIndexOf('?') + 1)
+ const obj = {}
+ const reg = /([^?&=]+)=([^?&=]*)/g
+ search.replace(reg, (rs, $1, $2) => {
+ const name = decodeURIComponent($1)
+ let val = decodeURIComponent($2)
+ val = String(val)
+ obj[name] = val
+ return rs
+ })
+ return obj
+}
+
+/**
+ * @param {string} input value
+ * @returns {number} output value
+ */
+export function byteLength(str) {
+ // returns the byte length of an utf8 string
+ let s = str.length
+ for (var i = str.length - 1; i >= 0; i--) {
+ const code = str.charCodeAt(i)
+ if (code > 0x7f && code <= 0x7ff) s++
+ else if (code > 0x7ff && code <= 0xffff) s += 2
+ if (code >= 0xDC00 && code <= 0xDFFF) i--
+ }
+ return s
+}
+
+/**
+ * @param {Array} actual
+ * @returns {Array}
+ */
+export function cleanArray(actual) {
+ const newArray = []
+ for (let i = 0; i < actual.length; i++) {
+ if (actual[i]) {
+ newArray.push(actual[i])
+ }
+ }
+ return newArray
+}
+
+/**
+ * @param {Object} json
+ * @returns {Array}
+ */
+export function param(json) {
+ if (!json) return ''
+ return cleanArray(
+ Object.keys(json).map(key => {
+ if (json[key] === undefined) return ''
+ return encodeURIComponent(key) + '=' + encodeURIComponent(json[key])
+ })
+ ).join('&')
+}
+
+/**
+ * @param {string} url
+ * @returns {Object}
+ */
+export function param2Obj(url) {
+ const search = decodeURIComponent(url.split('?')[1]).replace(/\+/g, ' ')
+ if (!search) {
+ return {}
+ }
+ const obj = {}
+ const searchArr = search.split('&')
+ searchArr.forEach(v => {
+ const index = v.indexOf('=')
+ if (index !== -1) {
+ const name = v.substring(0, index)
+ const val = v.substring(index + 1, v.length)
+ obj[name] = val
+ }
+ })
+ return obj
+}
+
+/**
+ * @param {string} val
+ * @returns {string}
+ */
+export function html2Text(val) {
+ const div = document.createElement('div')
+ div.innerHTML = val
+ return div.textContent || div.innerText
+}
+
+/**
+ * Merges two objects, giving the last one precedence
+ * @param {Object} target
+ * @param {(Object|Array)} source
+ * @returns {Object}
+ */
+export function objectMerge(target, source) {
+ if (typeof target !== 'object') {
+ target = {}
+ }
+ if (Array.isArray(source)) {
+ return source.slice()
+ }
+ Object.keys(source).forEach(property => {
+ const sourceProperty = source[property]
+ if (typeof sourceProperty === 'object') {
+ target[property] = objectMerge(target[property], sourceProperty)
+ } else {
+ target[property] = sourceProperty
+ }
+ })
+ return target
+}
+
+/**
+ * @param {HTMLElement} element
+ * @param {string} className
+ */
+export function toggleClass(element, className) {
+ if (!element || !className) {
+ return
+ }
+ let classString = element.className
+ const nameIndex = classString.indexOf(className)
+ if (nameIndex === -1) {
+ classString += '' + className
+ } else {
+ classString =
+ classString.substr(0, nameIndex) +
+ classString.substr(nameIndex + className.length)
+ }
+ element.className = classString
+}
+
+/**
+ * @param {string} type
+ * @returns {Date}
+ */
+export function getTime(type) {
+ if (type === 'start') {
+ return new Date().getTime() - 3600 * 1000 * 24 * 90
+ } else {
+ return new Date(new Date().toDateString())
+ }
+}
+
+/**
+ * @param {Function} func
+ * @param {number} wait
+ * @param {boolean} immediate
+ * @return {*}
+ */
+export function debounce(func, wait, immediate) {
+ let timeout, args, context, timestamp, result
+
+ const later = function() {
+ // 据上一次触发时间间隔
+ const last = +new Date() - timestamp
+
+ // 上次被包装函数被调用时间间隔 last 小于设定时间间隔 wait
+ if (last < wait && last > 0) {
+ timeout = setTimeout(later, wait - last)
+ } else {
+ timeout = null
+ // 如果设定为immediate===true,因为开始边界已经调用过了此处无需调用
+ if (!immediate) {
+ result = func.apply(context, args)
+ if (!timeout) context = args = null
+ }
+ }
+ }
+
+ return function(...args) {
+ context = this
+ timestamp = +new Date()
+ const callNow = immediate && !timeout
+ // 如果延时不存在,重新设定延时
+ if (!timeout) timeout = setTimeout(later, wait)
+ if (callNow) {
+ result = func.apply(context, args)
+ context = args = null
+ }
+
+ return result
+ }
+}
+
+/**
+ * This is just a simple version of deep copy
+ * Has a lot of edge cases bug
+ * If you want to use a perfect deep copy, use lodash's _.cloneDeep
+ * @param {Object} source
+ * @returns {Object}
+ */
+export function deepClone(source) {
+ if (!source && typeof source !== 'object') {
+ throw new Error('error arguments', 'deepClone')
+ }
+ const targetObj = source.constructor === Array ? [] : {}
+ Object.keys(source).forEach(keys => {
+ if (source[keys] && typeof source[keys] === 'object') {
+ targetObj[keys] = deepClone(source[keys])
+ } else {
+ targetObj[keys] = source[keys]
+ }
+ })
+ return targetObj
+}
+
+/**
+ * @param {Array} arr
+ * @returns {Array}
+ */
+export function uniqueArr(arr) {
+ return Array.from(new Set(arr))
+}
+
+/**
+ * @returns {string}
+ */
+export function createUniqueString() {
+ const timestamp = +new Date() + ''
+ const randomNum = parseInt((1 + Math.random()) * 65536) + ''
+ return (+(randomNum + timestamp)).toString(32)
+}
+
+/**
+ * Check if an element has a class
+ * @param {HTMLElement} elm
+ * @param {string} cls
+ * @returns {boolean}
+ */
+export function hasClass(ele, cls) {
+ return !!ele.className.match(new RegExp('(\\s|^)' + cls + '(\\s|$)'))
+}
+
+/**
+ * Add class to element
+ * @param {HTMLElement} elm
+ * @param {string} cls
+ */
+export function addClass(ele, cls) {
+ if (!hasClass(ele, cls)) ele.className += ' ' + cls
+}
+
+/**
+ * Remove class from element
+ * @param {HTMLElement} elm
+ * @param {string} cls
+ */
+export function removeClass(ele, cls) {
+ if (hasClass(ele, cls)) {
+ const reg = new RegExp('(\\s|^)' + cls + '(\\s|$)')
+ ele.className = ele.className.replace(reg, ' ')
+ }
+}
+
+export function makeMap(str, expectsLowerCase) {
+ const map = Object.create(null)
+ const list = str.split(',')
+ for (let i = 0; i < list.length; i++) {
+ map[list[i]] = true
+ }
+ return expectsLowerCase
+ ? val => map[val.toLowerCase()]
+ : val => map[val]
+}
+
+export const exportDefault = 'export default '
+
+export const beautifierConf = {
+ html: {
+ indent_size: '2',
+ indent_char: ' ',
+ max_preserve_newlines: '-1',
+ preserve_newlines: false,
+ keep_array_indentation: false,
+ break_chained_methods: false,
+ indent_scripts: 'separate',
+ brace_style: 'end-expand',
+ space_before_conditional: true,
+ unescape_strings: false,
+ jslint_happy: false,
+ end_with_newline: true,
+ wrap_line_length: '110',
+ indent_inner_html: true,
+ comma_first: false,
+ e4x: true,
+ indent_empty_lines: true
+ },
+ js: {
+ indent_size: '2',
+ indent_char: ' ',
+ max_preserve_newlines: '-1',
+ preserve_newlines: false,
+ keep_array_indentation: false,
+ break_chained_methods: false,
+ indent_scripts: 'normal',
+ brace_style: 'end-expand',
+ space_before_conditional: true,
+ unescape_strings: false,
+ jslint_happy: true,
+ end_with_newline: true,
+ wrap_line_length: '110',
+ indent_inner_html: true,
+ comma_first: false,
+ e4x: true,
+ indent_empty_lines: true
+ }
+}
+
+// 首字母大小
+export function titleCase(str) {
+ return str.replace(/( |^)[a-z]/g, L => L.toUpperCase())
+}
+
+// 下划转驼峰
+export function camelCase(str) {
+ return str.replace(/_[a-z]/g, str1 => str1.substr(-1).toUpperCase())
+}
+
+export function isNumberStr(str) {
+ return /^[+-]?(0|([1-9]\d*))(\.\d+)?$/g.test(str)
+}
+
diff --git a/oms-vue/src/utils/jsencrypt.js b/oms-vue/src/utils/jsencrypt.js
new file mode 100644
index 00000000..78d95234
--- /dev/null
+++ b/oms-vue/src/utils/jsencrypt.js
@@ -0,0 +1,30 @@
+import JSEncrypt from 'jsencrypt/bin/jsencrypt.min'
+
+// 密钥对生成 http://web.chacuo.net/netrsakeypair
+
+const publicKey = 'MFwwDQYJKoZIhvcNAQEBBQADSwAwSAJBAKoR8mX0rGKLqzcWmOzbfj64K8ZIgOdH\n' +
+ 'nzkXSOVOZbFu/TJhZ7rFAN+eaGkl3C4buccQd/EjEsj9ir7ijT7h96MCAwEAAQ=='
+
+const privateKey = 'MIIBVAIBADANBgkqhkiG9w0BAQEFAASCAT4wggE6AgEAAkEAqhHyZfSsYourNxaY\n' +
+ '7Nt+PrgrxkiA50efORdI5U5lsW79MmFnusUA355oaSXcLhu5xxB38SMSyP2KvuKN\n' +
+ 'PuH3owIDAQABAkAfoiLyL+Z4lf4Myxk6xUDgLaWGximj20CUf+5BKKnlrK+Ed8gA\n' +
+ 'kM0HqoTt2UZwA5E2MzS4EI2gjfQhz5X28uqxAiEA3wNFxfrCZlSZHb0gn2zDpWow\n' +
+ 'cSxQAgiCstxGUoOqlW8CIQDDOerGKH5OmCJ4Z21v+F25WaHYPxCFMvwxpcw99Ecv\n' +
+ 'DQIgIdhDTIqD2jfYjPTY8Jj3EDGPbH2HHuffvflECt3Ek60CIQCFRlCkHpi7hthh\n' +
+ 'YhovyloRYsM+IS9h/0BzlEAuO0ktMQIgSPT3aFAgJYwKpqRYKlLDVcflZFCKY7u3\n' +
+ 'UP8iWi1Qw0Y='
+
+// 加密
+export function encrypt(txt) {
+ const encryptor = new JSEncrypt()
+ encryptor.setPublicKey(publicKey) // 设置公钥
+ return encryptor.encrypt(txt) // 对数据进行加密
+}
+
+// 解密
+export function decrypt(txt) {
+ const encryptor = new JSEncrypt()
+ encryptor.setPrivateKey(privateKey) // 设置私钥
+ return encryptor.decrypt(txt) // 对数据进行解密
+}
+
diff --git a/oms-vue/src/utils/permission.js b/oms-vue/src/utils/permission.js
new file mode 100644
index 00000000..1730e332
--- /dev/null
+++ b/oms-vue/src/utils/permission.js
@@ -0,0 +1,51 @@
+import store from '@/store'
+
+/**
+ * 字符权限校验
+ * @param {Array} value 校验值
+ * @returns {Boolean}
+ */
+export function checkPermi(value) {
+ if (value && value instanceof Array && value.length > 0) {
+ const permissions = store.getters && store.getters.permissions
+ const permissionDatas = value
+ const all_permission = "*:*:*";
+
+ const hasPermission = permissions.some(permission => {
+ return all_permission === permission || permissionDatas.includes(permission)
+ })
+
+ if (!hasPermission) {
+ return false
+ }
+ return true
+ } else {
+ console.error(`need roles! Like checkPermi="['system:user:add','system:user:edit']"`)
+ return false
+ }
+}
+
+/**
+ * 角色权限校验
+ * @param {Array} value 校验值
+ * @returns {Boolean}
+ */
+export function checkRole(value) {
+ if (value && value instanceof Array && value.length > 0) {
+ const roles = store.getters && store.getters.roles
+ const permissionRoles = value
+ const super_admin = "admin";
+
+ const hasRole = roles.some(role => {
+ return super_admin === role || permissionRoles.includes(role)
+ })
+
+ if (!hasRole) {
+ return false
+ }
+ return true
+ } else {
+ console.error(`need roles! Like checkRole="['admin','editor']"`)
+ return false
+ }
+}
\ No newline at end of file
diff --git a/oms-vue/src/utils/request.js b/oms-vue/src/utils/request.js
new file mode 100644
index 00000000..0778c867
--- /dev/null
+++ b/oms-vue/src/utils/request.js
@@ -0,0 +1,160 @@
+import axios from 'axios'
+import { Notification, MessageBox, Message, Loading } from 'element-ui'
+import store from '@/store'
+import { getToken } from '@/utils/auth'
+import errorCode from '@/utils/errorCode'
+import { tansParams, blobValidate } from "@/utils/zhijian";
+import cache from '@/plugins/cache'
+import { saveAs } from 'file-saver'
+
+let downloadLoadingInstance;
+// 是否显示重新登录
+export let isRelogin = { show: false };
+
+axios.defaults.headers['Content-Type'] = 'application/json;charset=utf-8'
+// 创建axios实例
+const service = axios.create({
+ // axios中请求配置有baseURL选项,表示请求URL公共部分
+ baseURL: process.env.VUE_APP_BASE_API,
+ // 超时
+ timeout: 10000
+})
+
+// request拦截器
+service.interceptors.request.use(config => {
+ // 是否需要设置 token
+ const isToken = (config.headers || {}).isToken === false
+ // 是否需要防止数据重复提交
+ const isRepeatSubmit = (config.headers || {}).repeatSubmit === false
+ if (getToken() && !isToken) {
+ config.headers['Authorization'] = 'Bearer ' + getToken() // 让每个请求携带自定义token 请根据实际情况自行修改
+ }
+ // get请求映射params参数
+ if (config.method === 'get' && config.params) {
+ let url = config.url + '?' + tansParams(config.params);
+ url = url.slice(0, -1);
+ config.params = {};
+ config.url = url;
+ }
+ if (!isRepeatSubmit && (config.method === 'post' || config.method === 'put')) {
+ const requestObj = {
+ url: config.url,
+ data: typeof config.data === 'object' ? JSON.stringify(config.data) : config.data,
+ time: new Date().getTime()
+ }
+ const sessionObj = cache.session.getJSON('sessionObj')
+ if (sessionObj === undefined || sessionObj === null || sessionObj === '') {
+ cache.session.setJSON('sessionObj', requestObj)
+ } else {
+ const s_url = sessionObj.url; // 请求地址
+ const s_data = sessionObj.data; // 请求数据
+ const s_time = sessionObj.time; // 请求时间
+ const interval = 1000; // 间隔时间(ms),小于此时间视为重复提交
+ if (s_data === requestObj.data && requestObj.time - s_time < interval && s_url === requestObj.url) {
+ const message = '数据正在处理,请勿重复提交';
+ console.warn(`[${s_url}]: ` + message)
+ return Promise.reject(new Error(message))
+ } else {
+ cache.session.setJSON('sessionObj', requestObj)
+ }
+ }
+ }
+ return config
+}, error => {
+ console.log(error)
+ Promise.reject(error)
+})
+
+// 响应拦截器
+service.interceptors.response.use(res => {
+ // 未设置状态码则默认成功状态
+ const code = res.data.code || 200;
+ // 获取错误信息
+ const msg = errorCode[code] || res.data.msg || errorCode['default']
+ // 二进制数据则直接返回
+ if (res.request.responseType === 'blob' || res.request.responseType === 'arraybuffer') {
+ return res.data
+ }
+ if (code === 401) {
+ if (!isRelogin.show) {
+ isRelogin.show = true;
+ MessageBox.confirm('登录状态已过期,您可以继续留在该页面,或者重新登录', '系统提示', { confirmButtonText: '重新登录', cancelButtonText: '取消', type: 'warning' }).then(() => {
+ isRelogin.show = false;
+ store.dispatch('LogOut').then(() => {
+ location.href = '/index';
+ })
+ }).catch(() => {
+ isRelogin.show = false;
+ });
+ }
+ return Promise.reject('无效的会话,或者会话已过期,请重新登录。')
+ }else if (code === 1401) {
+ // if (!isRelogin.show) {
+ // isRelogin.show = true;
+ // MessageBox.confirm('Token已过期,需要重新授权', '系统提示', { confirmButtonText: '重新授权', cancelButtonText: '取消', type: 'warning' }).then(() => {
+ // isRelogin.show = false;
+ // // store.dispatch('LogOut').then(() => {
+ // location.href = 'http://taobao.com';/taoapi2/tao_oauth
+ // // })
+ // }).catch(() => {
+ // isRelogin.show = false;
+ // });
+ // }
+ // return Promise.reject('无效的会话,或者会话已过期,请重新登录。')
+ return res.data
+ } else if (code === 500) {
+ Message({ message: msg, type: 'error' })
+ return Promise.reject(new Error(msg))
+ } else if (code === 601) {
+ Message({ message: msg, type: 'warning' })
+ return Promise.reject('error')
+ } else if (code !== 200) {
+ Notification.error({ title: msg })
+ return Promise.reject('error')
+ } else {
+ return res.data
+ }
+ },
+ error => {
+ console.log('err' + error)
+ let { message } = error;
+ if (message == "Network Error") {
+ message = "后端接口连接异常";
+ } else if (message.includes("timeout")) {
+ message = "系统接口请求超时";
+ } else if (message.includes("Request failed with status code")) {
+ message = "系统接口" + message.substr(message.length - 3) + "异常";
+ }
+ Message({ message: message, type: 'error', duration: 5 * 1000 })
+ return Promise.reject(error)
+ }
+)
+
+// 通用下载方法
+export function download(url, params, filename, config) {
+ downloadLoadingInstance = Loading.service({ text: "正在下载数据,请稍候", spinner: "el-icon-loading", background: "rgba(0, 0, 0, 0.7)", })
+ return service.post(url, params, {
+ transformRequest: [(params) => { return tansParams(params) }],
+ headers: { 'Content-Type': 'application/x-www-form-urlencoded' },
+ responseType: 'blob',
+ ...config
+ }).then(async (data) => {
+ const isBlob = blobValidate(data);
+ if (isBlob) {
+ const blob = new Blob([data])
+ saveAs(blob, filename)
+ } else {
+ const resText = await data.text();
+ const rspObj = JSON.parse(resText);
+ const errMsg = errorCode[rspObj.code] || rspObj.msg || errorCode['default']
+ Message.error(errMsg);
+ }
+ downloadLoadingInstance.close();
+ }).catch((r) => {
+ console.error(r)
+ Message.error('下载文件出现错误,请联系管理员!')
+ downloadLoadingInstance.close();
+ })
+}
+
+export default service
diff --git a/oms-vue/src/utils/scroll-to.js b/oms-vue/src/utils/scroll-to.js
new file mode 100644
index 00000000..c5d8e04e
--- /dev/null
+++ b/oms-vue/src/utils/scroll-to.js
@@ -0,0 +1,58 @@
+Math.easeInOutQuad = function(t, b, c, d) {
+ t /= d / 2
+ if (t < 1) {
+ return c / 2 * t * t + b
+ }
+ t--
+ return -c / 2 * (t * (t - 2) - 1) + b
+}
+
+// requestAnimationFrame for Smart Animating http://goo.gl/sx5sts
+var requestAnimFrame = (function() {
+ return window.requestAnimationFrame || window.webkitRequestAnimationFrame || window.mozRequestAnimationFrame || function(callback) { window.setTimeout(callback, 1000 / 60) }
+})()
+
+/**
+ * Because it's so fucking difficult to detect the scrolling element, just move them all
+ * @param {number} amount
+ */
+function move(amount) {
+ document.documentElement.scrollTop = amount
+ document.body.parentNode.scrollTop = amount
+ document.body.scrollTop = amount
+}
+
+function position() {
+ return document.documentElement.scrollTop || document.body.parentNode.scrollTop || document.body.scrollTop
+}
+
+/**
+ * @param {number} to
+ * @param {number} duration
+ * @param {Function} callback
+ */
+export function scrollTo(to, duration, callback) {
+ const start = position()
+ const change = to - start
+ const increment = 20
+ let currentTime = 0
+ duration = (typeof (duration) === 'undefined') ? 500 : duration
+ var animateScroll = function() {
+ // increment the time
+ currentTime += increment
+ // find the value with the quadratic in-out easing function
+ var val = Math.easeInOutQuad(currentTime, start, change, duration)
+ // move the document.body
+ move(val)
+ // do the animation unless its over
+ if (currentTime < duration) {
+ requestAnimFrame(animateScroll)
+ } else {
+ if (callback && typeof (callback) === 'function') {
+ // the animation is done so lets callback
+ callback()
+ }
+ }
+ }
+ animateScroll()
+}
diff --git a/oms-vue/src/utils/validate.js b/oms-vue/src/utils/validate.js
new file mode 100644
index 00000000..adfa2542
--- /dev/null
+++ b/oms-vue/src/utils/validate.js
@@ -0,0 +1,83 @@
+/**
+ * @param {string} path
+ * @returns {Boolean}
+ */
+export function isExternal(path) {
+ return /^(https?:|mailto:|tel:)/.test(path)
+}
+
+/**
+ * @param {string} str
+ * @returns {Boolean}
+ */
+export function validUsername(str) {
+ const valid_map = ['admin', 'editor']
+ return valid_map.indexOf(str.trim()) >= 0
+}
+
+/**
+ * @param {string} url
+ * @returns {Boolean}
+ */
+export function validURL(url) {
+ const reg = /^(https?|ftp):\/\/([a-zA-Z0-9.-]+(:[a-zA-Z0-9.&%$-]+)*@)*((25[0-5]|2[0-4][0-9]|1[0-9]{2}|[1-9][0-9]?)(\.(25[0-5]|2[0-4][0-9]|1[0-9]{2}|[1-9]?[0-9])){3}|([a-zA-Z0-9-]+\.)*[a-zA-Z0-9-]+\.(com|edu|gov|int|mil|net|org|biz|arpa|info|name|pro|aero|coop|museum|[a-zA-Z]{2}))(:[0-9]+)*(\/($|[a-zA-Z0-9.,?'\\+&%$#=~_-]+))*$/
+ return reg.test(url)
+}
+
+/**
+ * @param {string} str
+ * @returns {Boolean}
+ */
+export function validLowerCase(str) {
+ const reg = /^[a-z]+$/
+ return reg.test(str)
+}
+
+/**
+ * @param {string} str
+ * @returns {Boolean}
+ */
+export function validUpperCase(str) {
+ const reg = /^[A-Z]+$/
+ return reg.test(str)
+}
+
+/**
+ * @param {string} str
+ * @returns {Boolean}
+ */
+export function validAlphabets(str) {
+ const reg = /^[A-Za-z]+$/
+ return reg.test(str)
+}
+
+/**
+ * @param {string} email
+ * @returns {Boolean}
+ */
+export function validEmail(email) {
+ const reg = /^(([^<>()\[\]\\.,;:\s@"]+(\.[^<>()\[\]\\.,;:\s@"]+)*)|(".+"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/
+ return reg.test(email)
+}
+
+/**
+ * @param {string} str
+ * @returns {Boolean}
+ */
+export function isString(str) {
+ if (typeof str === 'string' || str instanceof String) {
+ return true
+ }
+ return false
+}
+
+/**
+ * @param {Array} arg
+ * @returns {Boolean}
+ */
+export function isArray(arg) {
+ if (typeof Array.isArray === 'undefined') {
+ return Object.prototype.toString.call(arg) === '[object Array]'
+ }
+ return Array.isArray(arg)
+}
diff --git a/oms-vue/src/utils/zhijian.js b/oms-vue/src/utils/zhijian.js
new file mode 100644
index 00000000..8d7cafc7
--- /dev/null
+++ b/oms-vue/src/utils/zhijian.js
@@ -0,0 +1,233 @@
+
+
+/**
+ * 通用js方法封装处理
+ * Copyright (c) 2023 zhijian
+ */
+
+// 日期格式化
+export function parseTime(time, pattern) {
+ if (arguments.length === 0 || !time) {
+ return null
+ }
+ const format = pattern || '{y}-{m}-{d} {h}:{i}:{s}'
+ let date
+ if (typeof time === 'object') {
+ date = time
+ } else {
+ if ((typeof time === 'string') && (/^[0-9]+$/.test(time))) {
+ time = parseInt(time)
+ } else if (typeof time === 'string') {
+ time = time.replace(new RegExp(/-/gm), '/').replace('T', ' ').replace(new RegExp(/\.[\d]{3}/gm), '');
+ }
+ if ((typeof time === 'number') && (time.toString().length === 10)) {
+ time = time * 1000
+ }
+ date = new Date(time)
+ }
+ const formatObj = {
+ y: date.getFullYear(),
+ m: date.getMonth() + 1,
+ d: date.getDate(),
+ h: date.getHours(),
+ i: date.getMinutes(),
+ s: date.getSeconds(),
+ a: date.getDay()
+ }
+ const time_str = format.replace(/{(y|m|d|h|i|s|a)+}/g, (result, key) => {
+ let value = formatObj[key]
+ // Note: getDay() returns 0 on Sunday
+ if (key === 'a') { return ['日', '一', '二', '三', '四', '五', '六'][value] }
+ if (result.length > 0 && value < 10) {
+ value = '0' + value
+ }
+ return value || 0
+ })
+ return time_str
+}
+
+// 表单重置
+export function resetForm(refName) {
+ if (this.$refs[refName]) {
+ this.$refs[refName].resetFields();
+ }
+}
+
+// 添加日期范围
+export function addDateRange(params, dateRange, propName) {
+ let search = params;
+ search.params = typeof (search.params) === 'object' && search.params !== null && !Array.isArray(search.params) ? search.params : {};
+ dateRange = Array.isArray(dateRange) ? dateRange : [];
+ if (typeof (propName) === 'undefined') {
+ search.params['beginTime'] = dateRange[0];
+ search.params['endTime'] = dateRange[1];
+ } else {
+ search.params['begin' + propName] = dateRange[0];
+ search.params['end' + propName] = dateRange[1];
+ }
+ return search;
+}
+
+// 回显数据字典
+export function selectDictLabel(datas, value) {
+ if (value === undefined) {
+ return "";
+ }
+ var actions = [];
+ Object.keys(datas).some((key) => {
+ if (datas[key].value == ('' + value)) {
+ actions.push(datas[key].label);
+ return true;
+ }
+ })
+ if (actions.length === 0) {
+ actions.push(value);
+ }
+ return actions.join('');
+}
+
+// 回显数据字典(字符串、数组)
+export function selectDictLabels(datas, value, separator) {
+ if (value === undefined || value.length ===0) {
+ return "";
+ }
+ if (Array.isArray(value)) {
+ value = value.join(",");
+ }
+ var actions = [];
+ var currentSeparator = undefined === separator ? "," : separator;
+ var temp = value.split(currentSeparator);
+ Object.keys(value.split(currentSeparator)).some((val) => {
+ var match = false;
+ Object.keys(datas).some((key) => {
+ if (datas[key].value == ('' + temp[val])) {
+ actions.push(datas[key].label + currentSeparator);
+ match = true;
+ }
+ })
+ if (!match) {
+ actions.push(temp[val] + currentSeparator);
+ }
+ })
+ return actions.join('').substring(0, actions.join('').length - 1);
+}
+
+// 字符串格式化(%s )
+export function sprintf(str) {
+ var args = arguments, flag = true, i = 1;
+ str = str.replace(/%s/g, function () {
+ var arg = args[i++];
+ if (typeof arg === 'undefined') {
+ flag = false;
+ return '';
+ }
+ return arg;
+ });
+ return flag ? str : '';
+}
+
+// 转换字符串,undefined,null等转化为""
+export function parseStrEmpty(str) {
+ if (!str || str == "undefined" || str == "null") {
+ return "";
+ }
+ return str;
+}
+
+// 数据合并
+export function mergeRecursive(source, target) {
+ for (var p in target) {
+ try {
+ if (target[p].constructor == Object) {
+ source[p] = mergeRecursive(source[p], target[p]);
+ } else {
+ source[p] = target[p];
+ }
+ } catch (e) {
+ source[p] = target[p];
+ }
+ }
+ return source;
+};
+
+/**
+ * 构造树型结构数据
+ * @param {*} data 数据源
+ * @param {*} id id字段 默认 'id'
+ * @param {*} parentId 父节点字段 默认 'parentId'
+ * @param {*} children 孩子节点字段 默认 'children'
+ */
+export function handleTree(data, id, parentId, children) {
+ let config = {
+ id: id || 'id',
+ parentId: parentId || 'parentId',
+ childrenList: children || 'children'
+ };
+
+ var childrenListMap = {};
+ var nodeIds = {};
+ var tree = [];
+
+ for (let d of data) {
+ let parentId = d[config.parentId];
+ if (childrenListMap[parentId] == null) {
+ childrenListMap[parentId] = [];
+ }
+ nodeIds[d[config.id]] = d;
+ childrenListMap[parentId].push(d);
+ }
+
+ for (let d of data) {
+ let parentId = d[config.parentId];
+ if (nodeIds[parentId] == null) {
+ tree.push(d);
+ }
+ }
+
+ for (let t of tree) {
+ adaptToChildrenList(t);
+ }
+
+ function adaptToChildrenList(o) {
+ if (childrenListMap[o[config.id]] !== null) {
+ o[config.childrenList] = childrenListMap[o[config.id]];
+ }
+ if (o[config.childrenList]) {
+ for (let c of o[config.childrenList]) {
+ adaptToChildrenList(c);
+ }
+ }
+ }
+ return tree;
+}
+
+/**
+* 参数处理
+* @param {*} params 参数
+*/
+export function tansParams(params) {
+ let result = ''
+ for (const propName of Object.keys(params)) {
+ const value = params[propName];
+ var part = encodeURIComponent(propName) + "=";
+ if (value !== null && value !== "" && typeof (value) !== "undefined") {
+ if (typeof value === 'object') {
+ for (const key of Object.keys(value)) {
+ if (value[key] !== null && value[key] !== "" && typeof (value[key]) !== 'undefined') {
+ let params = propName + '[' + key + ']';
+ var subPart = encodeURIComponent(params) + "=";
+ result += subPart + encodeURIComponent(value[key]) + "&";
+ }
+ }
+ } else {
+ result += part + encodeURIComponent(value) + "&";
+ }
+ }
+ }
+ return result
+}
+
+// 验证是否为blob格式
+export function blobValidate(data) {
+ return data.type !== 'application/json'
+}
diff --git a/oms-vue/src/views/bill/orderShipCost.vue b/oms-vue/src/views/bill/orderShipCost.vue
new file mode 100644
index 00000000..84626aab
--- /dev/null
+++ b/oms-vue/src/views/bill/orderShipCost.vue
@@ -0,0 +1,332 @@
+
+
+
+
+
+
+
+
+
+ {{ item.name }}
+ 淘宝天猫
+ 拼多多
+ 抖店
+ 小红书
+ 快手小店
+ 其他
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 搜索
+ 重置
+
+
+
+
+
+ 导出
+
+
+
+
+
+
+
+
+
+
+ {{ shopList.find(x=>x.id === scope.row.shopId).name }}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ {{scope.row.receiverName}} {{scope.row.receiverPhone}}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/oms-vue/src/views/components/icons/element-icons.js b/oms-vue/src/views/components/icons/element-icons.js
new file mode 100644
index 00000000..9ea4d63f
--- /dev/null
+++ b/oms-vue/src/views/components/icons/element-icons.js
@@ -0,0 +1,3 @@
+const elementIcons = ['platform-eleme', 'eleme', 'delete-solid', 'delete', 's-tools', 'setting', 'user-solid', 'user', 'phone', 'phone-outline', 'more', 'more-outline', 'star-on', 'star-off', 's-goods', 'goods', 'warning', 'warning-outline', 'question', 'info', 'remove', 'circle-plus', 'success', 'error', 'zoom-in', 'zoom-out', 'remove-outline', 'circle-plus-outline', 'circle-check', 'circle-close', 's-help', 'help', 'minus', 'plus', 'check', 'close', 'picture', 'picture-outline', 'picture-outline-round', 'upload', 'upload2', 'download', 'camera-solid', 'camera', 'video-camera-solid', 'video-camera', 'message-solid', 'bell', 's-cooperation', 's-order', 's-platform', 's-fold', 's-unfold', 's-operation', 's-promotion', 's-home', 's-release', 's-ticket', 's-management', 's-open', 's-shop', 's-marketing', 's-flag', 's-comment', 's-finance', 's-claim', 's-custom', 's-opportunity', 's-data', 's-check', 's-grid', 'menu', 'share', 'd-caret', 'caret-left', 'caret-right', 'caret-bottom', 'caret-top', 'bottom-left', 'bottom-right', 'back', 'right', 'bottom', 'top', 'top-left', 'top-right', 'arrow-left', 'arrow-right', 'arrow-down', 'arrow-up', 'd-arrow-left', 'd-arrow-right', 'video-pause', 'video-play', 'refresh', 'refresh-right', 'refresh-left', 'finished', 'sort', 'sort-up', 'sort-down', 'rank', 'loading', 'view', 'c-scale-to-original', 'date', 'edit', 'edit-outline', 'folder', 'folder-opened', 'folder-add', 'folder-remove', 'folder-delete', 'folder-checked', 'tickets', 'document-remove', 'document-delete', 'document-copy', 'document-checked', 'document', 'document-add', 'printer', 'paperclip', 'takeaway-box', 'search', 'monitor', 'attract', 'mobile', 'scissors', 'umbrella', 'headset', 'brush', 'mouse', 'coordinate', 'magic-stick', 'reading', 'data-line', 'data-board', 'pie-chart', 'data-analysis', 'collection-tag', 'film', 'suitcase', 'suitcase-1', 'receiving', 'collection', 'files', 'notebook-1', 'notebook-2', 'toilet-paper', 'office-building', 'school', 'table-lamp', 'house', 'no-smoking', 'smoking', 'shopping-cart-full', 'shopping-cart-1', 'shopping-cart-2', 'shopping-bag-1', 'shopping-bag-2', 'sold-out', 'sell', 'present', 'box', 'bank-card', 'money', 'coin', 'wallet', 'discount', 'price-tag', 'news', 'guide', 'male', 'female', 'thumb', 'cpu', 'link', 'connection', 'open', 'turn-off', 'set-up', 'chat-round', 'chat-line-round', 'chat-square', 'chat-dot-round', 'chat-dot-square', 'chat-line-square', 'message', 'postcard', 'position', 'turn-off-microphone', 'microphone', 'close-notification', 'bangzhu', 'time', 'odometer', 'crop', 'aim', 'switch-button', 'full-screen', 'copy-document', 'mic', 'stopwatch', 'medal-1', 'medal', 'trophy', 'trophy-1', 'first-aid-kit', 'discover', 'place', 'location', 'location-outline', 'location-information', 'add-location', 'delete-location', 'map-location', 'alarm-clock', 'timer', 'watch-1', 'watch', 'lock', 'unlock', 'key', 'service', 'mobile-phone', 'bicycle', 'truck', 'ship', 'basketball', 'football', 'soccer', 'baseball', 'wind-power', 'light-rain', 'lightning', 'heavy-rain', 'sunrise', 'sunrise-1', 'sunset', 'sunny', 'cloudy', 'partly-cloudy', 'cloudy-and-sunny', 'moon', 'moon-night', 'dish', 'dish-1', 'food', 'chicken', 'fork-spoon', 'knife-fork', 'burger', 'tableware', 'sugar', 'dessert', 'ice-cream', 'hot-water', 'water-cup', 'coffee-cup', 'cold-drink', 'goblet', 'goblet-full', 'goblet-square', 'goblet-square-full', 'refrigerator', 'grape', 'watermelon', 'cherry', 'apple', 'pear', 'orange', 'coffee', 'ice-tea', 'ice-drink', 'milk-tea', 'potato-strips', 'lollipop', 'ice-cream-square', 'ice-cream-round']
+
+export default elementIcons
diff --git a/oms-vue/src/views/components/icons/index.vue b/oms-vue/src/views/components/icons/index.vue
new file mode 100644
index 00000000..d3c9a719
--- /dev/null
+++ b/oms-vue/src/views/components/icons/index.vue
@@ -0,0 +1,87 @@
+
+
+
+
+
+
+
+
+ {{ generateIconCode(item) }}
+
+
+
+ {{ item }}
+
+
+
+
+
+
+
+
+ {{ generateElementIconCode(item) }}
+
+
+
+ {{ item }}
+
+
+
+
+
+
+
+
+
+
+
diff --git a/oms-vue/src/views/components/icons/svg-icons.js b/oms-vue/src/views/components/icons/svg-icons.js
new file mode 100644
index 00000000..724cd8e9
--- /dev/null
+++ b/oms-vue/src/views/components/icons/svg-icons.js
@@ -0,0 +1,10 @@
+const req = require.context('../../../assets/icons/svg', false, /\.svg$/)
+const requireAll = requireContext => requireContext.keys()
+
+const re = /\.\/(.*)\.svg/
+
+const svgIcons = requireAll(req).map(i => {
+ return i.match(re)[1]
+})
+
+export default svgIcons
diff --git a/oms-vue/src/views/dashboard/BarChart.vue b/oms-vue/src/views/dashboard/BarChart.vue
new file mode 100644
index 00000000..cd33d2d2
--- /dev/null
+++ b/oms-vue/src/views/dashboard/BarChart.vue
@@ -0,0 +1,102 @@
+
+
+
+
+
diff --git a/oms-vue/src/views/dashboard/LineChart.vue b/oms-vue/src/views/dashboard/LineChart.vue
new file mode 100644
index 00000000..ddd1063d
--- /dev/null
+++ b/oms-vue/src/views/dashboard/LineChart.vue
@@ -0,0 +1,135 @@
+
+
+
+
+
diff --git a/oms-vue/src/views/dashboard/PanelGroup.vue b/oms-vue/src/views/dashboard/PanelGroup.vue
new file mode 100644
index 00000000..d5b2332a
--- /dev/null
+++ b/oms-vue/src/views/dashboard/PanelGroup.vue
@@ -0,0 +1,182 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/oms-vue/src/views/dashboard/PieChart.vue b/oms-vue/src/views/dashboard/PieChart.vue
new file mode 100644
index 00000000..c3600577
--- /dev/null
+++ b/oms-vue/src/views/dashboard/PieChart.vue
@@ -0,0 +1,79 @@
+
+
+
+
+
diff --git a/oms-vue/src/views/dashboard/RaddarChart.vue b/oms-vue/src/views/dashboard/RaddarChart.vue
new file mode 100644
index 00000000..b1790ca8
--- /dev/null
+++ b/oms-vue/src/views/dashboard/RaddarChart.vue
@@ -0,0 +1,116 @@
+
+
+
+
+
diff --git a/oms-vue/src/views/dashboard/mixins/resize.js b/oms-vue/src/views/dashboard/mixins/resize.js
new file mode 100644
index 00000000..b1e76e94
--- /dev/null
+++ b/oms-vue/src/views/dashboard/mixins/resize.js
@@ -0,0 +1,56 @@
+import { debounce } from '@/utils'
+
+export default {
+ data() {
+ return {
+ $_sidebarElm: null,
+ $_resizeHandler: null
+ }
+ },
+ mounted() {
+ this.initListener()
+ },
+ activated() {
+ if (!this.$_resizeHandler) {
+ // avoid duplication init
+ this.initListener()
+ }
+
+ // when keep-alive chart activated, auto resize
+ this.resize()
+ },
+ beforeDestroy() {
+ this.destroyListener()
+ },
+ deactivated() {
+ this.destroyListener()
+ },
+ methods: {
+ // use $_ for mixins properties
+ // https://vuejs.org/v2/style-guide/index.html#Private-property-names-essential
+ $_sidebarResizeHandler(e) {
+ if (e.propertyName === 'width') {
+ this.$_resizeHandler()
+ }
+ },
+ initListener() {
+ this.$_resizeHandler = debounce(() => {
+ this.resize()
+ }, 100)
+ window.addEventListener('resize', this.$_resizeHandler)
+
+ this.$_sidebarElm = document.getElementsByClassName('sidebar-container')[0]
+ this.$_sidebarElm && this.$_sidebarElm.addEventListener('transitionend', this.$_sidebarResizeHandler)
+ },
+ destroyListener() {
+ window.removeEventListener('resize', this.$_resizeHandler)
+ this.$_resizeHandler = null
+
+ this.$_sidebarElm && this.$_sidebarElm.removeEventListener('transitionend', this.$_sidebarResizeHandler)
+ },
+ resize() {
+ const { chart } = this
+ chart && chart.resize()
+ }
+ }
+}
diff --git a/oms-vue/src/views/data/goods/recommend_list.vue b/oms-vue/src/views/data/goods/recommend_list.vue
new file mode 100644
index 00000000..42cab770
--- /dev/null
+++ b/oms-vue/src/views/data/goods/recommend_list.vue
@@ -0,0 +1,13 @@
+
+推荐商品清单
+
+
+
+
+
diff --git a/oms-vue/src/views/data/goods/sale_hot_list.vue b/oms-vue/src/views/data/goods/sale_hot_list.vue
new file mode 100644
index 00000000..ddc5a13e
--- /dev/null
+++ b/oms-vue/src/views/data/goods/sale_hot_list.vue
@@ -0,0 +1,13 @@
+
+商品热卖榜
+
+
+
+
+
diff --git a/oms-vue/src/views/data/keyword/hot_keyword.vue b/oms-vue/src/views/data/keyword/hot_keyword.vue
new file mode 100644
index 00000000..4f357879
--- /dev/null
+++ b/oms-vue/src/views/data/keyword/hot_keyword.vue
@@ -0,0 +1,179 @@
+
+
+
+
diff --git a/oms-vue/src/views/data/market/info.vue b/oms-vue/src/views/data/market/info.vue
new file mode 100644
index 00000000..abfd788f
--- /dev/null
+++ b/oms-vue/src/views/data/market/info.vue
@@ -0,0 +1,14 @@
+
+ 市场动态
+
+
+
+
+
+
\ No newline at end of file
diff --git a/oms-vue/src/views/dou/order/index.vue b/oms-vue/src/views/dou/order/index.vue
new file mode 100644
index 00000000..e05e1880
--- /dev/null
+++ b/oms-vue/src/views/dou/order/index.vue
@@ -0,0 +1,1101 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 搜索
+ 重置
+
+
+
+
+
+ 手动添加
+
+
+ Execl导入
+
+
+ API拉取订单
+
+
+ 导出订单
+
+
+
+
+
+
+
+
+
+
+ 梦小妮牛仔裤
+
+
+
+
+
+
+
+
+
+
{{item.productName}}
+
{{item.goodsSpec}}
+ x {{item.comboNum}}
+ 售后
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 待支付
+ 备货中
+ 已发货
+ 已取消
+ 已完成
+
+
+ 待确认
+ 已确认
+ 已拦截
+
+
+
+
+
+
+ {{ parseTime(scope.row.orderCreateTime, '{y}-{m}-{d}') }}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 确认订单
+ 详情
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 订单商品
+
+
+ 添加
+
+
+ 删除
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ {{form.id}}
+ {{form.orderId}}
+
+ {{ shopList.find(x=>x.id === form.shopId)?shopList.find(x=>x.id === form.shopId).name:'' }}
+
+
+ 拼团
+ 普通
+
+
+ {{ form.appSource }}
+
+
+ {{ form.trafficeSource }}
+
+
+
+
+
+
+
+
+
+ {{form.buyerWords}}
+
+
+ {{form.sellerWords}}
+
+
+ {{form.cancelReason}}
+
+
+ {{ form.orderCreateTime }}
+
+ {{ form.expShipTime }}
+ {{ form.payTime }}
+
+
+
+ 待支付
+ 备货中
+ 已发货
+
+
+
+
+
+
+
+
+
+
+
+
+ {{form.shopCouponAmount}}
+ {{form.couponAmount}}
+ {{form.postAmount}}
+ {{form.orderTotalAmount}}
+ {{ form.payTypeName }}
+
+
+
+
+ {{form.postReceiver}}
+ {{form.postTel}}
+ {{form.province}}{{form.city}}{{form.town}}
+ {{form.postAddr}}
+
+
+
+ {{form.logisticsCompany}}
+ {{form.logisticsCode}}
+ {{form.logisticsTime}}
+
+ 订单商品
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 添加
+
+
+ 删除
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
{{saleAfterForm.productName}}
+
{{saleAfterForm.goodsSpec}}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/oms-vue/src/views/dou/refund/index.vue b/oms-vue/src/views/dou/refund/index.vue
new file mode 100644
index 00000000..a4eddaeb
--- /dev/null
+++ b/oms-vue/src/views/dou/refund/index.vue
@@ -0,0 +1,533 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 搜索
+ 重置
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 已发货仅退款
+ 退货退款
+ 未发货仅退款
+ 换货
+ 拦截退货
+
+
+
+
+
+
+ 梦小妮牛仔裤
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ {{ parseTime(scope.row.applyTime, '{y}-{m}-{d}') }}
+
+
+
+
+ 未处理
+ 已签收
+ 供应商已退款
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/oms-vue/src/views/efm/index.vue b/oms-vue/src/views/efm/index.vue
new file mode 100644
index 00000000..174e31de
--- /dev/null
+++ b/oms-vue/src/views/efm/index.vue
@@ -0,0 +1,307 @@
+
+
+
+
\ No newline at end of file
diff --git a/oms-vue/src/views/error/401.vue b/oms-vue/src/views/error/401.vue
new file mode 100644
index 00000000..448b6ecd
--- /dev/null
+++ b/oms-vue/src/views/error/401.vue
@@ -0,0 +1,88 @@
+
+
+
+ 返回
+
+
+
+
+ 401错误!
+
+ 您没有访问权限!
+ 对不起,您没有访问权限,请不要进行非法操作!您可以返回主页面
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/oms-vue/src/views/error/404.vue b/oms-vue/src/views/error/404.vue
new file mode 100644
index 00000000..96f075c1
--- /dev/null
+++ b/oms-vue/src/views/error/404.vue
@@ -0,0 +1,233 @@
+
+
+
+
+
+
+ 404错误!
+
+
+ {{ message }}
+
+
+ 对不起,您正在寻找的页面不存在。尝试检查URL的错误,然后按浏览器上的刷新按钮或尝试在我们的应用程序中找到其他内容。
+
+
+ 返回首页
+
+
+
+
+
+
+
+
+
diff --git a/oms-vue/src/views/goods/brand/index.vue b/oms-vue/src/views/goods/brand/index.vue
new file mode 100644
index 00000000..9920629b
--- /dev/null
+++ b/oms-vue/src/views/goods/brand/index.vue
@@ -0,0 +1,255 @@
+
+
+
+
+
+
+
+ 搜索
+ 重置
+
+
+
+
+
+ 新增
+
+
+ 修改
+
+
+ 删除
+
+
+ 导出
+
+
+
+
+
+
+
+
+
+
+
+ 修改
+ 删除
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/oms-vue/src/views/goods/category/categoryAttribute.vue b/oms-vue/src/views/goods/category/categoryAttribute.vue
new file mode 100644
index 00000000..3af5591f
--- /dev/null
+++ b/oms-vue/src/views/goods/category/categoryAttribute.vue
@@ -0,0 +1,282 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 搜索
+ 重置
+
+
+
+
+
+ 新增
+
+
+ 修改
+
+
+ 删除
+
+
+ 导出
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 修改
+ 删除
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/oms-vue/src/views/goods/category/categoryAttributeValue.vue b/oms-vue/src/views/goods/category/categoryAttributeValue.vue
new file mode 100644
index 00000000..eec43aff
--- /dev/null
+++ b/oms-vue/src/views/goods/category/categoryAttributeValue.vue
@@ -0,0 +1,304 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 搜索
+ 重置
+
+
+
+
+
+ 新增
+
+
+ 修改
+
+
+ 删除
+
+
+ 导出
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 修改
+ 删除
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/oms-vue/src/views/goods/category/index.vue b/oms-vue/src/views/goods/category/index.vue
new file mode 100644
index 00000000..de586780
--- /dev/null
+++ b/oms-vue/src/views/goods/category/index.vue
@@ -0,0 +1,351 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 搜索
+ 重置
+
+
+
+
+
+ 新增
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 正常
+ 已删除
+
+
+
+
+ 新增
+ 修改
+ 删除
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/oms-vue/src/views/goods/create.vue b/oms-vue/src/views/goods/create.vue
new file mode 100644
index 00000000..73efc5a2
--- /dev/null
+++ b/oms-vue/src/views/goods/create.vue
@@ -0,0 +1,585 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 颜色:
+
+
+
+
+
+
+
+
+ -
+
+
+
+
+ {{form.colorNames[color]}}
+
+
+
+
+
+
+ 尺码:
+
+
+
+
+
+ 款式:
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/oms-vue/src/views/goods/goodsInventory/index.vue b/oms-vue/src/views/goods/goodsInventory/index.vue
new file mode 100644
index 00000000..f814c434
--- /dev/null
+++ b/oms-vue/src/views/goods/goodsInventory/index.vue
@@ -0,0 +1,265 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 搜索
+ 重置
+
+
+
+
+
+ 导出
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ {{ parseTime(scope.row.createTime, '{y}-{m}-{d}') }}
+
+
+
+
+
+ {{ parseTime(scope.row.updateTime, '{y}-{m}-{d}') }}
+
+
+
+
+
+ 库存详情
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/oms-vue/src/views/goods/index.vue b/oms-vue/src/views/goods/index.vue
new file mode 100644
index 00000000..0b1c7aea
--- /dev/null
+++ b/oms-vue/src/views/goods/index.vue
@@ -0,0 +1,497 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 搜索
+ 重置
+
+
+
+
+
+ 添加商品
+
+
+
+ 导出
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ {{categoryList.find(x=>x.id === scope.row.categoryId).name}}
+
+
+
+
+
+
+
+
+
+
+
+
+ {{supplierList.find(x=>x.id === scope.row.supplierId).name}}
+
+
+
+
+
+ 销售中
+ 已下架
+
+
+
+
+ 修改
+ 删除
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/oms-vue/src/views/goods/spec/index.vue b/oms-vue/src/views/goods/spec/index.vue
new file mode 100644
index 00000000..0642d210
--- /dev/null
+++ b/oms-vue/src/views/goods/spec/index.vue
@@ -0,0 +1,344 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 搜索
+ 重置
+
+
+
+
+
+
+ 导出
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 上架中
+ 已下架
+
+
+
+
+
+
+
+ 修改
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/oms-vue/src/views/index.vue b/oms-vue/src/views/index.vue
new file mode 100644
index 00000000..1aa3e95f
--- /dev/null
+++ b/oms-vue/src/views/index.vue
@@ -0,0 +1,98 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/oms-vue/src/views/index22.vue b/oms-vue/src/views/index22.vue
new file mode 100644
index 00000000..d2d2ec63
--- /dev/null
+++ b/oms-vue/src/views/index22.vue
@@ -0,0 +1,98 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/oms-vue/src/views/login.vue b/oms-vue/src/views/login.vue
new file mode 100644
index 00000000..20e0a5ec
--- /dev/null
+++ b/oms-vue/src/views/login.vue
@@ -0,0 +1,219 @@
+
+
+
+ 启航电商ERP系统
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
![]()
+
+
+ 记住密码
+
+
+ 登 录
+ 登 录 中...
+
+
+ 立即注册
+
+
+
+
+
+
+
+
+
+
+
diff --git a/oms-vue/src/views/monitor/cache/index.vue b/oms-vue/src/views/monitor/cache/index.vue
new file mode 100644
index 00000000..e81da2e8
--- /dev/null
+++ b/oms-vue/src/views/monitor/cache/index.vue
@@ -0,0 +1,144 @@
+
+
+
+
+
+ 基本信息
+
+
+
+
+ Redis版本 |
+ {{ cache.info.redis_version }} |
+ 运行模式 |
+ {{ cache.info.redis_mode == "standalone" ? "单机" : "集群" }} |
+ 端口 |
+ {{ cache.info.tcp_port }} |
+ 客户端数 |
+ {{ cache.info.connected_clients }} |
+
+
+ 运行时间(天) |
+ {{ cache.info.uptime_in_days }} |
+ 使用内存 |
+ {{ cache.info.used_memory_human }} |
+ 使用CPU |
+ {{ parseFloat(cache.info.used_cpu_user_children).toFixed(2) }} |
+ 内存配置 |
+ {{ cache.info.maxmemory_human }} |
+
+
+ AOF是否开启 |
+ {{ cache.info.aof_enabled == "0" ? "否" : "是" }} |
+ RDB是否成功 |
+ {{ cache.info.rdb_last_bgsave_status }} |
+ Key数量 |
+ {{ cache.dbSize }} |
+ 网络入口/出口 |
+ {{ cache.info.instantaneous_input_kbps }}kps/{{cache.info.instantaneous_output_kbps}}kps |
+
+
+
+
+
+
+
+
+
+ 命令统计
+
+
+
+
+
+
+ 内存信息
+
+
+
+
+
+
+
+
diff --git a/oms-vue/src/views/monitor/cache/list.vue b/oms-vue/src/views/monitor/cache/list.vue
new file mode 100644
index 00000000..29a7c741
--- /dev/null
+++ b/oms-vue/src/views/monitor/cache/list.vue
@@ -0,0 +1,241 @@
+
+
+
+
+
+
+ 缓存列表
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 键名列表
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 缓存内容
+ 清理全部
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/oms-vue/src/views/monitor/druid/index.vue b/oms-vue/src/views/monitor/druid/index.vue
new file mode 100644
index 00000000..c6ad585c
--- /dev/null
+++ b/oms-vue/src/views/monitor/druid/index.vue
@@ -0,0 +1,15 @@
+
+
+
+
diff --git a/oms-vue/src/views/monitor/file/list.vue b/oms-vue/src/views/monitor/file/list.vue
new file mode 100644
index 00000000..62ed798f
--- /dev/null
+++ b/oms-vue/src/views/monitor/file/list.vue
@@ -0,0 +1,66 @@
+
+
+
+
+
+
+
diff --git a/oms-vue/src/views/monitor/job/index.vue b/oms-vue/src/views/monitor/job/index.vue
new file mode 100644
index 00000000..6365d3d7
--- /dev/null
+++ b/oms-vue/src/views/monitor/job/index.vue
@@ -0,0 +1,513 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 搜索
+ 重置
+
+
+
+
+
+ 新增
+
+
+ 修改
+
+
+ 删除
+
+
+ 导出
+
+
+ 日志
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 修改
+ 删除
+ handleCommand(command, scope.row)" v-hasPermi="['monitor:job:changeStatus', 'monitor:job:query']">
+ 更多
+
+ 执行一次
+ 任务详细
+ 调度日志
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 调用方法
+
+
+ Bean调用示例:ryTask.ryParams('ry')
+
Class类调用示例:com.zhijian.quartz.task.RyTask.ryParams('ry')
+
参数说明:支持字符串,布尔类型,长整型,浮点型,整型
+
+
+
+
+
+
+
+
+
+
+
+
+ 生成表达式
+
+
+
+
+
+
+
+
+
+ 立即执行
+ 执行一次
+ 放弃执行
+
+
+
+
+
+
+ 允许
+ 禁止
+
+
+
+
+
+
+ {{dict.label}}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ {{ form.jobId }}
+ {{ form.jobName }}
+
+
+ {{ jobGroupFormat(form) }}
+ {{ form.createTime }}
+
+
+ {{ form.cronExpression }}
+
+
+ {{ parseTime(form.nextValidTime) }}
+
+
+ {{ form.invokeTarget }}
+
+
+
+ 正常
+ 失败
+
+
+
+
+ 允许
+ 禁止
+
+
+
+
+ 默认策略
+ 立即执行
+ 执行一次
+ 放弃执行
+
+
+
+
+
+
+
+
+
+
diff --git a/oms-vue/src/views/monitor/job/log.vue b/oms-vue/src/views/monitor/job/log.vue
new file mode 100644
index 00000000..60bee1de
--- /dev/null
+++ b/oms-vue/src/views/monitor/job/log.vue
@@ -0,0 +1,295 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 搜索
+ 重置
+
+
+
+
+
+ 删除
+
+
+ 清空
+
+
+ 导出
+
+
+ 关闭
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ {{ parseTime(scope.row.createTime) }}
+
+
+
+
+ 详细
+
+
+
+
+
+
+
+
+
+
+
+ {{ form.jobLogId }}
+ {{ form.jobName }}
+
+
+ {{ form.jobGroup }}
+ {{ form.createTime }}
+
+
+ {{ form.invokeTarget }}
+
+
+ {{ form.jobMessage }}
+
+
+
+ 正常
+ 失败
+
+
+
+ {{ form.exceptionInfo }}
+
+
+
+
+
+
+
+
+
diff --git a/oms-vue/src/views/monitor/logininfor/index.vue b/oms-vue/src/views/monitor/logininfor/index.vue
new file mode 100644
index 00000000..d6af834c
--- /dev/null
+++ b/oms-vue/src/views/monitor/logininfor/index.vue
@@ -0,0 +1,246 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 搜索
+ 重置
+
+
+
+
+
+ 删除
+
+
+ 清空
+
+
+ 解锁
+
+
+ 导出
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ {{ parseTime(scope.row.loginTime) }}
+
+
+
+
+
+
+
+
+
+
diff --git a/oms-vue/src/views/monitor/online/index.vue b/oms-vue/src/views/monitor/online/index.vue
new file mode 100644
index 00000000..ad613c96
--- /dev/null
+++ b/oms-vue/src/views/monitor/online/index.vue
@@ -0,0 +1,122 @@
+
+
+
+
+
+
+
+
+
+
+ 搜索
+ 重置
+
+
+
+
+
+
+ {{(pageNum - 1) * pageSize + scope.$index + 1}}
+
+
+
+
+
+
+
+
+
+
+
+ {{ parseTime(scope.row.loginTime) }}
+
+
+
+
+ 强退
+
+
+
+
+
+
+
+
+
+
diff --git a/oms-vue/src/views/monitor/operlog/index.vue b/oms-vue/src/views/monitor/operlog/index.vue
new file mode 100644
index 00000000..34a3ce34
--- /dev/null
+++ b/oms-vue/src/views/monitor/operlog/index.vue
@@ -0,0 +1,313 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 搜索
+ 重置
+
+
+
+
+
+ 删除
+
+
+ 清空
+
+
+ 导出
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ {{ parseTime(scope.row.operTime) }}
+
+
+
+
+ {{ scope.row.costTime }}毫秒
+
+
+
+
+ 详细
+
+
+
+
+
+
+
+
+
+
+
+ {{ form.title }} / {{ typeFormat(form) }}
+ {{ form.operName }} / {{ form.operIp }} / {{ form.operLocation }}
+
+
+ {{ form.operUrl }}
+ {{ form.requestMethod }}
+
+
+ {{ form.method }}
+
+
+ {{ form.operParam }}
+
+
+ {{ form.jsonResult }}
+
+
+
+ 正常
+ 失败
+
+
+
+ {{ form.costTime }}毫秒
+
+
+ {{ parseTime(form.operTime) }}
+
+
+ {{ form.errorMsg }}
+
+
+
+
+
+
+
+
+
+
diff --git a/oms-vue/src/views/monitor/server/index.vue b/oms-vue/src/views/monitor/server/index.vue
new file mode 100644
index 00000000..15ffc9a6
--- /dev/null
+++ b/oms-vue/src/views/monitor/server/index.vue
@@ -0,0 +1,207 @@
+
+
+
+
+
+ CPU
+
+
+
+
+ 属性 |
+ 值 |
+
+
+
+
+ 核心数 |
+ {{ server.cpu.cpuNum }} |
+
+
+ 用户使用率 |
+ {{ server.cpu.used }}% |
+
+
+ 系统使用率 |
+ {{ server.cpu.sys }}% |
+
+
+ 当前空闲率 |
+ {{ server.cpu.free }}% |
+
+
+
+
+
+
+
+
+
+ 内存
+
+
+
+
+ 属性 |
+ 内存 |
+ JVM |
+
+
+
+
+ 总内存 |
+ {{ server.mem.total }}G |
+ {{ server.jvm.total }}M |
+
+
+ 已用内存 |
+ {{ server.mem.used}}G |
+ {{ server.jvm.used}}M |
+
+
+ 剩余内存 |
+ {{ server.mem.free }}G |
+ {{ server.jvm.free }}M |
+
+
+ 使用率 |
+ {{ server.mem.usage }}% |
+ {{ server.jvm.usage }}% |
+
+
+
+
+
+
+
+
+
+
+ 服务器信息
+
+
+
+
+
+ 服务器名称 |
+ {{ server.sys.computerName }} |
+ 操作系统 |
+ {{ server.sys.osName }} |
+
+
+ 服务器IP |
+ {{ server.sys.computerIp }} |
+ 系统架构 |
+ {{ server.sys.osArch }} |
+
+
+
+
+
+
+
+
+
+
+ Java虚拟机信息
+
+
+
+
+
+ Java名称 |
+ {{ server.jvm.name }} |
+ Java版本 |
+ {{ server.jvm.version }} |
+
+
+ 启动时间 |
+ {{ server.jvm.startTime }} |
+ 运行时长 |
+ {{ server.jvm.runTime }} |
+
+
+ 安装路径 |
+ {{ server.jvm.home }} |
+
+
+ 项目路径 |
+ {{ server.sys.userDir }} |
+
+
+ 运行参数 |
+ {{ server.jvm.inputArgs }} |
+
+
+
+
+
+
+
+
+
+
+ 磁盘状态
+
+
+
+
+
+ 盘符路径 |
+ 文件系统 |
+ 盘符类型 |
+ 总大小 |
+ 可用大小 |
+ 已用大小 |
+ 已用百分比 |
+
+
+
+
+ {{ sysFile.dirName }} |
+ {{ sysFile.sysTypeName }} |
+ {{ sysFile.typeName }} |
+ {{ sysFile.total }} |
+ {{ sysFile.free }} |
+ {{ sysFile.used }} |
+ {{ sysFile.usage }}% |
+
+
+
+
+
+
+
+
+
+
+
diff --git a/oms-vue/src/views/pdd/order/index.vue b/oms-vue/src/views/pdd/order/index.vue
new file mode 100644
index 00000000..0bf87959
--- /dev/null
+++ b/oms-vue/src/views/pdd/order/index.vue
@@ -0,0 +1,1220 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 搜索
+ 重置
+
+
+
+
+
+ 手动添加
+
+
+ Execl导入
+
+
+ API拉取订单
+
+
+ 导出订单
+
+
+
+
+
+
+
+
+
+
+ 梦小妮潮流女装
+
+
+
+
+
+
+
+
+
+
+
+
{{item.goodsName}}
+
{{item.goodsSpec}}
+
+ x {{item.quantity}}
+
+ 售后
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 待发货
+ 已发货
+ 已签收
+
+ 无售后或售后关闭
+ 售后处理中
+ 退款中
+ 退款成功
+
+ 待确认
+ 已确认
+ 已拦截
+
+
+
+
+
+
+ {{scope.row.trackingNumber}}
+ {{scope.row.shippingTime}}
+
+
+
+
+
+
+
+
+
+
+
+
+ {{scope.row.receiverName1}}
+ {{scope.row.province}}{{scope.row.city}}
+
+
+
+
+
+
+
+
+
+ {{ parseTime(scope.row.createdTime, '{y}-{m}-{d}') }}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 确认订单
+ 详情
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 订单商品
+
+
+ 添加
+
+
+ 删除
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ {{form.id}}
+ {{form.orderSn}}
+
+ {{ shopList.find(x=>x.id === form.shopId)?shopList.find(x=>x.id === form.shopId).name:'' }}
+
+
+ 定金订单
+ 普通订单
+
+
+ 是
+ 否
+
+
+ 非抽奖订单
+ 抽奖订单
+
+
+ 拼团中
+ 已成团
+ 团失败
+
+
+
+
+ {{form.buyerMemo}}
+
+
+ {{form.remark}}
+
+
+ {{ form.createdTime }}
+
+ {{ form.payTime }}
+ {{ form.updatedAt }}
+
+
+ 待发货
+ 已发货
+ 已签收
+
+
+ 无售后或售后关闭
+ 售后处理中
+ 退款中
+ 退款成功
+
+
+
+
+ {{form.goodsAmount}}
+ {{form.capitalFreeDiscount}}
+ {{form.sellerDiscount}}
+ {{form.platformDiscount}}
+ {{form.postage}}
+ {{form.payAmount}}
+
+
+
+
+ {{form.receiverName1}}
+ {{form.receiverPhone1}}
+ {{form.province}}{{form.city}}{{form.town}}
+ {{form.receiverAddress1}}
+
+
+
+ {{form.trackingCompany}}
+ {{form.trackingNumber}}
+ {{form.shippingTime}}
+
+
+ 订单商品
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 添加赠品
+
+
+ 删除
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
{{saleAfterForm.goodsName}}
+
{{saleAfterForm.goodsSpec}}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/oms-vue/src/views/pdd/refund/index.vue b/oms-vue/src/views/pdd/refund/index.vue
new file mode 100644
index 00000000..796cfda0
--- /dev/null
+++ b/oms-vue/src/views/pdd/refund/index.vue
@@ -0,0 +1,544 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 搜索
+ 重置
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 梦小妮潮流女装
+
+
+
+
+ 仅退款
+ 退货退款
+ 换货
+ 缺货补寄
+ 拦截退货
+
+
+
+
+
+
+
+
+ {{dateToString(scope.row.createdTime)}}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 未处理
+ 已签收
+ 供应商已退款
+
+
+
+
+ 未发货
+ 已发货
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/oms-vue/src/views/redirect.vue b/oms-vue/src/views/redirect.vue
new file mode 100644
index 00000000..db4c1d66
--- /dev/null
+++ b/oms-vue/src/views/redirect.vue
@@ -0,0 +1,12 @@
+
diff --git a/oms-vue/src/views/register.vue b/oms-vue/src/views/register.vue
new file mode 100644
index 00000000..312dce2c
--- /dev/null
+++ b/oms-vue/src/views/register.vue
@@ -0,0 +1,209 @@
+
+
+
+ 启航电商ERP系统
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
![]()
+
+
+
+
+ 注 册
+ 注 册 中...
+
+
+ 使用已有账户登录
+
+
+
+
+
+
+
+
+
+
+
diff --git a/oms-vue/src/views/sale/order/create.vue b/oms-vue/src/views/sale/order/create.vue
new file mode 100644
index 00000000..d59336cc
--- /dev/null
+++ b/oms-vue/src/views/sale/order/create.vue
@@ -0,0 +1,391 @@
+
+
+
+
+
+
+
+
+
+
+
+
+ {{ item.name }}
+ 淘宝天猫
+ 拼多多
+ 抖店
+ 小红书
+ 快手小店
+ 其他
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 添加
+
+
+ 删除
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/oms-vue/src/views/sale/order/index.vue b/oms-vue/src/views/sale/order/index.vue
new file mode 100644
index 00000000..fe6fb3cf
--- /dev/null
+++ b/oms-vue/src/views/sale/order/index.vue
@@ -0,0 +1,427 @@
+
+
+
+
+
+
+
+
+
+ {{ item.name }}
+ 淘宝天猫
+ 拼多多
+ 抖店
+ 小红书
+ 快手小店
+ 其他
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 搜索
+ 重置
+
+
+
+
+
+ 手动创建订单
+
+
+ 导出
+
+
+
+
+
+
+
+
+
+
+ {{ shopList.find(x=>x.id === scope.row.shopId).name }}
+
+
+
+
+
+
+
+
+
+
+
{{item.goodsTitle}}
+
{{item.goodsSpec}}
+ x {{item.quantity}}
+
+
+
+
+
+
+
+
+ {{scope.row.remark}}
+ {{scope.row.tag}}
+
+
+
+
+
+
+ 待发货
+ 已出库
+ 已发货
+ 已完成
+
+
+ 无售后或售后关闭
+ 售后处理中
+ 退款中
+ 退款成功
+
+
+
+
+
+
+
+
+
+
+
+ {{scope.row.receiverName}}
+ {{scope.row.province}} {{scope.row.city}} {{scope.row.town}}
+
+
+
+
+
+
+
+
+
+
+
+
+ 详情
+
+
+
+
+
+
+
+
+
+
+
+
+ {{form.id}}
+ {{form.orderNum}}
+
+
+ {{ shopList.find(x=>x.id === form.shopId)?shopList.find(x=>x.id === form.shopId).name:'' }}
+ 淘宝天猫
+ 拼多多
+ 抖店
+ 小红书
+ 快手小店
+ 其他
+
+
+
+
+ 实售
+ 淘宝客
+ 刷单
+ 返现
+
+
+ {{form.buyerMemo}}
+
+
+ {{form.remark}}
+
+
+ {{ form.createTime }}
+
+
+ {{ form.payTime }}
+ {{ form.updateTime }}
+
+
+ 待发货
+ 已发货
+ 已签收
+
+
+ 无售后或售后关闭
+ 售后处理中
+ 退款中
+ 退款成功
+
+
+
+
+ {{form.goodsAmount}}
+ {{form.discountAmount}}
+ {{form.postage}}
+ {{form.amount}}
+
+
+
+
+ {{form.receiverName}}
+ {{form.receiverPhone}}
+ {{form.province}}{{form.city}}{{form.town}}
+ {{form.address}}
+
+
+
+ 供应商代发
+ 仓库发货
+
+ {{form.shippingCompany}}
+ {{form.shippingNumber}}
+ {{form.shippingTime}}
+
+
+ 订单商品
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/oms-vue/src/views/sale/returned/index.vue b/oms-vue/src/views/sale/returned/index.vue
new file mode 100644
index 00000000..8d8c8d0e
--- /dev/null
+++ b/oms-vue/src/views/sale/returned/index.vue
@@ -0,0 +1,445 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 搜索
+ 重置
+
+
+
+
+
+
+
+ 导出
+
+
+
+
+
+
+
+
+
+
+ 退货
+ 换货
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ {{ parseTime(scope.row.receiveTime, '{y}-{m}-{d}') }}
+
+
+
+
+
+
+ 待收货
+ 已收货
+ 已完成
+
+
+
+
+ 确认收货
+ 入库
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/oms-vue/src/views/scm/agentShipping/index.vue b/oms-vue/src/views/scm/agentShipping/index.vue
new file mode 100644
index 00000000..e0ba783d
--- /dev/null
+++ b/oms-vue/src/views/scm/agentShipping/index.vue
@@ -0,0 +1,521 @@
+
+
+
+
+
+
+
+ {{ item.name }}
+ 淘宝天猫
+ 拼多多
+ 抖店
+ 小红书
+ 快手小店
+ 其他
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 搜索
+ 重置
+
+
+
+
+
+ 导出
+
+
+
+
+
+
+
+
+
+
+ {{ shopList.find(x=>x.id === scope.row.shopId)?shopList.find(x=>x.id === scope.row.shopId).name:'' }}
+
+
+
+
+
+ {{ supplierList.find(x=>x.id === scope.row.supplierId)?supplierList.find(x=>x.id === scope.row.supplierId).name:'' }}
+
+
+
+
+
+
+ {{ parseTime(scope.row.orderDate, '{y}-{m}-{d}') }}
+
+
+
+
+
+
+
+
+
{{scope.row.goodsTitle}}
+
{{scope.row.goodsSpec}}
+ x {{scope.row.quantity}}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ {{ parseTime(scope.row.shipTime, '{y}-{m}-{d}') }}
+
+
+
+
+ 待发货
+ 已发货
+ 已结算
+
+
+
+
+
+ 修改
+ 删除
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/oms-vue/src/views/scm/purchase/cost/index.vue b/oms-vue/src/views/scm/purchase/cost/index.vue
new file mode 100644
index 00000000..6a8b6416
--- /dev/null
+++ b/oms-vue/src/views/scm/purchase/cost/index.vue
@@ -0,0 +1,321 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 搜索
+ 重置
+
+
+
+
+
+ 导出
+
+
+
+
+
+
+
+
+
+
+ {{ parseTime(scope.row.orderDate, '{y}-{m}-{d}') }}
+
+
+
+
+
+
+
+
+
+
+
+ {{ parseTime(scope.row.confirmTime, '{y}-{m}-{d}') }}
+
+
+
+
+
+ {{ parseTime(scope.row.payTime, '{y}-{m}-{d}') }}
+
+
+
+
+
+
+
+ 付款
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/oms-vue/src/views/scm/purchase/order/create.vue b/oms-vue/src/views/scm/purchase/order/create.vue
new file mode 100644
index 00000000..8d257876
--- /dev/null
+++ b/oms-vue/src/views/scm/purchase/order/create.vue
@@ -0,0 +1,319 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 添加商品
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 编辑
+ 删除
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 立即创建
+ 取消
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/oms-vue/src/views/scm/purchase/order/detail.vue b/oms-vue/src/views/scm/purchase/order/detail.vue
new file mode 100644
index 00000000..1362f1a4
--- /dev/null
+++ b/oms-vue/src/views/scm/purchase/order/detail.vue
@@ -0,0 +1,124 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/oms-vue/src/views/scm/purchase/order/index.vue b/oms-vue/src/views/scm/purchase/order/index.vue
new file mode 100644
index 00000000..5e64dcfe
--- /dev/null
+++ b/oms-vue/src/views/scm/purchase/order/index.vue
@@ -0,0 +1,506 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 搜索
+ 重置
+
+
+
+
+
+ 创建采购订单
+
+
+ 导出
+
+
+
+
+
+
+
+
+
+ {{ supplierList.find(x=>x.id === scope.row.contactId)?supplierList.find(x=>x.id === scope.row.contactId).name :'' }}
+
+
+
+
+
+ {{ parseTime(scope.row.orderDate, '{y}-{m}-{d}') }}
+
+
+
+
+
+
+
+ {{ dateToString(scope.row.auditTime) }}
+
+
+
+
+
+ 待审核
+ 已审核
+ 已确认待供应商发货
+ 供应商已发货
+ 已收货
+ 已入库
+
+
+
+
+
+
+ {{ parseTime(scope.row.supplierDeliveryTime, '{y}-{m}-{d}') }}
+
+
+
+
+ {{ parseTime(scope.row.receivedTime, '{y}-{m}-{d}') }}
+
+
+
+
+ {{ parseTime(scope.row.stockInTime, '{y}-{m}-{d}') }}
+
+
+
+
+
+ 详情
+
+
+ 审核
+
+
+ 采购确认
+
+
+ 供应商发货
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ {{ item.name }}
+ {{item.number}}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/oms-vue/src/views/scm/purchase/order/item.vue b/oms-vue/src/views/scm/purchase/order/item.vue
new file mode 100644
index 00000000..0ae47f7d
--- /dev/null
+++ b/oms-vue/src/views/scm/purchase/order/item.vue
@@ -0,0 +1,467 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 搜索
+ 重置
+
+
+
+
+
+ 新增
+
+
+ 修改
+
+
+ 删除
+
+
+ 导出
+
+
+
+
+
+
+
+
+
+
+
+
+
+ {{ parseTime(scope.row.orderDate, '{y}-{m}-{d}') }}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 修改
+ 删除
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/oms-vue/src/views/scm/purchase/ship/create_stock_in_entry.vue b/oms-vue/src/views/scm/purchase/ship/create_stock_in_entry.vue
new file mode 100644
index 00000000..8e3041c1
--- /dev/null
+++ b/oms-vue/src/views/scm/purchase/ship/create_stock_in_entry.vue
@@ -0,0 +1,204 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 生成采购入库单
+
+
+
+
+
+
\ No newline at end of file
diff --git a/oms-vue/src/views/scm/purchase/ship/index.vue b/oms-vue/src/views/scm/purchase/ship/index.vue
new file mode 100644
index 00000000..6090f3ea
--- /dev/null
+++ b/oms-vue/src/views/scm/purchase/ship/index.vue
@@ -0,0 +1,431 @@
+
+
+
+
+
+
+
+
+
+
+
+
+ 搜索
+ 重置
+
+
+
+
+
+ 确认收货
+
+
+ 导出
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ {{ parseTime(scope.row.shipTime, "{y}-{m}-{d}") }}
+
+
+
+
+ 待收货
+ 已收货
+ 已入库
+
+
+
+
+
+
+
+ {{ parseTime(scope.row.orderDate, "{y}-{m}-{d}") }}
+
+
+
+
+
+ 采购单详情
+ 确认收货
+ 生成入库单
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/oms-vue/src/views/scm/supplier/index.vue b/oms-vue/src/views/scm/supplier/index.vue
new file mode 100644
index 00000000..59cfcb8f
--- /dev/null
+++ b/oms-vue/src/views/scm/supplier/index.vue
@@ -0,0 +1,425 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 搜索
+ 重置
+
+
+
+
+
+ 新增
+
+
+ 修改
+
+
+ 删除
+
+
+ 导出
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ {{ parseTime(scope.row.beginDate, '{y}-{m}-{d}') }}
+
+
+
+
+
+
+
+
+
+
+
+
+
+ {{ parseTime(scope.row.createTime, '{y}-{m}-{d}') }}
+
+
+
+
+ 修改
+ 删除
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/oms-vue/src/views/shop/goods/index.vue b/oms-vue/src/views/shop/goods/index.vue
new file mode 100644
index 00000000..67c767a1
--- /dev/null
+++ b/oms-vue/src/views/shop/goods/index.vue
@@ -0,0 +1,508 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 搜索
+ 重置
+
+
+
+
+
+ 新增
+
+
+ 修改
+
+
+ 删除
+
+
+ 导出
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ {{ parseTime(scope.row.publishTime, '{y}-{m}-{d}') }}
+
+
+
+
+ {{ parseTime(scope.row.createTime, '{y}-{m}-{d}') }}
+
+
+
+
+ 修改
+ 删除
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ ${subTable.functionName}信息
+
+
+ 添加
+
+
+ 删除
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/oms-vue/src/views/shop/index.vue b/oms-vue/src/views/shop/index.vue
new file mode 100644
index 00000000..3c02f44b
--- /dev/null
+++ b/oms-vue/src/views/shop/index.vue
@@ -0,0 +1,395 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 搜索
+ 重置
+
+
+
+
+
+ 新增
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 淘宝
+ 拼多多
+ 抖店
+ 小红书
+ 快手小店
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 修改
+ 删除
+
+ API参数设置
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/oms-vue/src/views/system/config/index.vue b/oms-vue/src/views/system/config/index.vue
new file mode 100644
index 00000000..3ab81fc2
--- /dev/null
+++ b/oms-vue/src/views/system/config/index.vue
@@ -0,0 +1,343 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 搜索
+ 重置
+
+
+
+
+
+ 新增
+
+
+ 修改
+
+
+ 删除
+
+
+ 导出
+
+
+ 刷新缓存
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ {{ parseTime(scope.row.createTime) }}
+
+
+
+
+ 修改
+ 删除
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ {{dict.label}}
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/oms-vue/src/views/system/dept/index.vue b/oms-vue/src/views/system/dept/index.vue
new file mode 100644
index 00000000..e502b4ea
--- /dev/null
+++ b/oms-vue/src/views/system/dept/index.vue
@@ -0,0 +1,340 @@
+
+
+
+
+
+
+
+
+
+
+
+
+ 搜索
+ 重置
+
+
+
+
+
+ 新增
+
+
+ 展开/折叠
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ {{ parseTime(scope.row.createTime) }}
+
+
+
+
+ 修改
+ 新增
+ 删除
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ {{dict.label}}
+
+
+
+
+
+
+
+
+
+
+
diff --git a/oms-vue/src/views/system/dict/data.vue b/oms-vue/src/views/system/dict/data.vue
new file mode 100644
index 00000000..324bb640
--- /dev/null
+++ b/oms-vue/src/views/system/dict/data.vue
@@ -0,0 +1,402 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 搜索
+ 重置
+
+
+
+
+
+ 新增
+
+
+ 修改
+
+
+ 删除
+
+
+ 导出
+
+
+ 关闭
+
+
+
+
+
+
+
+
+
+ {{scope.row.dictLabel}}
+ {{scope.row.dictLabel}}
+
+
+
+
+
+
+
+
+
+
+
+
+ {{ parseTime(scope.row.createTime) }}
+
+
+
+
+ 修改
+ 删除
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ {{dict.label}}
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/oms-vue/src/views/system/dict/index.vue b/oms-vue/src/views/system/dict/index.vue
new file mode 100644
index 00000000..6ca54571
--- /dev/null
+++ b/oms-vue/src/views/system/dict/index.vue
@@ -0,0 +1,347 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 搜索
+ 重置
+
+
+
+
+
+ 新增
+
+
+ 修改
+
+
+ 删除
+
+
+ 导出
+
+
+ 刷新缓存
+
+
+
+
+
+
+
+
+
+
+
+ {{ scope.row.dictType }}
+
+
+
+
+
+
+
+
+
+
+
+ {{ parseTime(scope.row.createTime) }}
+
+
+
+
+ 修改
+ 删除
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ {{dict.label}}
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/oms-vue/src/views/system/menu/index.vue b/oms-vue/src/views/system/menu/index.vue
new file mode 100644
index 00000000..2a83f9e9
--- /dev/null
+++ b/oms-vue/src/views/system/menu/index.vue
@@ -0,0 +1,452 @@
+
+
+
+
+
+
+
+
+
+
+
+
+ 搜索
+ 重置
+
+
+
+
+
+ 新增
+
+
+ 展开/折叠
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ {{ parseTime(scope.row.createTime) }}
+
+
+
+
+ 修改
+ 新增
+ 删除
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 目录
+ 菜单
+ 按钮
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 是否外链
+
+
+ 是
+ 否
+
+
+
+
+
+
+
+
+
+ 路由地址
+
+
+
+
+
+
+
+
+
+
+ 组件路径
+
+
+
+
+
+
+
+
+
+
+
+ 权限字符
+
+
+
+
+
+
+
+
+
+
+ 路由参数
+
+
+
+
+
+
+
+
+
+ 是否缓存
+
+
+ 缓存
+ 不缓存
+
+
+
+
+
+
+
+
+
+ 显示状态
+
+
+ {{dict.label}}
+
+
+
+
+
+
+
+
+
+ 菜单状态
+
+
+ {{dict.label}}
+
+
+
+
+
+
+
+
+
+
+
diff --git a/oms-vue/src/views/system/notice/index.vue b/oms-vue/src/views/system/notice/index.vue
new file mode 100644
index 00000000..7982b545
--- /dev/null
+++ b/oms-vue/src/views/system/notice/index.vue
@@ -0,0 +1,312 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 搜索
+ 重置
+
+
+
+
+
+ 新增
+
+
+ 修改
+
+
+ 删除
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ {{ parseTime(scope.row.createTime, '{y}-{m}-{d}') }}
+
+
+
+
+ 修改
+ 删除
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ {{dict.label}}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/oms-vue/src/views/system/post/index.vue b/oms-vue/src/views/system/post/index.vue
new file mode 100644
index 00000000..444bf634
--- /dev/null
+++ b/oms-vue/src/views/system/post/index.vue
@@ -0,0 +1,309 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 搜索
+ 重置
+
+
+
+
+
+ 新增
+
+
+ 修改
+
+
+ 删除
+
+
+ 导出
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ {{ parseTime(scope.row.createTime) }}
+
+
+
+
+ 修改
+ 删除
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ {{dict.label}}
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/oms-vue/src/views/system/role/authUser.vue b/oms-vue/src/views/system/role/authUser.vue
new file mode 100644
index 00000000..147aa33e
--- /dev/null
+++ b/oms-vue/src/views/system/role/authUser.vue
@@ -0,0 +1,199 @@
+
+
+
+
+
+
+
+
+
+
+ 搜索
+ 重置
+
+
+
+
+
+ 添加用户
+
+
+ 批量取消授权
+
+
+ 关闭
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ {{ parseTime(scope.row.createTime) }}
+
+
+
+
+ 取消授权
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/oms-vue/src/views/system/role/index.vue b/oms-vue/src/views/system/role/index.vue
new file mode 100644
index 00000000..fb3b5ef0
--- /dev/null
+++ b/oms-vue/src/views/system/role/index.vue
@@ -0,0 +1,605 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 搜索
+ 重置
+
+
+
+
+
+ 新增
+
+
+ 修改
+
+
+ 删除
+
+
+ 导出
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ {{ parseTime(scope.row.createTime) }}
+
+
+
+
+ 修改
+ 删除
+ handleCommand(command, scope.row)" v-hasPermi="['system:role:edit']">
+ 更多
+
+ 数据权限
+ 分配用户
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 权限字符
+
+
+
+
+
+
+
+
+ {{dict.label}}
+
+
+
+ 展开/折叠
+ 全选/全不选
+ 父子联动
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 展开/折叠
+ 全选/全不选
+ 父子联动
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/oms-vue/src/views/system/role/selectUser.vue b/oms-vue/src/views/system/role/selectUser.vue
new file mode 100644
index 00000000..b2b072f9
--- /dev/null
+++ b/oms-vue/src/views/system/role/selectUser.vue
@@ -0,0 +1,138 @@
+
+
+
+
+
+
+
+
+
+
+
+ 搜索
+ 重置
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ {{ parseTime(scope.row.createTime) }}
+
+
+
+
+
+
+
+
+
+
diff --git a/oms-vue/src/views/system/user/authRole.vue b/oms-vue/src/views/system/user/authRole.vue
new file mode 100644
index 00000000..ab5e72fc
--- /dev/null
+++ b/oms-vue/src/views/system/user/authRole.vue
@@ -0,0 +1,117 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ {{(pageNum - 1) * pageSize + scope.$index + 1}}
+
+
+
+
+
+
+
+
+ {{ parseTime(scope.row.createTime) }}
+
+
+
+
+
+
+
+
+ 提交
+ 返回
+
+
+
+
+
+
\ No newline at end of file
diff --git a/oms-vue/src/views/system/user/index.vue b/oms-vue/src/views/system/user/index.vue
new file mode 100644
index 00000000..ae87fe49
--- /dev/null
+++ b/oms-vue/src/views/system/user/index.vue
@@ -0,0 +1,670 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 搜索
+ 重置
+
+
+
+
+
+ 新增
+
+
+ 修改
+
+
+ 删除
+
+
+ 导入
+
+
+ 导出
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ {{ parseTime(scope.row.createTime) }}
+
+
+
+
+ 修改
+ 删除
+ handleCommand(command, scope.row)" v-hasPermi="['system:user:resetPwd', 'system:user:edit']">
+ 更多
+
+ 重置密码
+ 分配角色
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ {{dict.label}}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 将文件拖到此处,或点击上传
+
+
+ 是否更新已经存在的用户数据
+
+
仅允许导入xls、xlsx格式文件。
+
下载模板
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/oms-vue/src/views/system/user/profile/index.vue b/oms-vue/src/views/system/user/profile/index.vue
new file mode 100644
index 00000000..ad530f9a
--- /dev/null
+++ b/oms-vue/src/views/system/user/profile/index.vue
@@ -0,0 +1,91 @@
+
+
+
+
+
+
+ 个人信息
+
+
+
+
+
+
+
+ 基本资料
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/oms-vue/src/views/system/user/profile/resetPwd.vue b/oms-vue/src/views/system/user/profile/resetPwd.vue
new file mode 100644
index 00000000..64e8f8c4
--- /dev/null
+++ b/oms-vue/src/views/system/user/profile/resetPwd.vue
@@ -0,0 +1,68 @@
+
+
+
+
+
+
+
+
+
+
+
+
+ 保存
+ 关闭
+
+
+
+
+
diff --git a/oms-vue/src/views/system/user/profile/userAvatar.vue b/oms-vue/src/views/system/user/profile/userAvatar.vue
new file mode 100644
index 00000000..70d8487f
--- /dev/null
+++ b/oms-vue/src/views/system/user/profile/userAvatar.vue
@@ -0,0 +1,187 @@
+
+
+
+
+
+
+
+
+
+
+
![]()
+
+
+
+
+
+
+
+
+ 选择
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 提 交
+
+
+
+
+
+
+
+
diff --git a/oms-vue/src/views/system/user/profile/userInfo.vue b/oms-vue/src/views/system/user/profile/userInfo.vue
new file mode 100644
index 00000000..c09a20b4
--- /dev/null
+++ b/oms-vue/src/views/system/user/profile/userInfo.vue
@@ -0,0 +1,75 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 男
+ 女
+
+
+
+ 保存
+ 关闭
+
+
+
+
+
diff --git a/oms-vue/src/views/tao/order/index.vue b/oms-vue/src/views/tao/order/index.vue
new file mode 100644
index 00000000..6830c106
--- /dev/null
+++ b/oms-vue/src/views/tao/order/index.vue
@@ -0,0 +1,1046 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 搜索
+ 重置
+
+
+
+
+
+ 手动添加
+
+
+ Execl导入
+
+
+ API拉取订单
+
+
+
+ 导出订单
+
+
+
+
+
+
+
+
+
+ 梦小妮牛仔裤
+
+
+
+
+
+
+
+
+
+
{{item.goodsTitle}}
+
{{item.skuInfo}}
+ x {{item.quantity}}
+
+
+ 售后
+
+
+
+
+
+
+
+
+
+
+
+
+
+ {{ parseTime(scope.row.orderCreateTime, '{y}-{m}-{d}') }}
+
+
+
+
+
+
+
+
+
+
+
+
+ 待支付
+ 待发货
+ 已发货
+ 已取消
+ 已完成
+
+
+ 待确认
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 确认订单
+ 详情
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 订单商品
+
+
+ 添加
+
+
+ 删除
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ {{form.id}}
+
+ 淘宝
+ 天猫
+
+
+ 梦小妮牛仔裤
+
+
+ {{ parseTime(form.orderCreateTime, '{yyyy}-{m}-{dd}')}}
+
+
+
+ 实售
+ 淘宝客
+ 刷单
+ 返现
+
+
+ {{form.sellerMemo}}
+
+
+ {{form.buyerFeedback}}
+
+
+ {{form.remark}}
+
+ {{form.closeReason}}
+ {{form.statusStr}}
+
+
+
+ {{form.totalAmount}}
+ {{form.discountAmount}}
+ {{form.shippingFee}}
+ {{form.payAmount}}
+
+
+
+
+ {{form.receiver}}
+ {{form.phone}}
+ {{form.province}}{{form.city}}{{form.town}}
+ {{form.address}}
+
+
+ 订单商品
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 添加赠品
+
+
+ 删除
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
{{saleAfterForm.goodsTitle}}
+
{{saleAfterForm.skuInfo}}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/oms-vue/src/views/tao/orderAddress/index.vue b/oms-vue/src/views/tao/orderAddress/index.vue
new file mode 100644
index 00000000..adf1fd85
--- /dev/null
+++ b/oms-vue/src/views/tao/orderAddress/index.vue
@@ -0,0 +1,374 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 搜索
+ 重置
+
+
+
+
+
+ 新增
+
+
+ 修改
+
+
+ 删除
+
+
+ 导出
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 修改
+ 删除
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/oms-vue/src/views/tao/refund/index.vue b/oms-vue/src/views/tao/refund/index.vue
new file mode 100644
index 00000000..580f084a
--- /dev/null
+++ b/oms-vue/src/views/tao/refund/index.vue
@@ -0,0 +1,461 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 搜索
+ 重置
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 退货
+ 换货
+
+
+
+
+
+
+
+
+
{{scope.row.goodsTitle}}
+
{{scope.row.skuInfo}}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 未处理
+ 已签收
+ 供应商已退款
+
+
+
+
+
+
+
+
+ 梦小妮牛仔裤
+
+
+
+
+
+
+
+
+ 退货确认
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/oms-vue/src/views/tool/gen/basicInfoForm.vue b/oms-vue/src/views/tool/gen/basicInfoForm.vue
new file mode 100644
index 00000000..70295298
--- /dev/null
+++ b/oms-vue/src/views/tool/gen/basicInfoForm.vue
@@ -0,0 +1,60 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/oms-vue/src/views/tool/gen/editTable.vue b/oms-vue/src/views/tool/gen/editTable.vue
new file mode 100644
index 00000000..951497a7
--- /dev/null
+++ b/oms-vue/src/views/tool/gen/editTable.vue
@@ -0,0 +1,234 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ {{ dict.dictName }}
+ {{ dict.dictType }}
+
+
+
+
+
+
+
+
+
+
+
+
+ 提交
+ 返回
+
+
+
+
+
+
diff --git a/oms-vue/src/views/tool/gen/genInfoForm.vue b/oms-vue/src/views/tool/gen/genInfoForm.vue
new file mode 100644
index 00000000..2fb107de
--- /dev/null
+++ b/oms-vue/src/views/tool/gen/genInfoForm.vue
@@ -0,0 +1,299 @@
+
+
+
+
+
+ 生成模板
+
+
+
+
+
+
+
+
+
+
+ 生成包路径
+
+
+
+
+
+
+
+
+
+
+
+ 生成模块名
+
+
+
+
+
+
+
+
+
+
+
+ 生成业务名
+
+
+
+
+
+
+
+
+
+
+
+ 生成功能名
+
+
+
+
+
+
+
+
+
+
+
+ 上级菜单
+
+
+
+
+
+
+
+
+
+
+
+ 生成代码方式
+
+
+
+
+ zip压缩包
+ 自定义路径
+
+
+
+
+
+
+ 自定义路径
+
+
+
+
+
+
+
+ 最近路径快速选择
+
+
+
+ 恢复默认的生成基础路径
+
+
+
+
+
+
+
+
+
+
+
+
+ 树编码字段
+
+
+
+
+
+
+
+
+
+
+
+
+ 树父编码字段
+
+
+
+
+
+
+
+
+
+
+
+
+ 树名称字段
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 关联子表的表名
+
+
+
+
+
+
+
+
+
+
+
+
+ 子表关联的外键名
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/oms-vue/src/views/tool/gen/importTable.vue b/oms-vue/src/views/tool/gen/importTable.vue
new file mode 100644
index 00000000..3ea9532b
--- /dev/null
+++ b/oms-vue/src/views/tool/gen/importTable.vue
@@ -0,0 +1,120 @@
+
+
+
+
+
+
+
+
+
+
+
+ 搜索
+ 重置
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/oms-vue/src/views/tool/gen/index.vue b/oms-vue/src/views/tool/gen/index.vue
new file mode 100644
index 00000000..ccb1b11b
--- /dev/null
+++ b/oms-vue/src/views/tool/gen/index.vue
@@ -0,0 +1,337 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 搜索
+ 重置
+
+
+
+
+
+ 生成
+
+
+ 导入
+
+
+ 修改
+
+
+ 删除
+
+
+
+
+
+
+
+
+ {{(queryParams.pageNum - 1) * queryParams.pageSize + scope.$index + 1}}
+
+
+
+
+
+
+
+
+
+ 预览
+ 编辑
+ 删除
+ 同步
+ 生成代码
+
+
+
+
+
+
+
+
+ 复制
+
+
+
+
+
+
+
+
+
diff --git a/oms-vue/src/views/tool/swagger/index.vue b/oms-vue/src/views/tool/swagger/index.vue
new file mode 100644
index 00000000..b8becc67
--- /dev/null
+++ b/oms-vue/src/views/tool/swagger/index.vue
@@ -0,0 +1,15 @@
+
+
+
+
diff --git a/oms-vue/src/views/wms/location/index.vue b/oms-vue/src/views/wms/location/index.vue
new file mode 100644
index 00000000..0aff0dea
--- /dev/null
+++ b/oms-vue/src/views/wms/location/index.vue
@@ -0,0 +1,331 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 搜索
+ 重置
+
+
+
+
+
+ 新增
+
+
+ 修改
+
+
+ 删除
+
+
+ 导出
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 修改
+ 删除
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/oms-vue/src/views/wms/orderShipping/logistics.vue b/oms-vue/src/views/wms/orderShipping/logistics.vue
new file mode 100644
index 00000000..d3c0188a
--- /dev/null
+++ b/oms-vue/src/views/wms/orderShipping/logistics.vue
@@ -0,0 +1,324 @@
+
+
+
+
+
+
+
+
+
+ {{ item.name }}
+ 淘宝天猫
+ 拼多多
+ 抖店
+ 小红书
+ 快手小店
+ 其他
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 搜索
+ 重置
+
+
+
+
+
+ 导出
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ {{scope.row.receiverName}} {{scope.row.receiverPhone}}
+ {{scope.row.address}}
+
+
+
+
+
+
+
+
+
+ 长:{{scope.row.length}}mm 宽:{{scope.row.width}}mm 高:{{scope.row.height}}mm
+ 重量:{{scope.row.weight}}g
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/oms-vue/src/views/wms/orderShipping/shipping.vue b/oms-vue/src/views/wms/orderShipping/shipping.vue
new file mode 100644
index 00000000..35e7e29d
--- /dev/null
+++ b/oms-vue/src/views/wms/orderShipping/shipping.vue
@@ -0,0 +1,567 @@
+
+
+
+
+
+
+
+
+
+ {{ item.name }}
+ 淘宝天猫
+ 拼多多
+ 抖店
+ 小红书
+ 快手小店
+ 其他
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 搜索
+ 重置
+
+
+
+
+
+ 导出
+
+
+
+
+
+
+
+
+
+
+ {{ shopList.find(x=>x.id === scope.row.shopId).name }}
+
+
+
+
+
+
+
+
+
+
+
{{item.goodsTitle}}
+
{{item.goodsSpec}}
+ x {{item.quantity}}
+
+
+
+
+
+
+
+
+ {{scope.row.remark}}
+ {{scope.row.tag}}
+
+
+
+
+
+
+ 待发货
+ 已出库
+ 已发货
+ 已完成
+
+
+ 无售后或售后关闭
+ 售后处理中
+ 退款中
+ 退款成功
+
+
+
+
+
+
+
+
+
+
+
+ {{scope.row.receiverName}} {{scope.row.receiverPhone}}
+ {{scope.row.address}}
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 打包发货
+
+ 详情
+ 打印发货单
+
+
+
+
+
+
+
+
+
+
+
+
+ {{form.id}}
+ {{form.orderNum}}
+
+
+ {{ shopList.find(x=>x.id === form.shopId)?shopList.find(x=>x.id === form.shopId).name:'' }}
+ 淘宝天猫
+ 拼多多
+ 抖店
+ 小红书
+ 快手小店
+ 其他
+
+
+
+
+ 实售
+ 淘宝客
+ 刷单
+ 返现
+
+
+ {{form.buyerMemo}}
+
+
+ {{form.remark}}
+
+
+ {{ form.createTime }}
+
+
+ {{ form.payTime }}
+ {{ form.updateTime }}
+
+
+ 待发货
+ 已发货
+ 已签收
+
+
+ 无售后或售后关闭
+ 售后处理中
+ 退款中
+ 退款成功
+
+
+
+
+ {{form.goodsAmount}}
+ {{form.discountAmount}}
+ {{form.postage}}
+ {{form.amount}}
+
+
+
+
+ {{form.receiverName}}
+ {{form.receiverPhone}}
+ {{form.province}}{{form.city}}{{form.town}}
+ {{form.address}}
+
+
+
+ 供应商代发
+ 仓库发货
+
+ {{form.shippingCompany}}
+ {{form.shippingNumber}}
+ {{form.shippingTime}}
+
+
+ 订单商品
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ {{form.id}}
+ {{form.orderNum}}
+
+
+ {{ shopList.find(x=>x.id === form.shopId)?shopList.find(x=>x.id === form.shopId).name:'' }}
+ 淘宝天猫
+ 拼多多
+ 抖店
+ 小红书
+ 快手小店
+ 其他
+
+
+ {{form.buyerMemo}}
+
+
+ {{form.remark}}
+
+
+ {{ form.createTime }}
+
+
+
+ 待发货
+ 已发货
+ 已签收
+
+
+ 无售后或售后关闭
+ 售后处理中
+ 退款中
+ 退款成功
+
+
+ 供应商代发
+ 仓库发货
+
+ {{form.receiverName}}
+ {{form.receiverPhone}}
+ {{form.province}}{{form.city}}{{form.town}}
+ {{form.address}}
+
+
+
+
+
+ 商品明细
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ x
+ x
+
+
+
+
+
+
+
+
+
+
+
+ {{ item.name }}
+ {{item.number}}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/oms-vue/src/views/wms/orderShipping/stockOut.vue b/oms-vue/src/views/wms/orderShipping/stockOut.vue
new file mode 100644
index 00000000..12dbcb20
--- /dev/null
+++ b/oms-vue/src/views/wms/orderShipping/stockOut.vue
@@ -0,0 +1,413 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 搜索
+ 重置
+
+
+
+
+
+ 导出
+
+
+
+
+
+
+
+
+
+
+
+
+ 订单拣货出库
+ 采购退货出库
+ 盘点出库
+ 报损出库
+
+
+
+
+ 待拣货
+ 拣货中
+ 拣货完成
+ 已出库
+
+
+
+
+ 未打印
+ 已打印
+
+
+
+
+ {{ parseTime(scope.row.printTime, '{y}-{m}-{d}') }}
+
+
+
+
+ {{ parseTime(scope.row.createTime, '{y}-{m}-{d}') }}
+
+
+
+
+
+ {{ parseTime(scope.row.updateTime, '{y}-{m}-{d}') }}
+
+
+
+
+
+ {{ parseTime(scope.row.completeTime, '{y}-{m}-{d}') }}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 出库
+
+
+
+
+
+
+
+
+
+
+ {{form.stockOutNum}}
+
+ 订单拣货出库
+ 采购退货出库
+ 盘点出库
+ 报损出库
+
+ {{form.remark}}
+ {{form.goodsUnit}}
+ {{form.specUnit}}
+ {{form.specUnitTotal}}
+
+
+
+
+
+
+ 出库商品明细
+
+
+
+
+
+
+
+
+
+
+
+ {{scope.row.colorValue}} {{scope.row.sizeValue}} {{scope.row.styleValue}}
+
+
+
+
+
+
+
+
+
+ {{ item.locationNum }}
+ 剩余库存:{{ item.currentQty }}
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 出库
+
+
+
+
+
+
+
+
+
+
diff --git a/oms-vue/src/views/wms/orderShipping/stocking.vue b/oms-vue/src/views/wms/orderShipping/stocking.vue
new file mode 100644
index 00000000..4360c228
--- /dev/null
+++ b/oms-vue/src/views/wms/orderShipping/stocking.vue
@@ -0,0 +1,458 @@
+
+
+
+
+
+
+ {{ item.name }}
+ 淘宝天猫
+ 拼多多
+ 抖店
+ 小红书
+ 快手小店
+ 其他
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 搜索
+ 重置
+
+
+
+
+
+ 生成拣货单
+
+
+ 统计
+
+
+
+ 导出
+
+
+
+
+
+
+
+
+
+
+ {{ shopList.find(x=>x.id === scope.row.shopId).name }}
+
+
+
+
+
+
+
+ {{ parseTime(scope.row.orderDate, '{y}-{m}-{d}') }}
+
+
+
+
+
+
+
+
+
{{scope.row.goodsTitle}}
+
{{scope.row.goodsSpec}}
+ x {{scope.row.quantity}}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 待备货
+ 备货中
+ 已出库
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 拣货商品
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/oms-vue/src/views/wms/stockInEntry/index.vue b/oms-vue/src/views/wms/stockInEntry/index.vue
new file mode 100644
index 00000000..b8c9ed2a
--- /dev/null
+++ b/oms-vue/src/views/wms/stockInEntry/index.vue
@@ -0,0 +1,424 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 搜索
+ 重置
+
+
+
+
+
+ 导出
+
+
+
+
+
+
+
+
+
+
+
+
+ 采购订单
+
+
+
+
+
+
+
+
+
+
+ {{ parseTime(scope.row.stockInTime, '{y}-{m}-{d}') }}
+
+
+
+
+ 待入库
+ 部分入库
+ 完全入库
+
+
+
+
+ 入库
+ 入库完成
+
+
+
+
+
+
+
+
+
+
+ {{form.id}}
+ {{form.no}}
+ {{form.sourceNo}}
+
+ 采购订单
+
+
+
+ {{form.remark}}
+
+
+ 待入库
+ 部分入库
+ 完全入库
+
+
+
+ {{ form.createTime }}
+
+
+
+ {{ form.sourceGoodsUnit }}
+ {{ form.sourceSpecUnit }}
+ {{ form.sourceSpecUnitTotal }}
+
+
+
+ 入库单明细信息
+
+
+
+
+
+
+
+
+
+
+
+
+ {{scope.row.colorValue}} {{scope.row.sizeValue}} {{scope.row.styleValue}}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ {{ item.name }}
+ {{ item.number }}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/oms-vue/src/views/wms/stockOutEntry/index.vue b/oms-vue/src/views/wms/stockOutEntry/index.vue
new file mode 100644
index 00000000..12dbcb20
--- /dev/null
+++ b/oms-vue/src/views/wms/stockOutEntry/index.vue
@@ -0,0 +1,413 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 搜索
+ 重置
+
+
+
+
+
+ 导出
+
+
+
+
+
+
+
+
+
+
+
+
+ 订单拣货出库
+ 采购退货出库
+ 盘点出库
+ 报损出库
+
+
+
+
+ 待拣货
+ 拣货中
+ 拣货完成
+ 已出库
+
+
+
+
+ 未打印
+ 已打印
+
+
+
+
+ {{ parseTime(scope.row.printTime, '{y}-{m}-{d}') }}
+
+
+
+
+ {{ parseTime(scope.row.createTime, '{y}-{m}-{d}') }}
+
+
+
+
+
+ {{ parseTime(scope.row.updateTime, '{y}-{m}-{d}') }}
+
+
+
+
+
+ {{ parseTime(scope.row.completeTime, '{y}-{m}-{d}') }}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 出库
+
+
+
+
+
+
+
+
+
+
+ {{form.stockOutNum}}
+
+ 订单拣货出库
+ 采购退货出库
+ 盘点出库
+ 报损出库
+
+ {{form.remark}}
+ {{form.goodsUnit}}
+ {{form.specUnit}}
+ {{form.specUnitTotal}}
+
+
+
+
+
+
+ 出库商品明细
+
+
+
+
+
+
+
+
+
+
+
+ {{scope.row.colorValue}} {{scope.row.sizeValue}} {{scope.row.styleValue}}
+
+
+
+
+
+
+
+
+
+ {{ item.locationNum }}
+ 剩余库存:{{ item.currentQty }}
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 出库
+
+
+
+
+
+
+
+
+
+
diff --git a/oms-vue/src/views/xhs/order/index.vue b/oms-vue/src/views/xhs/order/index.vue
new file mode 100644
index 00000000..307ffc64
--- /dev/null
+++ b/oms-vue/src/views/xhs/order/index.vue
@@ -0,0 +1,973 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 搜索
+ 重置
+
+
+
+
+
+ 手动添加
+
+
+ Execl导入
+
+
+ API拉取订单
+
+
+ 导出订单
+
+
+
+
+
+
+
+
+
+
+ 珍姐姐de衣柜的店
+
+
+
+
+
+
+
+
+
+
{{item.itemName}}
+
{{item.itemSpec}}
+ x {{item.quantity}}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 待支付
+ 已支付
+ 清关中
+ 待发货
+ 部分发货
+ 待收货
+ 已完成
+ 已关闭
+ 已取消
+ 换货申请中
+
+
+ 待确认
+ 已确认
+ 已拦截
+
+
+
+
+
+
+
+ {{ dateToString(scope.row.orderCreatedTime) }}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 确认订单
+ 详情
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 小红书订单明细信息
+
+
+ 添加
+
+
+ 删除
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ {{form.id}}
+ {{form.orderId}}
+
+ {{ shopList.find(x=>x.id === form.shopId)?shopList.find(x=>x.id === form.shopId).name:'' }}
+
+
+ 普通订单
+ 定金预售
+ 全款预售
+ 延迟发货
+ 换货补发
+
+
+
+ {{form.customerRemark}}
+
+
+ {{form.sellerRemark}}
+
+
+
+ {{ dateToString(form.orderCreatedTime) }}
+
+ {{ dateToString(form.promiseLastDeliveryTime) }}
+
+ {{ dateToString(form.orderCancelTime) }}
+
+
+
+ 待支付
+ 处理中
+ 清关中
+ 待发货
+ 部分发货
+ 待收货
+ 已完成
+ 已关闭
+ 已取消
+ 换货申请中
+
+
+ 无售后
+ 售后处理中
+ 售后完成(含取消)
+
+
+
+
+
+ {{form.totalPayAmount /100}}
+
+ {{form.totalShippingFree / 100}}
+
+ {{ dateToString(form.orderPaidTime) }}
+
+
+
+
+
+ {{form.receiver}}
+ {{form.phone}}
+ {{form.province}}{{form.city}}{{form.district}}
+ {{form.address}}
+
+
+
+ {{form.expressCompanyCode}}
+ {{form.expressTrackingNo}}
+ {{dateToString(form.orderDeliveryTime)}}
+
+ 订单商品
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 订单商品
+
+
+ 添加赠品
+
+
+ 删除
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/oms-vue/src/views/xhs/orderReceiver/index.vue b/oms-vue/src/views/xhs/orderReceiver/index.vue
new file mode 100644
index 00000000..bdc9fd6e
--- /dev/null
+++ b/oms-vue/src/views/xhs/orderReceiver/index.vue
@@ -0,0 +1,346 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 搜索
+ 重置
+
+
+
+
+
+ 新增
+
+
+ 修改
+
+
+ 删除
+
+
+ 导出
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 修改
+ 删除
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/oms-vue/src/views/xhs/refund/index.vue b/oms-vue/src/views/xhs/refund/index.vue
new file mode 100644
index 00000000..a2ea29eb
--- /dev/null
+++ b/oms-vue/src/views/xhs/refund/index.vue
@@ -0,0 +1,785 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 搜索
+ 重置
+
+
+
+
+
+ 新增
+
+
+ 修改
+
+
+ 删除
+
+
+ 导出
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ {{ parseTime(scope.row.createOn, '{y}-{m}-{d}') }}
+
+
+
+
+ {{ parseTime(scope.row.modifyOn, '{y}-{m}-{d}') }}
+
+
+
+
+ 修改
+ 删除
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 小红书订单退款明细信息
+
+
+ 添加
+
+
+ 删除
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/oms-vue/vue.config.js b/oms-vue/vue.config.js
new file mode 100644
index 00000000..6d98ab0b
--- /dev/null
+++ b/oms-vue/vue.config.js
@@ -0,0 +1,134 @@
+'use strict'
+const path = require('path')
+
+function resolve(dir) {
+ return path.join(__dirname, dir)
+}
+
+const CompressionPlugin = require('compression-webpack-plugin')
+
+const name = process.env.VUE_APP_TITLE || '启航电商管理系统' // 网页标题
+
+const port = process.env.port || process.env.npm_config_port || 80 // 端口
+
+// vue.config.js 配置说明
+//官方vue.config.js 参考文档 https://cli.vuejs.org/zh/config/#css-loaderoptions
+// 这里只列一部分,具体配置参考文档
+module.exports = {
+ // 部署生产环境和开发环境下的URL。
+ // 默认情况下,Vue CLI 会假设你的应用是被部署在一个域名的根路径上
+ // 如果应用被部署在一个子路径上,你就需要用这个选项指定这个子路径。例如,如果你的应用被部署在 https://www.zhijian.vip/admin/,则设置 baseUrl 为 /admin/。
+ publicPath: process.env.NODE_ENV === "production" ? "/" : "/",
+ // 在npm run build 或 yarn build 时 ,生成文件的目录名称(要和baseUrl的生产环境路径一致)(默认dist)
+ outputDir: 'dist',
+ // 用于放置生成的静态资源 (js、css、img、fonts) 的;(项目打包之后,静态资源会放在这个文件夹下)
+ assetsDir: 'static',
+ // 是否开启eslint保存检测,有效值:ture | false | 'error'
+ lintOnSave: process.env.NODE_ENV === 'development',
+ // 如果你不需要生产环境的 source map,可以将其设置为 false 以加速生产环境构建。
+ productionSourceMap: false,
+ // webpack-dev-server 相关配置
+ devServer: {
+ host: '0.0.0.0',
+ port: port,
+ open: true,
+ proxy: {
+ // detail: https://cli.vuejs.org/config/#devserver-proxy
+ [process.env.VUE_APP_BASE_API]: {
+ target: `http://localhost:8080`,
+ changeOrigin: true,
+ pathRewrite: {
+ ['^' + process.env.VUE_APP_BASE_API]: ''
+ }
+ }
+ },
+ disableHostCheck: true
+ },
+ css: {
+ loaderOptions: {
+ sass: {
+ sassOptions: { outputStyle: "expanded" }
+ }
+ }
+ },
+ configureWebpack: {
+ name: name,
+ resolve: {
+ alias: {
+ '@': resolve('src')
+ }
+ },
+ plugins: [
+ // 使用gzip解压缩静态文件
+ new CompressionPlugin({
+ cache: false, // 不启用文件缓存
+ test: /\.(js|css|html)?$/i, // 压缩文件格式
+ filename: '[path].gz[query]', // 压缩后的文件名
+ algorithm: 'gzip', // 使用gzip压缩
+ minRatio: 0.8 // 压缩率小于1才会压缩
+ })
+ ],
+ },
+ chainWebpack(config) {
+ config.plugins.delete('preload') // TODO: need test
+ config.plugins.delete('prefetch') // TODO: need test
+
+ // set svg-sprite-loader
+ config.module
+ .rule('svg')
+ .exclude.add(resolve('src/assets/icons'))
+ .end()
+ config.module
+ .rule('icons')
+ .test(/\.svg$/)
+ .include.add(resolve('src/assets/icons'))
+ .end()
+ .use('svg-sprite-loader')
+ .loader('svg-sprite-loader')
+ .options({
+ symbolId: 'icon-[name]'
+ })
+ .end()
+
+ config.when(process.env.NODE_ENV !== 'development', config => {
+ config
+ .plugin('ScriptExtHtmlWebpackPlugin')
+ .after('html')
+ .use('script-ext-html-webpack-plugin', [{
+ // `runtime` must same as runtimeChunk name. default is `runtime`
+ inline: /runtime\..*\.js$/
+ }])
+ .end()
+
+ config.optimization.splitChunks({
+ chunks: 'all',
+ cacheGroups: {
+ libs: {
+ name: 'chunk-libs',
+ test: /[\\/]node_modules[\\/]/,
+ priority: 10,
+ chunks: 'initial' // only package third parties that are initially dependent
+ },
+ elementUI: {
+ name: 'chunk-elementUI', // split elementUI into a single package
+ test: /[\\/]node_modules[\\/]_?element-ui(.*)/, // in order to adapt to cnpm
+ priority: 20 // the weight needs to be larger than libs and app or it will be packaged into libs or app
+ },
+ commons: {
+ name: 'chunk-commons',
+ test: resolve('src/components'), // can customize your rules
+ minChunks: 3, // minimum common number
+ priority: 5,
+ reuseExistingChunk: true
+ }
+ }
+ })
+
+ config.optimization.runtimeChunk('single'),
+ {
+ from: path.resolve(__dirname, './public/robots.txt'), //防爬虫文件
+ to: './' //到根目录下
+ }
+ })
+ }
+}