修复高阶函数式组件的slot问题

修复了根据后台数据构建路有菜单时因引用传递导致的一些问题

修复用户导航的一些问题

增加了一些示例页面

部分文件位置调整

代码优化
master
toesbieya 6 years ago
parent fc13279ba4
commit de61b0f2e2
  1. 7
      vue/element-ui-personal/component/Message/main.vue
  2. 2
      vue/src/asset/style/element-ui.scss
  3. 2
      vue/src/asset/style/index.scss
  4. 8
      vue/src/component/CollapseCard/index.vue
  5. 4
      vue/src/component/OrgTree/index.vue
  6. 0
      vue/src/component/OrgTree/node.vue
  7. 0
      vue/src/component/OrgTree/style.scss
  8. 2
      vue/src/component/RegionSelector/Tree/TreeDialog.vue
  9. 9
      vue/src/component/abstract/Dialog/index.vue
  10. 16
      vue/src/component/abstract/Table/index.vue
  11. 34
      vue/src/component/form/Anchor/index.vue
  12. 7
      vue/src/component/form/Search/index.vue
  13. 96
      vue/src/component/form/ValidateInfo/index.vue
  14. 50
      vue/src/component/form/ValidateInfo/style.scss
  15. 2
      vue/src/globalMethod/BottomTip/main.vue
  16. 8
      vue/src/globalMethod/Guide/index.js
  17. 60
      vue/src/globalMethod/Guide/main.vue
  18. 7
      vue/src/globalMethod/Guide/style.scss
  19. 28
      vue/src/globalMethod/Guide/utils.js
  20. 4
      vue/src/globalMethod/Verify/index.js
  21. 7
      vue/src/layout/component/Navbar/component/HeadMenu.vue
  22. 27
      vue/src/layout/component/Navbar/index.vue
  23. 6
      vue/src/mixin/docDetailMixin.js
  24. 2
      vue/src/mixin/docTableMixin.js
  25. 60
      vue/src/mixin/guide/base.js
  26. 23
      vue/src/mixin/guide/data/navbar.js
  27. 18
      vue/src/mixin/guide/index.js
  28. 10
      vue/src/router/define.js
  29. 6
      vue/src/router/module/admin/child/default.js
  30. 4
      vue/src/router/module/admin/child/message.js
  31. 12
      vue/src/router/module/admin/child/purchase.js
  32. 12
      vue/src/router/module/admin/child/sell.js
  33. 2
      vue/src/router/module/admin/child/stock.js
  34. 14
      vue/src/router/module/admin/child/system.js
  35. 2
      vue/src/router/module/admin/index.js
  36. 0
      vue/src/router/module/dev/child/uploadFileDev.js
  37. 0
      vue/src/router/module/dev/index.js
  38. 0
      vue/src/router/module/doc/index.js
  39. 18
      vue/src/router/module/example/child/component.js
  40. 0
      vue/src/router/module/example/child/cool.js
  41. 16
      vue/src/router/module/example/child/directive.js
  42. 36
      vue/src/router/module/example/child/globalMethod.js
  43. 0
      vue/src/router/module/example/child/icon.js
  44. 0
      vue/src/router/module/example/child/iframe.js
  45. 0
      vue/src/router/module/example/child/test.js
  46. 2
      vue/src/router/module/example/index.js
  47. 10
      vue/src/router/module/index.js
  48. 4
      vue/src/router/util.js
  49. 5
      vue/src/store/module/resource.js
  50. 4
      vue/src/util/browser.js
  51. 31
      vue/src/util/tree.js
  52. 2
      vue/src/view/_app/403.vue
  53. 2
      vue/src/view/_app/404.vue
  54. 2
      vue/src/view/_app/500.vue
  55. 0
      vue/src/view/_app/login/LoginForm.vue
  56. 0
      vue/src/view/_app/login/RegisterForm.vue
  57. 0
      vue/src/view/_app/login/SetAnimation.vue
  58. 0
      vue/src/view/_app/login/index.vue
  59. 4
      vue/src/view/_app/login/style.scss
  60. 0
      vue/src/view/_app/redirect.vue
  61. 0
      vue/src/view/_common/DetailPage/index.vue
  62. 2
      vue/src/view/_common/DetailPage/style.scss
  63. 0
      vue/src/view/_common/ExceptionPage/index.vue
  64. 0
      vue/src/view/_common/ExceptionPage/style.scss
  65. 2
      vue/src/view/_common/ListPage/autoAdaptHeightMixin.js
  66. 0
      vue/src/view/_common/ListPage/index.vue
  67. 0
      vue/src/view/_common/SkeletonPage/index.vue
  68. 0
      vue/src/view/_common/SkeletonPage/style.scss
  69. 0
      vue/src/view/admin/index/component/DailyFinishOrderStat.vue
  70. 0
      vue/src/view/admin/index/component/DailyProfitStat.vue
  71. 2
      vue/src/view/admin/index/component/PanelGroup/PanelGroupItem.vue
  72. 0
      vue/src/view/admin/index/component/PanelGroup/index.vue
  73. 0
      vue/src/view/admin/index/component/TotalProfitGoods.vue
  74. 0
      vue/src/view/admin/index/indexPage.vue
  75. 0
      vue/src/view/admin/message/manage/EditDialog.vue
  76. 2
      vue/src/view/admin/message/manage/indexPage.vue
  77. 0
      vue/src/view/admin/message/user/AutoHidden.vue
  78. 0
      vue/src/view/admin/message/user/MessageStream.vue
  79. 0
      vue/src/view/admin/message/user/indexPage.vue
  80. 0
      vue/src/view/admin/purchase/inbound/component/OrderSelector.vue
  81. 24
      vue/src/view/admin/purchase/inbound/detailPage.vue
  82. 0
      vue/src/view/admin/purchase/inbound/indexPage.vue
  83. 0
      vue/src/view/admin/purchase/order/component/CategorySelector.vue
  84. 0
      vue/src/view/admin/purchase/order/component/SupplierSelector.vue
  85. 24
      vue/src/view/admin/purchase/order/detailPage.vue
  86. 0
      vue/src/view/admin/purchase/order/indexPage.vue
  87. 0
      vue/src/view/admin/sell/order/component/CustomerSelector.vue
  88. 0
      vue/src/view/admin/sell/order/component/StockSelector.vue
  89. 24
      vue/src/view/admin/sell/order/detailPage.vue
  90. 0
      vue/src/view/admin/sell/order/indexPage.vue
  91. 0
      vue/src/view/admin/sell/outbound/component/OrderSelector.vue
  92. 0
      vue/src/view/admin/sell/outbound/component/StockSelector.vue
  93. 24
      vue/src/view/admin/sell/outbound/detailPage.vue
  94. 0
      vue/src/view/admin/sell/outbound/indexPage.vue
  95. 0
      vue/src/view/admin/stock/current/DetailDialog.vue
  96. 0
      vue/src/view/admin/stock/current/indexPage.vue
  97. 0
      vue/src/view/admin/system/category/component/Form.vue
  98. 0
      vue/src/view/admin/system/category/component/List.vue
  99. 0
      vue/src/view/admin/system/category/indexPage.vue
  100. 0
      vue/src/view/admin/system/customer/EditDialog.vue
  101. Some files were not shown because too many files have changed in this diff Show More

