commit
1f7f498dbb
@ -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,56 @@
|
|||||||
|
import {
|
||||||
|
request
|
||||||
|
} from "@/utils/request";
|
||||||
|
|
||||||
|
export default {
|
||||||
|
|
||||||
|
LevelShow(data) {
|
||||||
|
return request({
|
||||||
|
url: "/admin/UserMembers/LevelShow",
|
||||||
|
method: "GET",
|
||||||
|
data,
|
||||||
|
})
|
||||||
|
},
|
||||||
|
|
||||||
|
LevelSave(data) {
|
||||||
|
return request({
|
||||||
|
url: "/admin/UserMembers/LevelSave",
|
||||||
|
method: "GET",
|
||||||
|
data,
|
||||||
|
})
|
||||||
|
},
|
||||||
|
|
||||||
|
SetList(data) {
|
||||||
|
return request({
|
||||||
|
url: "/admin/UserMembers/SetList",
|
||||||
|
method: "GET",
|
||||||
|
data,
|
||||||
|
})
|
||||||
|
},
|
||||||
|
|
||||||
|
SetSave(data) {
|
||||||
|
return request({
|
||||||
|
url: "/admin/UserMembers/SetSave",
|
||||||
|
method: "GET",
|
||||||
|
data,
|
||||||
|
})
|
||||||
|
},
|
||||||
|
|
||||||
|
DiscountList(data) {
|
||||||
|
return request({
|
||||||
|
url: "/admin/UserMembers/DiscountList",
|
||||||
|
method: "GET",
|
||||||
|
data,
|
||||||
|
})
|
||||||
|
},
|
||||||
|
|
||||||
|
CreateDiscount(data) {
|
||||||
|
return request({
|
||||||
|
url: "/admin/UserMembers/CreateDiscount",
|
||||||
|
method: "POST",
|
||||||
|
data,
|
||||||
|
})
|
||||||
|
},
|
||||||
|
|
||||||
|
|
||||||
|
};
|
||||||
@ -0,0 +1,176 @@
|
|||||||
|
<template>
|
||||||
|
<view>
|
||||||
|
<view v-if="props.modelValue && props.modelValue.length" @click="open(true)" class="flex gap-2 overflow-x-auto">
|
||||||
|
<view class=" flex rounded-[14px] relative" :key="img">
|
||||||
|
已选择 {{ props.modelValue.length || 0 }} 件商品
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
|
||||||
|
<view v-else @click="open(true)" class="flex gap-2 overflow-x-auto">
|
||||||
|
<view style="" class=" flex rounded-[14px] relative flex-col items-center justify-center">
|
||||||
|
<view class="font-bold text-[12px]">请选择商品</view>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
|
||||||
|
<wd-popup :z-index="998" v-model="show" closable position="left" custom-style="width: 86vw;" @close="close(false)">
|
||||||
|
<view class="pop yUpload h-dvh overflow-hidden">
|
||||||
|
<view class="bg-white overflow-hidden h-full" style="background-clip: content-box;">
|
||||||
|
|
||||||
|
<view class="bg-gray-100 p-4 flex">
|
||||||
|
<view>
|
||||||
|
<wd-button @tap="ok">确认选择</wd-button>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
|
||||||
|
<view v-if="LArr.length" class="shadow-lg ">
|
||||||
|
<view class="text px-2 mt-3 font-bold">已选择 ( {{ LArr.length || 0 }}) 件商品</view>
|
||||||
|
<view class="bg-gray images flex gap-2 overflow-x-auto p-4 pt-2 ">
|
||||||
|
<view @click="onClickCheck(item)" class=" border-gray-100 border-solid flex rounded-[14px] relative"
|
||||||
|
v-for="item of LArr" :key="img">
|
||||||
|
|
||||||
|
<div class="flex flex-col">
|
||||||
|
<view>
|
||||||
|
<wd-img mode="aspectFill" radius="10" :width="100" :height="100" :src="item.pic_url" />
|
||||||
|
</view>
|
||||||
|
<view class="list-item-name" style="width: 100px;">{{ item.name }}</view>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<view class="absolute bg-white opacity-80 inset-0 flex items-center justify-center border-spacing-1">取消选择
|
||||||
|
</view>
|
||||||
|
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
<view v-else class="shadow-lg ">
|
||||||
|
<view class="text p-3 font-bold">请选择商品</view>
|
||||||
|
</view>
|
||||||
|
|
||||||
|
<view class="overflow-hidden rounded-t-3xl">
|
||||||
|
<yList ref="yListRef" :apiObj="goods.list" :params="{ ...params, classify_id: 0 }">
|
||||||
|
<template #default="{ list }">
|
||||||
|
|
||||||
|
<view class="grid grid-cols-2 gap-4 p-4 overflow-hidden rounded-t-3xl">
|
||||||
|
<view
|
||||||
|
class="relative flex flex-col items-center justify-center bg-gray-100 p-4 rounded-md overflow-hidden"
|
||||||
|
v-for="item of list" :key="item.id">
|
||||||
|
<view class="list-item-img" @click="onClickCheck(item)"
|
||||||
|
:style="{ backgroundImage: 'url(' + item.pic_url + ')' }"></view>
|
||||||
|
|
||||||
|
<view class="list-item-name">{{ item.name }}</view>
|
||||||
|
|
||||||
|
<view @click="onClickCheck(item)"
|
||||||
|
class="absolute bg-white opacity-80 inset-2 flex items-center justify-center border-spacing-1"
|
||||||
|
v-if="idArr.includes(item.id)">取消选择</view>
|
||||||
|
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
|
||||||
|
</template>
|
||||||
|
</yList>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
|
||||||
|
</wd-popup>
|
||||||
|
|
||||||
|
</view>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup>
|
||||||
|
import { ref, computed } from 'vue'
|
||||||
|
import goods from '@/api/store/goods.js'
|
||||||
|
import yList from "/components/yList/index.vue"
|
||||||
|
const yListRef = ref(null)
|
||||||
|
|
||||||
|
const emit = defineEmits(['update:modelValue']);
|
||||||
|
const props = defineProps({
|
||||||
|
modelValue: {
|
||||||
|
type: String,
|
||||||
|
default: ""
|
||||||
|
},
|
||||||
|
})
|
||||||
|
|
||||||
|
const params = ref({
|
||||||
|
keywords: "",
|
||||||
|
status: "",
|
||||||
|
})
|
||||||
|
|
||||||
|
const LArr = ref([])
|
||||||
|
|
||||||
|
const idArr = computed(() => {
|
||||||
|
return LArr.value.map(item => item.id)
|
||||||
|
})
|
||||||
|
|
||||||
|
const show = ref(false)
|
||||||
|
const open = (O) => {
|
||||||
|
show.value = O
|
||||||
|
|
||||||
|
if (O && yListRef.value?.upData) {
|
||||||
|
yListRef.value.upData()
|
||||||
|
}
|
||||||
|
|
||||||
|
if (props.modelValue) {
|
||||||
|
if (Array.isArray(props.modelValue)) {
|
||||||
|
LArr.value = JSON.parse(JSON.stringify(props.modelValue))
|
||||||
|
} else {
|
||||||
|
LArr.value = [props.modelValue]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
open(false)
|
||||||
|
|
||||||
|
const close = () => {
|
||||||
|
// LArr.value = []
|
||||||
|
}
|
||||||
|
|
||||||
|
const ok = () => {
|
||||||
|
if (props.size == 1) {
|
||||||
|
emit("update:modelValue", LArr.value.pop())
|
||||||
|
} else {
|
||||||
|
emit("update:modelValue", LArr.value)
|
||||||
|
}
|
||||||
|
|
||||||
|
show.value = false
|
||||||
|
}
|
||||||
|
|
||||||
|
const onClickCheck = (row) => {
|
||||||
|
const index = LArr.value.findIndex(item => item.id === row.id)
|
||||||
|
|
||||||
|
if (index > -1) {
|
||||||
|
LArr.value.splice(index, 1)
|
||||||
|
} else {
|
||||||
|
LArr.value.unshift(row)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style lang="scss">
|
||||||
|
.list-item-img {
|
||||||
|
width: 100%;
|
||||||
|
height: 80px;
|
||||||
|
background-position: center center;
|
||||||
|
background-size: contain;
|
||||||
|
background-repeat: no-repeat;
|
||||||
|
}
|
||||||
|
|
||||||
|
.list-item-name {
|
||||||
|
text-align: center;
|
||||||
|
padding: 5px 10px;
|
||||||
|
overflow: hidden;
|
||||||
|
text-overflow: ellipsis;
|
||||||
|
white-space: nowrap;
|
||||||
|
font-size: 12px;
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.pop {
|
||||||
|
// position: fixed;
|
||||||
|
background: rgba(0, 0, 0, 0.256);
|
||||||
|
background-clip: border-box;
|
||||||
|
overflow: hidden;
|
||||||
|
inset: 0px;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
@ -1,5 +1,5 @@
|
|||||||
<template>
|
<template>
|
||||||
<view class="myTable">
|
<view class="yTable">
|
||||||
<kevyloading v-if="loading" type="bsm-loader" color="#618af8" transparent></kevyloading>
|
<kevyloading v-if="loading" type="bsm-loader" color="#618af8" transparent></kevyloading>
|
||||||
|
|
||||||
<wd-table :data="list" :border="true">
|
<wd-table :data="list" :border="true">
|
||||||
@ -0,0 +1,58 @@
|
|||||||
|
import { ref } from "vue"
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 用于执行 API 请求和管理相关状态的自定义钩子。
|
||||||
|
*
|
||||||
|
* @param {Function} apiF - 表示 API 请求的异步函数。
|
||||||
|
* @param {Object} [opt={}] - 可选配置选项。
|
||||||
|
* @param {Ref<boolean>} [opt.loading=false] - 可选的 loading 状态变量。
|
||||||
|
*
|
||||||
|
* @returns {Object} - 包含响应式变量和 fetchData 函数的对象。
|
||||||
|
* @property {Ref<boolean>} loading - 表示 API 请求加载状态的 ref。
|
||||||
|
* @property {Ref<any>} result - 表示 API 请求结果的 ref。
|
||||||
|
* @property {Ref<any>} error - 表示 API 请求失败时的错误的 ref。
|
||||||
|
* @property {Function} fetchData - 用于执行 API 请求并更新状态变量的函数。
|
||||||
|
*/
|
||||||
|
export const useApi = (apiF, opt = {}) => {
|
||||||
|
// 使用 ref 包装状态变量
|
||||||
|
const loading = opt.loading || ref(false)
|
||||||
|
const result = ref(null)
|
||||||
|
const error = ref(null)
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 执行 API 请求并更新状态的函数。
|
||||||
|
*
|
||||||
|
* @param {*} p - 用于 API 请求的参数。
|
||||||
|
* @returns {Promise} - 包含 API 响应对象的 Promise。
|
||||||
|
*/
|
||||||
|
const fetchData = async (p) => {
|
||||||
|
try {
|
||||||
|
// 开始请求,设置 loading 为 true
|
||||||
|
loading.value = true
|
||||||
|
// 执行异步 API 请求
|
||||||
|
const res = await apiF(p)
|
||||||
|
|
||||||
|
// 根据返回的 code 判断请求是否成功
|
||||||
|
if (res.code === 0) {
|
||||||
|
// 请求成功,更新 result 变量
|
||||||
|
result.value = res
|
||||||
|
} else {
|
||||||
|
// 请求失败,更新 error 变量
|
||||||
|
error.value = res
|
||||||
|
}
|
||||||
|
|
||||||
|
// 返回 API 响应对象
|
||||||
|
return res
|
||||||
|
} catch (err) {
|
||||||
|
// 捕获异常,更新 error 变量并抛出错误
|
||||||
|
error.value = err
|
||||||
|
throw err
|
||||||
|
} finally {
|
||||||
|
// 无论请求成功或失败,都会在最终阶段设置 loading 为 false
|
||||||
|
loading.value = false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 返回包含状态变量和 fetchData 函数的对象
|
||||||
|
return { loading, result, error, fetchData }
|
||||||
|
}
|
||||||
@ -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>
|
||||||
@ -0,0 +1,221 @@
|
|||||||
|
<template>
|
||||||
|
<view>
|
||||||
|
<kevyloading v-if="loading" type="bsm-loader" color="#618af8" transparent></kevyloading>
|
||||||
|
|
||||||
|
|
||||||
|
<wd-form ref="form" :model="storeData" :rules="formRules">
|
||||||
|
<!-- 基础信息 -->
|
||||||
|
<wd-cell-group title="基础信息" border>
|
||||||
|
<wd-input label="商城名称" label-width="100px" v-model="storeData.name" />
|
||||||
|
|
||||||
|
<!-- 商城LOGO -->
|
||||||
|
<wd-cell-group class="flex py-2 w-full" title="商城LOGO">
|
||||||
|
|
||||||
|
<view class="ml-3">
|
||||||
|
<yUpload v-model="storeData.logo_url" :size="1"></yUpload>
|
||||||
|
</view>
|
||||||
|
|
||||||
|
</wd-cell-group>
|
||||||
|
|
||||||
|
<!-- 门头照图片 -->
|
||||||
|
<wd-cell-group class="flex py-2 w-full" title="门头照图片">
|
||||||
|
|
||||||
|
<view class="ml-3">
|
||||||
|
<yUpload v-model="storeData.store_url" :size="1"></yUpload>
|
||||||
|
</view>
|
||||||
|
|
||||||
|
</wd-cell-group>
|
||||||
|
|
||||||
|
<!-- <wd-input label="联系人" label-width="100px" v-model="storeData.contact" /> -->
|
||||||
|
<wd-input label="联系方式" label-width="100px" v-model="storeData.mobile" />
|
||||||
|
<!-- 其他基础信息字段可以根据需要添加 -->
|
||||||
|
</wd-cell-group>
|
||||||
|
|
||||||
|
<!-- 地址信息 -->
|
||||||
|
<wd-cell-group class="flex py-2 w-full" title="所在地区">
|
||||||
|
<view class="ml-3">
|
||||||
|
<!-- 省市区选择器 -->
|
||||||
|
<uni-data-picker placeholder="请选择省市区" popup-title="请选择" :localdata="addrList" :map="{
|
||||||
|
text: 'name',
|
||||||
|
value: 'id',
|
||||||
|
}" v-model="storeData.district" @change="select">
|
||||||
|
</uni-data-picker>
|
||||||
|
</view>
|
||||||
|
</wd-cell-group>
|
||||||
|
|
||||||
|
<wd-input label="详细地址" label-width="100px" v-model="storeData.detail" use-suffix-slot>
|
||||||
|
</wd-input>
|
||||||
|
|
||||||
|
<!-- 其他信息 -->
|
||||||
|
<wd-cell-group title="其他信息" border>
|
||||||
|
<!-- 云喇叭通知表单项 -->
|
||||||
|
<wd-form-item label="云喇叭通知:" prop="zhangyou_device_name">
|
||||||
|
<wd-input v-model="storeData.zhangyou_device_name" placeholder="请输入设备编号" clearable />
|
||||||
|
|
||||||
|
<div style="color: #666;font-size: 12px;">
|
||||||
|
掌优4G云喇叭编号
|
||||||
|
</div>
|
||||||
|
</wd-form-item>
|
||||||
|
</wd-cell-group>
|
||||||
|
|
||||||
|
<view class="p-3 bg-white rounded mb-2">
|
||||||
|
<div class="name mb-2 text-xs">非营业时间下单</div>
|
||||||
|
<view class="bg-white px-3 py-2 rounded flex items-center">
|
||||||
|
<wd-switch v-model="storeData.is_opening" :active-value="1" :inactive-value="0" />
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
|
||||||
|
<view class="p-3 bg-white rounded mb-2">
|
||||||
|
<div class="name mb-2 text-xs">状态</div>
|
||||||
|
<view class="bg-white px-3 py-2 rounded flex items-center">
|
||||||
|
<wd-switch v-model="storeData.status" :active-value="1" :inactive-value="0" />
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
|
||||||
|
<!-- 提交按钮 -->
|
||||||
|
<view class="mt-2 px-12 py-3 bg-slate-50">
|
||||||
|
<wd-button type="primary" size="large" @click="handleSubmit" block>
|
||||||
|
保存
|
||||||
|
</wd-button>
|
||||||
|
</view>
|
||||||
|
</wd-form>
|
||||||
|
</view>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import { ref } from 'vue';
|
||||||
|
import yUpload from "@/components/yUpload/index.vue";
|
||||||
|
import uniDataPicker from "@/components/uni-data-picker/components/uni-data-picker/uni-data-picker.vue";
|
||||||
|
import system from '@/api/modules/system.js';
|
||||||
|
import index from '@/api/store/index.js';
|
||||||
|
import kevyloading from "@/components/kevy-loading/kevy-loading";
|
||||||
|
import utils from '@/utils/utils.js'
|
||||||
|
import shop from '@/api/store/shop.js';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 从本地存储中获取用户信息
|
||||||
|
*/
|
||||||
|
const user_info = uni.getStorageSync("user_info");
|
||||||
|
|
||||||
|
export default {
|
||||||
|
components: {
|
||||||
|
yUpload, uniDataPicker, kevyloading
|
||||||
|
},
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
utils,
|
||||||
|
user_info,
|
||||||
|
// 表单数据
|
||||||
|
storeData: {
|
||||||
|
name: '',
|
||||||
|
logo_url: '',
|
||||||
|
mobile: '',
|
||||||
|
district: null,
|
||||||
|
latlngCurrent: '',
|
||||||
|
pay_time: '',
|
||||||
|
confirm_time: '',
|
||||||
|
sale_time: '',
|
||||||
|
pay_type: [],
|
||||||
|
delivery_type: [],
|
||||||
|
after_sale_name: '',
|
||||||
|
after_sale_phone: '',
|
||||||
|
after_sale_address: '',
|
||||||
|
ali_express_app_code: '',
|
||||||
|
zhangyou_device_name: '',
|
||||||
|
},
|
||||||
|
shippingOptions: [
|
||||||
|
{ label: "邮寄", value: 1 },
|
||||||
|
{ label: "自提", value: 2 },
|
||||||
|
],
|
||||||
|
// 表单验证规则
|
||||||
|
formRules: {
|
||||||
|
name: [{ required: true, message: "请输入门店名称", trigger: "blur" }],
|
||||||
|
// 在这里添加其他字段的验证规则
|
||||||
|
},
|
||||||
|
// 地区选择器的数据
|
||||||
|
addrList: [
|
||||||
|
// 在这里添加省市区的数据
|
||||||
|
],
|
||||||
|
loading: false
|
||||||
|
};
|
||||||
|
},
|
||||||
|
onLoad(e) {
|
||||||
|
this.getDistrict();
|
||||||
|
// this.getStoreSetting();
|
||||||
|
|
||||||
|
this.storeData = JSON.parse(e.edit)
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
/**
|
||||||
|
* 获取省市区数据
|
||||||
|
*/
|
||||||
|
async getDistrict() {
|
||||||
|
const res = await system.getDistrict();
|
||||||
|
this.addrList = res.data;
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取门店设置
|
||||||
|
*/
|
||||||
|
async getStoreSetting() {
|
||||||
|
this.loading = true;
|
||||||
|
const res = await index.getStoreSetting();
|
||||||
|
|
||||||
|
if (res.data.id) {
|
||||||
|
this.storeData = res.data;
|
||||||
|
}
|
||||||
|
this.loading = false;
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 处理省市区选择变化
|
||||||
|
* @param {Object} value - 选择的值
|
||||||
|
*/
|
||||||
|
areaChange(value) {
|
||||||
|
// 处理省市区选择变化的逻辑
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 处理省市区选择
|
||||||
|
* @param {Object} detail - 选择器详细信息
|
||||||
|
*/
|
||||||
|
select({ detail }) {
|
||||||
|
if (detail.value.length) {
|
||||||
|
const [province_id, city_id, district_id] = detail.value.map(
|
||||||
|
(el) => el.value
|
||||||
|
);
|
||||||
|
|
||||||
|
this.storeData.province_id = province_id;
|
||||||
|
this.storeData.city_id = city_id;
|
||||||
|
this.storeData.district_id = district_id;
|
||||||
|
this.storeData.district = [province_id, city_id, district_id];
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 处理表单提交
|
||||||
|
*/
|
||||||
|
async handleSubmit() {
|
||||||
|
// 处理表单提交的逻辑
|
||||||
|
const res = await shop.edit({
|
||||||
|
...this.storeData
|
||||||
|
});
|
||||||
|
|
||||||
|
if (res.code == 0) {
|
||||||
|
setTimeout(() => {
|
||||||
|
uni.showToast({
|
||||||
|
title: '保存成功!',
|
||||||
|
icon: 'success'
|
||||||
|
});
|
||||||
|
}, 100);
|
||||||
|
uni.navigateBack()
|
||||||
|
}
|
||||||
|
},
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style>
|
||||||
|
/* 在这里添加样式,根据需要自定义表单样式 */
|
||||||
|
</style>
|
||||||
@ -0,0 +1,156 @@
|
|||||||
|
<template>
|
||||||
|
<view>
|
||||||
|
<kevyloading v-if="loading" type="bsm-loader" color="#618af8" transparent></kevyloading>
|
||||||
|
|
||||||
|
<wd-form ref="formEl" :model="dataForm" label-width="100px" class="demo-dataForm" :size="formSize" status-icon>
|
||||||
|
<wd-timeline>
|
||||||
|
<wd-timeline-item timestamp="基本设置" placement="top">
|
||||||
|
<div class="form">
|
||||||
|
<wd-form-item :prop="dataForm.image" label="背景图像">
|
||||||
|
<yUpload v-model="dataForm.image" :size="1"></yUpload>
|
||||||
|
</wd-form-item>
|
||||||
|
<wd-form-item :prop="dataForm.show_member" label="显示等级">
|
||||||
|
<wd-switch active-value="1" inactive-value="0" v-model="dataForm.show_member" />
|
||||||
|
</wd-form-item>
|
||||||
|
<wd-form-item :prop="dataForm.show_task" label="显示折扣">
|
||||||
|
<wd-switch active-value="1" inactive-value="0" v-model="dataForm.show_task" />
|
||||||
|
</wd-form-item>
|
||||||
|
<wd-form-item prop="dataForm.show_sign" label="显示签到">
|
||||||
|
<wd-switch active-value="1" inactive-value="0" v-model="dataForm.show_sign" />
|
||||||
|
</wd-form-item>
|
||||||
|
<wd-form-item :prop="dataForm.show_integral" label="显示积分">
|
||||||
|
<wd-switch active-value="1" inactive-value="0" v-model="dataForm.show_integral" />
|
||||||
|
</wd-form-item>
|
||||||
|
</div>
|
||||||
|
</wd-timeline-item>
|
||||||
|
|
||||||
|
<wd-timeline-item timestamp="成长值设置" placement="top">
|
||||||
|
<div class="form">
|
||||||
|
<wd-form-item :prop="dataForm.order_growth" label="下单成长值:">
|
||||||
|
<wd-input placeholder="请输入下单成长值" v-model.number="dataForm.order_growth"></wd-input>
|
||||||
|
</wd-form-item>
|
||||||
|
|
||||||
|
<wd-form-item :prop="dataForm.sign_growth" label="签到成长值:">
|
||||||
|
<wd-input placeholder="请输入签到成长值" v-model.number="dataForm.sign_growth"></wd-input>
|
||||||
|
</wd-form-item>
|
||||||
|
|
||||||
|
<wd-form-item :prop="dataForm.reg_growth" label="下级注册成长值:">
|
||||||
|
<wd-input placeholder="请输入下级注册成长值" v-model.number="dataForm.reg_growth"></wd-input>
|
||||||
|
</wd-form-item>
|
||||||
|
</div>
|
||||||
|
</wd-timeline-item>
|
||||||
|
</wd-timeline>
|
||||||
|
|
||||||
|
<!-- 提交按钮 -->
|
||||||
|
<view class="mt-2 px-12 py-3 bg-slate-50">
|
||||||
|
<wd-button type="primary" size="large" @click="handleSubmit" block>
|
||||||
|
保存
|
||||||
|
</wd-button>
|
||||||
|
</view>
|
||||||
|
|
||||||
|
</wd-form>
|
||||||
|
|
||||||
|
</view>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import { ref } from 'vue';
|
||||||
|
import yUpload from "@/components/yUpload/index.vue";
|
||||||
|
import uniDataPicker from "@/components/uni-data-picker/components/uni-data-picker/uni-data-picker.vue";
|
||||||
|
import system from '@/api/modules/system.js';
|
||||||
|
import index from '@/api/store/index.js';
|
||||||
|
import kevyloading from "@/components/kevy-loading/kevy-loading";
|
||||||
|
import utils from '@/utils/utils.js'
|
||||||
|
import userMembers from '@/api/store/userMembers.js';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 从本地存储中获取用户信息
|
||||||
|
*/
|
||||||
|
const user_info = uni.getStorageSync("user_info");
|
||||||
|
|
||||||
|
export default {
|
||||||
|
components: {
|
||||||
|
yUpload, uniDataPicker, kevyloading
|
||||||
|
},
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
utils,
|
||||||
|
user_info,
|
||||||
|
// 表单数据
|
||||||
|
dataForm: {
|
||||||
|
image: '',
|
||||||
|
show_member: 0,
|
||||||
|
show_sign: 0,
|
||||||
|
show_task: 0,
|
||||||
|
show_integral: 0,
|
||||||
|
},
|
||||||
|
columns: [],
|
||||||
|
loading: false
|
||||||
|
};
|
||||||
|
},
|
||||||
|
onLoad(e) {
|
||||||
|
this.getStoreSetting()
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
async getStoreSetting() {
|
||||||
|
this.loading = true;
|
||||||
|
const res = await userMembers.SetList();
|
||||||
|
|
||||||
|
if (res.data.settings) {
|
||||||
|
this.dataForm = res.data.settings;
|
||||||
|
}
|
||||||
|
this.loading = false;
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 处理省市区选择变化
|
||||||
|
* @param {Object} value - 选择的值
|
||||||
|
*/
|
||||||
|
areaChange(value) {
|
||||||
|
// 处理省市区选择变化的逻辑
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 处理省市区选择
|
||||||
|
* @param {Object} detail - 选择器详细信息
|
||||||
|
*/
|
||||||
|
select({ detail }) {
|
||||||
|
if (detail.value.length) {
|
||||||
|
const [province_id, city_id, district_id] = detail.value.map(
|
||||||
|
(el) => el.value
|
||||||
|
);
|
||||||
|
|
||||||
|
this.dataForm.province_id = province_id;
|
||||||
|
this.dataForm.city_id = city_id;
|
||||||
|
this.dataForm.district_id = district_id;
|
||||||
|
this.dataForm.district = [province_id, city_id, district_id];
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 处理表单提交
|
||||||
|
*/
|
||||||
|
async handleSubmit() {
|
||||||
|
// 处理表单提交的逻辑
|
||||||
|
const res = await userMembers.SetSave({
|
||||||
|
...this.dataForm
|
||||||
|
});
|
||||||
|
|
||||||
|
if (res.code == 0) {
|
||||||
|
setTimeout(() => {
|
||||||
|
uni.showToast({
|
||||||
|
title: '保存成功!',
|
||||||
|
icon: 'success'
|
||||||
|
});
|
||||||
|
}, 100);
|
||||||
|
}
|
||||||
|
this.getStoreSetting()
|
||||||
|
},
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style>
|
||||||
|
/* 在这里添加样式,根据需要自定义表单样式 */
|
||||||
|
</style>
|
||||||
@ -0,0 +1,5 @@
|
|||||||
|
import type { ComponentPublicInstance } from 'vue'
|
||||||
|
|
||||||
|
export type CalendarViewInstance = ComponentPublicInstance<{
|
||||||
|
scrollIntoView: () => void
|
||||||
|
}>
|
||||||
@ -0,0 +1,18 @@
|
|||||||
|
/*
|
||||||
|
* @Author: weisheng
|
||||||
|
* @Date: 2023-12-14 11:21:58
|
||||||
|
* @LastEditTime: 2024-01-03 21:51:36
|
||||||
|
* @LastEditors: weisheng
|
||||||
|
* @Description:
|
||||||
|
* @FilePath: /wot-design-uni/src/uni_modules/wot-design-uni/components/wd-cell-group/types.ts
|
||||||
|
* 记得注释
|
||||||
|
*/
|
||||||
|
import { type InjectionKey } from 'vue'
|
||||||
|
|
||||||
|
export type CelllGroupProvide = {
|
||||||
|
props: {
|
||||||
|
border?: boolean
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export const CELL_GROUP_KEY: InjectionKey<CelllGroupProvide> = Symbol('wd-cell-group')
|
||||||
@ -0,0 +1,30 @@
|
|||||||
|
/*
|
||||||
|
* @Author: weisheng
|
||||||
|
* @Date: 2023-12-14 11:21:58
|
||||||
|
* @LastEditTime: 2024-01-03 22:47:50
|
||||||
|
* @LastEditors: weisheng
|
||||||
|
* @Description:
|
||||||
|
* @FilePath: /wot-design-uni/src/uni_modules/wot-design-uni/components/wd-checkbox-group/types.ts
|
||||||
|
* 记得注释
|
||||||
|
*/
|
||||||
|
import { type InjectionKey } from 'vue'
|
||||||
|
|
||||||
|
type checkShape = 'circle' | 'square' | 'button'
|
||||||
|
|
||||||
|
export type checkboxGroupProvide = {
|
||||||
|
props: {
|
||||||
|
modelValue: Array<string | number | boolean>
|
||||||
|
cell?: boolean
|
||||||
|
shape?: checkShape
|
||||||
|
checkedColor?: string
|
||||||
|
disabled?: boolean
|
||||||
|
min?: number
|
||||||
|
max?: number
|
||||||
|
inline?: boolean
|
||||||
|
size?: string
|
||||||
|
name?: string
|
||||||
|
}
|
||||||
|
changeSelectState: (value: string | number | boolean) => void
|
||||||
|
}
|
||||||
|
|
||||||
|
export const CHECKBOX_GROUP_KEY: InjectionKey<checkboxGroupProvide> = Symbol('wd-checkbox-group')
|
||||||
@ -1,7 +1,25 @@
|
|||||||
/**
|
import { type ComponentPublicInstance, type InjectionKey } from 'vue'
|
||||||
* 折叠面板子项
|
|
||||||
*/
|
export type CollapseToggleAllOptions =
|
||||||
export interface CollapseItem {
|
| boolean
|
||||||
name: string
|
| {
|
||||||
expanded: boolean
|
expanded?: boolean
|
||||||
|
skipDisabled?: boolean
|
||||||
|
}
|
||||||
|
|
||||||
|
export type CollapseInstance = ComponentPublicInstance<{
|
||||||
|
toggleAll: (options?: boolean | CollapseToggleAllOptions) => void
|
||||||
|
}>
|
||||||
|
|
||||||
|
export type CollapseProvide = {
|
||||||
|
props: {
|
||||||
|
modelValue: string | Array<string> | boolean
|
||||||
|
accordion?: boolean
|
||||||
|
viewmore?: boolean
|
||||||
|
useMoreSlot?: boolean
|
||||||
|
lineNum?: number
|
||||||
|
}
|
||||||
|
toggle: (name: string, expanded: boolean) => void
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export const COLLAPSE_KEY: InjectionKey<CollapseProvide> = Symbol('wd-collapse')
|
||||||
|
|||||||
@ -0,0 +1,17 @@
|
|||||||
|
import { type InjectionKey, type Ref } from 'vue'
|
||||||
|
|
||||||
|
type DropDirction = 'up' | 'down'
|
||||||
|
|
||||||
|
export type DropMenuProvide = {
|
||||||
|
props: {
|
||||||
|
zIndex?: number
|
||||||
|
direction?: DropDirction
|
||||||
|
modal?: boolean
|
||||||
|
closeOnClickModal?: boolean
|
||||||
|
duration?: number
|
||||||
|
}
|
||||||
|
fold: (child?: any) => void
|
||||||
|
offset: Ref<number>
|
||||||
|
}
|
||||||
|
|
||||||
|
export const DROP_MENU_KEY: InjectionKey<DropMenuProvide> = Symbol('wd-drop-menu')
|
||||||
@ -0,0 +1,16 @@
|
|||||||
|
/*
|
||||||
|
* @Author: weisheng
|
||||||
|
* @Date: 2023-12-14 11:21:58
|
||||||
|
* @LastEditTime: 2024-01-03 21:37:58
|
||||||
|
* @LastEditors: weisheng
|
||||||
|
* @Description:
|
||||||
|
* @FilePath: /wot-design-uni/src/uni_modules/wot-design-uni/components/wd-grid/types.ts
|
||||||
|
* 记得注释
|
||||||
|
*/
|
||||||
|
import { type InjectionKey } from 'vue'
|
||||||
|
|
||||||
|
export type GridProvide = {
|
||||||
|
props: { clickable?: boolean; square?: boolean; column?: number; border?: boolean; bgColor?: string; gutter?: number }
|
||||||
|
}
|
||||||
|
|
||||||
|
export const GRID_KEY: InjectionKey<GridProvide> = Symbol('wd-grid')
|
||||||
@ -0,0 +1,18 @@
|
|||||||
|
import { type InjectionKey } from 'vue'
|
||||||
|
|
||||||
|
type RadioShape = 'dot' | 'button' | 'check'
|
||||||
|
|
||||||
|
export type RadioGroupProvide = {
|
||||||
|
props: {
|
||||||
|
modelValue?: string | number | boolean
|
||||||
|
shape?: RadioShape
|
||||||
|
checkedColor?: string
|
||||||
|
disabled?: boolean
|
||||||
|
cell?: boolean
|
||||||
|
size?: string
|
||||||
|
inline?: boolean
|
||||||
|
}
|
||||||
|
updateValue: (value: string | number | boolean) => void
|
||||||
|
}
|
||||||
|
|
||||||
|
export const RADIO_GROUP_KEY: InjectionKey<RadioGroupProvide> = Symbol('wd-radio-group')
|
||||||
@ -0,0 +1,7 @@
|
|||||||
|
import { type InjectionKey } from 'vue'
|
||||||
|
|
||||||
|
export type RowProvide = {
|
||||||
|
props: { gutter?: number }
|
||||||
|
}
|
||||||
|
|
||||||
|
export const ROW_KEY: InjectionKey<RowProvide> = Symbol('wd-row')
|
||||||
@ -0,0 +1,19 @@
|
|||||||
|
/*
|
||||||
|
* @Author: weisheng
|
||||||
|
* @Date: 2024-01-05 18:03:27
|
||||||
|
* @LastEditTime: 2024-01-05 18:08:28
|
||||||
|
* @LastEditors: weisheng
|
||||||
|
* @Description:
|
||||||
|
* @FilePath: /wot-design-uni/src/uni_modules/wot-design-uni/components/wd-sidebar/types.ts
|
||||||
|
* 记得注释
|
||||||
|
*/
|
||||||
|
import { type InjectionKey } from 'vue'
|
||||||
|
|
||||||
|
export type SidebarProvide = {
|
||||||
|
props: {
|
||||||
|
modelValue?: number | string
|
||||||
|
}
|
||||||
|
setChange: (value: number | string, label: string) => void
|
||||||
|
}
|
||||||
|
|
||||||
|
export const SIDEBAR_KEY: InjectionKey<SidebarProvide> = Symbol('wd-sidebar')
|
||||||
@ -0,0 +1,7 @@
|
|||||||
|
import { type InjectionKey } from 'vue'
|
||||||
|
|
||||||
|
export type StepsProvide = {
|
||||||
|
props: { active?: number; vertical?: boolean; dot?: boolean; space?: string; alignCenter?: boolean }
|
||||||
|
}
|
||||||
|
|
||||||
|
export const STEPS_KEY: InjectionKey<StepsProvide> = Symbol('wd-steps')
|
||||||
@ -1,7 +1,16 @@
|
|||||||
|
/*
|
||||||
|
* @Author: weisheng
|
||||||
|
* @Date: 2024-01-01 20:00:29
|
||||||
|
* @LastEditTime: 2024-01-06 15:32:06
|
||||||
|
* @LastEditors: weisheng
|
||||||
|
* @Description:
|
||||||
|
* @FilePath: /wot-design-uni/src/uni_modules/wot-design-uni/components/wd-tabbar-item/types.ts
|
||||||
|
* 记得注释
|
||||||
|
*/
|
||||||
/**
|
/**
|
||||||
* 折叠面板子项
|
* 折叠面板子项
|
||||||
*/
|
*/
|
||||||
export interface TabbarItem {
|
export interface TabbarItem {
|
||||||
// 唯一标识
|
// 唯一标识
|
||||||
name: string
|
name: string | number
|
||||||
}
|
}
|
||||||
|
|||||||
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue