Compare commits

..

No commits in common. 'main' and 'zhangyu' have entirely different histories.

@ -1,126 +1,91 @@
import { import {
request request
} from "@/utils/request"; } from "@/utils/request";
export default { export default {
SalesDiscounts: { SalesDiscounts: {
List(data) { List(data) {
return request({ return request({
url: "/shop/SalesDiscounts/List", url: "/shop/SalesDiscounts/List",
method: "GET", method: "GET",
data, data,
type: 'mall' type: 'mall'
}); });
}, },
GetItem(data) { GetItem(data) {
return request({ return request({
url: "/shop/SalesDiscounts/GetItem", url: "/shop/SalesDiscounts/GetItem",
method: "GET", method: "GET",
data, data,
type: 'mall' type: 'mall'
}); });
}, },
Create(data) { Create(data) {
return request({ return request({
url: "/shop/SalesDiscounts/Create", url: "/shop/SalesDiscounts/Create",
method: "POST", method: "POST",
data, data,
type: 'mall' type: 'mall'
}); });
}, },
}, },
SalesFullDiscounts: { SalesFullDiscounts: {
List(data) { List(data) {
return request({ return request({
url: "/shop/SalesFullDiscounts/List", url: "/shop/SalesFullDiscounts/List",
method: "GET", method: "GET",
data, data,
type: 'mall' type: 'mall'
}); });
}, },
GetItem(data) { GetItem(data) {
return request({ return request({
url: "/shop/SalesFullDiscounts/GetItem", url: "/shop/SalesFullDiscounts/GetItem",
method: "GET", method: "GET",
data, data,
type: 'mall' type: 'mall'
}); });
}, },
Create(data) { Create(data) {
return request({ return request({
url: "/shop/SalesFullDiscounts/Create", url: "/shop/SalesFullDiscounts/Create",
method: "POST", method: "POST",
data, data,
type: 'mall' type: 'mall'
}); });
}, },
}, },
SalesFullSetRedution: { SalesFullSetRedution: {
List(data) { List(data) {
return request({ return request({
url: "/shop/SalesFullSetRedution/List", url: "/shop/SalesFullSetRedution/List",
method: "GET", method: "GET",
data, data,
type: 'mall' type: 'mall'
}); });
}, },
GetItem(data) { GetItem(data) {
return request({ return request({
url: "/shop/SalesFullSetRedution/GetItem", url: "/shop/SalesFullSetRedution/GetItem",
method: "GET", method: "GET",
data, data,
type: 'mall' type: 'mall'
}); });
}, },
Create(data) { Create(data) {
return request({ return request({
url: "/shop/SalesFullSetRedution/Create", url: "/shop/SalesFullSetRedution/Create",
method: "POST", method: "POST",
data, data,
type: 'mall' type: 'mall'
}); });
}, },
}, }
caiwu: {
List(data) {
return request({
url: "/shop/shop/shareList",
method: "GET",
data,
type: 'mall'
});
},
cashList(data) {
return request({
url: "/shop/shop/cashList",
method: "GET",
data,
type: 'mall'
});
},
shopData(data) {
return request({
url: "/shop/shop/getData",
method: "GET",
data,
type: 'mall'
});
},
cashSubmit(data) {
return request({
url: "/shop/shop/cashSubmit",
method: "POST",
data,
type: 'mall'
});
},
}
}; };

@ -11,11 +11,4 @@ export default {
data, data,
}); });
}, },
captch(data) {
return request({
url: "/admin/auth/captch",
method: "POST",
data,
});
},
}; };

@ -1,46 +0,0 @@
import {
request
} from "@/utils/request";
export default {
content(data) {
return request({
url: "/admin/faceRecon/content",
method: "GET",
data,
type: 'store'
})
},
faceList(data) {
return request({
url: "/admin/OrderInpersonPayment/faceListH5",
method: "GET",
data,
type: 'store'
})
},
tuikuan(data) {
return request({
url: "/admin/faceRecon/tuikuan",
method: "POST",
data,
type: 'store'
})
},
shopList(data) {
return request({
url: "/admin/faceRecon/shopList",
method: "POST",
data,
type: 'store'
})
},
faceOrder(data) {
return request({
url: "/admin/faceRecon/faceOrder",
method: "POST",
data,
type: 'store'
})
},
};

@ -3,19 +3,15 @@
<view v-if="props.modelValue && props.modelValue.length" @click="open(true)" class="flex gap-2 overflow-x-auto"> <view v-if="props.modelValue && props.modelValue.length" @click="open(true)" class="flex gap-2 overflow-x-auto">
<view class=" border-gray-100 border-solid flex rounded-[14px] relative" <view class=" border-gray-100 border-solid flex rounded-[14px] relative"
v-for="img of (Array.isArray(props.modelValue) ? props.modelValue : [props.modelValue])" :key="img"> v-for="img of (Array.isArray(props.modelValue) ? props.modelValue : [props.modelValue])" :key="img">
<wd-img mode="aspectFill" radius="10" :width="width" :height="height" :src="img" /> <wd-img mode="aspectFill" radius="10" :width="100" :height="100" :src="img" />
</view> </view>
</view> </view>
<view v-else @click="open(true)" class="flex gap-2 overflow-x-auto"> <view v-else @click="open(true)" class="flex gap-2 overflow-x-auto">
<view <view style="width: 100px;height: 100px;"
:style="{
width: width + 'px',
height: height + 'px',
}"
class=" border-gray-100 border-solid flex rounded-[14px] relative flex-col items-center justify-center"> class=" border-gray-100 border-solid flex rounded-[14px] relative flex-col items-center justify-center">
<wd-icon name="image" size="28px"></wd-icon> <wd-icon name="image" size="28px"></wd-icon>
<view class="mt-2 font-bold text-[12px]" v-if="height > 70"></view> <view class="mt-2 font-bold text-[12px]">请选择</view>
</view> </view>
</view> </view>
@ -130,14 +126,6 @@ const props = defineProps({
type: Number, type: Number,
default: 1 default: 1
}, },
width: {
type: Number,
default: 100
},
height: {
type: Number,
default: 100
},
}) })
const LArr = ref([]) const LArr = ref([])

@ -1,146 +0,0 @@
<template>
<view>
<kevyloading v-if="loading" type="bsm-loader" color="#618af8" transparent></kevyloading>
<wd-form v-if="!loading" :model="form" :rules="rules" :disabled="mode == 'show'" ref="dialogForm"
label-width="100px">
<wd-form-item label="收款人" prop="user_name">
<wd-input placeholder="请输入收款人" v-model="dataForm.user_name" clearable
style="width: 100%"></wd-input>
</wd-form-item>
<wd-form-item label="联系电话" prop="user_mobile">
<wd-input placeholder="请输入联系电话" v-model="dataForm.user_mobile" clearable style="width: 100%"></wd-input>
</wd-form-item>
<wd-form-item label="提现金额" prop="user_name">
<wd-input type="number" placeholder="请输入提现金额" step="0.01" v-model.number="dataForm.cash_price" clearable
style="width: 100%"></wd-input>
</wd-form-item>
<wd-form-item label="提现类型" prop="user_name">
<wd-radio-group v-model="dataForm.type" :inline="true" shape='dot'>
<wd-radio :value="0">银行卡</wd-radio>
<wd-radio :value="1">微信</wd-radio>
<wd-radio :value="2">支付宝</wd-radio>
</wd-radio-group>
</wd-form-item>
<template v-if="dataForm.type == 0">
<wd-form-item label="开户行" prop="bank_name">
<wd-input placeholder="请输入开户行" v-model="dataForm.bank_name" clearable style="width: 100%"></wd-input>
</wd-form-item>
<wd-form-item label="银行卡号" prop="bank_code">
<wd-input placeholder="请输入银行卡号" v-model="dataForm.bank_code" clearable style="width: 100%"></wd-input>
</wd-form-item>
</template>
<template v-if="dataForm.type == 1">
<wd-form-item label="微信收款码" prop="wx_payee_pic">
<yUpload v-model="dataForm.wx_payee_pic" :size="1"></yUpload>
</wd-form-item>
</template>
<template v-if="dataForm.type == 2">
<wd-form-item label="支付宝账号" prop="ali_code">
<wd-input placeholder="请输入账号" v-model="dataForm.ali_code" clearable style="width: 100%"></wd-input>
</wd-form-item>
</template>
<!-- 提交按钮 -->
<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 yGoods from "@/components/yGoods/index.vue";
import uniDataPicker from "@/components/uni-data-picker/components/uni-data-picker/uni-data-picker.vue";
import kevyloading from "@/components/kevy-loading/kevy-loading";
import utils from '@/utils/utils.js'
import {
useApi
} from "@/hooks/useApi.js"
import discountApi from '@/api/mall/discount.js';
import yUpload from "@/components/yUpload/index.vue";
console.log(yGoods);
/**
* 从本地存储中获取用户信息
*/
const user_info = uni.getStorageSync("user_info");
export default {
components: {
yGoods,
uniDataPicker,
kevyloading,
yUpload
},
data() {
return {
utils,
user_info,
//
dataForm: {
type: 0,
ali_code: "",
bank_code: "",
bank_name: "",
user_mobile: "",
user_name: "",
wx_payee_pic: "",
cash_price: ''
},
columns: [],
loading: false
};
},
onLoad(e) {
this.getData()
},
methods: {
async getData() {
const res = await discountApi.caiwu.shopData()
console.log(res, 'res')
this.dataForm = res.data.default_cash ? res.data.default_cash : {}
},
/**
* 处理表单提交
*/
async handleSubmit() {
uni.showLoading({
title: '提交中'
})
//
const res = await discountApi.caiwu.cashSubmit({
...this.dataForm,
});
uni.hideLoading()
uni.showToast({
title: res.msg,
icon: 'none'
});
if (res.code == 0) {
setTimeout(() => {
uni.navigateBack()
}, 1500);
}
},
},
};
</script>
<style>
/* 在这里添加样式,根据需要自定义表单样式 */
</style>

@ -1,165 +0,0 @@
<template>
<view class="content">
<kevyloading v-if="loading" type="bsm-loader" color="#618af8" transparent></kevyloading>
<view class=" bg-white sticky top-0 z-50 flex items-center" style="height: 9vh;display: flex;justify-content: center;">
<view class="mr-2">
<wd-button @click="utils.toUrl('/mall/caiwu/cash/edit')" size="small">提现</wd-button>
</view>
</view>
<view class="grid p-2">
<yList height="91vh" ref="yListRef" :apiObj="fullDiscountApi.caiwu.cashList" :params="{ ...params }">
<template #default="{ list }">
<view>
<view v-for="item of list" class="goods">
<wd-card type="rectangle">
<template #title>
<view class="title">
<view>
<span class="mr-2">ID{{ item?.id }}</span>
</view>
<view style="display: flex;align-items: center;">
{{ item.create_time }}
<view class="p-2 mb-2 flex justify-between" style="font-size: 22rpx;">
<view>
<wd-button :round="false" size="small"
:type="['warning', 'success', 'warning', 'info', 'info'][item.status]">
<div>{{ ["待审核", "待打款", "已打款", "已拒绝"][item.status] }}</div>
</wd-button>
</view>
</view>
</view>
</view>
</template>
<view class="bg-gray-50 p-2 mb-2 flex justify-between" style="font-size: 22rpx;">
<view>
<template v-if="item.type == 0">
<div>开户行{{ item.bank_name }}</div>
<div>银行卡号{{ item.bank_code }}</div>
</template>
<template v-if="item.type == 1">
<div>
<img :src="item.wx_payee_pic" style="width: 30px;" alt="">
</div>
</template>
<template v-if="item.type == 2">
<div>{{ item.ali_code }}</div>
</template>
</view>
<view style="font-weight: bold;font-size: 32rpx;color: #19be6b;">
{{ item.cash_price }}
</view>
</view>
<view v-if="item.auditing_desc" class="bg-gray-50 p-2 mb-2 flex justify-between" style="font-size: 22rpx;">
<view>
<span class="mr-2 warn-state warn-status-processing bg-yellow-600"></span>
审核备注{{ item.auditing_desc }}
</view>
</view>
</wd-card>
</view>
</view>
</template>
</yList>
</view>
<wd-toast />
<wd-message-box></wd-message-box>
</view>
</template>
<script setup>
import {
ref,
nextTick
} from 'vue';
import utils from '@/utils/utils.js';
import fullDiscountApi from '@/api/mall/discount.js';
import kevyloading from "@/components/kevy-loading/kevy-loading";
import yList from "/components/yList/index.vue";
import {
onShow,
} from "@dcloudio/uni-app";
const yListRef = ref(null);
const popover = ref(false);
const params = ref({
name: null,
price: null,
send_type: null
});
/**
* @type {Ref<boolean>}
* 控制页面加载状态的 Ref
*/
const loading = ref(false);
//
onShow(() => {
})
</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;
}
}
.couponBox,
.title {
display: flex;
flex-direction: row;
justify-content: flex-start;
align-items: center;
}
.couponBox {
justify-content: flex-start;
}
.title {
justify-content: space-between;
}
.title-tip {
color: rgba(0, 0, 0, 0.25);
font-size: 12px;
}
</style>

@ -1,146 +0,0 @@
<template>
<view class="content">
<kevyloading v-if="loading" type="bsm-loader" color="#618af8" transparent></kevyloading>
<view class=" bg-white sticky top-0 z-50 flex items-center" style="height: 9vh;display: flex;justify-content: flex-end;">
<view style="text-align: center;width: 100%;color: red;font-weight: bold;">
余额{{ shop_info ? shop_info.money : '0.00' }}
</view>
</view>
<view class="grid p-2">
<yList height="91vh" ref="yListRef" :apiObj="fullDiscountApi.caiwu.List" :params="{ ...params }">
<template #default="{ list }">
<view>
<view v-for="item of list" class="goods">
<wd-card type="rectangle">
<template #title>
<view class="title">
<view>
<span class="mr-2">ID{{ item?.id }}</span>
</view>
<view>
{{ item.create_time }}
</view>
</view>
</template>
<view class="bg-gray-50 p-2 mb-2 flex justify-between" style="font-size: 22rpx;">
<view>
{{ item.desc_info }}
</view>
<view style="font-weight: bold;font-size: 32rpx;" :style="{
color: item.type == 1 ? '#19be6b' : '#fa3534'
}">
{{ item.type == 1 ? '+' : '-' }} {{ item.money }}
</view>
</view>
</wd-card>
</view>
</view>
</template>
</yList>
</view>
<wd-toast />
<wd-message-box></wd-message-box>
</view>
</template>
<script setup>
import {
ref,
nextTick
} from 'vue';
import utils from '@/utils/utils.js';
import fullDiscountApi from '@/api/mall/discount.js';
import kevyloading from "@/components/kevy-loading/kevy-loading";
import yList from "/components/yList/index.vue";
import {
onShow,
} from "@dcloudio/uni-app";
const yListRef = ref(null);
const popover = ref(false);
const params = ref({
name: null,
price: null,
send_type: null
});
const shop_info = ref(null);
/**
* @type {Ref<boolean>}
* 控制页面加载状态的 Ref
*/
const loading = ref(false);
const getData = async () => {
const res = await fullDiscountApi.caiwu.shopData()
console.log(res, 'res')
shop_info.value = res.data.shop_info ? res.data.shop_info : null
}
//
onShow(() => {
getData()
})
</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;
}
}
.couponBox,
.title {
display: flex;
flex-direction: row;
justify-content: flex-start;
align-items: center;
}
.couponBox {
justify-content: flex-start;
}
.title {
justify-content: space-between;
}
.title-tip {
color: rgba(0, 0, 0, 0.25);
font-size: 12px;
}
</style>

