pull/1/head
张宇 2 years ago
parent 853daaf00a
commit 52e1ccdaf3

@ -18,6 +18,8 @@ export default {
@import "tailwindcss/utilities"; @import "tailwindcss/utilities";
page { page {
min-height: 100vh; // min-height: calc(100vh - 44px);
min-height: calc(100vh);
background-color: rgb(247 248 250);
} }
</style> </style>

@ -0,0 +1,31 @@
import {
request
} from "@/utils/request";
export default {
list(data) {
return request({
url: "/admin/goods/goodsList",
method: "POST",
data,
});
},
goodsEditAttribute(data) {
return request({
url: "/admin/goods/goodsEditAttribute",
method: "POST",
data,
});
},
classify: {
list(data) {
return request({
url: "/admin/classify/list",
method: "POST",
data,
});
},
}
};

File diff suppressed because it is too large Load Diff

@ -0,0 +1,90 @@
<template>
<view class="myTable">
<wd-toast />
<kevyloading v-if="loading" type="bsm-loader" color="#618af8" transparent></kevyloading>
<scroll-view scroll-y="true" class="scroll-Y" @scrolltolower="lower">
<slot :list="list"></slot>
</scroll-view>
</view>
</template>
<script setup>
import { ref } from 'vue'
import kevyloading from "@/components/kevy-loading/kevy-loading";
import { useToast } from '@/uni_modules/wot-design-uni'
const toast = useToast()
const props = defineProps({
apiObj: {
type: Function,
default: () => (() => { })
},
params: {
type: Object,
default: () => ({})
}
})
const query = ref({
page: 1,
pageSize: 20
})
const loading = ref(false)
const total = ref(0)
const list = ref([])
const getData = async () => {
console.log(getData);
loading.value = true
const res = await props.apiObj({
...query.value,
...props.params
})
if (res.data.rows.length) {
query.value.pageSize = res.data.pageSize
total.value = res.data.total
list.value = [...list.value, ...res.data.rows]
} else {
toast.success('全部加载完了')
}
loading.value = false
}
getData()
const upData = async (upParams = {}) => {
loading.value = true
query.value.page = 1
query.value.pageSize = 20
const res = await props.apiObj({
...query.value,
...props.params,
...upParams
})
query.value.pageSize = res.data.pageSize
total.value = res.data.total
list.value = res.data.rows
loading.value = false
}
const lower = e => {
query.value.page++
getData()
}
defineExpose({
upData
})
</script>
<style lang="scss">
.scroll-Y {
height: calc(100vh - 120px);
}
</style>

@ -1,26 +1,82 @@
<template> <template>
<view class="myTable"> <view class="myTable">
<wd-pagination v-model="value" :total="total" :page-size="page" @change="handleChange" show-icon show-message /> <kevyloading v-if="loading" type="bsm-loader" color="#618af8" transparent></kevyloading>
<wd-table :data="list" :border="true">
<slot></slot>
</wd-table>
<wd-pagination v-model="query.page" :total="total" :page-size="query.pageSize" @change="handleChange" show-icon
show-message />
</view> </view>
</template> </template>
<script setup> <script setup>
import { ref } from 'vue' import { ref } from 'vue'
import kevyloading from "@/components/kevy-loading/kevy-loading";
const props = defineProps({ const props = defineProps({
apiObj: { apiObj: {
type: Function, type: Function,
default: () => (() => { }) default: () => (() => { })
},
params: {
type: Object,
default: () => ({})
} }
}) })
const value = ref("") const query = ref({
page: 1,
pageSize: 20
})
const loading = ref(false)
const total = ref(0) const total = ref(0)
const page = ref(1) const list = ref([])
const getData = async () => {
loading.value = true
const res = await props.apiObj({
...query.value,
...props.params
})
query.value.pageSize = res.data.pageSize
total.value = res.data.total
list.value = res.data.rows
loading.value = false
}
getData()
function handleChange(e) { const upData = async (upParams = {}) => {
console.log(e); loading.value = true
query.value.page = 1
query.value.pageSize = 20
const res = await props.apiObj({
...query.value,
...props.params,
...upParams
})
query.value.pageSize = res.data.pageSize
total.value = res.data.total
list.value = res.data.rows
loading.value = false
}
function handleChange({ value }) {
query.value.page = value
getData()
} }
defineExpose({
upData
})
</script> </script>
<style lang="scss"></style> <style lang="scss"></style>

@ -60,6 +60,7 @@
"navigationBarTextStyle": "black", "navigationBarTextStyle": "black",
"navigationBarTitleText": "uni-app", "navigationBarTitleText": "uni-app",
"navigationBarBackgroundColor": "#F8F8F8", "navigationBarBackgroundColor": "#F8F8F8",
"navigationStyle": "custom",
"backgroundColor": "#F8F8F8" "backgroundColor": "#F8F8F8"
}, },
"uniIdRouter": {} "uniIdRouter": {}

