feat(商品)

This commit is contained in:
Ankkaya 2024-06-12 18:33:39 +08:00
parent 1c71006dc5
commit d5e3d34e0f
13 changed files with 569 additions and 450 deletions

View File

@ -12,14 +12,35 @@
"path": "pages/index/redirect" "path": "pages/index/redirect"
}, },
{ {
"path": "pages/index/order", "path": "pages/index/index",
"style": { "style": {
"navigationBarTitleText": "订单" "navigationBarTitleText": "首页"
}, },
"meta": { "meta": {
"auth": true "auth": true
} }
}, },
{
"path": "pages/index/order",
"style": {
"navigationBarTitleText": "订单",
"enablePullDownRefresh": true
},
"meta": {
"auth": true
}
},
{
"path": "pages/index/product",
"style": {
"navigationBarTitleText": "产品",
"enablePullDownRefresh": true
},
"meta": {
"auth": false
}
},
{ {
"path": "pages/index/my", "path": "pages/index/my",
"style": { "style": {
@ -38,15 +59,6 @@
"auth": false "auth": false
} }
}, },
{
"path": "pages/index/index",
"style": {
"navigationBarTitleText": "首页"
},
"meta": {
"auth": true
}
},
{ {
"path": "pages/index/login", "path": "pages/index/login",
"style": { "style": {
@ -55,15 +67,6 @@
"meta": { "meta": {
"auth": false "auth": false
} }
},
{
"path": "pages/index/product",
"style": {
"navigationBarTitleText": "产品"
},
"meta": {
"auth": false
}
} }
], ],
"subPackages": [ "subPackages": [

View File

@ -2,7 +2,7 @@
<pb-layout navbar="inner" tabbar="/pages/index/index" :bgStyle="bgStyle"> <pb-layout navbar="inner" tabbar="/pages/index/index" :bgStyle="bgStyle">
<view class="dashboard-module ss-p-x-30"> <view class="dashboard-module ss-p-x-30">
<view class="merchant-info flex align-center"> <view class="merchant-info flex align-center">
<image class="logo" :src="merchantInfo.logo" mode="aspectFill"></image> <image class="logo" :src="merchantInfo?.logo" mode="aspectFill"></image>
<view class="detail flex flex-column justify-center gap-10"> <view class="detail flex flex-column justify-center gap-10">
<view class="name ss-font-26">{{ merchantInfo.name }}</view> <view class="name ss-font-26">{{ merchantInfo.name }}</view>

View File

@ -42,7 +42,7 @@
<script setup> <script setup>
import { ref, computed } from 'vue' import { ref, computed } from 'vue'
import $store from '@/peach/store' import AuthUtil from '@/peach/api/member/auth'
import peach from '@/peach' import peach from '@/peach'
const bgStyle = { const bgStyle = {
@ -76,7 +76,7 @@ const state = ref({
], ],
}) })
const userStore = $store('user') const userStore = peach.$store('user')
const remain = computed(() => { const remain = computed(() => {
return userStore.userWallet?.balance return userStore.userWallet?.balance
@ -99,7 +99,7 @@ function logOut() {
return return
} }
await AuthUtil.logout() await AuthUtil.logout()
peach.$store('user').logout() userStore.logOut()
peach.$router.go('/pages/index/login') peach.$router.go('/pages/index/login')
}, },
}) })

View File

@ -124,7 +124,7 @@
<script setup> <script setup>
import { ref } from 'vue' import { ref } from 'vue'
import OrderApi from '@/peach/api/trade/order' import OrderApi from '@/peach/api/trade/order'
import { onLoad, onReachBottom, onPullDownRefresh } from '@dcloudio/uni-app' import { onLoad, onShow, onReachBottom, onPullDownRefresh } from '@dcloudio/uni-app'
import { fen2yuan, formatOrderColor, formatOrderStatus, handleOrderButtons } from '@/peach/hooks/useGoods' import { fen2yuan, formatOrderColor, formatOrderStatus, handleOrderButtons } from '@/peach/hooks/useGoods'
import peach from '@/peach' import peach from '@/peach'
import _, { isEmpty } from 'lodash' import _, { isEmpty } from 'lodash'
@ -223,6 +223,10 @@ onLoad(async (options) => {
if (options.type) { if (options.type) {
state.value.currentTab = options.type state.value.currentTab = options.type
} }
})
onShow(async () => {
resetPagination(state.value.pagination)
await getOrderList() await getOrderList()
}) })