@ -1,90 +1,88 @@
<template> <template>
<view class="charts-box bg-white content p-2"> <view class="charts-box bg-white content p-2">
<view v-if="parent.id" class="p-4 mb-2 bg-slate-50"> <view v-if="parent.id" class="p-4 mb-2 bg-slate-50">
上级分类 ({{ parent.name }}) 上级分类 ({{ parent.name }})
</view> </view>
<wd-form ref="form" :model="baseForm"> <wd-form ref="form" :model="baseForm">
<wd-cell-group class="flex py-2 w-full" title="分类图片"> <wd-cell-group class="flex py-2 w-full" title="分类图片">
<view class="ml-3"> <view class="ml-3">
<yUpload v-model="baseForm.pic_url" :size="1"></yUpload> <yUpload v-model="baseForm.pic_url" :size="1"></yUpload>
</view> </view>
</wd-cell-group> </wd-cell-group>
<wd-form-item label-width="76px" label="分类名称" prop="address"> <wd-form-item label-width="76px" label="分类名称" prop="address">
<wd-input v-model="baseForm.name" placeholder="请输入分类名称" clearable /> <wd-input v-model="baseForm.name" placeholder="请输入分类名称" clearable />
</wd-form-item> </wd-form-item>
<wd-form-item label-width="80px" label="分类排序" prop="address"> <wd-form-item label-width="80px" label="分类排序" prop="address">
<view class="ml-3 flex"> <view class="ml-3 flex">
<wd-input-number v-model="baseForm.sort" /> <wd-input-number v-model="baseForm.sort" />
</view> </view>
</wd-form-item> </wd-form-item>
<wd-form-item label-width="80px" label="状态" prop="address"> <wd-form-item label-width="80px" label="状态" prop="address">
<view class="ml-3 flex"> <view class="ml-3 flex">
<wd-switch v-model="baseForm.status" :active-value="1" :inactive-value="0" /> <wd-switch v-model="baseForm.status" :active-value="1" :inactive-value="0" />
</view> </view>
</wd-form-item> </wd-form-item>
<view class="footer m-4"> <view class="footer m-4">
<wd-button @click="saveCat" type="primary" size="large" block>保存</wd-button> <wd-button @click="saveCat" type="primary" size="large" block>保存</wd-button>
</view> </view>
</wd-form> </wd-form>
</view> </view>
</template> </template>
<script setup> <script setup>
import { import { ref } from 'vue'
ref import goods from '@/api/mall/goods.js'
} from 'vue' import yUpload from "@/components/yUpload/index.vue"
import goods from '@/api/mall/goods.js' import {
import yUpload from "@/components/yUpload/index.vue" onLoad,
import { } from "@dcloudio/uni-app";
onLoad,
} from "@dcloudio/uni-app"; const parent = ref({})
const model = ref({})
const parent = ref({}) const baseForm = ref({})
const model = ref({})
const baseForm = ref({}) onLoad(async (e) => {
onLoad(async (e) => { if (e.parent) {
parent.value = JSON.parse(e.parent)
if (e.parent) { }
parent.value = JSON.parse(e.parent)
} if (e.edit) {
baseForm.value = JSON.parse(e.edit)
if (e.edit) { }
baseForm.value = JSON.parse(e.edit)
} })
}) const saveCat = () => {
const saveCat = () => { goods.classify.createItem({
parent_id: parent.value.id || baseForm.value.id || 0,
goods.classify.createItem({ ...baseForm.value
parent_id: parent.value.id || baseForm.value.id || 0, }).then(res => {
...baseForm.value if (res.code == 0) {
}).then(res => { uni.showToast({
if (res.code == 0) { title: '操作成功!',
uni.showToast({ icon: 'success'
title: '操作成功!', })
icon: 'success'
}) uni.navigateBack()
}
uni.navigateBack() })
}
}) }
}
</script> </script>
<style scoped> <style scoped>
/* 请根据实际需求修改父元素尺寸,组件自动识别宽高 */ /* 请根据实际需求修改父元素尺寸,组件自动识别宽高 */
.charts-box { .charts-box {
width: 100%; width: 100%;
height: 300px; height: 300px;
} }
</style> </style>

@ -1,19 +1,16 @@
<template> <template>
<view class="charts-box bg-white content"> <view class="charts-box bg-white content">
<view v-show="true" class="flex overflow-auto flex-wrap"> <view v-show="classifyList.length" class="flex overflow-auto flex-wrap">
<div class="grid grid-cols-3 gap-4 p-4 w-full"> <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%;" <wd-button @click="utils.toUrl('/mall/cat/edit?edit=' + JSON.stringify({}))" style="width: 100%;"
class="bg-[#f0f0f0] w-full flex-1" :round="false"> class="bg-[#f0f0f0] w-full flex-1" :round="false">
新增 新增
</wd-button> </wd-button>
<template v-if="classifyList.length"> <wd-button @click="showActions(cat)" style="width: 100%;" v-for="cat of classifyList"
<wd-button @click="showActions(cat)" style="width: 100%;" v-for="cat of classifyList" class="bg-[#f0f0f0] w-full flex-1" type="info" :round="false">
class="bg-[#f0f0f0] w-full flex-1" type="info" :round="false"> {{ cat.name }}
{{ cat.name }} </wd-button>
</wd-button>
</template>
</div> </div>
</view> </view>

@ -133,4 +133,4 @@ export default {
<style> <style>
/* 在这里添加样式,根据需要自定义表单样式 */ /* 在这里添加样式,根据需要自定义表单样式 */
</style> </style>

@ -2,141 +2,109 @@
<view class="content pt-2"> <view class="content pt-2">
<kevyloading v-if="loading" type="bsm-loader" color="#618af8" transparent></kevyloading> <kevyloading v-if="loading" type="bsm-loader" color="#618af8" transparent></kevyloading>
<wd-transition :duration="320" :show="true" name="zoom-in"> <view class="px-2 my-1">
<view class="px-2 my-1"> <div class="relative flex flex-col rounded-xl bg-white p-4 shadow-sm">
<div class="relative flex flex-col rounded-xl bg-white p-4 shadow-sm">
<div class="mb-2 pointer-events-auto relative inline-flex bg-white font-medium ">
<div class="mb-2 pointer-events-auto relative inline-flex bg-white font-medium "> <div class="flex items-baseline text-xs px-2">
<div class="flex items-baseline text-xs px-2"> <span class="mr-2 warn-state warn-status-processing bg-emerald-400"></span>
<span class="mr-2 warn-state warn-status-processing bg-emerald-400"></span> 基础功能
基础功能 </div>
</div> </div>
<view class="grid grid-cols-3 gap-3">
<div @click="utils.toUrl('/mall/cat/index')"
class="item border-2 border-solid border-gray-100 rounded bg-slate-50 p-2 flex justify-between"
style="font-size: 0.75rem;">
商品分类
</div> </div>
<view class="grid grid-cols-3 gap-3"> <div @click="utils.toUrl('/mall/goods/index')"
class="item border-2 border-solid border-gray-100 rounded bg-slate-50 p-2 flex justify-between"
style="font-size: 0.75rem;">
商品管理
</div>
<div @click="utils.toUrl('/mall/cat/index')" </view>
class="item border-2 border-solid border-gray-100 rounded bg-slate-50 p-2 flex justify-between"
style="font-size: 0.75rem;">
商品分类
</div>
<div @click="utils.toUrl('/mall/goods/index')" </div>
class="item border-2 border-solid border-gray-100 rounded bg-slate-50 p-2 flex justify-between" </view>
style="font-size: 0.75rem;">
商品管理
</div>
</view> <view class="px-2 my-1">
<div class="relative flex flex-col rounded-xl bg-white p-4 shadow-sm">
<div class="mb-2 pointer-events-auto relative inline-flex bg-white font-medium ">
<div class="flex items-baseline text-xs px-2">
<span class="mr-2 warn-state warn-status-processing bg-yellow-600"></span>
订单管理
</div>
</div> </div>
</view>
</wd-transition> <view class="grid grid-cols-3 gap-3">
<div @click="utils.toUrl('/mall/order/index')"
<wd-transition :duration="340" :show="true" name="zoom-in"> class="item border-2 border-solid border-gray-100 rounded bg-slate-50 p-2 flex justify-between"
<view class="px-2 my-1"> style="font-size: 0.75rem;">
<div class="relative flex flex-col rounded-xl bg-white p-4 shadow-sm"> 普通订单
<div class="mb-2 pointer-events-auto relative inline-flex bg-white font-medium ">
<div class="flex items-baseline text-xs px-2">
<span class="mr-2 warn-state warn-status-processing bg-yellow-600"></span>
订单管理
</div>
</div> </div>
<view class="grid grid-cols-3 gap-3"> <div @click="utils.toUrl('/mall/pickUp/index')"
<div @click="utils.toUrl('/mall/order/index')" class="item border-2 border-solid border-gray-100 rounded bg-slate-50 p-2 flex justify-between"
class="item border-2 border-solid border-gray-100 rounded bg-slate-50 p-2 flex justify-between" style="font-size: 0.75rem;">
style="font-size: 0.75rem;"> 自提订单
普通订单 </div>
</div>
<div @click="utils.toUrl('/mall/inpersonPay/index')"
class="item border-2 border-solid border-gray-100 rounded bg-slate-50 p-2 flex justify-between"
style="font-size: 0.75rem;">
当面付订单
</div>
</view>
<div @click="utils.toUrl('/mall/pickUp/index')"
class="item border-2 border-solid border-gray-100 rounded bg-slate-50 p-2 flex justify-between"
style="font-size: 0.75rem;">
自提订单
</div>
<div @click="utils.toUrl('/mall/inpersonPay/index')" </div>
class="item border-2 border-solid border-gray-100 rounded bg-slate-50 p-2 flex justify-between" </view>
style="font-size: 0.75rem;">
当面付订单
</div>
</view>
<view class="px-2 my-1">
<div class="relative flex flex-col rounded-xl bg-white p-4 shadow-sm">
<div class="mb-2 pointer-events-auto relative inline-flex bg-white font-medium ">
<div class="flex items-baseline text-xs px-2">
<span class="mr-2 warn-state warn-status-processing bg-stone-800"></span>
折扣管理
</div>
</div> </div>
</view>
</wd-transition> <view class="grid grid-cols-3 gap-3">
<div @click="utils.toUrl('/mall/discount/discount/index')"
<wd-transition :duration="360" :show="true" name="zoom-in"> class="item border-2 border-solid border-gray-100 rounded bg-slate-50 p-2 flex justify-between"
<view class="px-2 my-1"> style="font-size: 0.75rem;">
<div class="relative flex flex-col rounded-xl bg-white p-4 shadow-sm"> 限时折扣
</div>
<div class="mb-2 pointer-events-auto relative inline-flex bg-white font-medium ">
<div class="flex items-baseline text-xs px-2"> <div @click="utils.toUrl('/mall/discount/full_discount/index')"
<span class="mr-2 warn-state warn-status-processing bg-stone-800"></span> class="item border-2 border-solid border-gray-100 rounded bg-slate-50 p-2 flex justify-between"
折扣管理 style="font-size: 0.75rem;">
</div> 梯度折扣
</div> </div>
<view class="grid grid-cols-3 gap-3"> <div @click="utils.toUrl('/mall/discount/full_set_redution/index')"
<div @click="utils.toUrl('/mall/discount/discount/index')" class="item border-2 border-solid border-gray-100 rounded bg-slate-50 p-2 flex justify-between"
class="item border-2 border-solid border-gray-100 rounded bg-slate-50 p-2 flex justify-between" style="font-size: 0.75rem;">
style="font-size: 0.75rem;"> 满额立减
限时折扣 </div>
</div>
<!-- <div class="item border-2 border-solid border-gray-100 rounded bg-slate-50 p-2 flex justify-between"
<div @click="utils.toUrl('/mall/discount/full_discount/index')"
class="item border-2 border-solid border-gray-100 rounded bg-slate-50 p-2 flex justify-between"
style="font-size: 0.75rem;">
梯度折扣
</div>
<div @click="utils.toUrl('/mall/discount/full_set_redution/index')"
class="item border-2 border-solid border-gray-100 rounded bg-slate-50 p-2 flex justify-between"
style="font-size: 0.75rem;">
满额立减
</div>
<!-- <div class="item border-2 border-solid border-gray-100 rounded bg-slate-50 p-2 flex justify-between"
style="font-size: 0.75rem;"> style="font-size: 0.75rem;">
套餐优惠 套餐优惠
</div> --> </div> -->
</view> </view>
</div> </div>
</view> </view>
</wd-transition>
<wd-transition :duration="360" :show="true" name="zoom-in">
<view class="px-2 my-1">
<div class="relative flex flex-col rounded-xl bg-white p-4 shadow-sm">
<div class="mb-2 pointer-events-auto relative inline-flex bg-white font-medium ">
<div class="flex items-baseline text-xs px-2">
<span class="mr-2 warn-state warn-status-processing bg-yellow-600"></span>
财务
</div>
</div>
<view class="grid grid-cols-3 gap-3">
<div @click="utils.toUrl('/mall/caiwu/money/index')"
class="item border-2 border-solid border-gray-100 rounded bg-slate-50 p-2 flex justify-between"
style="font-size: 0.75rem;">
佣金管理
</div>
<div @click="utils.toUrl('/mall/caiwu/cash/index')"
class="item border-2 border-solid border-gray-100 rounded bg-slate-50 p-2 flex justify-between"
style="font-size: 0.75rem;">
提现管理
</div>
</view>
</div>
</view>
</wd-transition>
<view class="bg-transparent h-[80px]"></view> <view class="bg-transparent h-[80px]"></view>

File diff suppressed because it is too large Load Diff

@ -12,20 +12,10 @@
</template> </template>
</wd-search> </wd-search>
<wd-drop-menu custom-class="flex w-full bg-white" v-show="classifyList.length">
<wd-drop-menu-item @change="search({ value: params.keywords })" custom-class="flex-1" v-model="classify_id"
<view style="display: flex;"> :options="classifyList" label-key="name" value-key="id" />
<wd-drop-menu custom-class="flex w-full bg-white" v-show="classifyList.length"> </wd-drop-menu>
<wd-drop-menu-item @change="search({ value: params.keywords })" custom-class="flex-1" v-model="classify_id"
:options="classifyList" label-key="name" value-key="id" />
</wd-drop-menu>
<wd-drop-menu custom-class="flex w-full bg-white">
<wd-drop-menu-item @change="search({ value: params.keywords })" custom-class="flex-1" v-model="params.apply_status"
:options="apply_list" label-key="name" value-key="id" />
</wd-drop-menu>
</view>
</view> </view>
<div class="goodsBox p-2"> <div class="goodsBox p-2">
@ -103,7 +93,6 @@ const classify_id = ref(0)
const params = ref({ const params = ref({
keywords: "", keywords: "",
status: "", status: "",
apply_status: 1
}) })
const yListRef = ref(null) const yListRef = ref(null)
@ -111,8 +100,7 @@ const search = ({ value }) => {
yListRef.value.upData({ yListRef.value.upData({
keywords: value, keywords: value,
classify_id: classify_id.value, classify_id: classify_id.value,
status: params.value.status, status: params.value.status
apply_status: params.value.apply_status,
}) })
} }
const searchType = ref('全部') const searchType = ref('全部')
@ -129,21 +117,6 @@ const menu = ref([
content: '已下架' content: '已下架'
} }
]) ])
const apply_list = ref([
{
id: 0,
name: '审核中'
},
{
id: 1,
name: '审核通过'
},
{
id: 2,
name: '审核失败'
}
])
function changeSearchType({ item, index }) { function changeSearchType({ item, index }) {
searchType.value = item.content searchType.value = item.content

@ -9,7 +9,10 @@
</template> </template>
</wd-navbar> </wd-navbar>
</view> </view>
<view bg-color="#f7f8fa" class="w-full grid grid-cols-3 gap-3 px-3 my-4"> <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" <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%);"> style="background-image: linear-gradient(to top, #7ea0ff 0%, #a9bdf5 100%);">
<view class="font-bold">分类管理</view> <view class="font-bold">分类管理</view>

@ -42,21 +42,9 @@
</uni-data-picker> </uni-data-picker>
</view> </view>
</wd-cell-group> </wd-cell-group>
<wd-input label="详细地址" label-width="100px" v-model="shopData.detail" use-suffix-slot> <wd-input label="详细地址" label-width="100px" v-model="shopData.detail" use-suffix-slot>
</wd-input> </wd-input>
<!-- 地址信息 -->
<wd-cell-group class="flex py-2 w-full" title="经纬度">
<view class="ml-3" style="display: flex;align-items: center;">
{{ shopData.latlngCurrent }}
<view>
<wd-button @click="getLoa"></wd-button>
</view>
</view>
</wd-cell-group>
<!-- 其他信息 --> <!-- 其他信息 -->
<wd-cell-group title="其他信息" border> <wd-cell-group title="其他信息" border>
@ -104,203 +92,138 @@
</template> </template>
<script> <script>
import { import { ref } from 'vue';
ref import yUpload from "@/components/yUpload/index.vue";
} from 'vue'; import uniDataPicker from "@/components/uni-data-picker/components/uni-data-picker/uni-data-picker.vue";
import yUpload from "@/components/yUpload/index.vue"; import system from '@/api/modules/system.js';
import uniDataPicker from "@/components/uni-data-picker/components/uni-data-picker/uni-data-picker.vue"; import index from '@/api/mall/index.js';
import system from '@/api/modules/system.js'; import kevyloading from "@/components/kevy-loading/kevy-loading";
import index from '@/api/mall/index.js'; import utils from '@/utils/utils.js'
import kevyloading from "@/components/kevy-loading/kevy-loading"; import shop from '@/api/store/shop.js';
import utils from '@/utils/utils.js'
import shop from '@/api/store/shop.js';
/**
* 从本地存储中获取用户信息
/** */
* 从本地存储中获取用户信息 const user_info = uni.getStorageSync("user_info");
*/
const user_info = uni.getStorageSync("user_info"); export default {
components: {
export default { yUpload, uniDataPicker, kevyloading
components: { },
yUpload, data() {
uniDataPicker, return {
kevyloading utils,
}, user_info,
data() { //
return { shopData: {
utils, name: '',
user_info, logo_url: '',
// mobile: '',
shopData: { district: null,
name: '', latlngCurrent: '',
logo_url: '', pay_time: '',
mobile: '', confirm_time: '',
district: null, sale_time: '',
latlngCurrent: '', pay_type: [],
pay_time: '', delivery_type: [],
confirm_time: '', after_sale_name: '',
sale_time: '', after_sale_phone: '',
pay_type: [], after_sale_address: '',
delivery_type: [], ali_express_app_code: '',
after_sale_name: '', zhangyou_device_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.getShopSetting();
},
methods: {
/**
* 获取省市区数据
*/
async getDistrict() {
const res = await system.getDistrict();
this.addrList = res.data;
}, },
shippingOptions: [
/** { label: "邮寄", value: 1 },
* 获取门店设置 { label: "自提", value: 2 },
*/ ],
async getShopSetting() { //
this.loading = true; formRules: {
const res = await index.getShopSetting(); name: [{ required: true, message: "请输入门店名称", trigger: "blur" }],
//
if (res.data.id) {
this.shopData = res.data;
}
this.loading = false;
}, },
//
addrList: [
//
],
loading: false
};
},
onLoad(e) {
this.getDistrict();
this.getShopSetting();
},
methods: {
/**
* 获取省市区数据
*/
async getDistrict() {
const res = await system.getDistrict();
this.addrList = res.data;
},
/** /**
* 处理省市区选择变化 * 获取门店设置
* @param {Object} value - 选择的值 */
*/ async getShopSetting() {
areaChange(value) { this.loading = true;
// const res = await index.getShopSetting();
},
if (res.data.id) {
this.shopData = res.data;
}
this.loading = false;
},
/** /**
* 处理省市区选择 * 处理省市区选择变化
* @param {Object} detail - 选择器详细信息 * @param {Object} value - 选择的值
*/ */
select({ areaChange(value) {
detail //
}) { },
if (detail.value.length) {
const [province_id, city_id, district_id] = detail.value.map(
(el) => el.value
);
this.shopData.province_id = province_id;
this.shopData.city_id = city_id;
this.shopData.district_id = district_id;
this.shopData.district = [province_id, city_id, district_id];
}
},
getLoa() { /**
let that = this * 处理省市区选择
* @param {Object} detail - 选择器详细信息
uni.getLocation({ */
type: 'wgs84', select({ detail }) {
success: function (res) { if (detail.value.length) {
console.log('当前位置的经度:' + res.longitude); const [province_id, city_id, district_id] = detail.value.map(
console.log('当前位置的纬度:' + res.latitude); (el) => el.value
);
that.shopData.latitude = res.latitude;
that.shopData.longitude = res.longitude; this.shopData.province_id = province_id;
this.shopData.city_id = city_id;
that.shopData.latlngCurrent = res.latitude + ',' + res.longitude; this.shopData.district_id = district_id;
this.shopData.district = [province_id, city_id, district_id];
}, }
fail() { },
uni.showToast({
icon: 'none',
title: '定位失败'
})
}
});
return
if (navigator.geolocation) {
navigator.geolocation.getCurrentPosition(function(position) {
that.shopData.latitude = position.coords.latitude;
that.shopData.longitude = position.coords.longitude;
that.shopData.latlngCurrent = position.coords.latitude + ',' + position.coords.longitude;
console.log(position)
//
}, function(error) {
//
console.log(error)
uni.showToast({
icon: 'none',
title: '定位失败'
})
});
} else {
// Geolocation
console.log('浏览器不支持 Geolocation 接口')
uni.showToast({
icon: 'none',
title: '当前浏览器不支持定位'
})
}
},
/** /**
* 处理表单提交 * 处理表单提交
*/ */
async handleSubmit() { async handleSubmit() {
// //
const res = await shop.edit({ const res = await shop.edit({
...this.shopData ...this.shopData
}); });
if (res.code == 0) { if (res.code == 0) {
setTimeout(() => { setTimeout(() => {
uni.showToast({ uni.showToast({
title: '保存成功!', title: '保存成功!',
icon: 'success' icon: 'success'
}); });
}, 100); }, 100);
uni.navigateBack() uni.navigateBack()
} }
},
}, },
}; },
};
</script> </script>
<style> <style>
/* 在这里添加样式,根据需要自定义表单样式 */ /* 在这里添加样式,根据需要自定义表单样式 */
</style> </style>

@ -1,6 +1,6 @@
{ {
"name" : "数字化平台", "name" : "数字化平台",
"appid" : "__UNI__AF1F870", "appid" : "__UNI__D7DC1FF",
"description" : "", "description" : "",
"versionName" : "1.0.0", "versionName" : "1.0.0",
"versionCode" : "100", "versionCode" : "100",

1562
package-lock.json generated

File diff suppressed because it is too large Load Diff

@ -7,8 +7,6 @@
"weapp-tailwindcss-webpack-plugin": "^1.6.10" "weapp-tailwindcss-webpack-plugin": "^1.6.10"
}, },
"dependencies": { "dependencies": {
"html5-qrcode": "^2.3.8", "js-md5": "^0.8.3"
"js-md5": "^0.8.3",
"quill": "^1.3.7"
} }
} }