@ -10,10 +10,18 @@
<script setup> <script setup>
import utils from '@/utils/utils.js' import utils from '@/utils/utils.js'
const user_info = uni.getStorageSync("user_info"); const token = uni.getStorageSync("token");
if (user_info.type == 1) {
utils.toUrl("/store/index/index") if (token) {
const user_info = uni.getStorageSync("user_info");
if (user_info.type == 1) {
utils.toUrl("/store/index/index")
}
} else {
utils.toUrl("/pages/login/index")
} }
</script> </script>
<style> <style>

@ -1,5 +1,5 @@
<template> <template>
<view class="content min-h-dvh flex items-center justify-center"> <view class="content min-h-dvh flex items-center justify-center px-4">
<wd-form class="mb-36" ref="form" :model="model"> <wd-form class="mb-36" ref="form" :model="model">
<wd-cell-group border> <wd-cell-group border>
<wd-input label="用户名" label-width="100px" prop="username" clearable v-model="model.username" placeholder="请输入用户名" <wd-input label="用户名" label-width="100px" prop="username" clearable v-model="model.username" placeholder="请输入用户名"
@ -8,7 +8,7 @@
placeholder="请输入密码" :rules="[{ required: true, message: '请填写密码' }]" /> placeholder="请输入密码" :rules="[{ required: true, message: '请填写密码' }]" />
</wd-cell-group> </wd-cell-group>
<view class="footer mt-4"> <view class="footer mt-4">
<wd-button type="primary" size="medium" @click="handleSubmit" block>登录</wd-button> <wd-button :loading="loading" type="primary" size="medium" @click="handleSubmit" block>登录</wd-button>
</view> </view>
</wd-form> </wd-form>
</view> </view>
@ -25,9 +25,10 @@ const model = ref({
password: "", password: "",
}) })
const loading = ref(false)
const form = ref(null) const form = ref(null)
function handleSubmit() { function handleSubmit() {
loading.value = true
form.value form.value
.validate() .validate()
.then(({ valid, errors }) => { .then(({ valid, errors }) => {
@ -46,18 +47,22 @@ function handleSubmit() {
title: "登录成功", title: "登录成功",
}); });
if (res.data.type == 1) { console.log(res.data.user_info);
if (res.data.user_info.type == 1) {
utils.toUrl("/store/index/index") utils.toUrl("/store/index/index")
} }
} }
loading.value = false
}) })
} }
}) })
.catch((error) => { .catch((error) => {
console.log(error, 'error') console.log(error, 'error')
loading.value = false
}) })
} }
</script> </script>