View File

@ -15,6 +15,7 @@
:data="item" :data="item"
:topRadius="10" :topRadius="10"
:bottomRadius="10" :bottomRadius="10"
@refresh="refresh"
@click="peach.$router.go('/pages/product/manageGoods', { id: item.id, mark: 'detail' })" @click="peach.$router.go('/pages/product/manageGoods', { id: item.id, mark: 'detail' })"
/> />
</view> </view>
@ -42,7 +43,7 @@
<script setup> <script setup>
import { ref } from 'vue' import { ref } from 'vue'
import { onLoad, onReachBottom } from '@dcloudio/uni-app' import { onLoad, onShow, onReachBottom, onPullDownRefresh } from '@dcloudio/uni-app'
import GoodApi from '@/peach/api/trade/goods' import GoodApi from '@/peach/api/trade/goods'
import peach from '@/peach' import peach from '@/peach'
import _ from 'lodash' import _ from 'lodash'
@ -93,6 +94,7 @@ function addGoods() {
selectedProperty: null, selectedProperty: null,
goodsInfo: null, goodsInfo: null,
skus: null, skus: null,
specType: false,
}) })
peach.$router.go('/pages/product/manageGoods', { peach.$router.go('/pages/product/manageGoods', {
title: '添加商品', title: '添加商品',
@ -107,13 +109,28 @@ function loadMore() {
getList() getList()
} }
onLoad(async (options) => { function refresh() {
resetPagination(state.value.pagination)
getList() getList()
}
onShow(async () => {
resetPagination(state.value.pagination)
await getList()
}) })
onReachBottom(() => { onReachBottom(() => {
loadMore() loadMore()
}) })
//
onPullDownRefresh(() => {
resetPagination(state.value.pagination)
getList()
setTimeout(function () {
uni.stopPullDownRefresh()
}, 800)
})
</script> </script>
<style lang="scss" scoped> <style lang="scss" scoped>
@ -124,6 +141,7 @@ onReachBottom(() => {
bottom: 70px; bottom: 70px;
right: 20px; right: 20px;
font-size: 80rpx; font-size: 80rpx;
z-index: 999;
} }
.goods-list-box { .goods-list-box {

View File

@ -97,7 +97,7 @@ const props = defineProps({
}, },
}) })
const formData = ref({}) const formData = ref({})
const specType = computed(() => peach.$store('trade').goodsInfo?.specType || false) const specType = computed(() => peach.$store('trade').specType)
watch( watch(
() => props.skus, () => props.skus,

View File

@ -1,108 +1,94 @@
import { ref, computed } from "vue"; import { ref, computed } from 'vue'
import { onLoad } from "@dcloudio/uni-app"; import { onLoad } from '@dcloudio/uni-app'
import peach from "@/peach"; import peach from '@/peach'
import GoodsApi from "@/peach/api/trade/goods"; import GoodsApi from '@/peach/api/trade/goods'
import { SPEC_TYPE, SKU_RULE_CONFIG } from "./config"; import { SPEC_TYPE, SKU_RULE_CONFIG } from './config'
const pickerRef = ref(null); const pickerRef = ref(null)
// 多属性商品 sku 列表 // 多属性商品 sku 列表
const skus = ref([]); const skus = ref([])
const propertyList = ref([]); // 已选中商品规格的规格属性和值
const propertyList = ref([])
const goodsPropertyList = ref([]); const goodsPropertyList = ref([])
const propertyListRef = ref(null); const propertyListRef = ref(null)
const canEdit = computed(() => peach.$store("trade").canEdit); const canEdit = computed(() => peach.$store('trade').canEdit)
const formData = ref({ const formData = ref({
specType: true, specType: true,
specText: SPEC_TYPE[0].label, specText: SPEC_TYPE[0].label,
}); })
async function showPropertyList() { async function showPropertyList() {
await getGoodsProperty(); await getGoodsProperty()
propertyListRef.value.onOpen(); propertyListRef.value.onOpen()
} }
function onRDPickerConfirm(e) { function onRDPickerConfirm(e) {
formData.value.specType = SPEC_TYPE[e.value[0]].value; formData.value.specType = SPEC_TYPE[e.value[0]].value
formData.value.specText = SPEC_TYPE[e.value[0]].label; formData.value.specText = SPEC_TYPE[e.value[0]].label
// 如果商品规格不一致,则需要重新初始化 sku 列表 // 如果商品规格不一致,则需要重新初始化 sku 列表
initSku(); initSku()
peach.$store("trade").specType = SPEC_TYPE[e.value[0]].value;
} }
function pickerProperty() { function pickerProperty() {
if (canEdit.value) { if (canEdit.value) {
let index = formData.value.specType ? 1 : 0; let index = formData.value.specType ? 1 : 0
console.log(index); pickerRef.value.onOpen([index])
pickerRef.value.onOpen([index]);
} }
} }
async function onPropertyConfirm(e) { async function onPropertyConfirm(e) {
await getGoodsProperty(); await getGoodsProperty()
console.log(e); console.log(e)
} }
function onConfirm() { function onConfirm() {
console.log(skus.value); console.log(skus.value)
} }
async function getGoodsProperty() { async function getGoodsProperty() {
let { data } = await GoodsApi.getHistoryProperty(); let { data } = await GoodsApi.getHistoryProperty()
// 此处处理商品详情情况下,多规格属性
// 把 propertyList 中 id 相同的属性合并,并去重 // 把 propertyList 中 id 相同的属性合并,并去重
propertyList.value = peach.$store("trade").selectedProperty; propertyList.value = peach.$store('trade').selectedProperty || []
console.log(propertyList.value);
if (propertyList.value) {
// 根据已经选择数据,设置默认选中 // 根据已经选择数据,设置默认选中
data.forEach((item) => { data.forEach((item) => {
// 判断属性是否已经选中 // 判断属性是否已经选中
let propertyParent = propertyList.value.find( let propertyParent = propertyList.value.find((sitem) => sitem?.id === item.id)
(sitem) => sitem?.id === item.id
);
item.checked = propertyParent ? true : false; item.checked = propertyParent ? true : false
// 如果属性已经选中,查询子类中是否有选中 // 如果属性已经选中,查询子类中是否有选中
if (item.checked) { if (item.checked) {
item.propertyValues.forEach((child) => { item.propertyValues.forEach((child) => {
let childResult = propertyParent?.children.some( let childResult = propertyParent?.children.some((schild) => schild === child.id)
(schild) => schild === child.id child.checked = childResult ? true : false
); })
child.checked = childResult ? true : false;
});
} }
}); })
goodsPropertyList.value = data; goodsPropertyList.value = data
} else {
goodsPropertyList.value = [];
}
console.log(goodsPropertyList.value); console.log(goodsPropertyList.value)
} }
function changeSubProperty() { function changeSubProperty() {
// 修改子属性状态,需要同步更新 skus 的显示 // 修改子属性状态,需要同步更新 skus 的显示
console.log(goodsPropertyList.value); console.log(goodsPropertyList.value)
// 过滤父属性 checked 选项,深拷贝避免后面循环改变元数据内容 // 过滤父属性 checked 选项,深拷贝避免后面循环改变元数据内容
let temp = JSON.parse( let temp = JSON.parse(JSON.stringify(goodsPropertyList.value.filter((item) => item.checked)))
JSON.stringify(goodsPropertyList.value.filter((item) => item.checked))
);
temp.forEach((item) => { temp.forEach((item) => {
item.propertyValues = item.propertyValues.filter((child) => child.checked); item.propertyValues = item.propertyValues.filter((child) => child.checked)
}); })
let result = temp.map((item) => { let result = temp.map((item) => {
return item.propertyValues.map((child) => ({ return item.propertyValues.map((child) => ({
@ -110,15 +96,15 @@ function changeSubProperty() {
propertyName: item.name, propertyName: item.name,
valueId: child.id, valueId: child.id,
valueName: child.name, valueName: child.name,
})); }))
}); })
let tempSkus = []; let tempSkus = []
for (let item of reduceArr(result)) { for (let item of reduceArr(result)) {
let obj = { let obj = {
picUrl: "", picUrl: '',
barCode: "", barCode: '',
price: 0, price: 0,
marketPrice: 0, marketPrice: 0,
costPrice: 0, costPrice: 0,
@ -126,11 +112,11 @@ function changeSubProperty() {
weight: 0, weight: 0,
volume: 0, volume: 0,
properties: item, properties: item,
}; }
tempSkus.push(obj); tempSkus.push(obj)
} }
skus.value = tempSkus; skus.value = tempSkus
} }
/** /**
@ -143,8 +129,8 @@ function initSku() {
// 单规格 // 单规格
if (!formData.value.specType) { if (!formData.value.specType) {
let obj = { let obj = {
picUrl: "", picUrl: '',
barCode: "", barCode: '',
price: 0, price: 0,
marketPrice: 0, marketPrice: 0,
costPrice: 0, costPrice: 0,
@ -154,17 +140,20 @@ function initSku() {
properties: [ properties: [
{ {
propertyId: 0, propertyId: 0,
propertyName: "默认", propertyName: '默认',
valueId: 0, valueId: 0,
valueName: "默认", valueName: '默认',
}, },
], ],
}; }
skus.value = [obj]; skus.value = [obj]
} else { } else {
// 初始化已选中规格,属性和格式化后的结果
propertyList.value = []
goodsPropertyList.value = []
// 多规格 // 多规格
skus.value = []; skus.value = []
} }
} }
@ -176,108 +165,109 @@ function initSku() {
*/ */
function submitProperty() { function submitProperty() {
try { try {
validateSku(skus.value); validateSku(skus.value)
peach.$store("trade").skus = skus.value; peach.$store('trade').$patch({
peach.$router.back(); skus: skus.value,
specType: formData.value.specType,
})
peach.$router.back()
} catch (e) { } catch (e) {
console.log(skus.value); console.log(skus.value)
console.log(e, "校验失败"); console.log(e, '校验失败')
} }
} }
function validateSku(skus) { function validateSku(skus) {
let warningInfo = "请检查商品各行相关属性配置,"; let warningInfo = '请检查商品各行相关属性配置,'
let validateStatue = true; let validateStatue = true
let skusValue = skus ?? peach.$store("trade").skus; let skusValue = skus ?? peach.$store('trade').skus
// 判断如果是多规格,并且 skusValue 为空 [],则提示 // 判断如果是多规格,并且 skusValue 为空 [],则提示
if (formData.value.specType && skusValue.length < 1) { if (formData.value.specType && skusValue.length < 1) {
uni.showToast({ uni.showToast({
title: "请选择商品规格", title: '请选择商品规格',
icon: "none", icon: 'none',
duration: 4000, duration: 4000,
}); })
throw new Error("请选择商品规格"); throw new Error('请选择商品规格')
} }
for (const sku of skusValue) { for (const sku of skusValue) {
for (const rule of SKU_RULE_CONFIG) { for (const rule of SKU_RULE_CONFIG) {
const arg = getValue(sku, rule.name); const arg = getValue(sku, rule.name)
if (!rule.rule(arg)) { if (!rule.rule(arg)) {
validateStatue = false; validateStatue = false
warningInfo += rule.message; warningInfo += rule.message
break; break
} }
} }
if (!validateStatue) { if (!validateStatue) {
uni.showToast({ uni.showToast({
title: warningInfo, title: warningInfo,
icon: "none", icon: 'none',
duration: 4000, duration: 4000,
}); })
throw new Error(warningInfo); throw new Error(warningInfo)
} }
} }
} }
function getValue(obj, arg) { function getValue(obj, arg) {
const keys = arg.split("."); const keys = arg.split('.')
let value = obj; let value = obj
for (const key of keys) { for (const key of keys) {
if (value && typeof value === "object" && key in value) { if (value && typeof value === 'object' && key in value) {
value = value[key]; value = value[key]
} else { } else {
value = undefined; value = undefined
break; break
} }
} }
return value; return value
} }
function reduceArr(arr) { function reduceArr(arr) {
return arr.reduce((acc, cur) => { return arr.reduce((acc, cur) => {
let tempAcc = []; let tempAcc = []
if (acc.length < 1) { if (acc.length < 1) {
cur.forEach((item, index) => { cur.forEach((item, index) => {
if (tempAcc[index]) { if (tempAcc[index]) {
tempAcc[index].push(item); tempAcc[index].push(item)
} else { } else {
tempAcc[index] = [item]; tempAcc[index] = [item]
} }
}); })
} else { } else {
acc.forEach((item, index) => { acc.forEach((item, index) => {
cur.forEach((sitem, sindex) => { cur.forEach((sitem, sindex) => {
tempAcc.push([...item, sitem]); tempAcc.push([...item, sitem])
}); })
}); })
if (cur.length < 1) { if (cur.length < 1) {
tempAcc = acc; tempAcc = acc
} }
} }
return tempAcc; return tempAcc
}, []); }, [])
} }
const specType = computed( const specType = computed(() => peach.$store('trade').specType)
() => peach.$store("trade").goodsInfo?.specType || false
);
function initial() { function initial() {
onLoad(() => { onLoad(() => {
formData.value.specType = specType.value ? true : false; formData.value.specType = specType.value
formData.value.specText = SPEC_TYPE[specType.value ? 1 : 0].label; formData.value.specText = SPEC_TYPE[specType.value ? 1 : 0].label
skus.value = JSON.parse(JSON.stringify(peach.$store("trade").skus)); skus.value = JSON.parse(JSON.stringify(peach.$store('trade').skus))
// 如果新增商品 sku并且是单规格初始化 sku // 如果新增商品 sku并且是单规格初始化 sku
if (!skus.value) { if (!skus.value) {
initSku(); initSku()
} }
if (specType.value) { if (specType.value) {
getGoodsProperty(); getGoodsProperty()
} }
}); })
} }
export { export {
@ -297,4 +287,4 @@ export {
showPropertyList, showPropertyList,
goodsPropertyList, goodsPropertyList,
changeSubProperty, changeSubProperty,
}; }

View File

@ -120,7 +120,6 @@
placeholderStyle="color:#8a8a8a" placeholderStyle="color:#8a8a8a"
:inputBorder="false" :inputBorder="false"
v-model="formData.deliveryText" v-model="formData.deliveryText"
:disabled="!canEdit"
placeholder="请选择配送方式" placeholder="请选择配送方式"
disabled disabled
> >
@ -129,9 +128,18 @@
</template> </template>
</uni-easyinput> </uni-easyinput>
</uni-forms-item> </uni-forms-item>
<uni-forms-item label="商品详情"> <uni-forms-item label="虚拟销量" name="virtualSalesCount" required>
<uni-easyinput
v-model="formData.virtualSalesCount"
type="number"
:disabled="!canEdit"
placeholder="请输入虚拟销量"
/>
</uni-forms-item>
<uni-forms-item label="商品详情" required>
<piaoyiEditor <piaoyiEditor
:values="richValues" :values="richValues"
@changes="saveContens"
:maxlength="3000" :maxlength="3000"
:readOnly="richReadOnly" :readOnly="richReadOnly"
:photoUrl="photoUrl" :photoUrl="photoUrl"
@ -161,7 +169,7 @@ import GoodsApi from '@/peach/api/trade/goods'
import piaoyiEditor from '@/uni_modules/piaoyi-editor/components/piaoyi-editor/piaoyi-editor.vue' import piaoyiEditor from '@/uni_modules/piaoyi-editor/components/piaoyi-editor/piaoyi-editor.vue'
import peach from '@/peach' import peach from '@/peach'
import { baseUrl, apiPath } from '@/peach/config' import { baseUrl, apiPath } from '@/peach/config'
import { handleTree } from '@/peach/utils' import { handleTree, floatToFixed2, convertToInteger } from '@/peach/utils'
import { validateSku } from './js/sku' import { validateSku } from './js/sku'
const bgStyle = { const bgStyle = {
@ -198,12 +206,16 @@ const formData = ref({
'http://101.43.181.163:9001/mall-backend/8f11e372520501531d06bfce15ea97bbecead41c5e4a36d15d7e40af85729ff3.png', 'http://101.43.181.163:9001/mall-backend/8f11e372520501531d06bfce15ea97bbecead41c5e4a36d15d7e40af85729ff3.png',
], ],
name: '测试商品', name: '测试商品',
categoryId: [], categoryId: 91,
categoryText: '', categoryText: '',
brandId: '', brandId: 4,
keyword: '香酥鸭,但家', keyword: '香酥鸭,但家',
deliveryTypes: [], deliveryTypes: [3],
deliveryText: '', deliveryText: '',
sort: 0,
giveIntegral: 0,
virtualSalesCount: 0,
subCommissionType: false,
introduction: '但家贵阳香酥鸭现榨香酥鸭无任何添加剂香酥鸭但家贵阳香酥鸭现榨香酥鸭无任何添加剂香酥鸭', introduction: '但家贵阳香酥鸭现榨香酥鸭无任何添加剂香酥鸭但家贵阳香酥鸭现榨香酥鸭无任何添加剂香酥鸭',
}) })
@ -362,7 +374,8 @@ function getProduct(id) {
GoodsApi.getProduct({ id }).then((res) => { GoodsApi.getProduct({ id }).then((res) => {
formData.value = res.data formData.value = res.data
richValues.value = res.data.description //
richValues.value = res.data.description ? res.data.description + '<p><br/></p>' : ''
// categoryList formData.value.categoryId // categoryList formData.value.categoryId
let tempCategory = categoryList.value.find((item) => { let tempCategory = categoryList.value.find((item) => {
@ -390,18 +403,28 @@ function getProduct(id) {
return item.value === formData.value.deliveryTypes[0] return item.value === formData.value.deliveryTypes[0]
}).label }).label
formData.value.skus.forEach((item) => {
item.price = floatToFixed2(item.price)
item.marketPrice = floatToFixed2(item.marketPrice)
item.costPrice = floatToFixed2(item.costPrice)
})
peach.$store('trade').$patch({ peach.$store('trade').$patch({
goodsInfo: formData.value, goodsInfo: formData.value,
skus: formData.value.skus, skus: formData.value.skus,
specType: formData.value.specType,
}) })
}) })
} }
function saveContens(e) {
formData.value.description = e.html
}
function onSubmit() { function onSubmit() {
console.log('res', formData.value) console.log('res', formData.value)
console.log('richtext', richValues.value) console.log('richtext', richValues.value)
formData.value.description = richValues.value
formData.value.skus = peach.$store('trade').skus formData.value.skus = peach.$store('trade').skus
formRef.value formRef.value
@ -414,22 +437,42 @@ function onSubmit() {
tempObj.skus.forEach((item) => { tempObj.skus.forEach((item) => {
item.name = formData.value.name item.name = formData.value.name
item.price = convertToInteger(item.price)
item.marketPrice = convertToInteger(item.marketPrice)
item.costPrice = convertToInteger(item.costPrice)
}) })
tempObj.specType = peach.$store('trade').specType
let msg = ''
if (formData.value.id) { if (formData.value.id) {
tempObj.id = formData.value.id tempObj.id = formData.value.id
await GoodsApi.editProduct(tempObj) await GoodsApi.editProduct(tempObj)
msg = '修改成功'
} else { } else {
await GoodsApi.addProduct(tempObj) await GoodsApi.addProduct(tempObj)
msg = '添加成功'
} }
})
.catch((err) => {
uni.showToast({ uni.showToast({
title: err[0].errorMessage, title: msg,
icon: 'none', icon: 'none',
duration: 4000, duration: 4000,
}) })
setTimeout(() => {
peach.$router.redirect('/pages/index/product')
}, 1000)
})
.catch((err) => {
console.log('err', err) console.log('err', err)
if (err) {
uni.showToast({
title: err[0]?.errorMessage,
icon: 'none',
duration: 4000,
})
}
}) })
} }
@ -452,7 +495,7 @@ onLoad(async (options) => {
goodsTitle.value = options.title goodsTitle.value = options.title
// //
richReadOnly.value = true // richReadOnly.value = true
/** /**
* todo 滚动一定距离后修改富文本状态和 canEdit 一致 * todo 滚动一定距离后修改富文本状态和 canEdit 一致

View File

@ -33,6 +33,14 @@ const GoodsApi = {
data, data,
}) })
}, },
// 删除商品
delProduct: (data) => {
return request({
url: '/product/spu/delete',
method: 'DELETE',
params: data,
})
},
// 商品分类 // 商品分类
getGoodsCategory: (data) => { getGoodsCategory: (data) => {
return request({ return request({

View File

@ -59,6 +59,7 @@
import { ref, computed } from 'vue' import { ref, computed } from 'vue'
import { isArray } from 'lodash' import { isArray } from 'lodash'
import peach from '@/peach' import peach from '@/peach'
import GoodsApi from '@/peach/api/trade/goods'
import { fen2yuan, formatSales, formatStock } from '@/peach/hooks/useGoods' import { fen2yuan, formatSales, formatStock } from '@/peach/hooks/useGoods'
import { unix } from 'dayjs' import { unix } from 'dayjs'
@ -114,7 +115,7 @@ const props = defineProps({
}, },
}) })
const emits = defineEmits(['click']) const emits = defineEmits(['click', 'refresh'])
function onClick() { function onClick() {
emits('click') emits('click')
@ -155,6 +156,7 @@ function clickGoods(mark) {
selectedProperty: null, selectedProperty: null,
goodsInfo: null, goodsInfo: null,
skus: null, skus: null,
specType: false,
}) })
peach.$router.go('/pages/product/manageGoods', { peach.$router.go('/pages/product/manageGoods', {
id: props.data.id, id: props.data.id,
@ -165,8 +167,16 @@ function clickGoods(mark) {
uni.showModal({ uni.showModal({
title: '提示', title: '提示',
content: '是否删除该商品?', content: '是否删除该商品?',
success: (res) => { success: async (res) => {
if (res.confirm) { if (res.confirm) {
await GoodsApi.delProduct({ id: props.data.id })
uni.showToast({
title: '删除成功',
icon: 'none',
})
emits('refresh')
} }
}, },
}) })

View File

@ -1,21 +1,24 @@
import { ref, computed } from "vue"; import { ref, computed } from 'vue'
import { defineStore } from "pinia"; import { defineStore } from 'pinia'
const useTradeStore = defineStore("trade", () => { const useTradeStore = defineStore('trade', () => {
// 已选择规格类型 // 已选择规格类型
const selectedProperty = ref(null); const selectedProperty = ref(null)
// 商品信息 // 商品信息
const goodsInfo = ref(null); const goodsInfo = ref(null)
// 详情标记 // 详情标记
const detailTag = ref("edit"); const detailTag = ref('edit')
// 规格类型,默认单规格
const specType = ref(false)
// 商品属性 // 商品属性
const skus = ref(null); const skus = ref(null)
// 商品是否可编辑 // 商品是否可编辑
const canEdit = computed(() => (detailTag.value === "detail" ? false : true)); const canEdit = computed(() => (detailTag.value === 'detail' ? false : true))
return { return {
selectedProperty, selectedProperty,
@ -23,7 +26,8 @@ const useTradeStore = defineStore("trade", () => {
skus, skus,
canEdit, canEdit,
detailTag, detailTag,
}; specType,
}); }
})
export default useTradeStore; export default useTradeStore

View File

@ -56,6 +56,45 @@ export const handleTree = (data, id, parentId, children) => {
return tree return tree
} }
export const convertToInteger = (num) => {
if (typeof num === 'undefined') return 0
const parsedNumber = typeof num === 'string' ? parseFloat(num) : num
// TODO 分转元后还有小数则四舍五入
return Math.round(parsedNumber * 100)
}
/**
* 将一个整数转换为分数保留两位小数
* @param num
*/
export const formatToFraction = (num) => {
if (typeof num === 'undefined') return '0.00'
const parsedNumber = typeof num === 'string' ? parseFloat(num) : num
return (parsedNumber / 100.0).toFixed(2)
}
export const floatToFixed2 = (num) => {
let str = '0.00'
if (typeof num === 'undefined') {
return str
}
const f = formatToFraction(num)
const decimalPart = f.toString().split('.')[1]
const len = decimalPart ? decimalPart.length : 0
switch (len) {
case 0:
str = f.toString() + '.00'
break
case 1:
str = f.toString() + '0'
break
case 2:
str = f.toString()
break
}
return str
}
export function resetPagination(pagination) { export function resetPagination(pagination) {
pagination.list = [] pagination.list = []
pagination.total = 0 pagination.total = 0

View File

@ -263,7 +263,7 @@ export default {
}, },
clear() { clear() {
this.editorCtx.clear() this.editorCtx.clear()
this.$emit() this.$emit('update:modelValue', '')
}, },
insertDate() { insertDate() {
const date = new Date() const date = new Date()