@ -296,20 +296,6 @@
"navigationBarTitleText": "订单管理", "navigationBarTitleText": "订单管理",
"enablePullDownRefresh": false "enablePullDownRefresh": false
} }
},
{
"path": "recon/index",
"style": {
"navigationBarTitleText": "对账管理",
"enablePullDownRefresh": false
}
},
{
"path": "recon/list",
"style": {
"navigationBarTitleText": "订单",
"enablePullDownRefresh": false
}
} }
] ]
}, },
@ -434,27 +420,6 @@
"navigationBarTitleText": "满额立减", "navigationBarTitleText": "满额立减",
"enablePullDownRefresh": false "enablePullDownRefresh": false
} }
},
{
"path": "caiwu/money/index",
"style": {
"navigationBarTitleText": "佣金明细",
"enablePullDownRefresh": false
}
},
{
"path": "caiwu/cash/index",
"style": {
"navigationBarTitleText": "提现列表",
"enablePullDownRefresh": false
}
},
{
"path": "caiwu/cash/edit",
"style": {
"navigationBarTitleText": "提现",
"enablePullDownRefresh": false
}
} }
] ]
} }

@ -14,8 +14,7 @@ if (token) {
} else if (user_info.type == 3) { } else if (user_info.type == 3) {
utils.toUrl("/mall/index/index", "redirectTo") utils.toUrl("/mall/index/index", "redirectTo")
} else { } else {
// uni.clearStorage(); //
uni.setStorageSync('user_info', null)
} }
} else { } else {
utils.toUrl("/pages/login/index", "redirectTo") utils.toUrl("/pages/login/index", "redirectTo")

@ -3,13 +3,13 @@
<div class="flex items-center justify-center mb-2 fixed top-4 left-4"> <div class="flex items-center justify-center mb-2 fixed top-4 left-4">
<wd-transition :duration="300" :show="true" name="fade-left"> <wd-transition duration="300" :show="true" name="fade-left">
<view class="flex-1 overflow-hidden "> <view class="flex-1 overflow-hidden ">
<wd-img :width="34" :height="34" :src="webInfo.logo" mode="aspectFill" /> <wd-img :width="34" :height="34" :src="webInfo.logo" mode="aspectFill" />
</view> </view>
</wd-transition> </wd-transition>
<wd-transition :duration="400" :show="true" name="fade-left"> <wd-transition duration="400" :show="true" name="fade-left">
<text class="flex px-2 text-center justify-center"> <text class="flex px-2 text-center justify-center">
{{ webInfo.name }} {{ webInfo.name }}
</text> </text>
@ -21,38 +21,23 @@
<wd-form class="mb-24" ref="form" :model="model"> <wd-form class="mb-24" ref="form" :model="model">
<view class="rounded-md overflow-hidden"> <view class="rounded-md overflow-hidden">
<wd-cell-group border size="large"> <wd-cell-group border>
<wd-transition :duration="400" :show="true" name="fade-left"> <wd-transition duration="400" :show="true" name="fade-left">
<wd-input size="large" label="用户名" label-width="100px" prop="username" clearable <wd-input label="用户名" label-width="100px" prop="username" clearable v-model="model.username"
v-model="model.username" placeholder="请输入用户名" placeholder="请输入用户名" :rules="[{ required: true, message: '请填写用户名' }]" />
:rules="[{ required: true, message: '请填写用户名' }]" />
</wd-transition> </wd-transition>
<wd-transition :duration="450" :show="true" name="fade-left"> <wd-transition duration="450" :show="true" name="fade-left">
<wd-input size="large" label="密码" label-width="100px" prop="password" show-password clearable <wd-input label="密码" label-width="100px" prop="password" show-password clearable v-model="model.password"
v-model="model.password" placeholder="请输入密码" placeholder="请输入密码" :rules="[{ required: true, message: '请填写密码' }]" />
:rules="[{ required: true, message: '请填写密码' }]" />
</wd-transition> </wd-transition>
<wd-transition :duration="450" :show="true" name="fade-left">
<wd-input size="large" label="验证码" label-width="100px" clearable v-model="model.captch"
placeholder="请输入验证码" :rules="[{ required: true, message: '请填写验证码' }]" />
<view style="display: flex;justify-content: flex-end;padding: 10rpx 0;">
<image @click="getCaptch()" style="height: 60rpx;" :src="captch_img" mode="heightFix"></image>
</view>
</wd-transition>
</wd-cell-group> </wd-cell-group>
</view> </view>
<view class="footer mt-4 px-6"
style="text-align: right;font-size: 28rpx;color: #999;display: flex;align-items: center;justify-content: flex-end;">
记住密码
<!-- <checkbox v-model="is_save_user_pwd" style="transform:scale(0.7)" /> -->
<wd-checkbox v-model="is_save_user_pwd" shape="square"></wd-checkbox>
</view>
<view class="footer mt-4 px-6"> <view class="footer mt-4 px-6">
<wd-transition :duration="500" :show="true" name="fade-left"> <wd-transition duration="500" :show="true" name="fade-left">
<wd-button style="font-size: 20px;padding: 10px;" :loading="loading" type="primary" size="large" <wd-button :loading="loading" type="primary" size="medium" @click="handleSubmit" block>登录</wd-button>
@click="handleSubmit" block>登录</wd-button>
</wd-transition> </wd-transition>
</view> </view>
</wd-form> </wd-form>
@ -60,148 +45,122 @@
</template> </template>
<script setup> <script setup>
import { import { ref } from 'vue'
ref import user from '@/api/modules/user.js'
} from 'vue' import systemApi from '@/api/modules/system.js'
import user from '@/api/modules/user.js' import utils from '@/utils/utils.js'
import systemApi from '@/api/modules/system.js' import md5 from 'js-md5';
import utils from '@/utils/utils.js' uni.clearStorage(); //
import md5 from 'js-md5';
// uni.clearStorage(); // const webInfo = ref({})
const webInfo = ref({}) const getWebInfo = () => {
systemApi.getSetting().then(res => {
const getWebInfo = () => { webInfo.value = res.data
systemApi.getSetting().then(res => {
webInfo.value = res.data
})
}
getWebInfo()
console.log(uni.getStorageSync('user_pwd'), 'user_pwd')
const model = ref({
username: "",
password: "",
...(uni.getStorageSync('user_pwd') || {}),
captch: ''
}) })
}
const loading = ref(false)
const is_save_user_pwd = ref(true) getWebInfo()
const form = ref(null)
const captch_img = ref(null)
const model = ref({
// if (token) { username: "",
// const user_info = uni.getStorageSync("user_info"); password: "",
// if (user_info.type == 1) { })
// utils.toUrl("/store/index/index")
// } const loading = ref(false)
// } else { const form = ref(null)
// utils.toUrl("/pages/login/index")
// } // if (token) {
// const user_info = uni.getStorageSync("user_info");
getCaptch() // if (user_info.type == 1) {
function getCaptch() { // utils.toUrl("/store/index/index")
user.captch({ // }
// } else {
}).then(res => { // utils.toUrl("/pages/login/index")
console.log(res, 'res') // }
if (res.code == 0) {
captch_img.value = res.data function handleSubmit() {
} else { loading.value = true
form.value
} .validate()
}) .then(({ valid, errors }) => {
} if (valid) {
function handleSubmit() { user.login({
loading.value = true ...model.value,
form.value password: md5(model.value.password)
.validate() }).then(res => {
.then(({
valid, if (res.code == 0) {
errors uni.setStorageSync("token", res.data.access_token);
}) => { uni.setStorageSync("user_info", res.data.user_info);
if (valid) {
if (is_save_user_pwd.value) { uni.showToast({
uni.setStorageSync("user_pwd", model.value); icon: "none",
} title: "登录成功",
user.login({ });
...model.value,
password: md5(model.value.password), if (res.data.user_info.type == 1) {
captch: model.value.captch utils.toUrl("/store/index/index", "redirectTo")
}).then(res => { uni.setStorageSync("store_info", res.data.user_info);
} else if (res.data.user_info.type == 3) {
if (res.code == 0) { uni.setStorageSync("mall_token", res.data.access_token);
uni.setStorageSync("token", res.data.access_token); uni.setStorageSync("mall_info", res.data.user_info);
uni.setStorageSync("user_info", res.data.user_info); utils.toUrl("/mall/index/index", "redirectTo")
uni.showToast({
icon: "none",
title: "登录成功",
});
if (res.data.user_info.type == 1) {
utils.toUrl("/store/index/index", "redirectTo")
uni.setStorageSync("store_info", res.data.user_info);
} else if (res.data.user_info.type == 3) {
uni.setStorageSync("mall_token", res.data.access_token);
uni.setStorageSync("mall_info", res.data.user_info);
utils.toUrl("/mall/index/index", "redirectTo")
} else {
uni.showToast({
title: '登录平台开发中 ···',
icon: 'none'
})
}
loading.value = false
} else { } else {
uni.showToast({ uni.showToast({
title: res.message, title: '登录平台开发中 ···',
icon: 'none' icon: 'none'
}) })
getCaptch()
loading.value = false
} }
loading.value = false loading.value = false
}) } else {
} else { uni.showToast({
title: res.message,
icon: 'none'
})
loading.value = false
}
loading.value = false loading.value = false
} })
}) } else {
.catch((error) => {
console.log(error, 'error')
loading.value = false loading.value = false
}) }
} })
.catch((error) => {
console.log(error, 'error')
loading.value = false
})
}
</script> </script>
<style> <style>
.content { .content {
display: flex; display: flex;
flex-direction: column; flex-direction: column;
align-items: center; align-items: center;
justify-content: center; justify-content: center;
min-height: 100vh; min-height: 100vh;
} }
.logo { .logo {
height: 200rpx; height: 200rpx;
width: 200rpx; width: 200rpx;
margin-top: 200rpx; margin-top: 200rpx;
margin-left: auto; margin-left: auto;
margin-right: auto; margin-right: auto;
margin-bottom: 50rpx; margin-bottom: 50rpx;
} }
.text-area { .text-area {
display: flex; display: flex;
justify-content: center; justify-content: center;
} }
.title { .title {
font-size: 36rpx; font-size: 36rpx;
color: #8f8f94; color: #8f8f94;
} }
</style> </style>

@ -1,18 +1,17 @@
<template> <template>
<view class="charts-box bg-white content"> <view class="charts-box bg-white content">
<view v-show="true" class="flex overflow-auto flex-wrap"> <view v-show="classifyList.length" class="flex overflow-auto flex-wrap">
<div class="grid grid-cols-3 gap-4 p-4 w-full"> <div class="grid grid-cols-3 gap-4 p-4 w-full">
<wd-button @click="utils.toUrl('/store/cat/edit?edit=' + JSON.stringify({}))" style="width: 100%;" <wd-button @click="utils.toUrl('/store/cat/edit?edit=' + JSON.stringify({}))" style="width: 100%;"
class="bg-[#f0f0f0] w-full flex-1" :round="false"> class="bg-[#f0f0f0] w-full flex-1" :round="false">
新增 新增
</wd-button> </wd-button>
<template v-if="classifyList.length"> <wd-button @click="showActions(cat)" style="width: 100%;" v-for="cat of classifyList"
<wd-button @click="showActions(cat)" style="width: 100%;" v-for="cat of classifyList" class="bg-[#f0f0f0] w-full flex-1" type="info" :round="false">
class="bg-[#f0f0f0] w-full flex-1" type="info" :round="false"> {{ cat.name }}
{{ cat.name }} </wd-button>
</wd-button>
</template>
</div> </div>
</view> </view>

@ -1,550 +1,429 @@
<template> <template>
<view v-if="load" class="content p-2 bg-gray-100"> <view v-if="load" class="content p-2 bg-gray-100">
<wd-toast /> <wd-toast />
<wd-form ref="form" :model="model"> <wd-form ref="form" :model="model">
<wd-cell-group border> <wd-cell-group border>
<div class="rounded-md overflow-hidden"> <div class="rounded-md overflow-hidden">
<div class="bg-gray-100 "> <div class="bg-gray-100 ">
<div class="bg-gray-100 rounded mb-2"> <div class="bg-gray-100 rounded mb-2">
<div class="bg-white flex flex-col pt-3 pl-3"> <div class="bg-white flex flex-col pt-3 pl-3">
<div class="name mb-2 text-xs">缩略图</div> <div class="name mb-2 text-xs">缩略图</div>
<yUpload v-model="model.pic_url"></yUpload> <yUpload v-model="model.pic_url"></yUpload>
</div> </div>
</div> </div>
</div> </div>
<div class="bg-gray-100"> <div class="bg-gray-100">
<div class="bg-gray-100 rounded mb-2"> <div class="bg-gray-100 rounded mb-2">
<div class="bg-white flex flex-col pt-3 pl-3"> <div class="bg-white flex flex-col pt-3 pl-3">
<div class="name mb-2 text-xs">商品主图</div> <div class="name mb-2 text-xs">商品主图</div>
<yUpload v-model="model.pic_list" :size="4"></yUpload> <yUpload v-model="model.pic_list" :size="4"></yUpload>
</div> </div>
</div> </div>
</div> </div>
</div> </div>
<view class="h-2 bg-gray-100"></view> <view class="h-2 bg-gray-100"></view>
<view class=" p-3 rounded mb-2"> <view class=" p-3 rounded mb-2">
<div class="name mb-2 text-xs">商品名称</div> <div class="name mb-2 text-xs">商品名称</div>
<view class="bg-white px-3 py-1 rounded"> <view class="bg-white px-3 py-1 rounded">
<wd-textarea v-model="model.name" auto-height /> <wd-textarea v-model="model.name" auto-height />
</view> </view>
</view> </view>
<view class="h-2 bg-gray-100"></view> <view class="h-2 bg-gray-100"></view>
<view class=" p-3 rounded mb-2"> <view class=" p-3 rounded mb-2">
<div class="name mb-2 text-xs">商品分类</div> <div class="name mb-2 text-xs">商品分类</div>
<view class="bg-white px-3 py-1 rounded"> <view class="bg-white px-3 py-1 rounded">
<wd-checkbox-group v-model="model.classify_list"> <wd-checkbox-group v-model="model.classify_list">
<view class="flex overflow-auto flex-wrap"> <view class="flex overflow-auto flex-wrap">
<div class="grid grid-cols-3"> <div class="grid grid-cols-3">
<wd-checkbox style="width: 100%;" shape="button" v-for="cat of classifyList" <wd-checkbox style="width: 100%;" shape="button" v-for="cat of classifyList"
:modelValue="JSON.stringify(cat.parentIds)"> :modelValue="JSON.stringify(cat.parentIds)">
{{ cat.name }} {{ cat.name }}
</wd-checkbox> </wd-checkbox>
</div> </div>
</view> </view>
</wd-checkbox-group> </wd-checkbox-group>
</view> </view>
</view> </view>
<view class="h-2 bg-gray-100"></view> <view class="h-2 bg-gray-100"></view>
<view class="bg-gray-100 rounded mb-2"> <view class="bg-gray-100 rounded mb-2">
<div class="p-2 bg-white"> <div class="p-2 bg-white">
<div class="name mb-2 text-xs">服务内容</div> <div class="name mb-2 text-xs">服务内容</div>
<view class="bg-white px-3 py-1 rounded"> <view class="bg-white px-3 py-1 rounded">
<wd-input type="text" v-model="model.server_project" <wd-input type="text" v-model="model.server_project" placeholder="例子: 正品保障,极速发货,7天退换货。多个请使用英文逗号“,”分隔" />
placeholder="例子: 正品保障,极速发货,7天退换货。多个请使用英文逗号“,”分隔" /> </view>
</view> </div>
</div> </view>
</view>
<view class="h-2 bg-gray-100"></view>
<view class="h-2 bg-gray-100"></view>
<view class=" p-3 rounded mb-2">
<view class=" p-3 rounded mb-2"> <div class="name mb-2 text-xs">商品重量</div>
<div class="name mb-2 text-xs">商品重量</div> <view class="bg-white px-3 py-2 rounded flex items-center mb-4">
<view class="bg-white px-3 py-2 rounded flex items-center mb-4"> <wd-input-number v-model="model.weight" />
<wd-input-number v-model="model.weight" /> <view class="text-xs from-neutral-300 ml-4">千克</view>
<view class="text-xs from-neutral-300 ml-4">千克</view> </view>
</view>
<wd-picker v-if="freightRules.length" class="w-full" :columns="freightRules" label="运费模板"
<wd-picker v-if="freightRules.length" class="w-full" :columns="freightRules" label="运费模板" v-model="model.freight_id" />
v-model="model.freight_id" />
</view>
</view>
<view class="h-2 bg-gray-100"></view>
<view class="h-2 bg-gray-100"></view>
<view class="p-3 rounded mb-2">
<view class="p-3 rounded mb-2"> <div class="name mb-2 text-xs">商品状态</div>
<div class="name mb-2 text-xs">商品状态</div> <view class="bg-white px-3 py-2 rounded flex items-center">
<view class="bg-white px-3 py-2 rounded flex items-center"> <wd-switch v-model="model.status" :active-value="1" :inactive-value="0" />
<wd-switch v-model="model.status" :active-value="1" :inactive-value="0" /> </view>
</view> </view>
</view>
<view class="h-2 bg-gray-100"></view>
<view class="h-2 bg-gray-100"></view>
<view class="p-3 rounded mb-2">
<view class="p-3 rounded mb-2"> <div class="name mb-2 text-xs">规格</div>
<div class="name mb-2 text-xs">规格</div> <view class="bg-white px-3 py-2 rounded flex items-center">
<view class="bg-white px-3 py-2 rounded flex items-center"> <wd-radio-group shape="button" v-model="model.use_sku">
<wd-radio-group shape="button" v-model="model.use_sku"> <wd-radio :value="0">单规格</wd-radio>
<wd-radio :value="0">单规格</wd-radio> <wd-radio :value="1">多规格</wd-radio>
<wd-radio :value="1">多规格</wd-radio> </wd-radio-group>
</wd-radio-group> </view>
</view> </view>
</view>
<view class="h-2 bg-gray-100"></view>
<view class="h-2 bg-gray-100"></view>
<skuEdit ref="skuEditRef" :skuGroup="skuGroup"
<skuEdit ref="skuEditRef" :skuGroup="skuGroup" :Pdata="{ skuDefault, skuLibrary, skuGroup, use_sku: model.use_sku }">
:Pdata="{ skuDefault, skuLibrary, skuGroup, use_sku: model.use_sku }"> </skuEdit>
</skuEdit>
</wd-cell-group>
<view class="h-2 bg-gray-100"></view> <view class="footer mt-4">
<view> <wd-button @click="saveGoods" type="primary" size="large" block>保存</wd-button>
<view style="font-size: 36rpx;border-bottom: 1rpx solid #F0F0F0;display: flex;flex-wrap: wrap;align-items: center;"> </view>
<view </wd-form>
:style="{ </view>
margin: '20rpx',
fontWeight: formats.bold ? '800' : '400'
}"
@click="format('bold', (formats.bold ? false : true))">加粗</view>
<view
:style="{
margin: '20rpx',
fontWeight: formats.italic ? '800' : '400'
}"
@click="format('italic', (formats.italic ? false : true))">斜体</view>
<view
:style="{
margin: '20rpx',
fontWeight: formats.underline ? '800' : '400'
}"
@click="format('underline', (formats.underline ? false : true))">下划线</view>
<view
:style="{
margin: '20rpx',
fontWeight: formats.align == 'center' ? '800' : '400'
}"
@click="format('align', (formats.align == 'center' ? 'left' : 'center'))">居中</view>
<view style="margin: 20rpx;" >
<yUpload :width="40" :height="40" v-model="editor_upload" :size="4"></yUpload>
</view>
</view>
<view style="padding: 10px;">
<editor style="min-height: 70vh;" id="editor" class="ql-container"
placeholder="开始输入..." show-img-size show-img-toolbar
@statuschange="onStatusChange"
show-img-resize :read-only="false" @ready="onEditorReady">
</editor>
</view>
</view>
</wd-cell-group>
<view class="footer mt-4">
<wd-button @click="saveGoods" type="primary" size="large" block>保存</wd-button>
</view>
</wd-form>
</view>
</template> </template>
<script setup> <script setup>
import { import { ref } from 'vue';
ref, import { useToast, useMessage } from '@/uni_modules/wot-design-uni';
watch import goods from '@/api/store/goods.js';
} from 'vue'; import system from '@/api/modules/system.js';
import { import skuEdit from "./components/skuEdit.vue";
useToast, import yUpload from "@/components/yUpload/index.vue";
useMessage import { onLoad, onShow } from "@dcloudio/uni-app";
} from '@/uni_modules/wot-design-uni';
import goods from '@/api/store/goods.js'; /**
import system from '@/api/modules/system.js'; * @typedef {import('@/api/store/goods').GoodsItem} GoodsItem
import skuEdit from "./components/skuEdit.vue"; */
import yUpload from "@/components/yUpload/index.vue";
import { /**
onLoad, * @typedef {import('@/api/store/goods').FreightRule} FreightRule
onShow */
} from "@dcloudio/uni-app";
/**
/** * @typedef {Object} Sku
* @typedef {import('@/api/store/goods').GoodsItem} GoodsItem * @property {string} price - 商品价格
*/ * @property {string} stock - 商品库存
* @property {string} original_price - 商品原价
/** */
* @typedef {import('@/api/store/goods').FreightRule} FreightRule
*/ /**
* @typedef {Object} Model
/** * @property {number} id - 商品ID
* @typedef {Object} Sku * @property {Array<string>} classify_list - 商品分类组
* @property {string} price - 商品价格 * @property {string} name - 商品名称
* @property {string} stock - 商品库存 * @property {string} keywords - 商品关键词
* @property {string} original_price - 商品原价 * @property {number} sort - 商品排序
*/ * @property {number} status - 商品状态
* @property {number} freight_id - 运费规则ID
/** * @property {number} weight - 商品重量
* @typedef {Object} Model * @property {string} pic_url - 商品缩略图
* @property {number} id - 商品ID * @property {Array<string>} pic_list - 商品图组
* @property {Array<string>} classify_list - 商品分类组 * @property {string} video - 商品视频
* @property {string} name - 商品名称 * @property {string} detail - 图文详情
* @property {string} keywords - 商品关键词 * @property {number} use_sku - 是否使用规格
* @property {number} sort - 商品排序 * @property {Array<Sku>} sku_list - 规格信息
* @property {number} status - 商品状态 * @property {number} is_discount - 是否有折扣
* @property {number} freight_id - 运费规则ID * @property {number} discount - 折扣比例小数
* @property {number} weight - 商品重量 * @property {number} dist_price - 分销价格
* @property {string} pic_url - 商品缩略图 * @property {number} limit - 限购
* @property {Array<string>} pic_list - 商品图组 * @property {number} is_check - 自定义核销佣金
* @property {string} video - 商品视频 * @property {number} check_type - 佣金类型
* @property {string} detail - 图文详情 * @property {number} check_price - 佣金
* @property {number} use_sku - 是否使用规格 */
* @property {Array<Sku>} sku_list - 规格信息
* @property {number} is_discount - 是否有折扣 /**
* @property {number} discount - 折扣比例小数 * @typedef {Object} FileItem
* @property {number} dist_price - 分销价格 * @property {string} pic_url - 图片URL
* @property {number} limit - 限购 */
* @property {number} is_check - 自定义核销佣金
* @property {number} check_type - 佣金类型 /**
* @property {number} check_price - 佣金 * @typedef {Object} SkuGroup
*/ * @property {Array<Sku>} skuDefault - 默认规格
* @property {Array<Sku>} skuLibrary - 规格库
/** * @property {Array<Sku>} skuGroup - 规格组
* @typedef {Object} FileItem */
* @property {string} pic_url - 图片URL
*/ /**
* @typedef {Object} SkuEditRef
/** * @property {SkuGroup} skuGroup - 规格组
* @typedef {Object} SkuGroup * @property {number} skuDefault - 默认规格
* @property {Array<Sku>} skuDefault - 默认规格 * @property {number} skuLibrary - 规格库
* @property {Array<Sku>} skuLibrary - 规格库 */
* @property {Array<Sku>} skuGroup - 规格组
*/ /** @type {Ref<Array<FileItem>>} */
const fileList = ref([]);
/**
* @typedef {Object} SkuEditRef /**
* @property {SkuGroup} skuGroup - 规格组 * @param {Object} param0
* @property {number} skuDefault - 默认规格 * @param {FileItem} param0.file - 要删除的文件
* @property {number} skuLibrary - 规格库 * @param {Function} param0.resolve - 删除文件的回调函数
*/ * @param {number} param0.index - 文件索引
* @returns {void}
/** @type {Ref<Array<FileItem>>} */ */
const fileList = ref([]); const beforeRemove = ({ file, resolve, index }) => {
fileList.value.splice(index, 1);
/** resolve(true);
* @param {Object} param0 };
* @param {FileItem} param0.file - 要删除的文件
* @param {Function} param0.resolve - 删除文件的回调函数 /** @type {Ref<Model>} */
* @param {number} param0.index - 文件索引 const model = ref({
* @returns {void} classify_list: [], //
*/ name: "", //
const beforeRemove = ({ keywords: "", //
file, sort: 1000,
resolve, status: 0, //
index freight_id: 99999999, //
}) => { weight: 0, //
fileList.value.splice(index, 1); pic_url: "", //
resolve(true); pic_list: [], //
}; video: "", //
detail: "默认", //
use_sku: 0, // 使
const editorCtx = ref(null); sku_list: [], //
const onEditorReady = () => { is_discount: 0, //
// #ifdef MP-BAIDU discount: 50, //
editorCtx.value = requireDynamicLib('editorLib').createEditorContext('editor'); dist_price: 0, //
// #endif limit: 0, //
is_check: 0, //
// #ifdef APP-PLUS || MP-WEIXIN || H5 check_type: 0, //
uni.createSelectorQuery().select('#editor').context((res) => { check_price: 0, //
editorCtx.value = res.context });
}).exec()
// #endif /** @type {Ref<boolean>} */
} const load = ref(false);
const formats = ref({});
const onStatusChange = (e) => { /** @type {Ref<SkuGroup>} */
formats.value = e.detail const skuGroup = ref([]);
} /** @type {Ref<Array<GoodsItem>>} */
const skuDefault = ref([]);
const format = (name, value) => { /** @type {Ref<Array<GoodsItem>>} */
editorCtx.value.format(name, value) const skuLibrary = ref([]);
}
/** @type {Ref<SkuEditRef>} */
const editor_upload = ref([]); const skuEditRef = ref(null);
watch(editor_upload, (newX) => {
if (newX && newX.length > 0) { /** @type {Ref<Array<FreightRule>>} */
newX.forEach(item => { const freightRules = ref([{
editorCtx.value.insertImage({ label: "默认",
src: item, value: "99999999"
alt: '图像', }]);
success: function() {
console.log('insert image success') onLoad(async (e) => {
} model.value.id = e.id;
})
}) /**
* 获取运费规则
editor_upload.value = [] * @returns {void}
} */
// console.log(newX, `newX is`) const GetfreightRules = () => {
}) goods.freightRules().then(res => {
freightRules.value = [
...freightRules.value,
/** @type {Ref<Model>} */ ...res.data.rows.map(item => {
const model = ref({ return {
classify_list: [], // label: item.name,
name: "", // value: item.id
keywords: "", // };
sort: 1000, })
status: 0, // ];
freight_id: 99999999, // });
weight: 0, // };
pic_url: "", //
pic_list: [], // GetfreightRules();
video: "", //
detail: "默认", // if (e.id > 0) {
use_sku: 0, // 使 const res = await goods.goodsItem({
sku_list: [], // id: e.id
is_discount: 0, // });
discount: 50, //
dist_price: 0, // model.value = res.data;
limit: 0, // model.value.pic_list = res.data.pic_list.map(({ pic_url }) => pic_url);
is_check: 0, //
check_type: 0, // if (!model.value.freight_id) {
check_price: 0, // model.value.freight_id = 99999999;
}); }
model.value.classify_list = model.value.classify_list.map(item => JSON.stringify(item));
/** @type {Ref<boolean>} */
const load = ref(false); if (res.data.use_sku == 0) {
skuDefault.value = res.data.goods_sku;
/** @type {Ref<SkuGroup>} */ } else {
const skuGroup = ref([]); skuLibrary.value = res.data.goods_sku;
/** @type {Ref<Array<GoodsItem>>} */ }
const skuDefault = ref([]); skuGroup.value = res.data.sku_group ? res.data.sku_group : [];
/** @type {Ref<Array<GoodsItem>>} */ load.value = true;
const skuLibrary = ref([]); } else {
load.value = true;
/** @type {Ref<SkuEditRef>} */ }
const skuEditRef = ref(null); });
/** @type {Ref<Array<FreightRule>>} */ /**
const freightRules = ref([{ * 保存商品信息
label: "默认", * @returns {Promise<void>}
value: "99999999" */
}]); const saveGoods = async () => {
//
onLoad(async (e) => { if (model.value.classify_list.length === 0) {
model.value.id = e.id; return uni.showToast({
title: '请选择商品分类!',
/** icon: 'none'
* 获取运费规则 });
* @returns {void} }
*/
const GetfreightRules = () => { //
goods.freightRules().then(res => { if (model.value.name.trim() === "") {
freightRules.value = [ return uni.showToast({
...freightRules.value, title: '请输入商品名称!',
...res.data.rows.map(item => { icon: 'none'
return { });
label: item.name, }
value: item.id
}; //
}) if (model.value.weight < 0) {
]; return uni.showToast({
}); title: '请输入合法的商品重量!',
}; icon: 'none'
});
GetfreightRules(); }
if (e.id > 0) { //
const res = await goods.goodsItem({ if (String(model.value.pic_url).trim() === "") {
id: e.id return uni.showToast({
}); title: '请上传商品缩略图!',
icon: 'none'
model.value = res.data; });
model.value.pic_list = res.data.pic_list.map(({ }
pic_url
}) => pic_url); //
if (model.value.pic_list.length === 0) {
if (!model.value.freight_id) { return uni.showToast({
model.value.freight_id = 99999999; title: '请上传商品图片组!',
} icon: 'none'
model.value.classify_list = model.value.classify_list.map(item => JSON.stringify(item)); });
}
if (res.data.use_sku == 0) {
skuDefault.value = res.data.goods_sku; model.value.sku_group = [];
} else { model.value.sku_list = [];
skuLibrary.value = res.data.goods_sku; model.value.dist_price = Number.parseInt(model.value.dist_price);
}
skuGroup.value = res.data.sku_group ? res.data.sku_group : []; if (model.value.use_sku == 1) {
model.value.sku_group = skuEditRef.value.skuGroup;
setTimeout(() => { model.value.sku_list = skuEditRef.value.skuLibrary;
editorCtx.value.setContents({ } else {
html: res.data.detail model.value.sku_list = skuEditRef.value.skuDefault;
}) }
}, 1000)
if (!model.value.sku_list.length) {
load.value = true; uni.showToast({
} else { title: '规格不完整,请调整!',
load.value = true; icon: 'none'
} });
}); }
/** if (!model.value.sku_list.every(item => Boolean(item.price !== "" && item.stock !== "" && item.original_price !== ""))) {
* 保存商品信息 uni.showToast({
* @returns {Promise<void>} title: '规格不完整,请调整!',
*/ icon: 'none'
const saveGoods = async () => { });
//
if (model.value.classify_list.length === 0) { return;
return uni.showToast({ }
title: '请选择商品分类!',
icon: 'none' let freight_id = model.value.freight_id;
}); if (freight_id = 99999999) {
} freight_id = 0;
}
//
if (model.value.name.trim() === "") { const pic_list = model.value.pic_list.map(item => ({
return uni.showToast({ pic_url: item
title: '请输入商品名称!', }));
icon: 'none'
}); const classify_list = model.value.classify_list.map(item => JSON.parse(item));
}
const res = await goods.goodsEdit({ ...model.value, pic_list, freight_id, classify_list });
//
if (model.value.weight < 0) { if (res.code == 0) {
return uni.showToast({ uni.showToast({
title: '请输入合法的商品重量!', title: '商品信息保存成功!',
icon: 'none' icon: 'success'
}); });
}
uni.navigateBack();
// }
if (String(model.value.pic_url).trim() === "") { };
return uni.showToast({
title: '请上传商品缩略图!', /** @type {Ref<Array<Object>>} */
icon: 'none' const classifyList = ref([]);
});
} /**
* 获取商品分类
// * @returns {void}
if (model.value.pic_list.length === 0) { */
return uni.showToast({ const getClassify = () => {
title: '请上传商品图片组!', /**
icon: 'none' * 递归展平商品分类
}); * @param {Array<GoodsItem>} categories - 商品分类数组
} * @param {Array<number>} [parentIds=[]] - 父级分类ID数组
* @returns {Array<Object>} - 展平后的商品分类数组
model.value.sku_group = []; */
model.value.sku_list = []; function flattenCategories(categories, parentIds = []) {
model.value.dist_price = Number.parseInt(model.value.dist_price); let flatCategories = [];
if (model.value.use_sku == 1) { for (const category of categories) {
model.value.sku_group = skuEditRef.value.skuGroup; const categoryWithParents = {
model.value.sku_list = skuEditRef.value.skuLibrary; ...category,
} else { parentIds: [...parentIds, category.id],
model.value.sku_list = skuEditRef.value.skuDefault; };
}
flatCategories.push(categoryWithParents);
if (!model.value.sku_list.length) {
uni.showToast({ if (category.children && category.children.length > 0) {
title: '规格不完整,请调整!', flatCategories = flatCategories.concat(flattenCategories(category.children, [...parentIds, category.id]));
icon: 'none' }
}); }
}
return flatCategories;
if (!model.value.sku_list.every(item => Boolean(item.price !== "" && item.stock !== "" && item }
.original_price !== ""))) {
uni.showToast({ goods.classify.list().then(res => {
title: '规格不完整,请调整!', classifyList.value = flattenCategories(res.data);
icon: 'none' });
}); };
return; getClassify();
}
let freight_id = model.value.freight_id;
if (freight_id = 99999999) {
freight_id = 0;
}
const pic_list = model.value.pic_list.map(item => ({
pic_url: item
}));
const classify_list = model.value.classify_list.map(item => JSON.parse(item));
let detail = ''
await editorCtx.value.getContents({
success(res) {
detail = res.html
}
})
const res = await goods.goodsEdit({
...model.value,
pic_list,
freight_id,
classify_list,
detail
});
if (res.code == 0) {
uni.showToast({
title: '商品信息保存成功!',
icon: 'success'
});
uni.navigateBack();
}
};
/** @type {Ref<Array<Object>>} */
const classifyList = ref([]);
/**
* 获取商品分类
* @returns {void}
*/
const getClassify = () => {
/**
* 递归展平商品分类
* @param {Array<GoodsItem>} categories - 商品分类数组
* @param {Array<number>} [parentIds=[]] - 父级分类ID数组
* @returns {Array<Object>} - 展平后的商品分类数组
*/
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);
});
};
getClassify();
</script> </script>
<style lang="scss"></style> <style lang="scss"></style>

@ -30,12 +30,6 @@
</view> </view>
<view v-if="recommend.length" class="grid grid-cols-3 gap-3"> <view v-if="recommend.length" class="grid grid-cols-3 gap-3">
<view @click="utils.toUrl('/store/recon/index')"
class="items-center border-2 border-solid border-gray-100 rounded bg-slate-50 p-2 flex justify-between"
style="font-size: 0.75rem;">
收款对账
<wd-icon name="lenovo opacity-80" class="opacity-80" size="12px"></wd-icon>
</view>
<view v-for="item of recommend" @click="utils.toUrl(item.url)" <view v-for="item of recommend" @click="utils.toUrl(item.url)"
class="items-center border-2 border-solid border-gray-100 rounded bg-slate-50 p-2 flex justify-between" class="items-center border-2 border-solid border-gray-100 rounded bg-slate-50 p-2 flex justify-between"
style="font-size: 0.75rem;"> style="font-size: 0.75rem;">
@ -45,14 +39,7 @@
</view> </view>
<view v-else class="grid grid-cols-3 gap-3"> <view v-else class="grid grid-cols-3 gap-3">
<view @click="utils.toUrl('/store/recon/index')"
class="items-center border-2 border-solid border-gray-100 rounded bg-slate-50 p-2 flex justify-between"
style="font-size: 0.75rem;">
收款对账
<wd-icon name="lenovo opacity-80" class="opacity-80" size="12px"></wd-icon>
</view>
<view @click="utils.toUrl('/store/user/list')" <view @click="utils.toUrl('/store/user/list')"
class="items-center border-2 border-solid border-gray-100 rounded bg-slate-50 p-2 flex justify-between" class="items-center border-2 border-solid border-gray-100 rounded bg-slate-50 p-2 flex justify-between"
style="font-size: 0.75rem;"> style="font-size: 0.75rem;">
@ -73,8 +60,6 @@
订单管理 订单管理
<wd-icon name="lenovo opacity-80" class="opacity-80" size="12px"></wd-icon> <wd-icon name="lenovo opacity-80" class="opacity-80" size="12px"></wd-icon>
</view> </view>
</view> </view>

@ -1,593 +0,0 @@
<template>
<view class="content">
<view
style="padding: 120rpx 0 80rpx;background: #19be6b;display: flex;justify-content: space-around;align-items: center;color: #FFF;">
<!-- <view @click="saoma">
<view style="text-align: center;">
<wd-icon name="scan1" size="28px"></wd-icon>
</view>
<view style="text-align: center;margin-top: 10rpx;">
收款
</view>
</view> -->
<view @click="utils.toUrl('/store/recon/list')">
<view style="text-align: center;">
<wd-icon name="view-module" size="28px"></wd-icon>
</view>
<view style="text-align: center;margin-top: 10rpx;">
账单
</view>
</view>
<view @click="show_tuikuan = 1">
<view style="text-align: center;">
<wd-icon name="enter" size="28px"></wd-icon>
</view>
<view style="text-align: center;margin-top: 10rpx;">
退款
</view>
</view>
</view>
<!-- <view class="action-box">
<view>
<wd-icon color="#19be6b" name="edit-outline" size="14px"></wd-icon>
<view>
订单退款
</view>
</view>
<view>
<wd-icon color="#ff9900" name="scan" size="14px"></wd-icon>
<view>
订单核销
</view>
</view>
</view> -->
<view
style="padding: 20rpx;display: flex;align-items: center;justify-content: space-between;margin-top: 40rpx;">
<view style="color: #999;">
统计信息
</view>
<view class="pay-type-box">
<view @click="updatePay(0)" :class="pay_type == 0 ? 'time-active' : ''">
总计
</view>
<view @click="updatePay(1)" :class="pay_type == 1 ? 'time-active' : ''">
微信
</view>
<view @click="updatePay(2)" :class="pay_type == 2 ? 'time-active' : ''">
支付宝
</view>
</view>
<view style="color: #f29100;display: flex;align-items: center;" @click="show_shop = true">
{{ shop_info ? shop_info.name : '门店筛选' }}
<wd-icon name="swap" color="#f29100" size="18px"></wd-icon>
</view>
</view>
<!-- 时间 -->
<view class="content-time">
<view @click="updateTime(0)" :class="time_type == 0 ? 'time-active' : ''">
昨天
</view>
<view @click="updateTime(1)" :class="time_type == 1 ? 'time-active' : ''">
今天
</view>
<view :class="time_type == 2 ? 'time-active' : ''">
<wd-calendar type="daterange" v-model="date_list" allow-same-day :formatter="formatter"
@cancel="handleCancel" @confirm="handleConfirm" use-default-slot>
<text @click="updateTime(2)"></text>
</wd-calendar>
</view>
</view>
<view class="content-time-info">
{{ start_time }} - {{ end_time }}
</view>
<template v-if="content_info">
<view class="info-item" style="background: #19be6b;color: #FFF;">
<view>
<view style="font-size: 24rpx;">
订单总金额
</view>
<view style="font-weight: bold;margin-top: 10rpx;">
{{ content_info.order_total_price }}
</view>
</view>
<view style="width: 3rpx;background: #F0F0F0;height: 100rpx;"></view>
<view>
<view>
实收总金额
</view>
<view style="font-weight: bold;margin-top: 10rpx;">
{{ content_info.order_pay_price }}
</view>
</view>
</view>
<view class="info-item">
<view>
<view style="font-size: 24rpx;">
优惠总金额
</view>
<view style="font-weight: bold;margin-top: 10rpx;">
{{ content_info.order_prefer_price }}
</view>
</view>
<view style="width: 3rpx;background: #F0F0F0;height: 100rpx;"></view>
<view>
<view>
交易总笔数
</view>
<view style="font-weight: bold;margin-top: 10rpx;">
{{ content_info.order_count }}
</view>
</view>
</view>
<view class="info-item">
<view>
<view style="font-size: 24rpx;">
退款总金额
</view>
<view style="font-weight: bold;margin-top: 10rpx;">
{{ content_info.order_refund_price }}
</view>
</view>
<view style="width: 3rpx;background: #F0F0F0;height: 100rpx;"></view>
<view>
<view>
退款总笔数
</view>
<view style="font-weight: bold;margin-top: 10rpx;">
{{ content_info.order_refund_num }}
</view>
</view>
</view>
<view class="info-item">
<view>
<view style="font-size: 24rpx;">
余额收款
</view>
<view style="font-weight: bold;margin-top: 10rpx;">
{{ content_info.order_balance_price }}
</view>
</view>
<view style="width: 3rpx;background: #F0F0F0;height: 100rpx;"></view>
<view>
</view>
</view>
</template>
<view class="qrcode" v-if="show_qrcode">
<div id="reader"></div>
</view>
<wd-popup v-model="show_shop" custom-style="padding: 30px 40px;width: 80%;border-radius: 20rpx;" @close="handleClose">
<view class="shop_item_box" style="max-height: 1000rpx;overflow: scroll;">
<view @click="selectShop(null)"></view>
<view v-for="item in shop_list" @click="selectShop(item)">
{{ item.name }}
</view>
</view>
</wd-popup>
<wd-popup v-model="show_tuikuan" custom-style="padding: 30px 40px;width: 80%;border-radius: 20rpx;" @close="tuikuan_info = {}">
<view style="text-align: center;color: #000;">
退款信息
</view>
<view class="shop_item_box" style="max-height: 1000rpx;overflow: scroll;">
<view style="display: flex;align-items: center;justify-content: space-between;border: none;">
<view style="width: 150rpx;">
订单号
</view>
<view style="width: calc(100% - 150rpx);">
<wd-input style="width: 100%;" v-model="tuikuan_info.order_no" />
</view>
</view>
<view style="display: flex;align-items: center;justify-content: space-between;border: none;">
<view style="width: 150rpx;">
退款金额
</view>
<view style="width: calc(100% - 150rpx);">
<wd-input type="digit" style="width: 100%;" v-model="tuikuan_info.refund_price" />
</view>
</view>
<view style="border: none;display: flex;align-items: center;justify-content: space-around;">
<wd-button type="error" @click="show_tuikuan = 0;tuikuan_info = {}">取消</wd-button>
<wd-button @click="tuikuan(tuikuan_info.order_no)"></wd-button>
</view>
</view>
</wd-popup>
</view>
</template>
<script setup>
import {
ref,
computed
} from 'vue';
import utils from '@/utils/utils.js';
import recon from '@/api/store/recon.js';
import {
Html5Qrcode
} from "html5-qrcode"
const time_type = ref(1);
const pay_type = ref(0);
const start_time = ref(null);
const end_time = ref(null);
const content_info = ref(null);
const shop_list = ref([]);
const shop_info = ref(null);
const html5QrCode = ref(null);
const show_qrcode = ref(0);
const show_shop = ref(0);
const date_list = ref([])
const show_tuikuan = ref(0);
const tuikuan_info = ref({})
import {
onShow,
} from "@dcloudio/uni-app";
const updateTime = (type) => {
console.log(type, 'type')
time_type.value = type
if (type == 0) {
const now = new Date();
now.setTime(now.getTime() - 24 * 3600 * 1000)
const year = now.getFullYear()
const month = ('0' + (now.getMonth() + 1)).slice(-2)
const day = ('0' + now.getDate()).slice(-2)
start_time.value = year + '-' + month + '-' + day
end_time.value = year + '-' + month + '-' + day
getContent()
} else if (type == 1) {
const now = new Date();
const year = now.getFullYear()
const month = ('0' + (now.getMonth() + 1)).slice(-2)
const day = ('0' + now.getDate()).slice(-2)
start_time.value = year + '-' + month + '-' + day
end_time.value = year + '-' + month + '-' + day
getContent()
} else {
}
}
const updatePay = (type) => {
pay_type.value = type
getContent()
}
function handleConfirm({
value
}) {
const now = new Date();
now.setTime(value[0])
const year = now.getFullYear()
const month = ('0' + (now.getMonth() + 1)).slice(-2)
const day = ('0' + now.getDate()).slice(-2)
start_time.value = year + '-' + month + '-' + day
const now1 = new Date();
now1.setTime(value[1])
const year1 = now1.getFullYear()
const month1 = ('0' + (now1.getMonth() + 1)).slice(-2)
const day1 = ('0' + now1.getDate()).slice(-2)
end_time.value = year1 + '-' + month1 + '-' + day1
getContent()
}
function handleCancel(row) {
console.log('handleCancel', row)
updateTime(1)
}
const formatter = (day) => {
const date = new Date(day.date)
const now = new Date()
const year = date.getFullYear()
const month = date.getMonth()
const da = date.getDate()
const nowYear = now.getFullYear()
const nowMonth = now.getMonth()
const nowDa = now.getDate()
if (year === nowYear && month === nowMonth && da === nowDa) {
day.topInfo = '今天'
}
if (day.type === 'start') {
day.bottomInfo = '开始'
}
if (day.type === 'end') {
day.bottomInfo = '结束'
}
if (day.type === 'same') {
day.bottomInfo = '开始/结束'
}
return day
}
const getContent = (row) => {
recon.content({
start_time: start_time.value,
end_time: end_time.value,
pay_type: pay_type.value,
shop_id: shop_info.value ? shop_info.value.id : 0
}).then(res => {
if (res.code == 0) {
content_info.value = res.data
} else {
showNotify({
type: 'error',
message: '出错了'
})
}
})
}
const getShopList = (row) => {
recon.shopList({
}).then(res => {
if (res.code == 0) {
shop_list.value = res.data
} else {
}
})
}
const selectShop = (row) => {
shop_info.value = row
show_shop.value = 0
getContent()
}
const saoma = (row) => {
Html5Qrcode.getCameras()
.then((devices) => {
if (devices && devices.length) {
html5QrCode.value = new Html5Qrcode("reader");
start();
}
})
.catch((err) => {
// handle err
html5QrCode.value = new Html5Qrcode("reader");
uni.showToast({
icon: 'none',
title: '您需要授予相机访问权限'
})
});
}
const start = () => {
show_qrcode.value = 1
html5QrCode.value
.start({
facingMode: "environment"
}, {
fps: 2,
qrbox: {
width: 250,
height: 250
},
},
(decodedText, decodedResult) => {
recon.faceOrder({
qr_code: decodedText
}).then(res => {
if (res.code == 0) {
show_qrcode.value = 0
uni.showToast({
icon: 'none',
title: res.msg
})
} else {
uni.showToast({
icon: 'none',
title: res.msg
})
}
})
}
)
.catch((err) => {
show_qrcode.value = 0
uni.showToast({
icon: 'none',
title: '扫码出错'
})
});
}
const stop = (row) => {
html5QrCode.value.stop().then((ignore) => {
// QR Code scanning is stopped.
console.log("QR Code scanning stopped.");
})
.catch((err) => {
// Stop failed, handle it.
console.log("Unable to stop scanning.");
});
}
let search_date = computed({
get() {
}
})
const tuikuan = (order_no) => {
uni.showModal({
title: '提示',
content: '是否确认退款?',
success(res) {
if (res.confirm) {
uni.showLoading({
title: '提交中'
})
recon.tuikuan({
order_no,
refund_price: tuikuan_info.value ? tuikuan_info.value.refund_price : 0
}).then(res => {
uni.hideLoading()
if (res.code == 0) {
uni.showToast({
icon: 'none',
title: '退款成功'
})
show_tuikuan.value = 0
} else {
uni.showToast({
icon: 'none',
title: res.msg
})
}
})
}
}
})
};
//
onShow(() => {
if (time_type.value == 1) {
const now = new Date();
const year = now.getFullYear()
const month = ('0' + (now.getMonth() + 1)).slice(-2)
const day = ('0' + now.getDate()).slice(-2)
start_time.value = year + '-' + month + '-' + day
end_time.value = year + '-' + month + '-' + day
}
getContent()
getShopList()
})
</script>
<style lang="scss" scoped>
.action-box {
margin-top: 30rpx;
display: flex;
justify-content: space-around;
font-size: 24rpx;
}
.action-box>view {
padding: 40rpx;
background: #FFF;
width: 40%;
box-shadow: 0 0 10rpx #aaa;
text-align: center;
display: flex;
align-items: center;
justify-content: center;
}
.action-box>view>view {
margin-left: 10rpx;
}
.content-time {
display: flex;
align-items: center;
justify-content: center;
border-bottom: 1rpx solid #F0F0F0;
padding: 20rpx;
background: #FFF;
// margin-top: 30rpx;
}
.content-time>view {
margin: 10rpx;
}
.content-time>.time-active {
color: #18b566;
}
.content-time-info {
text-align: center;
font-size: 24rpx;
background: #FFF;
padding: 20rpx;
color: #71d5a1;
}
.info-item {
display: flex;
align-items: center;
justify-content: space-between;
background: #FFF;
color: #333;
padding: 20rpx 0;
border-bottom: 1rpx solid #F0F0F0;
}
.info-item>view {
text-align: center;
width: 50%;
font-size: 26rpx;
}
.pay-type-box {
display: flex;
justify-content: center;
font-size: 28rpx;
}
.pay-type-box>view {
padding: 4rpx 10rpx;
margin: 0 10rpx;
}
.pay-type-box>.time-active {
color: #fff;
background: #18b566;
border-radius: 10rpx;
}
.qrcode {
position: fixed;
top: 0;
bottom: 0;
left: 0;
right: 0;
background: rgba($color: #000000, $alpha: 0.48);
z-index: 5;
}
#reader {
top: 50%;
left: 0;
transform: translateY(-50%);
}
.shop_item_box>view {
padding: 20rpx 0;
border-bottom: 1rpx solid #F0F0F0;
}
</style>

@ -1,295 +0,0 @@
<template>
<view class="content">
<kevyloading v-if="loading" type="bsm-loader" color="#618af8" transparent></kevyloading>
<view class=" bg-white sticky top-0 z-50 flex items-center">
<view class="flex-1">
<wd-search @search="search({ value: params.keywords })" @clear="search({ value: params.keywords = '' })"
v-model="params.keywords" hide-cancel></wd-search>
</view>
</view>
<div class="grid p-2">
<yList height="91vh" ref="yListRef" :apiObj="recon.faceList" :params="{ ...params }">
<template #default="{ list: order_list }">
<div v-for="order of order_list" class="rounded-md overflow-hidden">
<wd-card class="rounded-md overflow-hidden" type="rectangle">
<template #title>
<view class="title">
<view>ID{{ order.id }}</view>
<view @click="utils.copy(order.order_no)" class="title-tip">
{{ order.order_no }}
<wd-icon name="file-copy" size="14px"></wd-icon>
</view>
</view>
</template>
<view style="height: 40px;display: block;" class="userBox" v-if="order.detail && order.detail.length > 0">
<view v-for="item of order.detail" style="width: 100%;">
<view style="color: rgba(0,0,0,0.85); font-size: 16px;display: flex;align-items: center;justify-content: space-around;">
<view style="width: 50%;">
{{ item.goods_name }}
</view>
<view style="width: 25%;">
x {{ item.num }}
</view>
<view style="width: 25%;">
<wd-tag class="mx-1" size="small" type="success">
{{ item.price }}
</wd-tag>
</view>
</view>
</view>
</view>
<template #footer>
<view class="flex justify-between items-center">
<view style="color: #999;">
{{ order.create_time }}
</view>
<view style="color: rgba(0,0,0,0.85);padding: 30rpx 0">
支付金额{{ order.pay_price }}
</view>
<view>
<wd-button @click="tuikuan_order = order;show_tuikuan=1;tuikuan_info.refund_price = tuikuan_order.pay_price" size="small"
style="margin-right: 0px;">退款</wd-button>
</view>
</view>
</template>
</wd-card>
</div>
</template>
</yList>
</div>
<wd-toast />
<wd-message-box></wd-message-box>
<wd-popup v-model="show_tuikuan" custom-style="padding: 30px 40px;width: 80%;border-radius: 20rpx;" @close="tuikuan_info = {}">
<view style="text-align: center;color: #000;">
退款信息
</view>
<view class="shop_item_box" style="max-height: 1000rpx;overflow: scroll;">
<view style="display: flex;align-items: center;justify-content: space-between;border: none;">
<view style="width: 150rpx;">
订单号
</view>
<view style="width: calc(100% - 150rpx);">
{{ tuikuan_order.order_no }}
</view>
</view>
<view style="display: flex;align-items: center;justify-content: space-between;border: none;">
<view style="width: 150rpx;">
退款金额
</view>
<view style="width: calc(100% - 150rpx);">
<wd-input type="digit" style="width: 100%;" v-model="tuikuan_info.refund_price" />
</view>
</view>
<view style="border: none;display: flex;align-items: center;justify-content: space-around;">
<wd-button type="error" @click="show_tuikuan = 0;tuikuan_info = {}">取消</wd-button>
<wd-button @click="tuikuan(tuikuan_order.order_no)"></wd-button>
</view>
</view>
</wd-popup>
</view>
</template>
<script setup>
import {
ref
} from 'vue';
import utils from '@/utils/utils.js';
import recon from '@/api/store/recon.js';
import myTabbar from "../components/myTabbar/index.vue";
import kevyloading from "@/components/kevy-loading/kevy-loading";
import {
useMessage
} from '@/uni_modules/wot-design-uni';
import {
useToast
} from '@/uni_modules/wot-design-uni'
import yList from "/components/yList/index.vue";
import {
onShow,
} from "@dcloudio/uni-app";
const toast = useToast()
const message1 = useMessage();
const originType = ref({
100: 'success',
101: 'success',
200: 'info',
201: 'danger',
300: 'warning',
})
const yListRef = ref(null);
const searchType = ref('订单号');
const popover = ref(false);
const show_tuikuan = ref(0);
const tuikuan_info = ref({})
const tuikuan_order = ref({})
const search = ({
value
}) => {
if (searchType.value == '昵称') {
yListRef.value.upData({
type: 'order_no',
keywords: params.value.keywords
});
}
if (searchType.value == '订单号') {
yListRef.value.upData({
type: 'order_no',
keywords: params.value.keywords
});
}
};
const tuikuan = (order_no) => {
uni.showModal({
title: '提示',
content: '是否确认退款?',
success(res) {
if (res.confirm) {
uni.showLoading({
title: '提交中'
})
recon.tuikuan({
order_no,
refund_price: tuikuan_info.value ? tuikuan_info.value.refund_price : 0
}).then(res => {
uni.hideLoading()
if (res.code == 0) {
uni.showToast({
icon: 'none',
title: '退款成功'
})
show_tuikuan.value = 0
} else {
uni.showToast({
icon: 'none',
title: res.msg
})
}
})
}
}
})
};
const menu = ref([{
content: '昵称'
},
{
content: '订单号'
},
]);
const params = ref({
keywords: "",
type: 'order_no',
status: -2
});
/**
* 切换搜索类型
* @param {Object} item - 切换的项
*/
function changeSearchType({
item,
index
}) {
searchType.value = item.content;
search(params.value.keywords)
}
/**
* @type {Ref<boolean>}
* 控制页面加载状态的 Ref
*/
const loading = ref(false);
const order_list = ref([]);
//
onShow(() => {
})
</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;
}
}
.userBox,
.title {
display: flex;
flex-direction: row;
justify-content: flex-start;
align-items: center;
}
.userBox {
justify-content: flex-start;
}
.title {
justify-content: space-between;
}
.title-tip {
color: rgba(0, 0, 0, 0.25);
font-size: 12px;
}
.shop_item_box>view {
padding: 20rpx 0;
border-bottom: 1rpx solid #F0F0F0;
}
</style>