@ -1,6 +1,7 @@
<template>
<transition name="el-message-fade" @after-leave="handleAfterLeave">
<div v-show="visible"
<div
v-show="visible"
:class="messageClass"
:style="positionStyle"
role="alert"
@ -44,6 +45,7 @@ export default {
center: false
}
},
computed: {
messageClass() {
return [
@ -70,11 +72,13 @@ export default {
return `animation-duration: ${this.duration}ms;animation-play-state:running`
}
},
watch: {
closed(newVal) {
if (newVal) this.visible = false
}
},
methods: {
handleAfterLeave() {
this.$destroy(true)
@ -98,6 +102,7 @@ export default {
}
}
},
mounted() {
this.startTimer()
}

@ -89,7 +89,7 @@
}
.el-loading-mask {
background: #fff;
background: #ffffff;
color: $--color-primary;
}

@ -165,7 +165,7 @@ $page-header-offsetHeight: $page-header-line-height + #{$page-view-margin * 2};
a {
color: #337ab7;
cursor: pointer;
text-decoration: none;
text-decoration: underline;
}
}

@ -2,7 +2,7 @@
<el-card :class="{collapsed}">
<div slot="header" class="clearfix">
<slot name="header">{{ header }}</slot>
<i class="el-icon-arrow-up form-collapse-card-icon"/>
<i class="el-icon-arrow-up collapse-card-icon"/>
</div>
<slot/>
</el-card>
@ -10,7 +10,7 @@
<script>
export default {
name: "FormCollapseCard",
name: "CollapseCard",
props: {
header: String
@ -35,14 +35,14 @@ export default {
</script>
<style>
.form-collapse-card-icon {
.collapse-card-icon {
float: right;
font-weight: bold;
transition: transform .3s;
cursor: pointer;
}
.collapsed .form-collapse-card-icon {
.collapsed .collapse-card-icon {
transform: rotate(180deg);
}

@ -16,7 +16,7 @@
</template>
<script>
import OrgTreeNode from "./OrgTreeNode"
import OrgTreeNode from "./node"
export default {
name: 'OrgTree',
@ -136,4 +136,4 @@ export default {
}
</script>
<style lang="scss" src="./tree.scss"></style>
<style lang="scss" src="./style.scss"></style>

@ -58,11 +58,9 @@ export default {
return (
<abstract-dialog
v-model={this.visible}
directives={[{name: 'drag-dialog'}]}
class="tree-dialog"
title="选择行政区域"
loading={this.loading}
appendToBody={true}
v-on:close={this.closeDialog}
>
<el-tree

@ -9,13 +9,12 @@ export default {
props: {
value: Boolean,
title: String,
loading: {type: Boolean, default: true},
width: {type: String, default: '30%'}
},
render(h, context) {
const {data, children, listeners, props: {value, title, loading, width}} = context
const {data, children, listeners, props: {value, loading, width}} = context
const onClose = function () {
return listeners.close ? () => listeners.close(false) : () => ({})
@ -26,13 +25,11 @@ export default {
v-drag-dialog
visible={value}
custom-class="abstract-dialog"
top={cssVariables['dialogTop']}
top={cssVariables.dialogTop}
width={width}
on-close={onClose}
{...data}
>
<slot slot="title" name="title">{title}</slot>
<div class="abstract-dialog-container">
<LoadingMask show={loading}/>
<el-scrollbar>
@ -42,8 +39,6 @@ export default {
<div style="margin-bottom: 17px"/>
</el-scrollbar>
</div>
<slot slot="footer" name="footer"/>
</el-dialog>
)
}

@ -7,10 +7,13 @@ export default {
functional: true,
render(h, context) {
const {data, children, scopedSlots} = context
const {data, children} = context
if (!scopedSlots.empty) {
scopedSlots.empty = () => <Empty/>
if (!data.scopedSlots) {
data.scopedSlots = {}
}
if (!data.scopedSlots.empty) {
data.scopedSlots.empty = () => <Empty/>
}
return (
@ -22,13 +25,6 @@ export default {
{...data}
>
{children}
{
Object
.entries(scopedSlots)
.map(([name, slot]) => (
name !== 'default' && <slot slot={name}>{slot()}</slot>
))
}
</el-table>
)
}

@ -21,9 +21,17 @@ export default {
props: {
reference: Function,
//{refref使reference()[ref]dom, label}
data: {type: Array, default: () => []},
//px
offsetTop: {type: Number, default: 15},
//px
bounds: {type: Number, default: 0},
//
getContainer: {
type: Function,
default: () => document.querySelector('#app .page-main>.scroll-container')
@ -33,33 +41,44 @@ export default {
data: () => ({cur: null}),
methods: {
//
close() {
this.$el.remove()
this.$destroy()
},
//ref
getCur(offsetTop, bounds) {
const sections = []
const container = this.getContainer()
for (const {ref} of this.data) {
const target = this.getDomFromRef(ref)
if (!target) continue
const top = getTopDistance(target, container)
if (top <= offsetTop + bounds) {
sections.push({ref, top})
}
}
//dom
if (sections.length) {
const max = sections.reduce((prev, curr) => (curr.top > prev.top ? curr : prev))
return max.ref
}
return null
},
getDomFromRef(ref) {
const refs = this.reference()
if (!refs) return null
return refs[ref]['$el'] || refs[ref][0]['$el']
const target = Array.isArray(refs[ref]) ? refs[ref][0] : refs[ref]
//vuedom
return target.$el || target
},
click(ref) {
@ -88,14 +107,15 @@ export default {
},
mounted() {
this.scroll = debounce(this.scroll)
this.scroll()
const container = this.getContainer()
this.handleScroll = debounce(this.scroll)
container.addEventListener('scroll', this.handleScroll)
container.addEventListener('scroll', this.scroll)
this.$once('hook:beforeDestroy', () => {
container.removeEventListener('scroll', this.handleScroll)
container.removeEventListener('scroll', this.scroll)
})
}
}
@ -110,7 +130,7 @@ export default {
top: 200px;
min-width: 72px;
border-radius: 4px 0 0 4px;
background: #fff;
background: #ffffff;
box-shadow: 0 2px 12px 0 rgba(166, 167, 173, 0.5);
z-index: 100;
@ -119,7 +139,7 @@ export default {
height: 28px;
line-height: 28px;
text-align: center;
color: #7C7E85;
color: #909399;
padding: 0 10px;
font-size: 12px;
cursor: pointer;
@ -130,7 +150,7 @@ export default {
}
&:not(:last-child) {
box-shadow: 0 1px 0 0 rgba(166, 167, 173, 0.1);
border-bottom: 1px solid rgba(166, 167, 173, 0.1);
}
}
}

@ -34,11 +34,9 @@ export default {
handleCollapse() {
this.collapse = !this.collapse
},
handleSearch() {
this.$emit('search')
},
handleReset() {
if (!this.initialModel || !this.model) {
return
@ -51,8 +49,8 @@ export default {
const vw = getElementInnerWidth(this.$el.parentNode)
if (vw < 768) return this.xs
else if (vw < 998) return this.sm
else if (vw < 1200) return this.md
if (vw < 998) return this.sm
if (vw < 1200) return this.md
return this.lg
},
@ -63,6 +61,7 @@ export default {
//
this.num = num === 1 ? num : num - 1
this.showCollapse = this.num < this.$slots.default.length
},

@ -38,6 +38,25 @@ export default {
},
methods: {
//
onClick({prop}) {
const formItem = this.getFormItem(prop)
formItem && formItem.$el.scrollIntoView({block: 'center'})
this.$refs.popover.doClose()
},
//el-form
getForm() {
return typeof this.form === 'function' ? this.form() : this.form
},
//propel-form-item
getFormItem(prop) {
const form = this.getForm()
return form && form.fields.find(i => i.prop === prop)
},
//el-formvalidate
onValidate(prop, success, msg) {
const alreadyIndex = this.error.findIndex(i => i.prop === prop)
if (alreadyIndex !== -1) {
@ -46,31 +65,16 @@ export default {
}
else {
if (success) return
const formItem = this.findFormItem(prop)
const formItem = this.getFormItem(prop)
this.error.push({prop, msg, label: formItem.label})
}
},
onClick({prop}) {
const formItem = this.findFormItem(prop)
formItem && formItem.$el.scrollIntoView({block: 'center'})
this.$refs.popover.doClose()
},
getFormRef() {
return typeof this.form === 'function' ? this.form() : this.form
},
findFormItem(prop) {
const form = this.getFormRef()
if (!form) return
return form.fields.find(i => i.prop === prop)
}
},
mounted() {
const form = this.getFormRef()
const form = this.getForm()
if (!form) return
form.$on('validate', this.onValidate)
this.$once('hook:beforeDestroy', () => {
form.$off('validate', this.onValidate)
@ -79,58 +83,4 @@ export default {
}
</script>
<style lang="scss">
@import "~@/asset/style/variables.scss";
.form-validate-info {
&.el-popper {
padding: 0;
}
&-ref {
padding: 0 10px;
cursor: pointer;
}
&-title {
text-align: center;
padding: 5px 16px 4px;
border-bottom: 1px solid #f0f0f0;
}
&-content {
max-height: 300px;
overflow: overlay;
}
&-item {
padding: 8px 16px;
background-color: #ffffff;
border-bottom: 1px solid #f0f0f0;
cursor: pointer;
transition: background-color .3s;
&:hover {
background-color: #e6f7ff;
}
.el-icon-circle-close {
float: left;
margin-top: 4px;
margin-right: 12px;
padding-bottom: 22px;
}
&-label {
margin-top: 2px;
color: rgba(0, 0, 0, .45);
font-size: 12px;
}
}
&-ref,
&-item .el-icon-circle-close {
color: $--color-danger;
}
}
</style>
<style lang="scss" src="./style.scss"></style>

@ -0,0 +1,50 @@
@import "~@/asset/style/variables.scss";
.form-validate-info {
&.el-popper {
padding: 0;
}
&-ref {
padding: 0 10px;
cursor: pointer;
}
&-ref,
&-item .el-icon-circle-close {
color: $--color-danger;
}
&-title {
text-align: center;
padding: 5px 16px 4px;
}
&-content {
max-height: 300px;
overflow: auto;
}
&-item {
padding: 8px 16px;
border-top: 1px solid $border-color-light;
cursor: pointer;
&:hover {
background-color: rgba($--color-primary, .1);
}
.el-icon-circle-close {
float: left;
margin-top: 4px;
margin-right: 12px;
padding-bottom: 22px;
}
&-label {
margin-top: 2px;
color: #909399;
font-size: 12px;
}
}
}

@ -30,7 +30,7 @@ export default {
}
</script>
<style lang="scss" scoped>
<style lang="scss">
.bottom-tip {
position: absolute;
width: 100%;

@ -14,7 +14,7 @@ const defaultOptions = {
prevBtnText: '上一步',
}
const guide = function (start, steps, beforeExit) {
const guide = function (steps, index, beforeExit) {
if (instance) instance.exit()
else {
instance = new GuideConstructor({data: {options: defaultOptions}})
@ -25,15 +25,15 @@ const guide = function (start, steps, beforeExit) {
instance.steps = steps
instance.beforeExit = beforeExit
this.$nextTick(() => instance.start(start))
this.$nextTick(() => instance.start(index))
}
guide.config = function (config) {
mergeObj(defaultOptions, config)
}
guide.exit = function () {
instance && instance.exit()
guide.exit = function (force) {
instance && instance.exit(force)
}
export default guide

@ -1,27 +1,26 @@
<template>
<div>
<el-popover ref="popover" :value="showPopover" trigger="manual" width="300">
<div v-html="step.content" style="padding: 10px"/>
<el-popover ref="popover" :value="showPopover" trigger="manual">
<div class="guide-popover-container">
<div v-html="step.content"/>
<div class="guide-popover-action">
<div class="action-close">
<el-button v-if="hasDone" size="small" @click="exit">
{{ step.doneBtnText }}
</el-button>
<el-button v-else size="small" @click="exit">
{{ step.closeBtnText }}
<el-button size="mini" type="dashed" plain @click="exit">
{{ hasDone ? step.doneBtnText : step.closeBtnText }}
</el-button>
</div>
<div class="action-step">
<el-button v-if="showPrevBtn" class="prev-btn" size="small" @click="previous">
<el-button v-if="showPrevBtn" class="prev-btn" size="mini" plain @click="previous">
{{ step.prevBtnText }}
</el-button>
<el-button v-if="showNextBtn" class="next-btn" size="small" @click="next">
<el-button v-if="showNextBtn" class="next-btn" size="mini" plain @click="next">
{{ step.nextBtnText }}
</el-button>
</div>
</div>
</div>
<div slot="reference" v-show="showStage" id="guide-stage" :style="stageStyle"/>
</el-popover>
@ -35,10 +34,9 @@
<script>
/**
* 由driver.js改造而来
* vue里交互型的导航不太行太多东西做不到换成引导手册吧
*/
import {debounce, isEmpty, deepClone} from "@/util"
import {addHighlightClasses, getCalculatedPosition, inMainPage, jump, removeHighlightClasses} from "./utils"
import {addHighlightClasses, getCalculatedPosition, removeHighlightClasses} from "./utils"
export default {
name: "Guide",
@ -73,9 +71,7 @@ export default {
return this.currentStep === this.steps.length - 1
},
step() {
if (!this.isActive
|| this.steps.length <= 0
|| !this.steps[this.currentStep]) {
if (!this.isActive || this.steps.length <= 0 || !this.steps[this.currentStep]) {
return {}
}
@ -89,7 +85,7 @@ export default {
watch: {
isActive(v) {
v ? document.body.classList.add('overflow-hidden') : document.body.classList.remove('overflow-hidden')
document.body.classList[v ? 'add' : 'remove']('overflow-hidden')
}
},
@ -115,11 +111,10 @@ export default {
this.showOverlay = true
this.showStage = true
},
exit() {
exit(force) {
if (!this.isActive) return
if (this.beforeExit) {
if (!force && this.beforeExit) {
const result = this.beforeExit(this.hasDone)
if (result && result.then) {
result.then(this.$_clear)
@ -138,13 +133,12 @@ export default {
if (this.step.onPrevious) {
const result = this.step.onPrevious()
if (result && result.then) {
result.then(this.$_movePrevious)
result.then(this.$_movePrevious, this.$_moveEnd)
}
else result !== false && this.$_movePrevious()
else result ? this.$_movePrevious() : this.$_moveEnd()
}
else this.$_movePrevious()
},
next() {
if (!this.isActive || this.moving) return
this.moving = true
@ -152,9 +146,9 @@ export default {
if (this.step.onNext) {
const result = this.step.onNext()
if (result && result.then) {
result.then(this.$_moveNext)
result.then(this.$_moveNext, this.$_moveEnd)
}
else result !== false && this.$_moveNext()
else result ? this.$_moveNext() : this.$_moveEnd()
}
else this.$_moveNext()
},
@ -170,13 +164,15 @@ export default {
this.currentStep--
this.$_highlight()
},
$_moveNext() {
if (!this.isActive) return
this.currentStep++
this.$_highlight()
},
$_moveEnd() {
this.$refs.popover.updatePopper()
this.moving = false
},
$_clear() {
if (!this.isActive) return
this.isActive = false
@ -185,11 +181,10 @@ export default {
this.currentStep = 0
this.steps = []
this.beforeExit = null
if (this.highlightedElement) removeHighlightClasses(this.highlightedElement)
this.highlightedElement && removeHighlightClasses(this.highlightedElement)
this.highlightedElement = null
this.lastHighlightedElement = null
},
$_highlight() {
if (isEmpty(this.step.element)) throw new Error(`step${this.currentStep}中element为空`)
@ -199,23 +194,22 @@ export default {
if (el === this.highlightedElement) return
if (this.highlightedElement) removeHighlightClasses(this.highlightedElement)
this.highlightedElement && removeHighlightClasses(this.highlightedElement)
this.lastHighlightedElement = this.highlightedElement
this.highlightedElement = el
if (inMainPage(el)) jump(el)
el.scrollIntoView({block: 'center'})
this.$_setStageStyle(getCalculatedPosition(el))
window.setTimeout(() => {
this.$refs.popover.updatePopper()
this.moving = false
this.$_moveEnd()
this.step.onHighlighted && this.step.onHighlighted()
}, 300)
addHighlightClasses(el)
},
$_setStageStyle({top, left, right, bottom}) {
const width = right - left
const height = bottom - top
@ -224,7 +218,7 @@ export default {
`height:${height}px;` +
`top:${top}px;` +
`left:${left}px;` +
`backgroundColor:${this.step.stageBackground}`
`background-color:${this.step.stageBackground}`
}
},

@ -16,10 +16,14 @@
will-change: unset !important;
}
.guide-popover-action {
.guide-popover-container {
min-width: 300px;
.guide-popover-action {
position: relative;
height: 100%;
width: 100%;
margin-top: 20px;
.action-close {
display: inline-block;
@ -35,6 +39,7 @@
right: 90px;
}
}
}
}
#guide-stage {

@ -31,26 +31,6 @@ export function getStyleProperty(element, propertyName, prefixVendor = false) {
return propertyValue && propertyValue.toLowerCase ? propertyValue.toLowerCase() : propertyValue
}
export function inMainPage(element) {
const appView = document.querySelector('.page-main')
if (!appView) throw new Error('路由页面未加载')
return appView.contains(element)
}
export function jump(element) {
if (!element.scrollIntoView) {
scrollManually(element)
return
}
try {
element.scrollIntoView({behavior: 'instant', block: 'center'})
}
catch (e) {
scrollManually(element)
}
}
export function removeHighlightClasses(element) {
element.classList.remove(CLASS_HIGHLIGHTED_ELEMENT)
element.classList.remove(CLASS_POSITION_RELATIVE)
@ -124,11 +104,3 @@ function fixStackingContext(element) {
parentNode = parentNode.parentNode
}
}
function scrollManually(element) {
const elementRect = element.getBoundingClientRect()
const absoluteElementTop = elementRect.top + window.pageYOffset
const middle = absoluteElementTop - (window.innerHeight / 2)
window.scrollTo(0, middle)
}

@ -4,7 +4,7 @@ import {isEmpty} from "@/util"
let Constructor = Vue.extend(Main)
const PuzzleVerify = function ({left, top} = {}) {
export default function ({left, top} = {}) {
const instance = new Constructor()
const position = getPosition({height: instance.height + 130, width: instance.width + 20, left, top})
@ -42,5 +42,3 @@ function getPosition({height, width, left, top} = {}) {
function center(full, part) {
return Math.round((full - part) / 2)
}
export default PuzzleVerify

@ -7,6 +7,7 @@ import {getters as appGetters, mutations as appMutations} from "@/layout/store/a
import NavMenu from "@/component/menu/NavMenu"
import NavMenuItem from "@/component/menu/NavMenu/item"
import {getActiveMenuByRoute} from "@/layout/util"
import {isDom} from "@/util/browser"
export default {
name: "HeadMenu",
@ -130,9 +131,11 @@ export default {
//mounted
setChildrenWidth() {
const ul = this.getMenuEl()
if (!ul) return
if (!isDom(ul)) return
const menuItemNodes = ul.children
if (!menuItemNodes || menuItemNodes.length === 0) return
//''
this.overflowedIndicatorWidth = 50
this.menuItemSizes = Array.from(menuItemNodes).map(i => i.getBoundingClientRect().width)
@ -163,7 +166,7 @@ export default {
},
createResizeObserver() {
//observer
if (!this.getMenuEl()) {
if (!isDom(this.getMenuEl())) {
if (this.resizeObserver) {
this.resizeObserver.disconnect()
this.resizeObserver = null

@ -1,6 +1,5 @@
<script type="jsx">
import {mapState} from 'vuex'
import guideMixin from '@/mixin/guide'
import hamburgerMixin from '@/layout/mixin/hamburger'
import Bell from "./component/Bell"
import HeadMenu from "./component/HeadMenu"
@ -14,10 +13,32 @@ import {refreshPage} from "@/util/route"
export default {
name: 'navbar',
mixins: [guideMixin.navbar, hamburgerMixin],
mixins: [hamburgerMixin],
components: {Bell, HeadMenu, Logo},
data() {
return {
guideSteps: [
{
element: '.setting-btn.navbar-item',
content: '这是个性设置按钮,可以根据自己喜好进行一些设置',
},
{
element: '.navbar .el-dropdown.navbar-item',
content: '这是用户中心',
},
{
element: '.tags-view-container',
content: `<p>这是tab栏,可以右键tab页进行相关操作</p>
<p>ctrl + 可以进行tab页的左右切换</p>
<p>当tab过多时通过鼠标滚轮来滚动</p>
<p>双击可以关闭</p>`,
},
]
}
},
computed: {
...mapState('user', ['avatar', 'name', 'prepareLogout']),
@ -51,7 +72,7 @@ export default {
this.$route.path !== path && this.$router.push(path)
break
case 'guide':
this.$guide(0, this.guideSteps)
this.$guide(this.guideSteps)
break
case 'logout':
if (!this.prepareLogout) {

@ -2,10 +2,10 @@ import {commonMethods} from "@/mixin/docTableMixin"
import AbstractForm from '@/component/abstract/Form'
import AbstractFormItem from "@/component/abstract/Form/item"
import AbstractTable from "@/component/abstract/Table"
import DetailPage from "@/view/app/common/DetailPage"
import CollapseCard from '@/component/CollapseCard'
import DetailPage from "@/view/_common/DetailPage"
import DocHistory from '@/component/biz/doc/DocHistory'
import DocSteps from '@/component/biz/doc/DocSteps'
import FormCollapseCard from '@/component/form/CollapseCard'
import UploadFile from '@/component/UploadFile'
import {isEmpty, mergeObj} from '@/util'
import {auth} from "@/util/auth"
@ -18,10 +18,10 @@ export default {
AbstractForm,
AbstractFormItem,
AbstractTable,
CollapseCard,
DetailPage,
DocHistory,
DocSteps,
FormCollapseCard,
UploadFile
},

@ -1,6 +1,6 @@
import tableMixin from '@/mixin/tablePageMixin'
import LinerProgress from '@/component/LinerProgress'
import ListPage from '@/view/app/common/ListPage'
import ListPage from '@/view/_common/ListPage'
import {isEmpty} from "@/util"
import {elConfirm, elError, elSuccess} from "@/util/message"
import {auth} from "@/util/auth"

@ -1,60 +0,0 @@
//删除所有url参数
function delAllUrlParam() {
let paramStartIndex = location.href.indexOf('?')
if (paramStartIndex > -1) {
const href = location.href.substring(0, paramStartIndex)
history.replaceState(null, null, [...href].join(''))
}
}
//将引导步骤中函数的this绑定为组件实例
function transformGuideSteps(instance, steps) {
steps.forEach(step => {
Object.keys(step).forEach(key => {
if (typeof step[key] === 'function') {
step[key] = step[key].bind(instance)
}
})
})
}
export default {
methods: {
$_prepareGuide(params) {
if (!['navbar', 'sidebar'].includes(this.$options.name)) return
if ('guide' in params) {
delAllUrlParam()
for (const key of ['navbar', 'sidebar']) {
if (params[key] && this.$options.name === key) {
return this.$guide(params.guide, this.guideSteps)
}
}
}
}
},
computed: {
routeParams() {
return this.$route.params
}
},
watch: {
routeParams(v) {
this.$_prepareGuide(v)
}
},
created() {
transformGuideSteps(this, this.guideSteps)
},
activated() {
const params = this.$route.params
if (!params.navbar && !params.sidebar && 'guide' in params) {
delAllUrlParam()
this.$guide(params.guide, this.guideSteps)
}
}
}

@ -1,23 +0,0 @@
/*
* 导航栏引导步骤
* */
const steps = [
{
element: '.setting-btn.navbar-item',
content: '这是个性设置按钮,可以根据自己喜好进行一些设置',
},
{
element: '.navbar .el-dropdown.navbar-item',
content: '这是用户中心',
},
{
element: '.tags-view-container',
content: `<p>这是tab栏,可以右键tab页进行相关操作</p>
<p>ctrl + 可以进行tab页的左右切换</p>
<p>当tab过多时通过鼠标滚轮来滚动</p>
<p>双击可以关闭</p>`,
},
]
export default steps

@ -1,18 +0,0 @@
const modulesFiles = require.context('./data', false, /\.js$/)
import baseMixin from './base'
const modules = modulesFiles.keys().reduce((modules, modulePath) => {
const moduleName = modulePath.replace(/^\.\/(.*)\.\w+$/, '$1')
const value = modulesFiles(modulePath)
modules[moduleName] = {
data() {
return {
guideSteps: value.default
}
},
...baseMixin
}
return modules
}, {})
export default modules

@ -1,9 +1,9 @@
import Layout from "@/layout/index"
import Redirect from "@/view/app/redirect"
import Login from "@/view/app/login/index"
import Page403 from "@/view/app/403"
import Page404 from "@/view/app/404"
import Page500 from "@/view/app/500"
import Redirect from "@/view/_app/redirect"
import Login from "@/view/_app/login/index"
import Page403 from "@/view/_app/403"
import Page404 from "@/view/_app/404"
import Page500 from "@/view/_app/500"
import routes from './module'
import {deepClone} from "@/util"

@ -1,16 +1,16 @@
//路由表:系统页面
//路由表:默认页面
const router = [
{
path: 'index',
component: 'index/',
component: 'admin/index/',
name: 'index',
meta: {title: '首页', affix: true, icon: 'svg-home', noAuth: true, pageHeader: false, sort: 0}
},
{
path: 'user',
name: 'userCenter',
component: 'userCenter/',
component: 'admin/userCenter/',
meta: {title: '个人中心', noCache: true, icon: 'svg-user', noAuth: true, pageHeader: false, hidden: true},
}
]

@ -7,13 +7,13 @@ const router = {
{
path: 'manage',
name: 'messageManagement',
component: 'message/manage/',
component: 'admin/message/manage/',
meta: {title: '消息管理'}
},
{
path: 'user',
name: 'userMessage',
component: 'message/user/',
component: 'admin/message/user/',
meta: {title: '个人消息', noAuth: true, noCache: true}
}
]

@ -7,12 +7,12 @@ const router = {
{
path: 'order',
name: 'purchaseOrder',
component: 'purchase/order/',
component: 'admin/purchase/order/',
meta: {title: '采购订单'}
},
{
path: 'order/detail/:type(see|add|edit)/:id?',
component: 'purchase/order/detail',
component: 'admin/purchase/order/detail',
meta: {
title: '采购订单详情页',
hidden: true,
@ -30,18 +30,18 @@ const router = {
},
activeMenu: '/purchase/order',
usePathKey: true,
commonModule: '@/view/purchase/order/detail'
commonModule: '@/view/admin/purchase/order/detail'
}
},
{
path: 'inbound',
name: 'purchaseInbound',
component: 'purchase/inbound/',
component: 'admin/purchase/inbound/',
meta: {title: '采购入库'}
},
{
path: 'inbound/detail/:type(see|add|edit)/:id?',
component: 'purchase/inbound/detail',
component: 'admin/purchase/inbound/detail',
meta: {
title: '采购入库详情页',
hidden: true,
@ -59,7 +59,7 @@ const router = {
},
activeMenu: '/purchase/inbound',
usePathKey: true,
commonModule: '@/view/purchase/inbound/detail'
commonModule: '@/view/admin/purchase/inbound/detail'
}
}
]

@ -7,12 +7,12 @@ const router = {
{
path: 'order',
name: 'sellOrder',
component: 'sell/order/',
component: 'admin/sell/order/',
meta: {title: '销售订单'}
},
{
path: 'order/detail/:type(see|add|edit)/:id?',
component: 'sell/order/detail',
component: 'admin/sell/order/detail',
meta: {
title: '销售订单详情页',
hidden: true,
@ -30,18 +30,18 @@ const router = {
},
activeMenu: '/sell/order',
usePathKey: true,
commonModule: '@/view/sell/order/detail'
commonModule: '@/view/admin/sell/order/detail'
}
},
{
path: 'outbound',
name: 'sellOutbound',
component: 'sell/outbound/',
component: 'admin/sell/outbound/',
meta: {title: '销售出库'}
},
{
path: 'outbound/detail/:type(see|add|edit)/:id?',
component: 'sell/outbound/detail',
component: 'admin/sell/outbound/detail',
meta: {
title: '销售出库详情页',
hidden: true,
@ -59,7 +59,7 @@ const router = {
},
activeMenu: '/sell/outbound',
usePathKey: true,
commonModule: '@/view/sell/outbound/detail'
commonModule: '@/view/admin/sell/outbound/detail'
}
}
]

@ -7,7 +7,7 @@ const router = {
{
path: 'current',
name: 'currentStock',
component: 'stock/current/',
component: 'admin/stock/current/',
meta: {title: '当前库存'}
}
]

@ -7,43 +7,43 @@ const router = {
{
path: 'department',
name: 'departmentManagement',
component: 'system/department/',
component: 'admin/system/department/',
meta: {title: '部门管理'}
},
{
path: 'menu',
name: 'menuManagement',
component: 'system/menu/',
component: 'admin/system/menu/',
meta: {title: '菜单管理', noCache: true}
},
{
path: 'role',
name: 'roleManagement',
component: 'system/role/',
component: 'admin/system/role/',
meta: {title: '角色管理'}
},
{
path: 'user',
name: 'userManagement',
component: 'system/user/',
component: 'admin/system/user/',
meta: {title: '用户管理'}
},
{
path: 'category',
name: 'categorySetting',
component: 'system/category/',
component: 'admin/system/category/',
meta: {title: '商品分类'}
},
{
path: 'customer',
name: 'customerManagement',
component: 'system/customer/',
component: 'admin/system/customer/',
meta: {title: '客户管理'}
},
{
path: 'supplier',
name: 'supplierManagement',
component: 'system/supplier/',
component: 'admin/system/supplier/',
meta: {title: '供应商管理'}
}
]

@ -1,4 +1,4 @@
/*顶级菜单:默认*/
/*顶级菜单:后台管理*/
import {context2array} from '@/router/util'

@ -3,32 +3,22 @@ export default {
meta: {title: '组件', icon: 'el-icon-s-grid'},
children: [
{
path: 'uploadExample',
path: 'upload',
component: 'example/component/upload',
meta: {title: '上传文件'}
},
{
path: 'skeletonExample',
path: 'skeleton',
component: 'example/component/skeleton',
meta: {title: '骨架屏'}
},
{
path: 'rippleExample',
component: 'example/component/ripple',
meta: {title: '波纹'}
},
{
path: 'signatureExample',
component: 'example/component/signature',
meta: {title: '手写签名'}
},
{
path: 'regionSelectorExample',
path: 'regionSelector',
component: 'example/component/regionSelector',
meta: {title: '行政区划选择'}
},
{
path: 'treeSelectExample',
path: 'treeSelect',
component: 'example/component/treeSelect',
meta: {title: '树选择'}
}

@ -0,0 +1,16 @@
export default {
path: 'directive',
meta: {title: '全局指令', icon: 'el-icon-s-grid'},
children: [
{
path: 'dragDialog',
component: 'example/directive/dragDialog',
meta: {title: '可拖拽dialog'}
},
{
path: 'ripple',
component: 'example/directive/ripple',
meta: {title: '波纹'}
}
]
}

@ -0,0 +1,36 @@
export default {
path: 'global',
meta: {title: '全局方法', icon: 'el-icon-s-opportunity'},
children: [
{
path: 'message',
component: 'example/globalMethod/message',
meta: {title: '消息提示'}
},
{
path: 'bottomTip',
component: 'example/globalMethod/bottomTip',
meta: {title: '底部消息提示'}
},
{
path: 'guide',
component: 'example/globalMethod/guide',
meta: {title: '导航'}
},
{
path: 'imageViewer',
component: 'example/globalMethod/imageViewer',
meta: {title: '图片预览'}
},
{
path: 'signature',
component: 'example/globalMethod/signature',
meta: {title: '手写签名'}
},
{
path: 'verify',
component: 'example/globalMethod/verify',
meta: {title: '拼图验证'}
}
]
}

@ -7,6 +7,6 @@ const files = require.context('./child', false, /\.js$/)
export default {
path: '/example',
component: 'Layout',
meta: {title: '演示用例', icon: 'svg-show', noAuth: true, noCache: true},
meta: {title: '演示用例', icon: 'svg-show', noAuth: true, noCache: true, sort: 1},
children: context2array(files)
}

@ -1,6 +1,6 @@
import defaultRoot from './defaultRoot'
import exampleRoot from './exampleRoot'
import devRoot from './devRoot'
import docRoot from './docRoot'
import admin from './admin'
import example from './example'
import dev from './dev'
import doc from './doc'
export default [defaultRoot, exampleRoot, devRoot, docRoot]
export default [admin, example, dev, doc]

@ -1,6 +1,6 @@
import Layout from '@/layout'
import SkeletonPage from '@/view/app/common/SkeletonPage'
import Page500 from '@/view/app/500'
import SkeletonPage from '@/view/_common/SkeletonPage'
import Page500 from '@/view/_app/500'
import {isEmpty} from "@/util"
import {isExternal, isString} from "@/util/validate"

@ -22,6 +22,8 @@ const state = {
const mutations = {
resource(state, {data, admin}) {
data = deepClone(data)
state.resourceMap = generateResourceMap(data)
//如果不是admin用户,那么过滤admin类型的权限
@ -48,9 +50,10 @@ const actions = {
.then(({data}) => {
commit('resource', {data: data || [], admin})
//动态添加路由,这里不需要进行权限过滤
const routes = transformOriginRouteData(data)
metaExtend(routes)
//动态添加路由,这里不需要进行权限过滤
//可能存在多次调用的情况,所以仅在第一次调用时添加进vue-router
!state.init && addDynamicRoutes(routes)

@ -13,13 +13,13 @@ export function isMobile() {
}
/**
* 判断是否为dom元素
* 判断是否为dom元素是则返回true
*
* @param obj
* @return {boolean}
*/
export function isDom(obj) {
return !!obj && typeof obj === 'object' && obj.nodeType === 1 && typeof obj.nodeName === 'string'
return obj && typeof obj === 'object' && obj.nodeType === 1 && typeof obj.nodeName === 'string'
}
/**

@ -1,23 +1,38 @@
import {deepClone} from "@/util"
import {createWorker} from '@/util/worker'
const DEFAULT_PROPS = {id: 'id', pid: 'pid', children: 'children', leafHasChildren: true}
const DEFAULT_PROPS = {
//节点的id属性名称
id: 'id',
//节点的父级id属性名称
pid: 'pid',
//节点的子级节点属性名称
children: 'children',
//根节点的判定方法,传入函数时参数为节点对象
rootPredicate: 0,
//叶子节点是否能有children属性
leafHasChildren: false
}
/**
* 列表转树形结构
*
* @param list {array}
* @param rootSign {number|String|Function} 根节点的判定方法
* @param props 树的配置项{id, pid, children, leafHasChildren}
* @param props 树的配置项{id, pid, children, rootPredicate, leafHasChildren}
* @return {array}
*/
export function createTree(list, rootSign = 0, props = {}) {
export function createTree(list, props = {}) {
if (!list || list.length <= 0) return []
const {
id = DEFAULT_PROPS.id,
pid = DEFAULT_PROPS.pid,
children = DEFAULT_PROPS.children,
rootPredicate = DEFAULT_PROPS.rootPredicate,
leafHasChildren = DEFAULT_PROPS.leafHasChildren
} = props
@ -29,9 +44,9 @@ export function createTree(list, rootSign = 0, props = {}) {
})
const predicate = (() => {
return typeof rootSign === 'function'
? rootSign
: key => key === rootSign
return typeof rootPredicate === 'function'
? rootPredicate
: key => key === rootPredicate
})()
return list.filter(node => {
@ -105,7 +120,7 @@ export function createLimitTreeByMap(fullMap, limit) {
findParent(node)
}
const result = createTree(Object.values(resultNodes), '0')
const result = createTree(Object.values(resultNodes), {rootPredicate: '0'})
result.forEach(i => calc(i))

@ -1,5 +1,5 @@
<script type="text/jsx">
import ExceptionPage from '@/view/app/common/ExceptionPage'
import ExceptionPage from '@/view/_common/ExceptionPage'
export default {
name: 'Page403',

@ -1,5 +1,5 @@
<script type="text/jsx">
import ExceptionPage from '@/view/app/common/ExceptionPage'
import ExceptionPage from '@/view/_common/ExceptionPage'
export default {
name: 'Page404',

@ -1,5 +1,5 @@
<script type="text/jsx">
import ExceptionPage from '@/view/app/common/ExceptionPage'
import ExceptionPage from '@/view/_common/ExceptionPage'
export default {
name: 'Page500',

@ -1,9 +1,9 @@
@import "~@/asset/style/variables.scss";
$bg: #283443;
$light_gray: #fff;
$light_gray: #ffffff;
$dark_gray: #889aa4;
$cursor: #fff;
$cursor: #ffffff;
@supports (-webkit-mask: none) and (not (cater-color: $cursor)) {
.login-container .el-input input {

@ -8,7 +8,7 @@
&-header {
margin: -#{$page-view-margin} -#{$page-view-margin} 0 -#{$page-view-margin};
padding: 16px 32px 0 32px;
background: #fff;
background: #ffffff;
border-bottom: 1px solid $border-color-light;
> .el-page-header {

@ -17,7 +17,7 @@ export default {
methods: {
//设置表格距离视窗底部的理想距离(分页高度 + el-card的1px边距 + el-card padding + 页面margin)
calcDesiredDistance() {
const pageViewMargin = parseFloat(cssVariables['pageViewMargin'])
const pageViewMargin = parseFloat(cssVariables.pageViewMargin)
const paginationHeight = this.$el.querySelector('.table-container > .el-pagination') ? 50 : 0
this.desiredDistance = paginationHeight + 1 + 20 + pageViewMargin
},

@ -40,7 +40,7 @@ export default {
position: relative;
overflow: hidden;
color: #666;
background: #fff;
background: #ffffff;
border-radius: 4px;
box-shadow: 0 2px 12px 0 rgba(0, 0, 0, .1);
border-color: rgba(0, 0, 0, .05);

@ -44,7 +44,7 @@
<script>
import tableMixin from '@/mixin/tablePageMixin'
import EditDialog from './EditDialog'
import ListPage from '@/view/app/common/ListPage'
import ListPage from '@/view/_common/ListPage'
import {search, add, update, del} from "@/api/message/manage"
import {isEmpty} from '@/util'
import {wic} from "@/util/auth"

@ -10,20 +10,20 @@
@close="close"
>
<abstract-form :model="form" :rules="rules">
<form-collapse-card ref="progress" header="流程进度">
<collapse-card ref="progress" header="流程进度">
<doc-steps :status="form.status" :type="type"/>
</form-collapse-card>
</collapse-card>
<form-collapse-card ref="base" header="基础信息">
<collapse-card ref="base" header="基础信息">
<abstract-form-item label="采购订单" prop="pid">
<el-input v-if="canSave" :value="form.pid" readonly>
<el-button slot="append" @click="parentDialog=true">选择</el-button>
</el-input>
<template v-else>{{ form.pid }}</template>
</abstract-form-item>
</form-collapse-card>
</collapse-card>
<form-collapse-card ref="goods" header="入库商品">
<collapse-card ref="goods" header="入库商品">
<abstract-table :data="form.data" :highlight-current-row="false">
<el-table-column align="center" label="#" type="index" width="80"/>
<el-table-column align="center" label="商 品" prop="cname"/>
@ -41,18 +41,18 @@
</template>
</el-table-column>
</abstract-table>
</form-collapse-card>
</collapse-card>
<form-collapse-card ref="attachment" header="附件">
<collapse-card ref="attachment" header="附件">
<upload-file
:file-list="form.imageList"
:disabled="!canSave"
@remove="removeUpload"
@success="uploadSuccess"
/>
</form-collapse-card>
</collapse-card>
<form-collapse-card ref="remark" header="备注">
<collapse-card ref="remark" header="备注">
<el-input
v-model="form.remark"
:rows="4"
@ -61,11 +61,11 @@
show-word-limit
type="textarea"
/>
</form-collapse-card>
</collapse-card>
<form-collapse-card ref="history" header="单据历史">
<collapse-card ref="history" header="单据历史">
<doc-history :id="form.id"/>
</form-collapse-card>
</collapse-card>
</abstract-form>
<order-selector v-model="parentDialog" @select="selectParent"/>

@ -10,20 +10,20 @@
@close="close"
>
<abstract-form :model="form" :rules="rules">
<form-collapse-card ref="progress" header="流程进度">
<collapse-card ref="progress" header="流程进度">
<doc-steps :status="form.status" :finish="form.finish" :type="type"/>
</form-collapse-card>
</collapse-card>
<form-collapse-card ref="base" header="基础信息">
<collapse-card ref="base" header="基础信息">
<abstract-form-item label="供应商" prop="sname">
<el-input v-if="canSave" :value="form.sname" readonly>
<el-button slot="append" @click="supplierDialog=true">选择</el-button>
</el-input>
<template v-else>{{ form.sname }}</template>
</abstract-form-item>
</form-collapse-card>
</collapse-card>
<form-collapse-card ref="goods" header="采购商品">
<collapse-card ref="goods" header="采购商品">
<abstract-table :data="form.data" :highlight-current-row="false">
<el-table-column align="center" label="#" type="index" width="80"/>
<el-table-column align="center" label="商 品">
@ -87,18 +87,18 @@
</el-button>
</div>
</abstract-table>
</form-collapse-card>
</collapse-card>
<form-collapse-card ref="attachment" header="附件">
<collapse-card ref="attachment" header="附件">
<upload-file
:file-list="form.imageList"
:disabled="!canSave"
@remove="removeUpload"
@success="uploadSuccess"
/>
</form-collapse-card>
</collapse-card>
<form-collapse-card ref="remark" header="备注">
<collapse-card ref="remark" header="备注">
<el-input
v-model="form.remark"
:rows="4"
@ -107,11 +107,11 @@
show-word-limit
type="textarea"
/>
</form-collapse-card>
</collapse-card>
<form-collapse-card ref="history" header="单据历史">
<collapse-card ref="history" header="单据历史">
<doc-history :id="form.id"/>
</form-collapse-card>
</collapse-card>
</abstract-form>
<supplier-selector v-model="supplierDialog" @select="selectSupplier"/>

@ -10,20 +10,20 @@
@close="close"
>
<abstract-form :model="form" :rules="rules">
<form-collapse-card ref="progress" header="流程进度">
<collapse-card ref="progress" header="流程进度">
<doc-steps :status="form.status" :finish="form.finish" :type="type"/>
</form-collapse-card>
</collapse-card>
<form-collapse-card ref="base" header="基础信息">
<collapse-card ref="base" header="基础信息">
<abstract-form-item label="客 户" prop="customerName">
<el-input v-if="canSave" :value="form.customerName" readonly>
<el-button slot="append" @click="customerDialog=true">选择</el-button>
</el-input>
<template v-else>{{ form.customerName }}</template>
</abstract-form-item>
</form-collapse-card>
</collapse-card>
<form-collapse-card ref="goods" header="销售商品">
<collapse-card ref="goods" header="销售商品">
<abstract-table :data="form.data" :highlight-current-row="false">
<el-table-column align="center" label="#" type="index" width="80"/>
<el-table-column align="center" label="商品" prop="cname"/>
@ -70,18 +70,18 @@
</el-button>
</div>
</abstract-table>
</form-collapse-card>
</collapse-card>
<form-collapse-card ref="attachment" header="附件">
<collapse-card ref="attachment" header="附件">
<upload-file
:file-list="form.imageList"
:disabled="!canSave"
@remove="removeUpload"
@success="uploadSuccess"
/>
</form-collapse-card>
</collapse-card>
<form-collapse-card ref="remark" header="备注">
<collapse-card ref="remark" header="备注">
<el-input
v-model="form.remark"
:rows="4"
@ -90,11 +90,11 @@
show-word-limit
type="textarea"
/>
</form-collapse-card>
</collapse-card>
<form-collapse-card ref="history" header="单据历史">
<collapse-card ref="history" header="单据历史">
<doc-history :id="form.id"/>
</form-collapse-card>
</collapse-card>
</abstract-form>
<stock-selector v-model="stockDialog" @select="selectStock"/>

@ -10,20 +10,20 @@
@close="close"
>
<abstract-form :model="form" :rules="rules">
<form-collapse-card ref="progress" header="流程进度">
<collapse-card ref="progress" header="流程进度">
<doc-steps :status="form.status" :type="type"/>
</form-collapse-card>
</collapse-card>
<form-collapse-card ref="base" header="基础信息">
<collapse-card ref="base" header="基础信息">
<abstract-form-item label="销售订单" prop="pid">
<el-input v-if="canSave" :value="form.pid" readonly>
<el-button slot="append" @click="parentDialog=true">选择</el-button>
</el-input>
<template v-else>{{ form.pid }}</template>
</abstract-form-item>
</form-collapse-card>
</collapse-card>
<form-collapse-card ref="goods" header="出库商品">
<collapse-card ref="goods" header="出库商品">
<abstract-table :data="displayTableData" :highlight-current-row="false">
<el-table-column align="center" type="expand">
<el-table slot-scope="{row}" :data="row.data" border show-summary
@ -56,18 +56,18 @@
<el-table-column align="center" label="出库数量" prop="num" width="150"/>
<el-table-column align="center" label="订单剩余未出库数量" prop="remainNum" width="250"/>
</abstract-table>
</form-collapse-card>
</collapse-card>
<form-collapse-card ref="attachment" header="附件">
<collapse-card ref="attachment" header="附件">
<upload-file
:file-list="form.imageList"
:disabled="!canSave"
@remove="removeUpload"
@success="uploadSuccess"
/>
</form-collapse-card>
</collapse-card>
<form-collapse-card ref="remark" header="备注">
<collapse-card ref="remark" header="备注">
<el-input
v-model="form.remark"
:rows="4"
@ -76,11 +76,11 @@
show-word-limit
type="textarea"
/>
</form-collapse-card>
</collapse-card>
<form-collapse-card ref="history" header="单据历史">
<collapse-card ref="history" header="单据历史">
<doc-history :id="form.id"/>
</form-collapse-card>
</collapse-card>
</abstract-form>
<order-selector v-model="parentDialog" @select="selectParent"/>

Some files were not shown because too many files have changed in this diff Show More

Loading…
Cancel
Save