@ -0,0 +1,149 @@
<template>
<view class="content">
<wd-notify />
<wd-search @search="search" v-model="params.keywords" hide-cancel>
<template #prefix>
<wd-popover v-model="popover" mode="menu" :content="menu" @menuclick="changeSearchType">
<view class="search-type">
<text>{{ searchType }}</text>
<wd-icon custom-class="icon-arrow" name="fill-arrow-down"></wd-icon>
</view>
</wd-popover>
</template>
</wd-search>
<myTable ref="table" :apiObj="goods.list" :params="params">
<wd-table-col fixed prop="id" width="60" align="center" label="ID"></wd-table-col>
<wd-table-col prop="name" width="180" label="商品名称"></wd-table-col>
<wd-table-col prop="stock_num" align="center" width="80" label="库存">
<template #value="{ row }">
<view class="custom-class">
<wd-tag v-if="row.stock_num > 0" type="primary">{{ row.stock_num }}</wd-tag>
<wd-tag v-else type="warning">{{ row.stock_num }}</wd-tag>
</view>
</template>
</wd-table-col>
<wd-table-col prop="stock_num" align="center" width="80" label="状态">
<template #value="{ row }">
<view class="custom-class">
<wd-switch @change="changeS(row)" v-model="row.status" :inactive-value="0" :active-value="1" size="16px" />
</view>
</template>
</wd-table-col>
<wd-table-col width="120" align="center" label="操作">
<template #value="{ row }">
<view class="custom-class">
<wd-button :round="false" size="small">编辑</wd-button>
</view>
</template>
</wd-table-col>
</myTable>
</view>
</template>
<script setup>
import { ref } from 'vue'
import myTable from "/components/myTable/index.vue"
import goods from '@/api/store/goods.js'
import utils from '@/utils/utils.js'
import { useNotify } from '@/uni_modules/wot-design-uni'
const { showNotify, closeNotify } = useNotify()
const params = {
keywords: "",
calssify_id: "",
status: "",
}
const searchType = ref('全部')
const popover = ref(false)
const menu = ref([
{
content: '全部'
},
{
content: '已上架'
},
{
content: '已下架'
}
])
const table = ref(null)
const search = ({ value }) => {
table.value.upData({
keywords: value
})
}
function changeSearchType({ item, index }) {
searchType.value = item.content
if (item.content == '全部') {
params.status = ""
}
if (item.content == '已上架') {
params.status = 1
}
if (item.content == '已下架') {
params.status = 0
}
search({
value: ""
})
}
const changeS = (row) => {
goods.goodsEditAttribute({
id: row.id,
value: [1, 0][row.status],
type: "status"
}).then(res => {
if (res.code == 0) {
showNotify({ type: 'primary', message: '操作成功' })
} else {
showNotify({ type: 'error', message: '出错了' })
}
})
}
</script>
<style lang="scss" scoped>
.search-type {
position: relative;
height: 30px;
line-height: 30px;
padding: 0 8px 0 16px;
font-size: 24rpx;
color: rgba(0, 0, 0, .45);
}
.search-type::after {
position: absolute;
content: '';
width: 1px;
right: 0;
top: 5px;
bottom: 5px;
background: rgba(0, 0, 0, 0.25);
}
.search-type {
:deep(.icon-arrow) {
display: inline-block;
font-size: 20px;
vertical-align: middle;
}
}
</style>