@ -1,47 +1,14 @@
## 0.2.172024-01-23 ## 0.2.132024-01-12
### [0.2.17](https://github.com/Moonofweisheng/wot-design-uni/compare/v0.2.16...v0.2.17) (2024-01-23) ### [0.2.13](https://github.com/Moonofweisheng/wot-design-uni/compare/v0.2.12...v0.2.13) (2024-01-12)
### ✨ Features | 新功能 ### Bug Fixes | Bug 修复
* ✨ Form 表单组件提供开关控制是否model变化时重置提示信息 ([b9f46ba](https://github.com/Moonofweisheng/wot-design-uni/commit/b9f46ba0da85acd7312753a34dd0ad3f2f7379a2)), closes [#166](https://github.com/Moonofweisheng/wot-design-uni/issues/166) * 修复演示文档刷新后指向localhost的问题 ([4cd8b16](https://github.com/Moonofweisheng/wot-design-uni/commit/4cd8b16bdf5ea8e93cff85396025844e9ebd031c))
# 更新日志 # 更新日志
### [0.2.17](https://github.com/Moonofweisheng/wot-design-uni/compare/v0.2.16...v0.2.17) (2024-01-23)
### ✨ Features | 新功能
* ✨ Form 表单组件提供开关控制是否model变化时重置提示信息 ([b9f46ba](https://github.com/Moonofweisheng/wot-design-uni/commit/b9f46ba0da85acd7312753a34dd0ad3f2f7379a2)), closes [#166](https://github.com/Moonofweisheng/wot-design-uni/issues/166)
### [0.2.16](https://github.com/Moonofweisheng/wot-design-uni/compare/v0.2.15...v0.2.16) (2024-01-21)
### ✏️ Documentation | 文档
* ✏️ 修复文档中关于日期选择器最大日期描述错误的问题 ([bb76ce3](https://github.com/Moonofweisheng/wot-design-uni/commit/bb76ce332c6977cbae981790aa356bc27c0d9efa))
### [0.2.15](https://github.com/Moonofweisheng/wot-design-uni/compare/v0.2.14...v0.2.15) (2024-01-15)
### 🐛 Bug Fixes | Bug 修复
* 🐛 修复 Tab class类名属性错误的问题 ([dc87df7](https://github.com/Moonofweisheng/wot-design-uni/commit/dc87df70c7920d7cfabc571ace8beb2ce0dc2a7c))
### ✏️ Documentation | 文档
* ✏️ 修复 Upload 文档中before-upload钩子参数描述错误的问题 ([3ec7299](https://github.com/Moonofweisheng/wot-design-uni/commit/3ec7299ce724fce771b782f6110ba6ec29376291))
### [0.2.14](https://github.com/Moonofweisheng/wot-design-uni/compare/v0.2.13...v0.2.14) (2024-01-14)
### ✨ Features | 新功能
* ✨ InputNumber步进器支持禁用输入框 ([933bce3](https://github.com/Moonofweisheng/wot-design-uni/commit/933bce314618956ff922daacef5b3594f36baf9b))
### [0.2.13](https://github.com/Moonofweisheng/wot-design-uni/compare/v0.2.12...v0.2.13) (2024-01-12) ### [0.2.13](https://github.com/Moonofweisheng/wot-design-uni/compare/v0.2.12...v0.2.13) (2024-01-12)

@ -26,15 +26,12 @@ interface Props {
model: Record<string, any> model: Record<string, any>
// //
rules?: FormRules rules?: FormRules
//
resetOnChange?: boolean
customClass?: string customClass?: string
customStyle?: string customStyle?: string
} }
const props = withDefaults(defineProps<Props>(), { const props = withDefaults(defineProps<Props>(), {
rules: () => ({}), rules: () => ({}),
resetOnChange: true,
customClass: '', customClass: '',
customStyle: '' customStyle: ''
}) })
@ -47,9 +44,7 @@ linkChildren({ props, errorMessages: errorMessages })
watch( watch(
() => props.model, () => props.model,
() => { () => {
if (props.resetOnChange) { clearMessage()
clearMessage()
}
}, },
{ immediate: true, deep: true } { immediate: true, deep: true }
) )
@ -134,14 +129,6 @@ async function validate(prop?: string): Promise<{ valid: boolean; errors: ErrorM
showMessage(error) showMessage(error)
}) })
if (valid) {
if (prop) {
clearMessage(prop)
} else {
clearMessage()
}
}
return { return {
valid, valid,
errors errors
@ -169,14 +156,10 @@ function showMessage(errorMsg: ErrorMessage) {
} }
} }
function clearMessage(prop?: string) { function clearMessage() {
if (prop) { Object.keys(errorMessages).forEach((key) => {
errorMessages[prop] = '' errorMessages[key] = ''
} else { })
Object.keys(errorMessages).forEach((key) => {
errorMessages[key] = ''
})
}
} }
function reset() { function reset() {

@ -1,14 +1,14 @@
<template> <template>
<view :class="`wd-input-number ${customClass} ${disabled ? 'is-disabled' : ''} ${withoutInput ? 'is-without-input' : ''}`"> <view :class="`wd-input-number ${customClass} ${disabled ? 'is-disabled' : ''} ${withoutInput ? 'is-without-input' : ''}`">
<view :class="`wd-input-number__action ${minDisabled || disableMinus ? 'is-disabled' : ''}`" @click="sub"> <view :class="`wd-input-number__action ${minDisabled ? 'is-disabled' : ''}`" @click="sub">
<wd-icon name="decrease" custom-class="wd-input-number__action-icon"></wd-icon> <wd-icon name="decrease" custom-class="wd-input-number__action-icon"></wd-icon>
</view> </view>
<view v-if="!withoutInput" class="wd-input-number__inner" @click.stop=""> <view v-if="!withoutInput" class="wd-input-number__inner">
<input <input
class="wd-input-number__input" class="wd-input-number__input"
:style="`${inputWidth ? 'width: ' + inputWidth : ''}`" :style="`${inputWidth ? 'width: ' + inputWidth : ''}`"
type="digit" type="digit"
:disabled="disabled || disableInput" :disabled="disabled"
v-model="inputValue" v-model="inputValue"
:placeholder="placeholder" :placeholder="placeholder"
@input="handleInput" @input="handleInput"
@ -17,7 +17,7 @@
/> />
<view class="wd-input-number__input-border"></view> <view class="wd-input-number__input-border"></view>
</view> </view>
<view :class="`wd-input-number__action ${maxDisabled || disablePlus ? 'is-disabled' : ''}`" @click="add"> <view :class="`wd-input-number__action ${maxDisabled ? 'is-disabled' : ''}`" @click="add">
<wd-icon name="add" custom-class="wd-input-number__action-icon"></wd-icon> <wd-icon name="add" custom-class="wd-input-number__action-icon"></wd-icon>
</view> </view>
</view> </view>
@ -47,13 +47,11 @@ interface Props {
stepStrictly?: boolean stepStrictly?: boolean
precision?: number precision?: number
disabled?: boolean disabled?: boolean
disableInput?: boolean
disableMinus?: boolean
disablePlus?: boolean
withoutInput?: boolean withoutInput?: boolean
inputWidth?: string | number inputWidth?: string | number
allowNull?: boolean allowNull?: boolean
placeholder?: string placeholder?: string
name?: string
} }
const props = withDefaults(defineProps<Props>(), { const props = withDefaults(defineProps<Props>(), {
@ -64,13 +62,11 @@ const props = withDefaults(defineProps<Props>(), {
stepStrictly: false, stepStrictly: false,
precision: 0, precision: 0,
disabled: false, disabled: false,
disableInput: false,
disableMinus: false,
disablePlus: false,
withoutInput: false, withoutInput: false,
inputWidth: 36, inputWidth: 36,
allowNull: false, allowNull: false,
placeholder: '' placeholder: '',
name: ''
}) })
const minDisabled = ref<boolean>(false) const minDisabled = ref<boolean>(false)
@ -172,14 +168,14 @@ function changeStep(val: string | number, step: number) {
} }
function sub() { function sub() {
if (minDisabled.value || props.disableMinus) return if (minDisabled.value) return
const newValue = changeStep(inputValue.value, -props.step) const newValue = changeStep(inputValue.value, -props.step)
dispatchChangeEvent(newValue) dispatchChangeEvent(newValue)
} }
function add() { function add() {
if (maxDisabled.value || props.disablePlus) return if (maxDisabled.value) return
const newValue = changeStep(inputValue.value, props.step) const newValue = changeStep(inputValue.value, props.step)
dispatchChangeEvent(newValue) dispatchChangeEvent(newValue)

@ -1,6 +1,6 @@
<template> <template>
<view :class="`wd-tab ${customClass}`"> <view :class="`wd-tab ${customClass}`">
<view v-if="painted" class="wd-tab__body" :style="isShow ? '' : 'display: none;'"> <view v-if="painted" cclass="wd-tab__body" :style="isShow ? '' : 'display: none;'">
<slot /> <slot />
</view> </view>
</view> </view>
@ -16,7 +16,7 @@ export default {
} }
</script> </script>
<script lang="ts" setup> <script lang="ts" setup>
import { getCurrentInstance, ref, watch } from 'vue' import { getCurrentInstance, onBeforeMount, ref, watch } from 'vue'
import { getType, isDef } from '../common/util' import { getType, isDef } from '../common/util'
import { useParent } from '../composables/useParent' import { useParent } from '../composables/useParent'
import { TABS_KEY } from '../wd-tabs/types' import { TABS_KEY } from '../wd-tabs/types'

@ -2,7 +2,7 @@
"id": "wot-design-uni", "id": "wot-design-uni",
"name": "wot-design-uni", "name": "wot-design-uni",
"displayName": "wot-design-uni 基于vue3+Typescript的高颜值组件库", "displayName": "wot-design-uni 基于vue3+Typescript的高颜值组件库",
"version": "0.2.17", "version": "0.2.13",
"description": "一个基于Vue3+TS开发的uni-app组件库提供60+高质量组件,支持暗黑模式和自定义主题。", "description": "一个基于Vue3+TS开发的uni-app组件库提供60+高质量组件,支持暗黑模式和自定义主题。",
"keywords": [ "keywords": [
"wot-design-uni", "wot-design-uni",

@ -154,7 +154,7 @@ const uploadImage = async ({ filePath, formData, name } = {}) => {
}; };
uni.uploadFile({ uni.uploadFile({
url: env.host + '/admin/system/uploadImage', url: 'https://saasdemo.byin.vip/admin/system/uploadImage',
filePath: filePath, filePath: filePath,
name: name || 'file', // 表单中文件字段的名称 name: name || 'file', // 表单中文件字段的名称
formData: formData, formData: formData,

@ -158,10 +158,8 @@ export default {
loginOut() { loginOut() {
const [curRoute, curRouteParam] = this.getRouterInfo() const [curRoute, curRouteParam] = this.getRouterInfo()
uni.setStorageSync("backPage", "/" + curRoute + curRouteParam) uni.setStorageSync("backPage", "/" + curRoute + curRouteParam)
// uni.clearStorage();
uni.setStorageSync("store_info", null) uni.clearStorage();
uni.setStorageSync("user_info", null)
uni.setStorageSync("token", null)
this.toUrl("/pages/login/index", "redirectTo"); this.toUrl("/pages/login/index", "redirectTo");
}, },

@ -292,17 +292,6 @@ browserslist@^4.21.10:
node-releases "^2.0.14" node-releases "^2.0.14"
update-browserslist-db "^1.0.13" update-browserslist-db "^1.0.13"
call-bind@^1.0.2, call-bind@^1.0.6, call-bind@^1.0.7:
version "1.0.7"
resolved "https://registry.yarnpkg.com/call-bind/-/call-bind-1.0.7.tgz#06016599c40c56498c18769d2730be242b6fa3b9"
integrity sha512-GHTSNSYICQ7scH7sZ+M2rFopRoLh8t2bLSW6BbgrtLsahOIB5iyAVJf9GjWK3cYTDaMj4XdBpM1cA6pIS0Kv2w==
dependencies:
es-define-property "^1.0.0"
es-errors "^1.3.0"
function-bind "^1.1.2"
get-intrinsic "^1.2.4"
set-function-length "^1.2.1"
camelcase-css@^2.0.1: camelcase-css@^2.0.1:
version "2.0.1" version "2.0.1"
resolved "https://registry.yarnpkg.com/camelcase-css/-/camelcase-css-2.0.1.tgz#ee978f6947914cc30c6b44741b6ed1df7f043fd5" resolved "https://registry.yarnpkg.com/camelcase-css/-/camelcase-css-2.0.1.tgz#ee978f6947914cc30c6b44741b6ed1df7f043fd5"
@ -337,11 +326,6 @@ chokidar@^3.5.3:
optionalDependencies: optionalDependencies:
fsevents "~2.3.2" fsevents "~2.3.2"
clone@^2.1.1:
version "2.1.2"
resolved "https://registry.yarnpkg.com/clone/-/clone-2.1.2.tgz#1b7f4b9f591f1e8f83670401600345a02887435f"
integrity sha512-3Pe/CF1Nn94hyhIYpjtiLhdCoEoz0DqQ+988E9gmeEdQZlojxnOb74wctFyuwWQHzqyf9X7C7MG8juUpqBJT8w==
color-convert@^1.9.0: color-convert@^1.9.0:
version "1.9.3" version "1.9.3"
resolved "https://registry.yarnpkg.com/color-convert/-/color-convert-1.9.3.tgz#bb71850690e1f136567de629d2d5471deda4c1e8" resolved "https://registry.yarnpkg.com/color-convert/-/color-convert-1.9.3.tgz#bb71850690e1f136567de629d2d5471deda4c1e8"
@ -392,36 +376,6 @@ debug@^4.1.0:
dependencies: dependencies:
ms "2.1.2" ms "2.1.2"
deep-equal@^1.0.1:
version "1.1.2"
resolved "https://registry.yarnpkg.com/deep-equal/-/deep-equal-1.1.2.tgz#78a561b7830eef3134c7f6f3a3d6af272a678761"
integrity sha512-5tdhKF6DbU7iIzrIOa1AOUt39ZRm13cmL1cGEh//aqR8x9+tNfbywRf0n5FD/18OKMdo7DNEtrX2t22ZAkI+eg==
dependencies:
is-arguments "^1.1.1"
is-date-object "^1.0.5"
is-regex "^1.1.4"
object-is "^1.1.5"
object-keys "^1.1.1"
regexp.prototype.flags "^1.5.1"
define-data-property@^1.0.1, define-data-property@^1.1.4:
version "1.1.4"
resolved "https://registry.yarnpkg.com/define-data-property/-/define-data-property-1.1.4.tgz#894dc141bb7d3060ae4366f6a0107e68fbe48c5e"
integrity sha512-rBMvIzlpA8v6E+SJZoo++HAYqsLrkg7MSfIinMPFhmkorw7X+dOXVJQs+QT69zGkzMyfDnIMN2Wid1+NbL3T+A==
dependencies:
es-define-property "^1.0.0"
es-errors "^1.3.0"
gopd "^1.0.1"
define-properties@^1.2.1:
version "1.2.1"
resolved "https://registry.yarnpkg.com/define-properties/-/define-properties-1.2.1.tgz#10781cc616eb951a80a034bafcaa7377f6af2b6c"
integrity sha512-8QmQKqEASLd5nx0U1B1okLElbUuuttJ/AnYmRXbbbGDWh6uS208EjD4Xqq/I9wK7u0v6O08XhTWnt5XtEbR6Dg==
dependencies:
define-data-property "^1.0.1"
has-property-descriptors "^1.0.0"
object-keys "^1.1.1"
didyoumean@^1.2.2: didyoumean@^1.2.2:
version "1.2.2" version "1.2.2"
resolved "https://registry.yarnpkg.com/didyoumean/-/didyoumean-1.2.2.tgz#989346ffe9e839b4555ecf5666edea0d3e8ad037" resolved "https://registry.yarnpkg.com/didyoumean/-/didyoumean-1.2.2.tgz#989346ffe9e839b4555ecf5666edea0d3e8ad037"
@ -457,18 +411,6 @@ emojis-list@^3.0.0:
resolved "https://registry.yarnpkg.com/emojis-list/-/emojis-list-3.0.0.tgz#5570662046ad29e2e916e71aae260abdff4f6a78" resolved "https://registry.yarnpkg.com/emojis-list/-/emojis-list-3.0.0.tgz#5570662046ad29e2e916e71aae260abdff4f6a78"
integrity sha512-/kyM18EfinwXZbno9FyUGeFh87KC8HRQBQGildHZbEuRyWFOmv1U10o9BBp8XVZDVNNuQKyIGIu5ZYAAXJ0V2Q== integrity sha512-/kyM18EfinwXZbno9FyUGeFh87KC8HRQBQGildHZbEuRyWFOmv1U10o9BBp8XVZDVNNuQKyIGIu5ZYAAXJ0V2Q==
es-define-property@^1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/es-define-property/-/es-define-property-1.0.0.tgz#c7faefbdff8b2696cf5f46921edfb77cc4ba3845"
integrity sha512-jxayLKShrEqqzJ0eumQbVhTYQM27CfT1T35+gCgDFoL82JLsXqTJ76zv6A0YLOgEnLUMvLzsDsGIrl8NFpT2gQ==
dependencies:
get-intrinsic "^1.2.4"
es-errors@^1.3.0:
version "1.3.0"
resolved "https://registry.yarnpkg.com/es-errors/-/es-errors-1.3.0.tgz#05f75a25dab98e4fb1dcd5e1472c0546d5057c8f"
integrity sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==
escalade@^3.1.1: escalade@^3.1.1:
version "3.1.1" version "3.1.1"
resolved "https://registry.yarnpkg.com/escalade/-/escalade-3.1.1.tgz#d8cfdc7000965c5a0174b4a82eaa5c0552742e40" resolved "https://registry.yarnpkg.com/escalade/-/escalade-3.1.1.tgz#d8cfdc7000965c5a0174b4a82eaa5c0552742e40"
@ -479,21 +421,6 @@ escape-string-regexp@^1.0.5:
resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz#1b61c0562190a8dff6ae3bb2cf0200ca130b86d4" resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz#1b61c0562190a8dff6ae3bb2cf0200ca130b86d4"
integrity sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg== integrity sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==
eventemitter3@^2.0.3:
version "2.0.3"
resolved "https://registry.yarnpkg.com/eventemitter3/-/eventemitter3-2.0.3.tgz#b5e1079b59fb5e1ba2771c0a993be060a58c99ba"
integrity sha512-jLN68Dx5kyFHaePoXWPsCGW5qdyZQtLYHkxkg02/Mz6g0kYpDx4FyP6XfArhQdlOC4b8Mv+EMxPo/8La7Tzghg==
extend@^3.0.2:
version "3.0.2"
resolved "https://registry.yarnpkg.com/extend/-/extend-3.0.2.tgz#f8b1136b4071fbd8eb140aff858b1019ec2915fa"
integrity sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==
fast-diff@1.1.2:
version "1.1.2"
resolved "https://registry.yarnpkg.com/fast-diff/-/fast-diff-1.1.2.tgz#4b62c42b8e03de3f848460b639079920695d0154"
integrity sha512-KaJUt+M9t1qaIteSvjc6P3RbMdXsNhK61GRftR6SNxqmhthcd9MGIi4T+o0jD8LUSpSnSKXE20nLtJ3fOHxQig==
fast-glob@^3.3.0: fast-glob@^3.3.0:
version "3.3.2" version "3.3.2"
resolved "https://registry.yarnpkg.com/fast-glob/-/fast-glob-3.3.2.tgz#a904501e57cfdd2ffcded45e99a54fef55e46129" resolved "https://registry.yarnpkg.com/fast-glob/-/fast-glob-3.3.2.tgz#a904501e57cfdd2ffcded45e99a54fef55e46129"
@ -542,22 +469,6 @@ function-bind@^1.1.2:
resolved "https://registry.yarnpkg.com/function-bind/-/function-bind-1.1.2.tgz#2c02d864d97f3ea6c8830c464cbd11ab6eab7a1c" resolved "https://registry.yarnpkg.com/function-bind/-/function-bind-1.1.2.tgz#2c02d864d97f3ea6c8830c464cbd11ab6eab7a1c"
integrity sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA== integrity sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==
functions-have-names@^1.2.3:
version "1.2.3"
resolved "https://registry.yarnpkg.com/functions-have-names/-/functions-have-names-1.2.3.tgz#0404fe4ee2ba2f607f0e0ec3c80bae994133b834"
integrity sha512-xckBUXyTIqT97tq2x2AMb+g163b5JFysYk0x4qxNFwbfQkmNZoiRHb6sPzI9/QV33WeuvVYBUIiD4NzNIyqaRQ==
get-intrinsic@^1.1.3, get-intrinsic@^1.2.4:
version "1.2.4"
resolved "https://registry.yarnpkg.com/get-intrinsic/-/get-intrinsic-1.2.4.tgz#e385f5a4b5227d449c3eabbad05494ef0abbeadd"
integrity sha512-5uYhsJH8VJBTv7oslg4BznJYhDoRI6waYCxMmCdnTrcCrHA/fCFKoTFz2JKKE0HdDFUF7/oQuhzumXJK7paBRQ==
dependencies:
es-errors "^1.3.0"
function-bind "^1.1.2"
has-proto "^1.0.1"
has-symbols "^1.0.3"
hasown "^2.0.0"
glob-parent@^5.1.2, glob-parent@~5.1.2: glob-parent@^5.1.2, glob-parent@~5.1.2:
version "5.1.2" version "5.1.2"
resolved "https://registry.yarnpkg.com/glob-parent/-/glob-parent-5.1.2.tgz#869832c58034fe68a4093c17dc15e8340d8401c4" resolved "https://registry.yarnpkg.com/glob-parent/-/glob-parent-5.1.2.tgz#869832c58034fe68a4093c17dc15e8340d8401c4"
@ -588,42 +499,11 @@ globals@^11.1.0:
resolved "https://registry.yarnpkg.com/globals/-/globals-11.12.0.tgz#ab8795338868a0babd8525758018c2a7eb95c42e" resolved "https://registry.yarnpkg.com/globals/-/globals-11.12.0.tgz#ab8795338868a0babd8525758018c2a7eb95c42e"
integrity sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA== integrity sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==
gopd@^1.0.1:
version "1.0.1"
resolved "https://registry.yarnpkg.com/gopd/-/gopd-1.0.1.tgz#29ff76de69dac7489b7c0918a5788e56477c332c"
integrity sha512-d65bNlIadxvpb/A2abVdlqKqV563juRnZ1Wtk6s1sIR8uNsXR70xqIzVqxVf1eTqDunwT2MkczEeaezCKTZhwA==
dependencies:
get-intrinsic "^1.1.3"
has-flag@^3.0.0: has-flag@^3.0.0:
version "3.0.0" version "3.0.0"
resolved "https://registry.yarnpkg.com/has-flag/-/has-flag-3.0.0.tgz#b5d454dc2199ae225699f3467e5a07f3b955bafd" resolved "https://registry.yarnpkg.com/has-flag/-/has-flag-3.0.0.tgz#b5d454dc2199ae225699f3467e5a07f3b955bafd"
integrity sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw== integrity sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==
has-property-descriptors@^1.0.0, has-property-descriptors@^1.0.2:
version "1.0.2"
resolved "https://registry.yarnpkg.com/has-property-descriptors/-/has-property-descriptors-1.0.2.tgz#963ed7d071dc7bf5f084c5bfbe0d1b6222586854"
integrity sha512-55JNKuIW+vq4Ke1BjOTjM2YctQIvCT7GFzHwmfZPGo5wnrgkid0YQtnAleFSqumZm4az3n2BS+erby5ipJdgrg==
dependencies:
es-define-property "^1.0.0"
has-proto@^1.0.1:
version "1.0.3"
resolved "https://registry.yarnpkg.com/has-proto/-/has-proto-1.0.3.tgz#b31ddfe9b0e6e9914536a6ab286426d0214f77fd"
integrity sha512-SJ1amZAJUiZS+PhsVLf5tGydlaVB8EdFpaSO4gmiUKUOxk8qzn5AIy4ZeJUmh22znIdk/uMAUT2pl3FxzVUH+Q==
has-symbols@^1.0.3:
version "1.0.3"
resolved "https://registry.yarnpkg.com/has-symbols/-/has-symbols-1.0.3.tgz#bb7b2c4349251dce87b125f7bdf874aa7c8b39f8"
integrity sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A==
has-tostringtag@^1.0.0:
version "1.0.2"
resolved "https://registry.yarnpkg.com/has-tostringtag/-/has-tostringtag-1.0.2.tgz#2cdc42d40bef2e5b4eeab7c01a73c54ce7ab5abc"
integrity sha512-NqADB8VjPFLM2V0VvHUewwwsw0ZWBaIdgo+ieHtK3hasLz4qeCRjYcqfB6AQrBggRKppKF8L52/VqdVsO47Dlw==
dependencies:
has-symbols "^1.0.3"
hasown@^2.0.0: hasown@^2.0.0:
version "2.0.0" version "2.0.0"
resolved "https://registry.yarnpkg.com/hasown/-/hasown-2.0.0.tgz#f4c513d454a57b7c7e1650778de226b11700546c" resolved "https://registry.yarnpkg.com/hasown/-/hasown-2.0.0.tgz#f4c513d454a57b7c7e1650778de226b11700546c"
@ -631,19 +511,6 @@ hasown@^2.0.0:
dependencies: dependencies:
function-bind "^1.1.2" function-bind "^1.1.2"
html5-qrcode@^2.3.8:
version "2.3.8"
resolved "https://registry.yarnpkg.com/html5-qrcode/-/html5-qrcode-2.3.8.tgz#0b0cdf7a9926cfd4be530e13a51db47592adfa0d"
integrity sha512-jsr4vafJhwoLVEDW3n1KvPnCCXWaQfRng0/EEYk1vNcQGcG/htAdhJX0be8YyqMoSz7+hZvOZSTAepsabiuhiQ==
is-arguments@^1.1.1:
version "1.1.1"
resolved "https://registry.yarnpkg.com/is-arguments/-/is-arguments-1.1.1.tgz#15b3f88fda01f2a97fec84ca761a560f123efa9b"
integrity sha512-8Q7EARjzEnKpt/PCD7e1cgUS0a6X8u5tdSiMqXhojOdoV9TsMsiO+9VLC5vAmO8N7/GmXn7yjR8qnA6bVAEzfA==
dependencies:
call-bind "^1.0.2"
has-tostringtag "^1.0.0"
is-binary-path@~2.1.0: is-binary-path@~2.1.0:
version "2.1.0" version "2.1.0"
resolved "https://registry.yarnpkg.com/is-binary-path/-/is-binary-path-2.1.0.tgz#ea1f7f3b80f064236e83470f86c09c254fb45b09" resolved "https://registry.yarnpkg.com/is-binary-path/-/is-binary-path-2.1.0.tgz#ea1f7f3b80f064236e83470f86c09c254fb45b09"
@ -658,13 +525,6 @@ is-core-module@^2.13.0:
dependencies: dependencies:
hasown "^2.0.0" hasown "^2.0.0"
is-date-object@^1.0.5:
version "1.0.5"
resolved "https://registry.yarnpkg.com/is-date-object/-/is-date-object-1.0.5.tgz#0841d5536e724c25597bf6ea62e1bd38298df31f"
integrity sha512-9YQaSxsAiSwcvS33MBk3wTCVnWK+HhF8VZR2jRxehM16QcVOdHqPn4VPHmRK4lSr38n9JriurInLcP90xsYNfQ==
dependencies:
has-tostringtag "^1.0.0"
is-extglob@^2.1.1: is-extglob@^2.1.1:
version "2.1.1" version "2.1.1"
resolved "https://registry.yarnpkg.com/is-extglob/-/is-extglob-2.1.1.tgz#a88c02535791f02ed37c76a1b9ea9773c833f8c2" resolved "https://registry.yarnpkg.com/is-extglob/-/is-extglob-2.1.1.tgz#a88c02535791f02ed37c76a1b9ea9773c833f8c2"
@ -687,14 +547,6 @@ is-number@^7.0.0:
resolved "https://registry.yarnpkg.com/is-number/-/is-number-7.0.0.tgz#7535345b896734d5f80c4d06c50955527a14f12b" resolved "https://registry.yarnpkg.com/is-number/-/is-number-7.0.0.tgz#7535345b896734d5f80c4d06c50955527a14f12b"
integrity sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng== integrity sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==
is-regex@^1.1.4:
version "1.1.4"
resolved "https://registry.yarnpkg.com/is-regex/-/is-regex-1.1.4.tgz#eef5663cd59fa4c0ae339505323df6854bb15958"
integrity sha512-kvRdxDsxZjhzUX07ZnLydzS1TU/TJlTUHHY4YLL87e37oUA49DfkLqgy+VjFocowy29cKvcSiu+kIv728jTTVg==
dependencies:
call-bind "^1.0.2"
has-tostringtag "^1.0.0"
isexe@^2.0.0: isexe@^2.0.0:
version "2.0.0" version "2.0.0"
resolved "https://registry.yarnpkg.com/isexe/-/isexe-2.0.0.tgz#e8fbf374dc556ff8947a10dcb0572d633f2cfa10" resolved "https://registry.yarnpkg.com/isexe/-/isexe-2.0.0.tgz#e8fbf374dc556ff8947a10dcb0572d633f2cfa10"
@ -839,24 +691,6 @@ object-hash@^3.0.0:
resolved "https://registry.yarnpkg.com/object-hash/-/object-hash-3.0.0.tgz#73f97f753e7baffc0e2cc9d6e079079744ac82e9" resolved "https://registry.yarnpkg.com/object-hash/-/object-hash-3.0.0.tgz#73f97f753e7baffc0e2cc9d6e079079744ac82e9"
integrity sha512-RSn9F68PjH9HqtltsSnqYC1XXoWe9Bju5+213R98cNGttag9q9yAOTzdbsqvIa7aNm5WffBZFpWYr2aWrklWAw== integrity sha512-RSn9F68PjH9HqtltsSnqYC1XXoWe9Bju5+213R98cNGttag9q9yAOTzdbsqvIa7aNm5WffBZFpWYr2aWrklWAw==
object-is@^1.1.5:
version "1.1.6"
resolved "https://registry.yarnpkg.com/object-is/-/object-is-1.1.6.tgz#1a6a53aed2dd8f7e6775ff870bea58545956ab07"
integrity sha512-F8cZ+KfGlSGi09lJT7/Nd6KJZ9ygtvYC0/UYYLI9nmQKLMnydpB9yvbv9K1uSkEu7FU9vYPmVwLg328tX+ot3Q==
dependencies:
call-bind "^1.0.7"
define-properties "^1.2.1"
object-keys@^1.1.1:
version "1.1.1"
resolved "https://registry.yarnpkg.com/object-keys/-/object-keys-1.1.1.tgz#1c47f272df277f3b1daf061677d9c82e2322c60e"
integrity sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==
parchment@^1.1.4:
version "1.1.4"
resolved "https://registry.yarnpkg.com/parchment/-/parchment-1.1.4.tgz#aeded7ab938fe921d4c34bc339ce1168bc2ffde5"
integrity sha512-J5FBQt/pM2inLzg4hEWmzQx/8h8D0CiDxaG3vyp9rKrQRSDgBlhjdP5jQGgosEajXPSQouXGHOmVdgo7QmJuOg==
path-key@^3.1.0: path-key@^3.1.0:
version "3.1.1" version "3.1.1"
resolved "https://registry.yarnpkg.com/path-key/-/path-key-3.1.1.tgz#581f6ade658cbba65a0d3380de7753295054f375" resolved "https://registry.yarnpkg.com/path-key/-/path-key-3.1.1.tgz#581f6ade658cbba65a0d3380de7753295054f375"
@ -967,27 +801,6 @@ queue-microtask@^1.2.2:
resolved "https://registry.yarnpkg.com/queue-microtask/-/queue-microtask-1.2.3.tgz#4929228bbc724dfac43e0efb058caf7b6cfb6243" resolved "https://registry.yarnpkg.com/queue-microtask/-/queue-microtask-1.2.3.tgz#4929228bbc724dfac43e0efb058caf7b6cfb6243"
integrity sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A== integrity sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==
quill-delta@^3.6.2:
version "3.6.3"
resolved "https://registry.yarnpkg.com/quill-delta/-/quill-delta-3.6.3.tgz#b19fd2b89412301c60e1ff213d8d860eac0f1032"
integrity sha512-wdIGBlcX13tCHOXGMVnnTVFtGRLoP0imqxM696fIPwIf5ODIYUHIvHbZcyvGlZFiFhK5XzDC2lpjbxRhnM05Tg==
dependencies:
deep-equal "^1.0.1"
extend "^3.0.2"
fast-diff "1.1.2"
quill@^1.3.7:
version "1.3.7"
resolved "https://registry.yarnpkg.com/quill/-/quill-1.3.7.tgz#da5b2f3a2c470e932340cdbf3668c9f21f9286e8"
integrity sha512-hG/DVzh/TiknWtE6QmWAF/pxoZKYxfe3J/d/+ShUWkDvvkZQVTPeVmUJVu1uE6DDooC4fWTiCLh84ul89oNz5g==
dependencies:
clone "^2.1.1"
deep-equal "^1.0.1"
eventemitter3 "^2.0.3"
extend "^3.0.2"
parchment "^1.1.4"
quill-delta "^3.6.2"
read-cache@^1.0.0: read-cache@^1.0.0:
version "1.0.0" version "1.0.0"
resolved "https://registry.yarnpkg.com/read-cache/-/read-cache-1.0.0.tgz#e664ef31161166c9751cdbe8dbcf86b5fb58f774" resolved "https://registry.yarnpkg.com/read-cache/-/read-cache-1.0.0.tgz#e664ef31161166c9751cdbe8dbcf86b5fb58f774"
@ -1002,16 +815,6 @@ readdirp@~3.6.0:
dependencies: dependencies:
picomatch "^2.2.1" picomatch "^2.2.1"
regexp.prototype.flags@^1.5.1:
version "1.5.2"
resolved "https://registry.yarnpkg.com/regexp.prototype.flags/-/regexp.prototype.flags-1.5.2.tgz#138f644a3350f981a858c44f6bb1a61ff59be334"
integrity sha512-NcDiDkTLuPR+++OCKB0nWafEmhg/Da8aUPLPMQbK+bxKKCm1/S5he+AqYa4PlMCVBalb4/yxIRub6qkEx5yJbw==
dependencies:
call-bind "^1.0.6"
define-properties "^1.2.1"
es-errors "^1.3.0"
set-function-name "^2.0.1"
resolve@^1.1.7, resolve@^1.22.2: resolve@^1.1.7, resolve@^1.22.2:
version "1.22.8" version "1.22.8"
resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.22.8.tgz#b6c87a9f2aa06dfab52e3d70ac8cde321fa5a48d" resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.22.8.tgz#b6c87a9f2aa06dfab52e3d70ac8cde321fa5a48d"
@ -1040,28 +843,6 @@ semver@^7.3.8:
dependencies: dependencies:
lru-cache "^6.0.0" lru-cache "^6.0.0"
set-function-length@^1.2.1:
version "1.2.2"
resolved "https://registry.yarnpkg.com/set-function-length/-/set-function-length-1.2.2.tgz#aac72314198eaed975cf77b2c3b6b880695e5449"
integrity sha512-pgRc4hJ4/sNjWCSS9AmnS40x3bNMDTknHgL5UaMBTMyJnU90EgWh1Rz+MC9eFu4BuN/UwZjKQuY/1v3rM7HMfg==
dependencies:
define-data-property "^1.1.4"
es-errors "^1.3.0"
function-bind "^1.1.2"
get-intrinsic "^1.2.4"
gopd "^1.0.1"
has-property-descriptors "^1.0.2"
set-function-name@^2.0.1:
version "2.0.2"
resolved "https://registry.yarnpkg.com/set-function-name/-/set-function-name-2.0.2.tgz#16a705c5a0dc2f5e638ca96d8a8cd4e1c2b90985"
integrity sha512-7PGFlmtwsEADb0WYyvCMa1t+yke6daIG4Wirafur5kcf+MhUnPms1UeR0CKQdTZD81yESwMHbtn+TR+dMviakQ==
dependencies:
define-data-property "^1.1.4"
es-errors "^1.3.0"
functions-have-names "^1.2.3"
has-property-descriptors "^1.0.2"
shebang-command@^2.0.0: shebang-command@^2.0.0:
version "2.0.0" version "2.0.0"
resolved "https://registry.yarnpkg.com/shebang-command/-/shebang-command-2.0.0.tgz#ccd0af4f8835fbdc265b82461aaf0c36663f34ea" resolved "https://registry.yarnpkg.com/shebang-command/-/shebang-command-2.0.0.tgz#ccd0af4f8835fbdc265b82461aaf0c36663f34ea"

Loading…
Cancel
Save