123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392 |
- <template>
- <div>
- <div v-if="patternData">
- <div class="attr__box">
- <div class="attr__list" v-if="!value.id">
- <div class="item" v-for="(attr, index) in patternData" :key="index">
- <div class="attr__title">
- <div class="attr__name">{{attr.name}}</div>
- <Input
- class="attr__input"
- v-if="attr.hand_add_status"
- v-model="attr.text"
- icon="md-add-circle"
- @on-enter="addAttr(attr.text, index)"
- @on-click="addAttr(attr.text, index)"></Input>
- </div>
- <div class="attr__item">
- <CheckboxGroup v-model="attr.selected" @on-change="onCheckGroupChange">
- <Checkbox
- class="tag"
- v-for="(value, valueIndex) in attr.list"
- :key="valueIndex"
- :label="value">
- <button class="close">
- <Icon
- size="20"
- color="#ed4014"
- type="md-close-circle"
- v-on:click.stop.capture="remove(attr, valueIndex)" />
- </button>
- <span style="user-select: none;">{{value}}</span>
- </Checkbox>
- </CheckboxGroup>
- </div>
- </div>
- </div>
- <div class="attr__table" v-if="tableData.tableHead.length > 5">
- <div class="thead">
- <div class="tr">
- <div class="th" v-for="(head, headIndex) in tableData.tableHead" :key="headIndex">{{head}}</div>
- </div>
- </div class="thead">
- <div class="tbody">
- <div
- v-for="(body, bodyIndex) in tableData.tableBody"
- :key="bodyIndex"
- class="tr"
- :class="{ 'disabled': body.invisible }">
- <div class="td" v-for="(value, valueIndex) in body.value" :key="valueIndex">
- {{value}}
- </div>
- <div class="td">
- <InputNumber
- :disabled="!!body.invisible"
- v-model="values[body.id].price"
- :min="0"
- size="small"
- @on-change="onValueChange" />
- </div>
- <div class="td">
- <InputNumber
- :disabled="!!body.invisible"
- v-model="values[body.id].stock"
- :min="0"
- :precision="0"
- size="small"
- @on-change="onValueChange" />
- </div>
- <div class="td">
- <InputNumber
- :disabled="!!body.invisible"
- v-model="values[body.id].cost_price"
- :min="0"
- size="small"
- @on-change="onValueChange" />
- </div>
- <div class="td">
- <InputNumber
- :disabled="!!body.invisible"
- v-model="values[body.id].origin_price"
- :min="0"
- size="small"
- @on-change="onValueChange" />
- </div>
- <div class="td">
- <Button
- size="small"
- :type="values[body.id].is_main ? 'primary' : 'default'"
- :disabled="!!values[body.id].invisible"
- @click="onMainChange(body.id)">主规格</Button>
- <Button size="small" @click="onHidden(body.id, values[body.id].invisible)">
- {{ values[body.id].invisible ? '恢复' : '隐藏' }}
- </Button>
- </div>
- </div>
- </div>
- </div>
- </div>
- </div>
- <error :text="error[data.keyword]" />
- </div>
- </template>
- <script>
- export default {
- props: ['data', 'value', 'option', 'error'],
- computed: {
- patternData () {
- return this.value.patternData
- },
- },
- data () {
- return {
- products: [],
- tableData: {
- tableHead: [],
- tableBody: [],
- },
- values: {},
- }
- },
- methods: {
- addAttr (v, index) {
- if (!v.trim()) return
- this.patternData[index].list.push(v)
- this.patternData[index].text = ''
- },
- remove (attr, valueIndex) {
- const removeItem = attr.list[valueIndex]
- const selectedIndex = attr.selected.indexOf(removeItem)
- if (selectedIndex !== -1) attr.selected.splice(selectedIndex, 1)
- attr.list.splice(valueIndex, 1)
- this.getTable()
- },
- onCheckGroupChange (e) {
- this.getTable()
- },
- cartesianProduct (array) {
- if (array.length < 2) return array[0] || []
- return [].reduce.call(array, (last, current) => {
- let res = []
- last.forEach((l) => {
- current.forEach((c) => {
- let temp = [].concat(Array.isArray(l) ? l : [l])
- temp.push(c)
- res.push(temp)
- })
- })
- return res
- })
- },
- getTable () {
- const values = Object.assign({}, this.values)
- const tableHead = this.patternData
- .filter(i => i.selected.length)
- .map(i => i.name)
- .concat(['售价(元)', '库存', '成本价(元)', '划线价(元)', '操作'])
- const tableBody = this.cartesianProduct(
- this.patternData.filter(i => i.selected.length).map(i => i.selected)
- ).map(item => {
- const id = Array.isArray(item) ? item.join('_') : item
- values[id] = values[id] || {
- stock: 0,
- price: 0,
- origin_price: 0,
- cost_price: 0,
- is_main: 0,
- invisible: 0,
- }
- return {
- id,
- stock: 0,
- price: 0,
- origin_price: 0,
- cost_price: 0,
- is_main: 0,
- invisible: 0,
- value: Array.isArray(item) ? item : [item],
- }
- })
- if (this.value.id) {
- const exsitIds = []
- this.value.sku.forEach(({
- names,
- price,
- origin_price: originPrice,
- cost_price: costPrice,
- ...others
- }, index) => {
- const id = names.map(i => i.value).join('_')
- exsitIds.push(tableBody.find(t => t.id === id).id)
- Object.assign(values[id], {
- invisible: 0,
- price: price / 100,
- origin_price: originPrice / 100,
- cost_price: costPrice / 100,
- ...others,
- })
- })
- Object.keys(values).forEach(id => {
- if (this.value.id && !exsitIds.includes(id)) {
- const index = tableBody.findIndex(i => i.id === id)
- tableBody.splice(index, 1)
- delete values[id]
- }
- })
- }
- if (tableBody.length) {
- let exist = 0
- Object.keys(values).find(id => {
- const isMain = values[id].is_main
- values[id].is_main = Number(tableBody.find(t => t.id === id) && isMain)
- exist = values[id].is_main
- return exist
- })
- if (!exist) values[tableBody[0].id].is_main = 1
- }
- this.tableData.tableHead = tableHead
- this.tableData.tableBody = tableBody
- this.values = values
- },
- onMainChange (id) {
- Object.keys(this.values).forEach(i => {
- this.values[i].is_main = Number(i === id)
- })
- this.onValueChange()
- },
- onHidden (id, status) {
- this.values[id].invisible = Number(!this.values[id].invisible)
- if (status) {
- let hasMain = false
- this.tableData.tableBody.forEach(i => {
- if (this.values[i.id].is_main && !this.values[i.id].invisible) hasMain = true
- })
- if (!hasMain) {
- const item = this.tableData.tableBody.find(i => {
- return !this.values[i.id].invisible
- })
- if (item) this.onMainChange(item.id)
- }
- } else {
- if (this.values[id].is_main) {
- const item = this.tableData.tableBody.find(i => {
- return !this.values[i.id].invisible
- })
- if (item) this.onMainChange(item.id)
- }
- }
- this.onValueChange()
- },
- onValueChange () {
- const data = Object.keys(this.values).map(id => {
- const {
- invisible,
- price,
- origin_price: originPrice,
- cost_price: costPrice,
- ...other
- } = this.values[id]
- const result = !invisible && this.tableData.tableBody.map(i => i.id).includes(id)
- ? {
- price: !price ? price : price.toFixed(2) * 100,
- origin_price: !originPrice ? originPrice : originPrice.toFixed(2) * 100,
- cost_price: !costPrice ? costPrice : costPrice.toFixed(2) * 100,
- ...other,
- }
- : null
- if (result && !this.value.id) {
- result.value = id.split('_')
- }
- return result
- }).filter(Boolean)
- const item = this.value.patternData.filter(i => i.selected.length).map(i => (
- {
- id: i.id,
- value: i.selected,
- }
- ))
- this.$hub.$emit(this.data.hub, {
- type: 'value',
- payload: Object.assign(this.value, {
- [this.data.keyword]: data,
- attribute_item: item,
- }),
- })
- },
- },
- mounted () {
- this.getTable()
- },
- }
- </script>
- <style lang="scss" scoped>
- .attr__list {
- border: 1px solid #ddd;
- padding: 4px 8px;
- .attr__title {
- display: flex;
- align-items: center;
- padding: 4px 0;
- background: #eaeaea;
- .attr__name {
- width: 100px;
- font-size: 16px;
- padding-left: 10px;
- }
- .attr__input {
- width: 150px;
- }
- }
- .attr__item {
- margin-top: 4px;
- }
- }
- .item + .item {
- margin-top: 4px;
- }
- .tag {
- box-sizing: border-box;
- position: relative;
- padding: 2px 4px;
- border: 1px solid #ccc;
- border-radius: 2px;
- font-size: 14px;
- .close {
- position: absolute;
- top: -10px;
- right: -10px;
- opacity: 0;
- transition: all .2s;
- border: 0;
- background: transparent;
- outline: none;
- }
- &:hover .close {
- opacity: 1;
- }
- }
- .attr__table {
- box-sizing: border-box;
- width: 100%;
- font-size: 14px;
- margin-top: 4px;
- border: 1px solid #ddd;
- .thead {
- font-weight: bold;
- padding: 5px;
- }
- .tr {
- box-sizing: inherit;
- display: flex;
- justify-content: center;
- align-items: center;
- .th, .td {
- box-sizing: inherit;
- flex: 1;
- text-align: center;
- }
- }
- .tbody {
- .tr {
- padding: 5px;
- border-top: 1px solid #ccc;
- &:hover {
- background: #ccc;
- }
- }
- }
- }
- .disabled {
- background: #ddd;
- }
- </style>
|