@ -1,11 +1,208 @@
<template> <template>
<view class="content p-4"> <view class="content">
<view class=" bg-white sticky top-0 z-50">
<wd-search @search="search" v-model="params.keywords" hide-cancel>
<template #prefix>
<wd-popover v-model="popover" mode="menu" :content="menu" @menuclick="changeSearchType">
<view class="search-type">
<text>{{ searchType }}</text>
<wd-icon custom-class="icon-arrow" name="fill-arrow-down"></wd-icon>
</view>
</wd-popover>
</template>
</wd-search>
<wd-drop-menu custom-class="flex w-full bg-white" v-show="classifyList.length">
<wd-drop-menu-item custom-class="flex-1" v-model="value2" :options="classifyList" label-key="name"
value-key="id" />
</wd-drop-menu>
</view>
<div class="goodsBox p-2">
<myList ref="myListRef" :apiObj="goods.list" :params="params">
<template #default="{ list }">
<div>
<div v-for="item of list" class="goods">
<wd-card type="rectangle">
<template #title>
<view class="title">
<view>库存<span class="font-bold">{{ item.stock_num }}</span></view>
<view v-if="!(item.stock_num > 0)" class="title-tip">
<wd-icon name="warning" size="14px" custom-style="vertical-align: bottom" />
商品库存不足
</view>
</view>
</template>
<view style="height: 60px;" class="content">
<image :src="item.pic_url" width="40" height="40" alt="joy"
style="border-radius: 4px; margin-right: 12px;width: 60px;height: 60px;min-width: 60px;" />
<view>
<view style="color: rgba(0,0,0,0.85); font-size: 16px;">{{ item.name }}</view>
<view class="font-bold" style="color: rgb(255, 0, 0); font-size: 16px;">{{ item.price_min }}</view>
</view>
</view>
<template #footer>
<view>
<wd-button @click="changeS(item)" v-if="item.status == 1" size="small" plain
style="margin-right: 8px;">下架</wd-button>
<wd-button @click="changeS(item)" v-if="item.status !== 1" size="small"
style="margin-right: 8px;">上架</wd-button>
<wd-button size="small">编辑</wd-button>
</view>
</template>
</wd-card>
</div>
</div>
</template>
</myList>
</div>
<wd-toast />
</view> </view>
</template> </template>
<script setup> <script setup>
import utils from '@/utils/utils.js' import { ref } from 'vue'
import goods from '@/api/store/goods.js'
import myList from "/components/myList/index.vue"
import { useToast } from '@/uni_modules/wot-design-uni'
const toast = useToast()
const option2 = ref([
{ label: '综合', value: 0 },
{ label: '销量', value: 1 },
{ label: '上架时间', value: 2 }
])
const value2 = ref(0)
// const tab = ref(0)
const params = {
keywords: "",
calssify_id: 0,
status: "",
}
const myListRef = ref(null)
const search = ({ value }) => {
myListRef.value.upData({
keywords: value
})
}
const searchType = ref('全部')
const popover = ref(false)
const menu = ref([
{
content: '全部'
},
{
content: '已上架'
},
{
content: '已下架'
}
])
function changeSearchType({ item, index }) {
searchType.value = item.content
if (item.content == '全部') {
params.status = ""
}
if (item.content == '已上架') {
params.status = 1
}
if (item.content == '已下架') {
params.status = 0
}
search({
value: ""
})
}
const changeS = (row) => {
goods.goodsEditAttribute({
id: row.id,
value: [1, 0][row.status],
type: "status"
}).then(res => {
if (res.code == 0) {
toast.success('操作成功')
row.status = [1, 0][row.status]
} else {
showNotify({ type: 'error', message: '出错了' })
}
})
}
const classifyList = ref([])
const getClassify = () => {
goods.classify.list().then(res => {
classifyList.value = res.data
classifyList.value.unshift({
id: 0,
name: "店铺分类"
})
})
}
getClassify()
</script> </script>
<style></style> <style lang="scss" scoped>
.search-type {
position: relative;
height: 30px;
line-height: 30px;
padding: 0 8px 0 16px;
font-size: 24rpx;
color: rgba(0, 0, 0, .45);
}
.search-type::after {
position: absolute;
content: '';
width: 1px;
right: 0;
top: 5px;
bottom: 5px;
background: rgba(0, 0, 0, 0.25);
}
.search-type {
:deep(.icon-arrow) {
display: inline-block;
font-size: 20px;
vertical-align: middle;
}
}
.goodsBox {
.content,
.title {
display: flex;
flex-direction: row;
justify-content: flex-start;
align-items: center;
}
.content {
justify-content: flex-start;
}
.title {
justify-content: space-between;
}
.title-tip {
color: rgba(0, 0, 0, 0.25);
font-size: 12px;
}
}
</style>

@ -1,11 +1,11 @@
<template> <template>
<view class="content p-4"> <view class="content p-4">
<view class="w-full grid grid-cols-2 gap-4"> <view class="w-full grid grid-cols-2 gap-4">
<view @click="utils.toUrl('/store/order/index')" <!-- <view @click="utils.toUrl('/store/order/index')"
class="text-white bg-gradient-to-r from-orange-200 to-orange-400 shadow rounded-md p-4"> class="text-white bg-gradient-to-r from-orange-200 to-orange-400 shadow rounded-md p-4">
<wd-icon name="circle1" size="24px"></wd-icon> <wd-icon name="circle1" size="24px"></wd-icon>
<view class="mt-2 text-end font-bold ">订单中心</view> <view class="mt-2 text-end font-bold ">订单中心</view>
</view> </view> -->
<view @click="utils.toUrl('/store/goods/index')" <view @click="utils.toUrl('/store/goods/index')"
class="text-white bg-gradient-to-r from-orange-200 to-orange-400 shadow rounded-md p-4"> class="text-white bg-gradient-to-r from-orange-200 to-orange-400 shadow rounded-md p-4">
<wd-icon name="goods" size="24px"></wd-icon> <wd-icon name="goods" size="24px"></wd-icon>

@ -1,11 +1,11 @@
<template> <template>
<view class="content p-4"> <view class="content p-4">
<!-- <myTable></myTable> -->
</view> </view>
</template> </template>
<script setup> <script setup>
import utils from '@/utils/utils.js' import myTable from "/components/myTable/index.vue"
</script> </script>
<style></style> <style></style>

Loading…
Cancel
Save