upda
parent
931e2e043f
commit
7eff39995c
@ -0,0 +1,68 @@
|
||||
import {
|
||||
request
|
||||
} from "@/utils/request";
|
||||
|
||||
export default {
|
||||
list(data) {
|
||||
return request({
|
||||
url: "/shop/shopGoods/goodsList",
|
||||
method: "POST",
|
||||
data,
|
||||
});
|
||||
},
|
||||
|
||||
goodsEditAttribute(data) {
|
||||
return request({
|
||||
url: "/shop/shopGoods/goodsEditAttribute",
|
||||
method: "POST",
|
||||
data,
|
||||
});
|
||||
},
|
||||
|
||||
classify: {
|
||||
list(data) {
|
||||
return request({
|
||||
url: "/shop/shopClassify/list",
|
||||
method: "POST",
|
||||
data,
|
||||
});
|
||||
},
|
||||
|
||||
createItem(data) {
|
||||
return request({
|
||||
url: "/shop/shopClassify/createItem",
|
||||
method: "POST",
|
||||
data,
|
||||
});
|
||||
},
|
||||
|
||||
},
|
||||
|
||||
freightRules(data) {
|
||||
return request({
|
||||
url: "/shop/freightRules/list",
|
||||
method: "POST",
|
||||
data,
|
||||
});
|
||||
},
|
||||
|
||||
goodsItem(data) {
|
||||
return request({
|
||||
url: "/shop/shopGoods/goodsItem",
|
||||
method: "POST",
|
||||
data,
|
||||
});
|
||||
},
|
||||
|
||||
goodsEdit(data) {
|
||||
return request({
|
||||
url: "/shop/shopGoods/goodsEdit",
|
||||
method: "POST",
|
||||
data,
|
||||
});
|
||||
},
|
||||
|
||||
|
||||
|
||||
|
||||
};
|
||||
@ -0,0 +1,50 @@
|
||||
import {
|
||||
request
|
||||
} from "@/utils/request";
|
||||
|
||||
export default {
|
||||
dataCount: {
|
||||
oneLine(data) {
|
||||
return request({
|
||||
url: "/shop/dataCount/oneLine",
|
||||
method: "POST",
|
||||
data,
|
||||
});
|
||||
},
|
||||
orderProfit(data) {
|
||||
return request({
|
||||
url: "/shop/dataCount/orderProfit",
|
||||
method: "POST",
|
||||
data,
|
||||
});
|
||||
},
|
||||
orderGood(data) {
|
||||
return request({
|
||||
url: "/shop/dataCount/orderGood",
|
||||
method: "POST",
|
||||
data,
|
||||
});
|
||||
},
|
||||
|
||||
},
|
||||
|
||||
getStoreSetting(data) {
|
||||
return request({
|
||||
url: "/shop/store/getStoreSetting",
|
||||
method: "POST",
|
||||
data,
|
||||
})
|
||||
},
|
||||
|
||||
setStoreSetting(data) {
|
||||
return request({
|
||||
url: "/shop/store/setStoreSetting",
|
||||
method: "POST",
|
||||
data,
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
};
|
||||
@ -0,0 +1,106 @@
|
||||
import {
|
||||
request
|
||||
} from "@/utils/request";
|
||||
|
||||
export default {
|
||||
orderList(data) {
|
||||
return request({
|
||||
url: "/shop/order/orderList",
|
||||
method: "POST",
|
||||
data,
|
||||
});
|
||||
},
|
||||
|
||||
orderSend(data) {
|
||||
return request({
|
||||
url: "/shop/order/orderSend",
|
||||
method: "POST",
|
||||
data,
|
||||
});
|
||||
},
|
||||
|
||||
GetExpressList(data) {
|
||||
return request({
|
||||
url: "/admin/order/GetExpressList",
|
||||
method: "POST",
|
||||
data,
|
||||
});
|
||||
},
|
||||
|
||||
printOrder(data) {
|
||||
return request({
|
||||
url: "/shop/order/printOrder",
|
||||
method: "POST",
|
||||
data,
|
||||
});
|
||||
},
|
||||
|
||||
updateNotes(data) {
|
||||
return request({
|
||||
url: "/shop/order/updateNotes",
|
||||
method: "POST",
|
||||
data,
|
||||
});
|
||||
},
|
||||
|
||||
// 核销记录
|
||||
checkLog(data) {
|
||||
return request({
|
||||
url: "/shop/shop/checkLog",
|
||||
method: "POST",
|
||||
data,
|
||||
});
|
||||
},
|
||||
|
||||
confirmCancel(data) {
|
||||
return request({
|
||||
url: "/shop/order/confirmCancel",
|
||||
method: "POST",
|
||||
data,
|
||||
});
|
||||
},
|
||||
|
||||
after_sale: {
|
||||
index(data) {
|
||||
return request({
|
||||
url: "/shop/after_sale/index",
|
||||
method: "POST",
|
||||
data,
|
||||
});
|
||||
},
|
||||
|
||||
|
||||
update(data) {
|
||||
return request({
|
||||
url: "/shop/after_sale/update",
|
||||
method: "POST",
|
||||
data,
|
||||
});
|
||||
},
|
||||
|
||||
show(data) {
|
||||
return request({
|
||||
url: "/shop/after_sale/show",
|
||||
method: "POST",
|
||||
data,
|
||||
});
|
||||
},
|
||||
|
||||
express(data) {
|
||||
return request({
|
||||
url: "/client/common/express",
|
||||
method: "POST",
|
||||
data,
|
||||
});
|
||||
},
|
||||
enums(data) {
|
||||
return request({
|
||||
url: "/client/after_sale/enums",
|
||||
method: "POST",
|
||||
data,
|
||||
});
|
||||
},
|
||||
|
||||
},
|
||||
|
||||
};
|
||||
@ -0,0 +1,41 @@
|
||||
import {
|
||||
request
|
||||
} from "@/utils/request";
|
||||
|
||||
export default {
|
||||
|
||||
list(data) {
|
||||
return request({
|
||||
url: "/shop/shop/List",
|
||||
method: "POST",
|
||||
data,
|
||||
})
|
||||
},
|
||||
|
||||
edit(data) {
|
||||
return request({
|
||||
url: "/shop/shop/edit",
|
||||
method: "POST",
|
||||
data,
|
||||
})
|
||||
},
|
||||
|
||||
editStatus(data) {
|
||||
return request({
|
||||
url: "/shop/shop/editStatus",
|
||||
method: "POST",
|
||||
data,
|
||||
})
|
||||
},
|
||||
|
||||
synchronousGoods(data) {
|
||||
return request({
|
||||
url: "/shop/shop/synchronousGoods",
|
||||
method: "POST",
|
||||
data,
|
||||
})
|
||||
},
|
||||
|
||||
|
||||
|
||||
};
|
||||
@ -0,0 +1,51 @@
|
||||
import {
|
||||
request
|
||||
} from "@/utils/request";
|
||||
|
||||
export default {
|
||||
|
||||
userList(data) {
|
||||
return request({
|
||||
url: "/shop/user/userList",
|
||||
method: "GET",
|
||||
data,
|
||||
})
|
||||
},
|
||||
|
||||
userItem(data) {
|
||||
return request({
|
||||
url: "/shop/user/userItem",
|
||||
method: "GET",
|
||||
data,
|
||||
})
|
||||
},
|
||||
|
||||
|
||||
getLog(data) {
|
||||
return request({
|
||||
url: "/shop/user/getLog",
|
||||
method: "GET",
|
||||
data,
|
||||
})
|
||||
},
|
||||
|
||||
changeInformation(data) {
|
||||
return request({
|
||||
url: "/shop/user/changeInformation",
|
||||
method: "GET",
|
||||
data,
|
||||
})
|
||||
},
|
||||
|
||||
UpdateLevel(data) {
|
||||
return request({
|
||||
url: "/shop/user/UpdateLevel",
|
||||
method: "GET",
|
||||
data,
|
||||
})
|
||||
},
|
||||
|
||||
|
||||
|
||||
|
||||
};
|
||||
@ -0,0 +1,56 @@
|
||||
import {
|
||||
request
|
||||
} from "@/utils/request";
|
||||
|
||||
export default {
|
||||
|
||||
LevelShow(data) {
|
||||
return request({
|
||||
url: "/shop/UserMembers/LevelShow",
|
||||
method: "GET",
|
||||
data,
|
||||
})
|
||||
},
|
||||
|
||||
LevelSave(data) {
|
||||
return request({
|
||||
url: "/shop/UserMembers/LevelSave",
|
||||
method: "GET",
|
||||
data,
|
||||
})
|
||||
},
|
||||
|
||||
SetList(data) {
|
||||
return request({
|
||||
url: "/shop/UserMembers/SetList",
|
||||
method: "GET",
|
||||
data,
|
||||
})
|
||||
},
|
||||
|
||||
SetSave(data) {
|
||||
return request({
|
||||
url: "/shop/UserMembers/SetSave",
|
||||
method: "GET",
|
||||
data,
|
||||
})
|
||||
},
|
||||
|
||||
DiscountList(data) {
|
||||
return request({
|
||||
url: "/shop/UserMembers/DiscountList",
|
||||
method: "GET",
|
||||
data,
|
||||
})
|
||||
},
|
||||
|
||||
CreateDiscount(data) {
|
||||
return request({
|
||||
url: "/shop/UserMembers/CreateDiscount",
|
||||
method: "POST",
|
||||
data,
|
||||
})
|
||||
},
|
||||
|
||||
|
||||
};
|
||||
@ -0,0 +1,130 @@
|
||||
<template>
|
||||
<view class="charts-box bg-white content">
|
||||
<view v-show="classifyList.length" class="flex overflow-auto flex-wrap">
|
||||
<div class="grid grid-cols-3 gap-4 p-4 w-full">
|
||||
|
||||
<wd-button @click="utils.toUrl('/mall/cat/edit?edit=' + JSON.stringify({}))" style="width: 100%;"
|
||||
class="bg-[#f0f0f0] w-full flex-1" :round="false">
|
||||
新增
|
||||
</wd-button>
|
||||
<wd-button @click="showActions(cat)" style="width: 100%;" v-for="cat of classifyList"
|
||||
class="bg-[#f0f0f0] w-full flex-1" type="info" :round="false">
|
||||
{{ cat.name }}
|
||||
</wd-button>
|
||||
|
||||
</div>
|
||||
</view>
|
||||
|
||||
<wd-action-sheet v-model="show" :actions="actions" @close="close" @select="select" />
|
||||
<kevyloading v-if="loading" type="bsm-loader" color="#618af8" transparent></kevyloading>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { ref } from 'vue'
|
||||
import utils from '@/utils/utils.js'
|
||||
import goods from '@/api/mall/goods.js'
|
||||
import kevyloading from "@/components/kevy-loading/kevy-loading";
|
||||
/** @type {Ref<boolean>} */
|
||||
const loading = ref(false);
|
||||
|
||||
import {
|
||||
onShow,
|
||||
} from "@dcloudio/uni-app";
|
||||
|
||||
const model = ref({})
|
||||
const baseForm = ref({})
|
||||
|
||||
const show = ref(false)
|
||||
const actions = ref([
|
||||
{
|
||||
name: '编辑分类'
|
||||
},
|
||||
{
|
||||
name: '新增子项'
|
||||
}
|
||||
])
|
||||
|
||||
const opt = ref("编辑分类")
|
||||
|
||||
function showActions(row) {
|
||||
show.value = true
|
||||
model.value = row
|
||||
console.log(row);
|
||||
}
|
||||
|
||||
function close() {
|
||||
show.value = false
|
||||
}
|
||||
|
||||
function select({ item, index }) {
|
||||
opt.value = item.name
|
||||
|
||||
if (opt.value == '编辑分类') {
|
||||
// message.alert({
|
||||
// title: "编辑分类"
|
||||
// })
|
||||
|
||||
baseForm.value = model.value
|
||||
utils.toUrl('/mall/cat/edit?edit=' + JSON.stringify(baseForm.value))
|
||||
}
|
||||
|
||||
if (opt.value == '新增子项') {
|
||||
|
||||
console.log(model.value);
|
||||
|
||||
if (model.value.parentIds.length == 3) {
|
||||
return uni.showToast({
|
||||
title: '三级分类不可新增子级',
|
||||
icon: 'none'
|
||||
})
|
||||
} else {
|
||||
baseForm.value = model.value
|
||||
utils.toUrl('/mall/cat/edit?edit=' + JSON.stringify({}) + "&parent=" + JSON.stringify(baseForm.value))
|
||||
}
|
||||
|
||||
// baseForm.value = model.value
|
||||
// utils.toUrl('/mall/cat/edit?edit=' + JSON.stringify(baseForm.value))
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
const classifyList = ref([])
|
||||
const getClassify = () => {
|
||||
loading.value = true
|
||||
function flattenCategories(categories, parentIds = []) {
|
||||
let flatCategories = [];
|
||||
|
||||
for (const category of categories) {
|
||||
const categoryWithParents = {
|
||||
...category,
|
||||
parentIds: [...parentIds, category.id],
|
||||
};
|
||||
|
||||
flatCategories.push(categoryWithParents);
|
||||
|
||||
if (category.children && category.children.length > 0) {
|
||||
flatCategories = flatCategories.concat(flattenCategories(category.children, [...parentIds, category.id]));
|
||||
}
|
||||
}
|
||||
|
||||
return flatCategories;
|
||||
}
|
||||
goods.classify.list().then(res => {
|
||||
classifyList.value = flattenCategories(res.data)
|
||||
loading.value = false
|
||||
})
|
||||
}
|
||||
|
||||
onShow(() => {
|
||||
getClassify()
|
||||
})
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
/* 请根据实际需求修改父元素尺寸,组件自动识别宽高 */
|
||||
.charts-box {
|
||||
width: 100%;
|
||||
height: 300px;
|
||||
}
|
||||
</style>
|
||||
@ -0,0 +1,26 @@
|
||||
<template>
|
||||
<view class="myTabbar">
|
||||
<wd-tabbar custom-class="mb-3" fixed safeAreaInsetBottom placeholder v-model="tab" shape="round">
|
||||
<wd-tabbar-item @click="utils.toUrl('/store/index/index')" name="home" title="首页" icon="home"></wd-tabbar-item>
|
||||
<!-- <wd-tabbar-item name="cart" title="分类" icon="cart"></wd-tabbar-item> -->
|
||||
<wd-tabbar-item name="user" @click="utils.toUrl('/store/user/list')" title="用户管理" icon="user"></wd-tabbar-item>
|
||||
<wd-tabbar-item @click="utils.toUrl('/store/shop/list')" name="shop" title="门店管理" icon="detection"></wd-tabbar-item>
|
||||
<!-- <wd-tabbar-item name="user" title="我的" icon="user"></wd-tabbar-item> -->
|
||||
</wd-tabbar>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import utils from '@/utils/utils.js';
|
||||
|
||||
const props = defineProps({
|
||||
tab: {
|
||||
type: String,
|
||||
default: "home"
|
||||
}
|
||||
})
|
||||
|
||||
const tab = props.tab
|
||||
</script>
|
||||
|
||||
<style lang="scss"></style>
|
||||
@ -0,0 +1,374 @@
|
||||
<template>
|
||||
<view class="skuEdit">
|
||||
<wd-table rowHeight="100" :data="Pdata.use_sku == 0
|
||||
? skuDefault
|
||||
: skuLibrary
|
||||
" :stripe="false">
|
||||
<wd-table-col prop="name" label="SKU">
|
||||
|
||||
<template #value="scope">
|
||||
<view class="custom-class">
|
||||
<span style="margin-right: 4px" v-for="(item, index) of scope.row
|
||||
.attr_list" :key="index">
|
||||
{{ item.name }}
|
||||
</span>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
</wd-table-col>
|
||||
<wd-table-col prop="school" label="售价">
|
||||
<template #value="scope">
|
||||
<view class="px-2 pb-1 bg-white">
|
||||
<wd-input placeholder="售价" v-model="scope.row.price" type="number" />
|
||||
</view>
|
||||
</template>
|
||||
</wd-table-col>
|
||||
<wd-table-col prop="major" label="原价">
|
||||
<template #value="scope">
|
||||
<view class="px-2 pb-1 bg-white">
|
||||
<wd-input placeholder="原价" v-model="scope.row.original_price" type="number">
|
||||
</wd-input>
|
||||
</view>
|
||||
</template>
|
||||
</wd-table-col>
|
||||
<wd-table-col prop="major" label="库存">
|
||||
<template #value="scope">
|
||||
<view class="px-2 pb-1 bg-white">
|
||||
<wd-input placeholder="库存" v-model="scope.row.stock" type="number">
|
||||
</wd-input>
|
||||
</view>
|
||||
</template>
|
||||
</wd-table-col>
|
||||
<wd-table-col prop="major" label="产品号">
|
||||
<template #value="scope">
|
||||
<view class="px-2 pb-1 bg-white">
|
||||
<wd-input placeholder="产品号" v-model="scope.row.no">
|
||||
</wd-input>
|
||||
</view>
|
||||
</template>
|
||||
</wd-table-col>
|
||||
|
||||
<wd-table-col prop="major" label="产品图">
|
||||
<template #value="scope">
|
||||
<view class="overflow-hidden w-full h-full flex items-center justify-center">
|
||||
<view class="px-2 pb-1 bg-white flex items-center justify-center mt-4 overflow-hidden">
|
||||
<yUpload v-model="scope.row.pic_url"></yUpload>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
</wd-table-col>
|
||||
|
||||
</wd-table>
|
||||
|
||||
<view v-show="Pdata.use_sku == 1" class="bg-gray-100 rounded mb-2">
|
||||
<div class="p-2 bg-white w-full">
|
||||
<div class="name mb-2 text-xs">规格设置</div>
|
||||
<view class="flex bg-white px-3 py-1 rounded w-full">
|
||||
<div class="flex-1 mr-4">
|
||||
<wd-input type="text" v-model="addGroupData.name" />
|
||||
</div>
|
||||
<wd-button @click="addSkuGroup">添加规格组</wd-button>
|
||||
</view>
|
||||
</div>
|
||||
|
||||
<div class="p-2 bg-white">
|
||||
<div style="display: flex; flex-flow: column; align-items: flex-start;">
|
||||
<div class="name mb-2 text-xs">规格组</div>
|
||||
|
||||
<div class="w-full bg-gray-100 p-2" v-for="(item, index) in skuGroup" :key="index">
|
||||
<div class="flex items-center justify-between w-full bg-white p-2">
|
||||
<div class="mr-3">
|
||||
<wd-tag type="primary" custom-class="space" closable @close="moveGroup(index)">{{
|
||||
item.name }}</wd-tag>
|
||||
</div>
|
||||
<div class="mr-3">
|
||||
<wd-input type="text" v-model="addGouppItemData[index]" />
|
||||
</div>
|
||||
<wd-button type="warning" @click="addGroupItem(index)">添加规格</wd-button>
|
||||
</div>
|
||||
<div type="flex" style="margin: 12px 0;">
|
||||
<div class="name mb-2 text-xs">规格:</div>
|
||||
<view class="flex gap-2 flex-wrap">
|
||||
<wd-tag custom-class="space1" closable round type="warning" class="mx-1"
|
||||
v-for="(value, key) in item.groupItem" :key="key" style="margin-left: 10px"
|
||||
@close="removeGroupItem(index, key)">{{ value.name
|
||||
}}</wd-tag>
|
||||
</view>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</view>
|
||||
|
||||
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import yUpload from "@/components/yUpload/index.vue"
|
||||
import { useToast } from '@/uni_modules/wot-design-uni'
|
||||
const toast = useToast()
|
||||
|
||||
export default {
|
||||
name: "skuEdit",
|
||||
props: {
|
||||
Pdata: {
|
||||
type: Object,
|
||||
default: () => ({})
|
||||
},
|
||||
},
|
||||
components: {
|
||||
yUpload
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
// sku规格开始
|
||||
skuDefault: [
|
||||
{
|
||||
attr_list: [{ group_name: "默认", name: "默认" }],
|
||||
price: "", // 售价
|
||||
original_price: "", // 原价
|
||||
stock: "", // 库存
|
||||
pic_url: "", // 图片
|
||||
no: "", // 货号
|
||||
},
|
||||
],
|
||||
skuGroup: [],
|
||||
addGroupData: {
|
||||
name: "",
|
||||
groupItem: [],
|
||||
}, //添加规格组默认数据
|
||||
addGouppItemData: [],
|
||||
skuLibrary: [], // 规格库
|
||||
// 批量设置
|
||||
all_price: "",
|
||||
all_original_price: "",
|
||||
all_stock: "",
|
||||
all_no: "",
|
||||
// sku规格结束
|
||||
}
|
||||
},
|
||||
created() {
|
||||
this.skuDefault = this.Pdata.skuDefault.length ? this.Pdata.skuDefault : this.skuDefault
|
||||
this.skuLibrary = this.Pdata.skuLibrary
|
||||
this.skuGroup = this.Pdata.skuGroup
|
||||
},
|
||||
methods: {
|
||||
successImage($event, index) {
|
||||
console.log($event, index);
|
||||
},
|
||||
|
||||
/**
|
||||
* 处理规格数据
|
||||
*/
|
||||
setGoodsAttrItem(attrGroup, attrList, index) {
|
||||
var attrList1 = [];
|
||||
if (index < attrGroup.length) {
|
||||
if (index === 0 || attrList.length === 0) {
|
||||
if (attrGroup[index].groupItem.length > 0) {
|
||||
attrGroup[index].groupItem.forEach((element) => {
|
||||
element.group_name = attrGroup[index].name;
|
||||
attrList1.push([element]);
|
||||
});
|
||||
}
|
||||
} else {
|
||||
if (attrGroup[index].groupItem.length > 0) {
|
||||
attrList.forEach((element) => {
|
||||
attrGroup[index].groupItem.forEach((element1) => {
|
||||
element1.group_name = attrGroup[index].name;
|
||||
attrList1.push(element.concat([element1]));
|
||||
});
|
||||
});
|
||||
} else {
|
||||
attrList1 = attrList;
|
||||
}
|
||||
}
|
||||
++index;
|
||||
return this.setGoodsAttrItem(attrGroup, attrList1, index);
|
||||
} else {
|
||||
return attrList;
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* 获取其他详细数据
|
||||
*/
|
||||
getAttrDataInfo(attr) {
|
||||
var attrList = [];
|
||||
attr.forEach((element) => {
|
||||
var setAttr = {};
|
||||
if (this.skuLibrary) {
|
||||
this.skuLibrary.forEach((element2) => {
|
||||
if (element2.attr_list.length === element.length) {
|
||||
var loading = true;
|
||||
if (
|
||||
loading &&
|
||||
this.compareAttr(element2.attr_list, element)
|
||||
) {
|
||||
setAttr = element2;
|
||||
loading = false;
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
var data = {
|
||||
id: setAttr && setAttr.id ? setAttr.id : 0,
|
||||
attr_list: element,
|
||||
price: setAttr && setAttr.price ? setAttr.price : element.reduce((price, i) => price + i.price, 0).toFixed(2),
|
||||
original_price:
|
||||
setAttr && setAttr.original_price
|
||||
? setAttr.original_price
|
||||
: element.reduce((price, i) => price + i.price, 0).toFixed(2),
|
||||
stock: setAttr && setAttr.stock ? setAttr.stock : 0,
|
||||
pic_url: setAttr && setAttr.pic_url ? setAttr.pic_url : "",
|
||||
no: setAttr && setAttr.no ? setAttr.no : "",
|
||||
};
|
||||
for (const key in setAttr) {
|
||||
if (key.indexOf("member") !== -1) {
|
||||
data[key] = setAttr[key];
|
||||
}
|
||||
}
|
||||
attrList.push(data);
|
||||
});
|
||||
return attrList;
|
||||
},
|
||||
compareAttr(val1, val2) {
|
||||
var compareLen = 0;
|
||||
val1.forEach((element1) => {
|
||||
val2.forEach((element2) => {
|
||||
if (element1.name === element2.name) {
|
||||
compareLen++;
|
||||
}
|
||||
});
|
||||
});
|
||||
return compareLen === val1.length;
|
||||
},
|
||||
// 添加规格组
|
||||
addSkuGroup() {
|
||||
|
||||
if (!this.addGroupData.name) {
|
||||
uni.showToast({
|
||||
title: '请填写规格组名称',
|
||||
icon: 'none'
|
||||
})
|
||||
return
|
||||
}
|
||||
|
||||
// 添加一个一个规格类
|
||||
console.log("添加了一个规格组");
|
||||
this.skuGroup.push(this.addGroupData);
|
||||
console.log("skuGroup发生了变换");
|
||||
// 回复默认数据
|
||||
this.addGroupData = {
|
||||
name: "",
|
||||
groupItem: [],
|
||||
};
|
||||
},
|
||||
|
||||
// 删除规格组
|
||||
moveGroup(index) {
|
||||
if (this.skuGroup[index].groupItem.length === 0) {
|
||||
console.log("删除的组合没有规格!!!");
|
||||
this.skuGroup.splice(index, 1);
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
this.skuGroup.splice(index, 1);
|
||||
var attrList = this.setGoodsAttrItem(this.skuGroup, [], 0);
|
||||
this.skuLibrary = this.getAttrDataInfo(attrList);
|
||||
this.calculateCombinationPrice(this.skuLibrary);
|
||||
},
|
||||
// 计算组合价格的方法
|
||||
calculateCombinationPrice(skuLibrary) {
|
||||
console.log(skuLibrary);
|
||||
skuLibrary.forEach((sku) => {
|
||||
// 计算每个 SKU 组合的价格
|
||||
let combinationPrice = 0;
|
||||
|
||||
// 遍历 SKU 的属性列表
|
||||
sku.attr_list.forEach((attr) => {
|
||||
// 累加每个属性项的价格
|
||||
combinationPrice += attr.price;
|
||||
});
|
||||
|
||||
// 将组合价格保存到 SKU 对象中
|
||||
sku.price = combinationPrice.toFixed(2);
|
||||
sku.original_price = combinationPrice.toFixed(2);
|
||||
});
|
||||
|
||||
this.skuLibrary = skuLibrary
|
||||
|
||||
},
|
||||
// 添加规格
|
||||
addGroupItem(index) {
|
||||
const _skuGroup = this.skuGroup
|
||||
|
||||
if (this.skuGroup[index].groupItem.length === 0) {
|
||||
console.log("新的组合出现了!!!");
|
||||
// 计算组合价格
|
||||
setTimeout(() => {
|
||||
// console.log(this.skuGroup);
|
||||
this.calculateCombinationPrice(this.skuLibrary);
|
||||
});
|
||||
} else {
|
||||
console.log(_skuGroup);
|
||||
}
|
||||
|
||||
|
||||
if (!this.addGouppItemData[index]) {
|
||||
if (!this.addGroupData.name) {
|
||||
uni.showToast({
|
||||
title: '请填写规格名称',
|
||||
icon: 'none'
|
||||
})
|
||||
return
|
||||
}
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
this.skuGroup[index].groupItem.push({
|
||||
group_name: this.skuGroup[index].name,
|
||||
name: this.addGouppItemData[index],
|
||||
price: 0
|
||||
});
|
||||
console.log(this.skuGroup);
|
||||
|
||||
// todo 这里还有问题
|
||||
var attrList = this.setGoodsAttrItem(this.skuGroup, [], 0);
|
||||
console.log(attrList);
|
||||
this.skuLibrary = this.getAttrDataInfo(attrList);
|
||||
this.addGouppItemData = [];
|
||||
|
||||
// // 计算组合价格
|
||||
// this.calculateCombinationPrice(this.skuLibrary);
|
||||
},
|
||||
|
||||
// 删除规格
|
||||
removeGroupItem(index, key) {
|
||||
this.skuGroup[index].groupItem.splice(key, 1);
|
||||
var attrList = this.setGoodsAttrItem(this.skuGroup, [], 0);
|
||||
this.skuLibrary = this.getAttrDataInfo(attrList);
|
||||
},
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
:deep(.space) {
|
||||
padding: 6px 10px;
|
||||
}
|
||||
|
||||
:deep(.space1) {
|
||||
padding: 6px 10px;
|
||||
background: #f0883a !important;
|
||||
color: white !important;
|
||||
|
||||
.wd-tag__close {
|
||||
color: white;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
@ -0,0 +1,45 @@
|
||||
// #ifdef H5
|
||||
export default {
|
||||
name: 'Keypress',
|
||||
props: {
|
||||
disable: {
|
||||
type: Boolean,
|
||||
default: false
|
||||
}
|
||||
},
|
||||
mounted () {
|
||||
const keyNames = {
|
||||
esc: ['Esc', 'Escape'],
|
||||
tab: 'Tab',
|
||||
enter: 'Enter',
|
||||
space: [' ', 'Spacebar'],
|
||||
up: ['Up', 'ArrowUp'],
|
||||
left: ['Left', 'ArrowLeft'],
|
||||
right: ['Right', 'ArrowRight'],
|
||||
down: ['Down', 'ArrowDown'],
|
||||
delete: ['Backspace', 'Delete', 'Del']
|
||||
}
|
||||
const listener = ($event) => {
|
||||
if (this.disable) {
|
||||
return
|
||||
}
|
||||
const keyName = Object.keys(keyNames).find(key => {
|
||||
const keyName = $event.key
|
||||
const value = keyNames[key]
|
||||
return value === keyName || (Array.isArray(value) && value.includes(keyName))
|
||||
})
|
||||
if (keyName) {
|
||||
// 避免和其他按键事件冲突
|
||||
setTimeout(() => {
|
||||
this.$emit(keyName, {})
|
||||
}, 0)
|
||||
}
|
||||
}
|
||||
document.addEventListener('keyup', listener)
|
||||
this.$once('hook:beforeDestroy', () => {
|
||||
document.removeEventListener('keyup', listener)
|
||||
})
|
||||
},
|
||||
render: () => {}
|
||||
}
|
||||
// #endif
|
||||
@ -0,0 +1,563 @@
|
||||
export default {
|
||||
props: {
|
||||
localdata: {
|
||||
type: [Array, Object],
|
||||
default () {
|
||||
return []
|
||||
}
|
||||
},
|
||||
spaceInfo: {
|
||||
type: Object,
|
||||
default () {
|
||||
return {}
|
||||
}
|
||||
},
|
||||
collection: {
|
||||
type: String,
|
||||
default: ''
|
||||
},
|
||||
action: {
|
||||
type: String,
|
||||
default: ''
|
||||
},
|
||||
field: {
|
||||
type: String,
|
||||
default: ''
|
||||
},
|
||||
orderby: {
|
||||
type: String,
|
||||
default: ''
|
||||
},
|
||||
where: {
|
||||
type: [String, Object],
|
||||
default: ''
|
||||
},
|
||||
pageData: {
|
||||
type: String,
|
||||
default: 'add'
|
||||
},
|
||||
pageCurrent: {
|
||||
type: Number,
|
||||
default: 1
|
||||
},
|
||||
pageSize: {
|
||||
type: Number,
|
||||
default: 20
|
||||
},
|
||||
getcount: {
|
||||
type: [Boolean, String],
|
||||
default: false
|
||||
},
|
||||
getone: {
|
||||
type: [Boolean, String],
|
||||
default: false
|
||||
},
|
||||
gettree: {
|
||||
type: [Boolean, String],
|
||||
default: false
|
||||
},
|
||||
manual: {
|
||||
type: Boolean,
|
||||
default: false
|
||||
},
|
||||
value: {
|
||||
type: [Array, String, Number],
|
||||
default () {
|
||||
return []
|
||||
}
|
||||
},
|
||||
modelValue: {
|
||||
type: [Array, String, Number],
|
||||
default () {
|
||||
return []
|
||||
}
|
||||
},
|
||||
preload: {
|
||||
type: Boolean,
|
||||
default: false
|
||||
},
|
||||
stepSearh: {
|
||||
type: Boolean,
|
||||
default: true
|
||||
},
|
||||
selfField: {
|
||||
type: String,
|
||||
default: ''
|
||||
},
|
||||
parentField: {
|
||||
type: String,
|
||||
default: ''
|
||||
},
|
||||
multiple: {
|
||||
type: Boolean,
|
||||
default: false
|
||||
},
|
||||
map: {
|
||||
type: Object,
|
||||
default() {
|
||||
return {
|
||||
text: "text",
|
||||
value: "value"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
loading: false,
|
||||
errorMessage: '',
|
||||
loadMore: {
|
||||
contentdown: '',
|
||||
contentrefresh: '',
|
||||
contentnomore: ''
|
||||
},
|
||||
dataList: [],
|
||||
selected: [],
|
||||
selectedIndex: 0,
|
||||
page: {
|
||||
current: this.pageCurrent,
|
||||
size: this.pageSize,
|
||||
count: 0
|
||||
}
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
isLocaldata() {
|
||||
return !this.collection.length
|
||||
},
|
||||
postField() {
|
||||
let fields = [this.field];
|
||||
if (this.parentField) {
|
||||
fields.push(`${this.parentField} as parent_value`);
|
||||
}
|
||||
return fields.join(',');
|
||||
},
|
||||
dataValue() {
|
||||
let isModelValue = Array.isArray(this.modelValue) ? (this.modelValue.length > 0) : (this.modelValue !== null || this.modelValue !== undefined)
|
||||
return isModelValue ? this.modelValue : this.value
|
||||
},
|
||||
hasValue() {
|
||||
if (typeof this.dataValue === 'number') {
|
||||
return true
|
||||
}
|
||||
return (this.dataValue != null) && (this.dataValue.length > 0)
|
||||
}
|
||||
},
|
||||
created() {
|
||||
this.$watch(() => {
|
||||
var al = [];
|
||||
['pageCurrent',
|
||||
'pageSize',
|
||||
'spaceInfo',
|
||||
'value',
|
||||
'modelValue',
|
||||
'localdata',
|
||||
'collection',
|
||||
'action',
|
||||
'field',
|
||||
'orderby',
|
||||
'where',
|
||||
'getont',
|
||||
'getcount',
|
||||
'gettree'
|
||||
].forEach(key => {
|
||||
al.push(this[key])
|
||||
});
|
||||
return al
|
||||
}, (newValue, oldValue) => {
|
||||
let needReset = false
|
||||
for (let i = 2; i < newValue.length; i++) {
|
||||
if (newValue[i] != oldValue[i]) {
|
||||
needReset = true
|
||||
break
|
||||
}
|
||||
}
|
||||
if (newValue[0] != oldValue[0]) {
|
||||
this.page.current = this.pageCurrent
|
||||
}
|
||||
this.page.size = this.pageSize
|
||||
|
||||
this.onPropsChange()
|
||||
})
|
||||
this._treeData = []
|
||||
},
|
||||
methods: {
|
||||
onPropsChange() {
|
||||
this._treeData = []
|
||||
},
|
||||
getCommand(options = {}) {
|
||||
/* eslint-disable no-undef */
|
||||
let db = uniCloud.database(this.spaceInfo)
|
||||
|
||||
const action = options.action || this.action
|
||||
if (action) {
|
||||
db = db.action(action)
|
||||
}
|
||||
|
||||
const collection = options.collection || this.collection
|
||||
db = db.collection(collection)
|
||||
|
||||
const where = options.where || this.where
|
||||
if (!(!where || !Object.keys(where).length)) {
|
||||
db = db.where(where)
|
||||
}
|
||||
|
||||
const field = options.field || this.field
|
||||
if (field) {
|
||||
db = db.field(field)
|
||||
}
|
||||
|
||||
const orderby = options.orderby || this.orderby
|
||||
if (orderby) {
|
||||
db = db.orderBy(orderby)
|
||||
}
|
||||
|
||||
const current = options.pageCurrent !== undefined ? options.pageCurrent : this.page.current
|
||||
const size = options.pageSize !== undefined ? options.pageSize : this.page.size
|
||||
const getCount = options.getcount !== undefined ? options.getcount : this.getcount
|
||||
const getTree = options.gettree !== undefined ? options.gettree : this.gettree
|
||||
|
||||
const getOptions = {
|
||||
getCount,
|
||||
getTree
|
||||
}
|
||||
if (options.getTreePath) {
|
||||
getOptions.getTreePath = options.getTreePath
|
||||
}
|
||||
|
||||
db = db.skip(size * (current - 1)).limit(size).get(getOptions)
|
||||
|
||||
return db
|
||||
},
|
||||
getNodeData(callback) {
|
||||
if (this.loading) {
|
||||
return
|
||||
}
|
||||
this.loading = true
|
||||
this.getCommand({
|
||||
field: this.postField,
|
||||
where: this._pathWhere()
|
||||
}).then((res) => {
|
||||
this.loading = false
|
||||
this.selected = res.result.data
|
||||
callback && callback()
|
||||
}).catch((err) => {
|
||||
this.loading = false
|
||||
this.errorMessage = err
|
||||
})
|
||||
},
|
||||
getTreePath(callback) {
|
||||
if (this.loading) {
|
||||
return
|
||||
}
|
||||
this.loading = true
|
||||
|
||||
this.getCommand({
|
||||
field: this.postField,
|
||||
getTreePath: {
|
||||
startWith: `${this.selfField}=='${this.dataValue}'`
|
||||
}
|
||||
}).then((res) => {
|
||||
this.loading = false
|
||||
let treePath = []
|
||||
this._extractTreePath(res.result.data, treePath)
|
||||
this.selected = treePath
|
||||
callback && callback()
|
||||
}).catch((err) => {
|
||||
this.loading = false
|
||||
this.errorMessage = err
|
||||
})
|
||||
},
|
||||
loadData() {
|
||||
if (this.isLocaldata) {
|
||||
this._processLocalData()
|
||||
return
|
||||
}
|
||||
|
||||
if (this.dataValue != null) {
|
||||
this._loadNodeData((data) => {
|
||||
this._treeData = data
|
||||
this._updateBindData()
|
||||
this._updateSelected()
|
||||
})
|
||||
return
|
||||
}
|
||||
|
||||
if (this.stepSearh) {
|
||||
this._loadNodeData((data) => {
|
||||
this._treeData = data
|
||||
this._updateBindData()
|
||||
})
|
||||
} else {
|
||||
this._loadAllData((data) => {
|
||||
this._treeData = []
|
||||
this._extractTree(data, this._treeData, null)
|
||||
this._updateBindData()
|
||||
})
|
||||
}
|
||||
},
|
||||
_loadAllData(callback) {
|
||||
if (this.loading) {
|
||||
return
|
||||
}
|
||||
this.loading = true
|
||||
|
||||
this.getCommand({
|
||||
field: this.postField,
|
||||
gettree: true,
|
||||
startwith: `${this.selfField}=='${this.dataValue}'`
|
||||
}).then((res) => {
|
||||
this.loading = false
|
||||
callback(res.result.data)
|
||||
this.onDataChange()
|
||||
}).catch((err) => {
|
||||
this.loading = false
|
||||
this.errorMessage = err
|
||||
})
|
||||
},
|
||||
_loadNodeData(callback, pw) {
|
||||
if (this.loading) {
|
||||
return
|
||||
}
|
||||
this.loading = true
|
||||
|
||||
this.getCommand({
|
||||
field: this.postField,
|
||||
where: pw || this._postWhere(),
|
||||
pageSize: 500
|
||||
}).then((res) => {
|
||||
this.loading = false
|
||||
callback(res.result.data)
|
||||
this.onDataChange()
|
||||
}).catch((err) => {
|
||||
this.loading = false
|
||||
this.errorMessage = err
|
||||
})
|
||||
},
|
||||
_pathWhere() {
|
||||
let result = []
|
||||
let where_field = this._getParentNameByField();
|
||||
if (where_field) {
|
||||
result.push(`${where_field} == '${this.dataValue}'`)
|
||||
}
|
||||
|
||||
if (this.where) {
|
||||
return `(${this.where}) && (${result.join(' || ')})`
|
||||
}
|
||||
|
||||
return result.join(' || ')
|
||||
},
|
||||
_postWhere() {
|
||||
let result = []
|
||||
let selected = this.selected
|
||||
let parentField = this.parentField
|
||||
if (parentField) {
|
||||
result.push(`${parentField} == null || ${parentField} == ""`)
|
||||
}
|
||||
if (selected.length) {
|
||||
for (var i = 0; i < selected.length - 1; i++) {
|
||||
result.push(`${parentField} == '${selected[i].value}'`)
|
||||
}
|
||||
}
|
||||
|
||||
let where = []
|
||||
if (this.where) {
|
||||
where.push(`(${this.where})`)
|
||||
}
|
||||
if (result.length) {
|
||||
where.push(`(${result.join(' || ')})`)
|
||||
}
|
||||
|
||||
return where.join(' && ')
|
||||
},
|
||||
_nodeWhere() {
|
||||
let result = []
|
||||
let selected = this.selected
|
||||
if (selected.length) {
|
||||
result.push(`${this.parentField} == '${selected[selected.length - 1].value}'`)
|
||||
}
|
||||
|
||||
if (this.where) {
|
||||
return `(${this.where}) && (${result.join(' || ')})`
|
||||
}
|
||||
|
||||
return result.join(' || ')
|
||||
},
|
||||
_getParentNameByField() {
|
||||
const fields = this.field.split(',');
|
||||
let where_field = null;
|
||||
for (let i = 0; i < fields.length; i++) {
|
||||
const items = fields[i].split('as');
|
||||
if (items.length < 2) {
|
||||
continue;
|
||||
}
|
||||
if (items[1].trim() === 'value') {
|
||||
where_field = items[0].trim();
|
||||
break;
|
||||
}
|
||||
}
|
||||
return where_field
|
||||
},
|
||||
_isTreeView() {
|
||||
return (this.parentField && this.selfField)
|
||||
},
|
||||
_updateSelected() {
|
||||
var dl = this.dataList
|
||||
var sl = this.selected
|
||||
let textField = this.map.text
|
||||
let valueField = this.map.value
|
||||
for (var i = 0; i < sl.length; i++) {
|
||||
var value = sl[i].value
|
||||
var dl2 = dl[i]
|
||||
for (var j = 0; j < dl2.length; j++) {
|
||||
var item2 = dl2[j]
|
||||
if (item2[valueField] === value) {
|
||||
sl[i].text = item2[textField]
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
_updateBindData(node) {
|
||||
const {
|
||||
dataList,
|
||||
hasNodes
|
||||
} = this._filterData(this._treeData, this.selected)
|
||||
|
||||
let isleaf = this._stepSearh === false && !hasNodes
|
||||
|
||||
if (node) {
|
||||
node.isleaf = isleaf
|
||||
}
|
||||
|
||||
this.dataList = dataList
|
||||
this.selectedIndex = dataList.length - 1
|
||||
|
||||
if (!isleaf && this.selected.length < dataList.length) {
|
||||
this.selected.push({
|
||||
value: null,
|
||||
text: "请选择"
|
||||
})
|
||||
}
|
||||
|
||||
return {
|
||||
isleaf,
|
||||
hasNodes
|
||||
}
|
||||
},
|
||||
_filterData(data, paths) {
|
||||
let dataList = []
|
||||
let hasNodes = true
|
||||
|
||||
dataList.push(data.filter((item) => {
|
||||
return (item.parent_value === null || item.parent_value === undefined || item.parent_value === '')
|
||||
}))
|
||||
for (let i = 0; i < paths.length; i++) {
|
||||
var value = paths[i].value
|
||||
var nodes = data.filter((item) => {
|
||||
return item.parent_value === value
|
||||
})
|
||||
|
||||
if (nodes.length) {
|
||||
dataList.push(nodes)
|
||||
} else {
|
||||
hasNodes = false
|
||||
}
|
||||
}
|
||||
|
||||
return {
|
||||
dataList,
|
||||
hasNodes
|
||||
}
|
||||
},
|
||||
_extractTree(nodes, result, parent_value) {
|
||||
let list = result || []
|
||||
let valueField = this.map.value
|
||||
for (let i = 0; i < nodes.length; i++) {
|
||||
let node = nodes[i]
|
||||
|
||||
let child = {}
|
||||
for (let key in node) {
|
||||
if (key !== 'children') {
|
||||
child[key] = node[key]
|
||||
}
|
||||
}
|
||||
if (parent_value !== null && parent_value !== undefined && parent_value !== '') {
|
||||
child.parent_value = parent_value
|
||||
}
|
||||
result.push(child)
|
||||
|
||||
let children = node.children
|
||||
if (children) {
|
||||
this._extractTree(children, result, node[valueField])
|
||||
}
|
||||
}
|
||||
},
|
||||
_extractTreePath(nodes, result) {
|
||||
let list = result || []
|
||||
for (let i = 0; i < nodes.length; i++) {
|
||||
let node = nodes[i]
|
||||
|
||||
let child = {}
|
||||
for (let key in node) {
|
||||
if (key !== 'children') {
|
||||
child[key] = node[key]
|
||||
}
|
||||
}
|
||||
result.push(child)
|
||||
|
||||
let children = node.children
|
||||
if (children) {
|
||||
this._extractTreePath(children, result)
|
||||
}
|
||||
}
|
||||
},
|
||||
_findNodePath(key, nodes, path = []) {
|
||||
let textField = this.map.text
|
||||
let valueField = this.map.value
|
||||
for (let i = 0; i < nodes.length; i++) {
|
||||
let node = nodes[i]
|
||||
let children = node.children
|
||||
let text = node[textField]
|
||||
let value = node[valueField]
|
||||
|
||||
path.push({
|
||||
value,
|
||||
text
|
||||
})
|
||||
|
||||
if (value === key) {
|
||||
return path
|
||||
}
|
||||
|
||||
if (children) {
|
||||
const p = this._findNodePath(key, children, path)
|
||||
if (p.length) {
|
||||
return p
|
||||
}
|
||||
}
|
||||
|
||||
path.pop()
|
||||
}
|
||||
return []
|
||||
},
|
||||
_processLocalData() {
|
||||
this._treeData = []
|
||||
this._extractTree(this.localdata, this._treeData)
|
||||
|
||||
var inputValue = this.dataValue
|
||||
if (inputValue === undefined) {
|
||||
return
|
||||
}
|
||||
|
||||
if (Array.isArray(inputValue)) {
|
||||
inputValue = inputValue[inputValue.length - 1]
|
||||
if (typeof inputValue === 'object' && inputValue[this.map.value]) {
|
||||
inputValue = inputValue[this.map.value]
|
||||
}
|
||||
}
|
||||
|
||||
this.selected = this._findNodePath(inputValue, this.localdata)
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,92 @@
|
||||
{
|
||||
"id": "uni-data-picker",
|
||||
"displayName": "uni-data-picker 数据驱动的picker选择器",
|
||||
"version": "1.0.3",
|
||||
"description": "单列、多列级联选择器,常用于省市区城市选择、公司部门选择、多级分类等场景",
|
||||
"keywords": [
|
||||
"uni-ui",
|
||||
"uniui",
|
||||
"picker",
|
||||
"级联",
|
||||
"省市区",
|
||||
""
|
||||
],
|
||||
"repository": "https://github.com/dcloudio/uni-ui",
|
||||
"engines": {
|
||||
"HBuilderX": ""
|
||||
},
|
||||
"directories": {
|
||||
"example": "../../temps/example_temps"
|
||||
},
|
||||
"dcloudext": {
|
||||
"category": [
|
||||
"前端组件",
|
||||
"通用组件"
|
||||
],
|
||||
"sale": {
|
||||
"regular": {
|
||||
"price": "0.00"
|
||||
},
|
||||
"sourcecode": {
|
||||
"price": "0.00"
|
||||
}
|
||||
},
|
||||
"contact": {
|
||||
"qq": ""
|
||||
},
|
||||
"declaration": {
|
||||
"ads": "无",
|
||||
"data": "无",
|
||||
"permissions": "无"
|
||||
},
|
||||
"npmurl": "https://www.npmjs.com/package/@dcloudio/uni-ui"
|
||||
},
|
||||
"uni_modules": {
|
||||
"dependencies": [
|
||||
"uni-load-more",
|
||||
"uni-icons",
|
||||
"uni-scss"
|
||||
],
|
||||
"encrypt": [],
|
||||
"platforms": {
|
||||
"cloud": {
|
||||
"tcb": "y",
|
||||
"aliyun": "y"
|
||||
},
|
||||
"client": {
|
||||
"App": {
|
||||
"app-vue": "y",
|
||||
"app-nvue": "y"
|
||||
},
|
||||
"H5-mobile": {
|
||||
"Safari": "y",
|
||||
"Android Browser": "y",
|
||||
"微信浏览器(Android)": "y",
|
||||
"QQ浏览器(Android)": "y"
|
||||
},
|
||||
"H5-pc": {
|
||||
"Chrome": "y",
|
||||
"IE": "y",
|
||||
"Edge": "y",
|
||||
"Firefox": "y",
|
||||
"Safari": "y"
|
||||
},
|
||||
"小程序": {
|
||||
"微信": "y",
|
||||
"阿里": "y",
|
||||
"百度": "y",
|
||||
"字节跳动": "y",
|
||||
"QQ": "y"
|
||||
},
|
||||
"快应用": {
|
||||
"华为": "u",
|
||||
"联盟": "u"
|
||||
},
|
||||
"Vue": {
|
||||
"vue2": "y",
|
||||
"vue3": "y"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,298 @@
|
||||
<template>
|
||||
<view class="content pt-[44px]">
|
||||
<kevyloading v-if="loading" type="bsm-loader" color="#618af8" transparent></kevyloading>
|
||||
|
||||
<view class="w-full">
|
||||
<wd-navbar fixed safeAreaInsetTop :leftText="user_info?.info?.name || '商城首页'">
|
||||
<template #right>
|
||||
<wd-icon @click="utils.toUrl('/mall/setup/index')" name="setting" size="22px"></wd-icon>
|
||||
</template>
|
||||
</wd-navbar>
|
||||
</view>
|
||||
|
||||
<view bg-color="#f7f8fa" class="w-full grid grid-cols-3 gap-3 px-3 my-4">
|
||||
|
||||
|
||||
<view @click="utils.toUrl('/mall/cat/index')" class="text-white rounded-3xl p-4 pb-0 shadow-lg overflow-hidden"
|
||||
style="background-image: linear-gradient(to top, #7ea0ff 0%, #a9bdf5 100%);">
|
||||
<view class="font-bold">分类管理</view>
|
||||
<view class="h-0.5 w-5 mt-0.5 bg-white"></view>
|
||||
|
||||
<view class="flex justify-end">
|
||||
<div class="rotate-[-28deg] translate-y-3 translate-x-5">
|
||||
<wd-icon name="chat opacity-80" class="opacity-80" size="42px"></wd-icon>
|
||||
</div>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<view @click="utils.toUrl('/mall/goods/index')" class="text-white rounded-3xl p-4 pb-0 shadow-lg overflow-hidden"
|
||||
style="background-image: linear-gradient(to top, #7ea0ff 0%, #a9bdf5 100%);">
|
||||
<view class="font-bold">商品管理</view>
|
||||
<view class="h-0.5 w-5 mt-0.5 bg-white"></view>
|
||||
|
||||
<view class="flex justify-end">
|
||||
<div class="rotate-[-28deg] translate-y-3 translate-x-5">
|
||||
<wd-icon name="goods opacity-80" class="opacity-80" size="42px"></wd-icon>
|
||||
</div>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<view @click="utils.toUrl('/mall/order/index')" class="text-white rounded-3xl p-4 pb-0 shadow-lg overflow-hidden"
|
||||
style="background-image: linear-gradient(to top, #7ea0ff 0%, #a9bdf5 100%);">
|
||||
<view class="font-bold">订单管理</view>
|
||||
<view class="h-0.5 w-5 mt-0.5 bg-white"></view>
|
||||
|
||||
<view class="flex justify-end">
|
||||
<div class="rotate-[-28deg] translate-y-3 translate-x-5">
|
||||
<wd-icon name="gift opacity-80" class="opacity-80" size="42px"></wd-icon>
|
||||
</div>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<!-- <view @click="utils.toUrl('/mall/check/list')" class="text-white rounded-3xl p-4 pb-0 shadow-lg overflow-hidden"
|
||||
style="background-image: linear-gradient(to top, #7ea0ff 0%, #a9bdf5 100%);">
|
||||
<view class="font-bold">核销记录</view>
|
||||
<view class="h-0.5 w-5 mt-0.5 bg-white"></view>
|
||||
|
||||
<view class="flex justify-end">
|
||||
<div class="rotate-[-28deg] translate-y-3 translate-x-5">
|
||||
<wd-icon name="phone" class="opacity-80" size="42px"></wd-icon>
|
||||
</div>
|
||||
</view>
|
||||
</view> -->
|
||||
|
||||
|
||||
|
||||
|
||||
<!-- <view @click="utils.toUrl('/mall/order/index')" class="text-white rounded-3xl p-4 pb-0 shadow-lg overflow-hidden"
|
||||
style="background-image: linear-gradient(to top, #7ea0ff 0%, #a9bdf5 100%);">
|
||||
<view class="font-bold">订单管理</view>
|
||||
<view class="h-0.5 w-5 mt-0.5 bg-white"></view>
|
||||
|
||||
<view class="flex justify-end">
|
||||
<div class="rotate-[-28deg] translate-y-3 translate-x-5">
|
||||
<wd-icon name="gift opacity-80" size="42px"></wd-icon>
|
||||
</div>
|
||||
</view>
|
||||
</view> -->
|
||||
|
||||
|
||||
|
||||
</view>
|
||||
|
||||
<view style="transition: 1s;" class="w-full h-full bg-white pt-4 rounded-tr-3xl rounded-tl-3xl shadow-lg oh">
|
||||
<view class="order mb-2">
|
||||
<wd-grid v-show="oneLine.ok">
|
||||
<wd-grid-item @click="utils.toUrl('/mall/user/list')" icon="round" :text="`用户 (${oneLine.user_count})`" />
|
||||
<wd-grid-item @click="utils.toUrl('/mall/goods/index')" icon="round" :text="`商品 (${oneLine.goods_count})`" />
|
||||
<wd-grid-item @click="utils.toUrl('/mall/goods/index')" icon="round"
|
||||
:text="`售罄 (${oneLine.empty_stock_count})`" />
|
||||
<wd-grid-item @click="utils.toUrl('/mall/order/index')" icon="round" :text="`订单 (${oneLine.order_count})`" />
|
||||
</wd-grid>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<view class="flex-1 bg-white p-2 pb-4">
|
||||
<!-- <div class="name mb-2">订单数据</div> -->
|
||||
<view class=" p-2 rounded-md">
|
||||
<div class="rounded-md overflow-hidden">
|
||||
<wd-tabs @change="getOrderProfit">
|
||||
<wd-tab :title="`今天`" :name="1"></wd-tab>
|
||||
<wd-tab :title="`本周`" :name="2"></wd-tab>
|
||||
<wd-tab :title="`本月`" :name="3"></wd-tab>
|
||||
<wd-tab :title="`本年`" :name="4"></wd-tab>
|
||||
</wd-tabs>
|
||||
</div>
|
||||
|
||||
<div class="grid grid-cols-2 gap-2 my-4">
|
||||
<div @click="utils.toUrl('/mall/order/index?s=' + (index + 1))"
|
||||
class="item rounded-1xl bg-slate-50 p-2 flex justify-between" style="font-size: 24rpx;"
|
||||
v-for="(item, index) of orderProfit.categories">
|
||||
{{ item }}
|
||||
|
||||
<text>{{ orderProfit.series[0].data[index] }}</text>
|
||||
</div>
|
||||
|
||||
<div @click="utils.toUrl('/mall/afterSale/index')"
|
||||
class="item rounded-1xl bg-slate-50 p-2 flex justify-between" style="font-size: 24rpx;">
|
||||
售后订单
|
||||
<text>∞</text>
|
||||
</div>
|
||||
|
||||
|
||||
</div>
|
||||
|
||||
<bar :barData="orderProfit"></bar>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<view class="flex-1 bg-white p-2 pb-4 ">
|
||||
<view class=" p-2 rounded-md">
|
||||
<div class="rounded-md overflow-hidden">
|
||||
<wd-tabs @change="getOrderGood">
|
||||
<wd-tab :title="`今天`" :name="1"></wd-tab>
|
||||
<wd-tab :title="`本周`" :name="2"></wd-tab>
|
||||
<wd-tab :title="`本月`" :name="3"></wd-tab>
|
||||
<wd-tab :title="`本年`" :name="4"></wd-tab>
|
||||
</wd-tabs>
|
||||
</div>
|
||||
|
||||
<div class="grid grid-cols-2 gap-2 my-4">
|
||||
<div class="item rounded-1xl bg-slate-50 p-2 flex justify-between" style="font-size: 24rpx;"
|
||||
v-for="(item, index) of orderGood.categories">
|
||||
{{ item }}
|
||||
|
||||
<text>{{ orderGood.series[0].data[index] }}</text>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<bar :barData="orderGood"></bar>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<view class="bg-white h-[80px]"></view>
|
||||
|
||||
<view class="fixed left-2 right-2 bottom-4 z-50">
|
||||
<myTabbar></myTabbar>
|
||||
</view>
|
||||
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { ref } from 'vue';
|
||||
import utils from '@/utils/utils.js';
|
||||
import index from '@/api/mall/index.js';
|
||||
import myTabbar from "../components/myTabbar/index.vue";
|
||||
import bar from "../components/bar/bar.vue";
|
||||
import kevyloading from "@/components/kevy-loading/kevy-loading";
|
||||
|
||||
/**
|
||||
* @type {Ref<boolean>}
|
||||
* 控制页面加载状态的 Ref
|
||||
*/
|
||||
const loading = ref(false);
|
||||
|
||||
/**
|
||||
* 从本地存储中获取用户信息
|
||||
*/
|
||||
const user_info = uni.getStorageSync("user_info");
|
||||
|
||||
/**
|
||||
* @type {Ref<Object>}
|
||||
* 存储一行数据的 Ref
|
||||
*/
|
||||
const oneLine = ref({});
|
||||
|
||||
/**
|
||||
* 获取一行数据的函数
|
||||
*/
|
||||
const getOneLine = () => {
|
||||
index.dataCount.oneLine().then(res => {
|
||||
oneLine.value = res.data;
|
||||
oneLine.value.ok = true;
|
||||
});
|
||||
};
|
||||
|
||||
// 初始化调用获取一行数据
|
||||
getOneLine();
|
||||
|
||||
/**
|
||||
* @type {Ref<Object>}
|
||||
* 存储订单利润数据的 Ref
|
||||
*/
|
||||
const orderProfit = ref({});
|
||||
|
||||
/**
|
||||
* 获取订单利润数据的函数
|
||||
* @param {Object} e - 包含索引的对象
|
||||
*/
|
||||
const getOrderProfit = (e) => {
|
||||
loading.value = true;
|
||||
index.dataCount.orderProfit({
|
||||
date: e.index + 1
|
||||
}).then(res => {
|
||||
if (res.code === 0) {
|
||||
const statusData = res.data.reduce((obj, cur) => {
|
||||
obj[cur.status] = cur;
|
||||
return obj;
|
||||
}, {});
|
||||
|
||||
const arr = [
|
||||
{ name: "未付款订单", data: statusData[0]?.count || 0 },
|
||||
{ name: "待发货订单", data: statusData[1]?.count || 0 },
|
||||
{ name: "已发货订单", data: statusData[2]?.count || 0 },
|
||||
{ name: "已完成订单", data: statusData[3]?.count || 0 },
|
||||
{ name: "已取消订单", data: statusData[4]?.count || 0 }
|
||||
];
|
||||
|
||||
orderProfit.value.categories = arr.map(item => item.name);
|
||||
orderProfit.value.series = [
|
||||
{ name: "订单数据", data: arr.map(item => item.data) }
|
||||
];
|
||||
|
||||
loading.value = false;
|
||||
console.log(orderProfit.value);
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
// 初始化调用获取订单利润数据
|
||||
getOrderProfit({ index: 0 });
|
||||
|
||||
/**
|
||||
* @type {Ref<Object>}
|
||||
* 存储订单商品数据的 Ref
|
||||
*/
|
||||
const orderGood = ref({});
|
||||
|
||||
/**
|
||||
* 获取订单商品数据的函数
|
||||
* @param {Object} e - 包含索引的对象
|
||||
*/
|
||||
const getOrderGood = (e) => {
|
||||
loading.value = true;
|
||||
index.dataCount.orderGood({
|
||||
date: e.index + 1
|
||||
}).then(res => {
|
||||
if (res.code === 0) {
|
||||
const payTypeData = res.data.reduce((obj, cur) => {
|
||||
obj[cur.pay_type] = cur;
|
||||
return obj;
|
||||
}, {});
|
||||
|
||||
const totalPrice = (
|
||||
(Number(payTypeData[1]?.pay_price) || 0) +
|
||||
(Number(payTypeData[2]?.pay_price) || 0) +
|
||||
(Number(payTypeData[3]?.pay_price) || 0)
|
||||
);
|
||||
|
||||
const arr = [
|
||||
{ name: "总成交金额", data: totalPrice || 0 },
|
||||
{ name: "支付宝支付", data: payTypeData[1]?.pay_price || 0 },
|
||||
{ name: "微信支付", data: payTypeData[2]?.pay_price || 0 },
|
||||
{ name: "余额支付", data: payTypeData[3]?.pay_price || 0 },
|
||||
];
|
||||
|
||||
orderGood.value.categories = arr.map(item => item.name);
|
||||
orderGood.value.series = [
|
||||
{ name: "交易数据", data: arr.map(item => item.data) }
|
||||
];
|
||||
|
||||
loading.value = false;
|
||||
console.log(orderGood.value);
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
// 初始化调用获取订单商品数据
|
||||
getOrderGood({ index: 0 });
|
||||
|
||||
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.content {
|
||||
padding-top: 44px;
|
||||
}
|
||||
</style>
|
||||
Loading…
Reference in New Issue