This commit is contained in:
2026-05-05 16:35:30 +08:00
parent ed0d1aaacf
commit 2b63fe4147
19 changed files with 777 additions and 121 deletions
@@ -0,0 +1,28 @@
package com.quoted.web.controller.product;
import com.quoted.common.core.controller.BaseController;
import com.quoted.common.core.domain.AjaxResult;
import com.quoted.common.core.domain.entity.SysMenu;
import com.quoted.system.domain.vo.ProductPriceRequestVo;
import com.quoted.system.service.IProductPriceService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.*;
/**
* 缓存监控
* <p>
* quoted
*/
@RestController
@RequestMapping("/product")
public class ProductController extends BaseController {
@Autowired
IProductPriceService productPriceService;
@PostMapping("/getPrice")
public AjaxResult getPrice(@RequestBody ProductPriceRequestVo product) {
return success(productPriceService.getProductPrice(product));
}
}
+3 -2
View File
@@ -52,13 +52,13 @@
<groupId>org.apache.commons</groupId>
<artifactId>commons-lang3</artifactId>
</dependency>
<!-- JSON工具类 -->
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
</dependency>
<!-- 阿里JSON解析器 -->
<dependency>
<groupId>com.alibaba.fastjson2</groupId>
@@ -113,6 +113,7 @@
<artifactId>javax.servlet-api</artifactId>
</dependency>
</dependencies>
</project>
+7 -1
View File
@@ -22,7 +22,13 @@
<groupId>com.quoted</groupId>
<artifactId>quoted-common</artifactId>
</dependency>
<!-- https://mvnrepository.com/artifact/org.projectlombok/lombok -->
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.18.12</version>
<scope>provided</scope>
</dependency>
</dependencies>
</project>
@@ -0,0 +1,22 @@
package com.quoted.system.domain.vo;
import lombok.Data;
@Data
public class ProductCraftItemChildrenVo {
/**
* 类型
*/
private String type;
/**
* 值
*/
private String value;
/**
* 内置定义参数
*/
private Integer count;
private Double width;
private Double length;
private String size;
}
@@ -0,0 +1,24 @@
package com.quoted.system.domain.vo;
import lombok.Data;
import java.util.ArrayList;
import java.util.List;
@Data
public class ProductCraftItemVo {
/**
* 工艺
*/
private String type;
/**
* 值
*/
private String value;
/**
* 工艺复项
*/
private List<ProductCraftItemChildrenVo> children = new ArrayList<>();
}
@@ -0,0 +1,12 @@
package com.quoted.system.domain.vo;
import lombok.Data;
@Data
public class ProductPriceDto {
private double price;
private Integer count;
private Integer number;
private String message;
}
@@ -0,0 +1,40 @@
package com.quoted.system.domain.vo;
import lombok.Data;
import java.util.ArrayList;
import java.util.List;
@Data
public class ProductPriceRequestVo {
/**
* 类型
*/
private String types;
/**
* 材质
*/
private String material;
/**
* 长
*/
private Double length;
/**
* 宽
*/
private Double width;
/**
* 数量
*/
private Integer count;
/**
* 款数
*/
private Integer number;
/**
* 旺旺
*/
private String customerWw;
private List<ProductCraftItemVo> crafts = new ArrayList<>();
}
@@ -0,0 +1,11 @@
package com.quoted.system.service;
import com.quoted.system.domain.vo.ProductPriceDto;
import com.quoted.system.domain.vo.ProductPriceRequestVo;
import java.util.List;
public interface IProductPriceService {
public List<ProductPriceDto> getProductPrice(ProductPriceRequestVo product);
}
@@ -0,0 +1,26 @@
package com.quoted.system.service.impl;
import com.quoted.system.domain.vo.ProductPriceDto;
import com.quoted.system.domain.vo.ProductPriceRequestVo;
import com.quoted.system.service.IProductPriceService;
import com.quoted.system.utils.StickerUtils;
import org.springframework.stereotype.Service;
import java.util.ArrayList;
import java.util.List;
@Service
public class ISysConfigServiceImpl implements IProductPriceService {
@Override
public List<ProductPriceDto> getProductPrice(ProductPriceRequestVo product) {
List<ProductPriceDto> list = new ArrayList<>();
if ("不干胶".equals(product.getTypes())) {
list = StickerUtils.getPrice(product);
}
return list;
}
}
@@ -0,0 +1,20 @@
package com.quoted.system.utils;
import com.quoted.system.domain.vo.ProductCraftItemVo;
import com.quoted.system.domain.vo.ProductPriceRequestVo;
import java.util.ArrayList;
import java.util.List;
public class PriceCommonUtils {
static List<String> getCraftList(ProductPriceRequestVo requestVo) {
List<String> craft_list = new ArrayList<>();
if (requestVo.getCrafts().size() > 0) {
for (ProductCraftItemVo craft : requestVo.getCrafts()) {
craft_list.add(craft.getValue());
}
}
return craft_list;
}
}
@@ -0,0 +1,197 @@
package com.quoted.system.utils;
import com.quoted.system.domain.vo.ProductPriceDto;
import com.quoted.system.domain.vo.ProductPriceRequestVo;
import org.apache.commons.math3.stat.descriptive.summary.Product;
import java.util.ArrayList;
import java.util.List;
public class StickerUtils {
public static List<ProductPriceDto> getPrice(ProductPriceRequestVo product) {
List<ProductPriceDto> list = new ArrayList<>();
Double length = product.getLength();
Double width = product.getWidth();
Integer count = product.getCount();
Integer number = product.getNumber();
List<String> craft_list = PriceCommonUtils.getCraftList(product);
double area = length * width / 10000;
switch (product.getMaterial()) {
case "铜板纸不干胶":
// 带1厘米的尺寸,都变成2
if (1 < length && length < 2) {
length = Math.ceil(length);
}
if (1 < width && width < 2) {
width = Math.ceil(width);
}
// 小数部分,四舍五入
length = (double) Math.round(length);
width = (double) Math.round(width);
// 尺寸小数部分四舍五入后的面积
double roundArea = length * width / 10000;
// 一个名片位内做特价:75折,价格在前端写死
double[] priceArr = null;
int[] counts = {500, 1000, 2000, 3000, 5000, 10000, 20000, 30000, 40000, 50000};
double areas[] = {0.004, 0.006, 0.008, 0.01, 0.012, 0.015, 0.017, 0.018, 0.02, 0.03, 0.04, 0.06, 0.1, 0.2, 0.3};
//覆膜是否要加价
boolean isMo = true;
int MaxCount = 0;
if (length == 1 && width == 1) {
priceArr = new double[]{30, 35, 50, 55, 100, 180, 270, 370, 470, 570};
} else if ((length == 2 && width == 1) || (length == 1 && width == 2)) {
priceArr = new double[]{35, 40, 55, 60, 110, 190, 280, 380, 480, 580};
} else if ((length > 2 && length <= 5 && width == 1) || (width > 2 && width <= 5 && length == 1)) {
priceArr = new double[]{35, 40, 55, 70, 120, 210, 308, 435, 555, 683};
} else if ((length > 1 && length <= 3 && width == 2) || (width > 1 && width <= 3 && length == 2)) {
priceArr = new double[]{35, 40, 55, 70, 120, 210, 308, 435, 555, 683};
} else if ((length > 3 && length <= 5 && width == 2) || (width > 3 && width <= 5 && length == 2)) {
priceArr = new double[]{35, 40, 55, 70, 120, 220, 348, 492, 642, 798};
} else if ((length >= 3 && length <= 5 && width == 3) || (length == 3 && width <= 5 && width >= 3)) {
priceArr = new double[]{35, 40, 55, 70, 120, 220, 348, 492, 642, 798};
} else if (length == 4 && width == 4) {
priceArr = new double[]{35, 40, 55, 70, 120, 220, 348, 492, 642, 798};
} else if ((length == 5 && width == 4) || (length == 4 && width == 5)) {
priceArr = new double[]{35, 40, 55, 70, 150, 240, 420, 600, 790, 980};
} else if (((length <= 9 && width <= 5.4) || (length <= 5.4 && width <= 9))) {
counts = new int[]{500, 1000, 2000, 3000, 5000, 10000, 20000, 30000, 40000, 50000, 60000, 70000, 80000, 90000, 100000};
priceArr = new double[]{60, 70, 95, 125, 175, 270, 510, 800, 1000, 1200, 1400, 1600, 1800, 2000, 2200};
isMo = false;
} else if (area <= 0.003) {
counts = new int[]{500, 1000, 2000, 3000, 5000, 10000, 20000, 30000, 40000, 50000, 60000, 70000, 80000, 90000, 100000};
priceArr = new double[]{65, 75, 100, 130, 180, 275, 515, 805, 1005, 1205, 1405, 1605, 1805, 2005, 2205};
isMo = false;
MaxCount = 40000;
} else {
counts = new int[]{500, 1000, 2000, 3000, 5000, 10000, 20000, 30000, 40000, 50000, 60000, 70000, 80000, 90000, 100000};
double basePrice = 0;
if (area <= 0.004) {
basePrice = 7.5;
} else if (area <= 0.006) {
basePrice = 6.5;
} else if (area <= 0.2) {
basePrice = 5.5;
} else if (area <= 0.3) {
basePrice = 5;
} else if (area > 0.3) {
basePrice = 4.5;
}
ProductPriceDto pro = new ProductPriceDto();
if (count > counts[counts.length - 1]) {
pro.setCount(count);
pro.setPrice(Math.ceil(area * count * basePrice));
list.add(pro);
}
for (int i = 0; i < counts.length; i++) {
if (counts[i] < count || list.size() > 3) {
continue;
}
double[] arrPrice = new double[16];
if (counts[i] == 500) {
arrPrice = new double[]{37, 33, 30, 26, 25, 21, 19, 18, 17, 19, 17, 12.8, 12.5, 12, 11.5, 11};
} else if (counts[i] == 1000) {
arrPrice = new double[]{21, 19, 17, 17, 15, 14, 14, 12, 12, 12.5, 13, 9, 9, 8, 8, 7.8};
} else if (counts[i] == 2000) {
arrPrice = new double[]{14, 13, 13, 12, 11, 11, 10, 10, 9, 10, 11, 7.8, 7.5, 7.5, 7.2, 7};
} else if (counts[i] == 3000) {
arrPrice = new double[]{12, 11, 11, 10, 9, 9.5, 9, 8, 8, 9, 10, 6.8, 6.5, 6.5, 6, 6.5};
} else if (counts[i] == 5000) {
arrPrice = new double[]{10, 9.5, 8, 7.8, 8.5, 9, 8.3, 7, 8, 6.5, 8, 6, 6, 6, 5.5, 5};
} else if (counts[i] == 10000) {
arrPrice = new double[]{8, 7.5, 6.5, 6.5, 7.6, 8, 7.3, 6, 7.5, 6, 6, 6, 6, 6, 5, 5};
} else if (counts[i] == 20000) {
arrPrice = new double[]{7.6, 6.5, 5.5, 5.5, 5.5, 5.5, 5.5, 5.5, 5.5, 5.5, 5.5, 5.5, 5.5, 5.5, 5, 4.5};
} else if (counts[i] == 30000) {
arrPrice = new double[]{7.6, 6.5, 5.5, 5.5, 5.5, 5.5, 5.5, 5.5, 5.5, 5.5, 5.5, 5.5, 5.5, 5.5, 5, 4.5};
} else if (counts[i] == 40000) {
arrPrice = new double[]{7.6, 6.5, 5.5, 5.5, 5.5, 5.5, 5.5, 5.5, 5.5, 5.5, 5.5, 5.5, 5.5, 5.5, 5, 4.5};
} else if (counts[i] == 50000) {
arrPrice = new double[]{7.5, 6.5, 5.5, 5.5, 5.5, 5.5, 5.5, 5.5, 5.5, 5.5, 5.5, 5.5, 5.5, 5.5, 5, 4.5};
} else if (counts[i] == 60000) {
arrPrice = new double[]{7.5, 6.5, 5.5, 5.5, 5.5, 5.5, 5.5, 5.5, 5.5, 5.5, 5.5, 5.5, 5.5, 5.5, 5, 4.5};
} else if (counts[i] == 70000) {
arrPrice = new double[]{7.5, 6.5, 5.5, 5.5, 5.5, 5.5, 5.5, 5.5, 5.5, 5.5, 5.5, 5.5, 5.5, 5.5, 5, 4.5};
} else if (counts[i] == 80000) {
arrPrice = new double[]{7.5, 6.5, 5.5, 5.5, 5.5, 5.5, 5.5, 5.5, 5.5, 5.5, 5.5, 5.5, 5.5, 5.5, 5, 4.5};
} else if (counts[i] == 90000) {
arrPrice = new double[]{7.5, 6.5, 5.5, 5.5, 5.5, 5.5, 5.5, 5.5, 5.5, 5.5, 5.5, 5.5, 5.5, 5.5, 5, 4.5};
} else if (counts[i] == 100000) {
arrPrice = new double[]{7.5, 6.5, 5.5, 5.5, 5.5, 5.5, 5.5, 5.5, 5.5, 5.5, 5.5, 5.5, 5.5, 5.5, 5, 4.5};
}
double pirce = getPriceInArea(counts[i], area, arrPrice, areas);
pro = new ProductPriceDto();
pro.setCount(counts[i]);
pro.setPrice(Math.ceil(pirce));
list.add(pro);
break;
}
}
ProductPriceDto pro = null;
if (MaxCount == 0) {
for (int i = 0; i < counts.length; i++) {
if (counts[i] < count || list.size() > 3) {
continue;
}
pro = new ProductPriceDto();
pro.setCount(counts[i]);
double price = priceArr[i];
if (craft_list.contains("覆哑膜") && isMo) {
price = Math.ceil(price * 1.2);
}
pro.setPrice(price);
list.add(pro);
}
} else {
pro = new ProductPriceDto();
pro.setCount(count);
double price = Math.ceil((Math.ceil(count / 10000.0) - 4) * 150 + 720);
pro.setPrice(price);
list.add(pro);
}
break;
default:
break;
}
return list;
}
// 判断小尺寸是否大于大尺寸价格
private static double getPriceInArea(int count, Double area, double[] priceArr, double[] areas) {
double lastPrice = 0, price = 0;
if (area > areas[areas.length - 1]) {
price = area * count * priceArr[areas.length - 1];
lastPrice = area * count * priceArr[areas.length - 2];
if (lastPrice > price) {
price = lastPrice;
}
}
for (int i = 0; i < areas.length; i++) {
if (areas[i] < area) {
continue;
}
double lastArea = 0;
if (i > 0) {
lastArea = areas[i - 1];
lastPrice = lastArea * count * priceArr[i - 1];
}
price = area * count * priceArr[i];
if (lastPrice > price) {
price = lastPrice;
}
break;
}
return price;
}
}
+8
View File
@@ -0,0 +1,8 @@
import request from "@/utils/request";
export function getProductPrice(data) {
return request({
url: "/product/getPrice",
method: "post",
data: data,
});
}
+27 -33
View File
@@ -1,11 +1,5 @@
<template>
<el-image
:src="`${realSrc}`"
fit="cover"
:style="`width:${realWidth};height:${realHeight};`"
:preview-src-list="realSrcList"
preview-teleported
>
<el-image :src="`${realSrc}`" :fit="fit" :style="`width:${realWidth};height:${realHeight};`" :preview-src-list="realSrcList" preview-teleported>
<template #error>
<div class="image-slot">
<el-icon><picture-filled /></el-icon>
@@ -15,56 +9,56 @@
</template>
<script setup>
import { isExternal } from "@/utils/validate"
import { isExternal } from "@/utils/validate";
const props = defineProps({
src: {
type: String,
default: ""
default: "",
},
fit: {
type: String,
default: "cover",
},
width: {
type: [Number, String],
default: ""
default: "",
},
height: {
type: [Number, String],
default: ""
}
})
default: "",
},
});
const realSrc = computed(() => {
if (!props.src) {
return
return;
}
let real_src = props.src.split(",")[0]
let real_src = props.src.split(",")[0];
if (isExternal(real_src)) {
return real_src
return real_src;
}
return import.meta.env.VITE_APP_BASE_API + real_src
})
return import.meta.env.VITE_APP_BASE_API + real_src;
});
const realSrcList = computed(() => {
if (!props.src) {
return
return;
}
let real_src_list = props.src.split(",")
let srcList = []
real_src_list.forEach(item => {
let real_src_list = props.src.split(",");
let srcList = [];
real_src_list.forEach((item) => {
if (isExternal(item)) {
return srcList.push(item)
return srcList.push(item);
}
return srcList.push(import.meta.env.VITE_APP_BASE_API + item)
})
return srcList
})
return srcList.push(import.meta.env.VITE_APP_BASE_API + item);
});
return srcList;
});
const realWidth = computed(() =>
typeof props.width == "string" ? props.width : `${props.width}px`
)
const realWidth = computed(() => (typeof props.width == "string" ? props.width : `${props.width}px`));
const realHeight = computed(() =>
typeof props.height == "string" ? props.height : `${props.height}px`
)
const realHeight = computed(() => (typeof props.height == "string" ? props.height : `${props.height}px`));
</script>
<style lang="scss" scoped>
@@ -0,0 +1,27 @@
<template>
<el-carousel height="600px" indicator-position="outside" trigger="click">
<el-carousel-item v-for="item in images" :key="item" style="display: flex; align-items: center; justify-content: center">
<el-image :src="item" fit="contain" width="100%" height="100%" loading="lazy" :preview-src-list="images" preview-teleported close-on-press-escape hide-on-click-modal></el-image>
</el-carousel-item>
</el-carousel>
<view>
<text v-if="remark" style="color: red; font-weight: bold; font-size: 18px; white-space: pre-line"> 预计发货时间:<br />{{ remark }}</text>
</view>
</template>
<script setup>
import { ref, watch } from "vue";
const props = defineProps({
images: {
type: Array,
required: true,
default: () => [],
},
remark: {
type: String,
default: "",
},
});
const localData = ref(props.modelValue);
</script>
@@ -0,0 +1,36 @@
<template>
<el-input v-model="localData" type="text" @input="changeValue" style="width: 100px">
<template #append v-if="$slots.append"> <slot name="append" /></template>
<template #prefix v-if="$slots.prefix"> <slot name="prefix" /></template>
<template #suffix v-if="$slots.suffix"> <slot name="suffix" /></template>
<template #prepend v-if="$slots.prepend"> <slot name="prepend" /></template>
</el-input>
</template>
<script setup>
import { ref, watch } from "vue";
const props = defineProps({
modelValue: {
type: String,
required: true,
default: () => "",
},
});
const emits = defineEmits(["update:modelValue"]);
const localData = ref(props.modelValue);
watch(
() => props.modelValue,
(val) => {
if (val && val.length > 0) {
localData.value = JSON.parse(JSON.stringify(val));
}
},
{ deep: true, immediate: true },
);
const changeValue = (val) => {
localData.value = val.replace(/[^0-9.]/g, ""); // 只保留数字和小数点
emits("update:modelValue", localData.value);
};
</script>
@@ -0,0 +1,46 @@
<template>
<view class="result-container">
<el-button type="primary" @click="handleGetPrice">获取价格</el-button>
<el-input type="textarea" style="width: 400px; height: 400px" rows="10" resize="none" readonly></el-input>
</view>
</template>
<script setup>
import { ref, watch } from "vue";
import { ElMessage } from "element-plus";
import { getProductPrice } from "@/api/product/index.js";
const props = defineProps({
data: {
type: Object,
required: true,
},
});
const emits = defineEmits(["verifyCraftData"]);
const handleGetPrice = () => {
emits("verifyCraftData", (result) => {
let { valid, message } = result;
if (!valid) {
ElMessage({
message: message || "报价数据验证失败",
type: "error",
grouping: true,
});
return;
}
getProductPrice(props.data).then((res) => {
console.log(res);
});
});
};
</script>
<style lang="scss" scoped>
.result-container {
display: flex;
flex-direction: column;
align-items: flex-start;
gap: 20px;
}
</style>
@@ -11,7 +11,7 @@
<el-select v-if="child.type === 'select'" v-model="child.value" @change="emitChange('child', { itemIndex: index, optionValue: option.value, childKey: key, value: $event })" style="width: 150px">
<el-option v-for="opt in child.options" :key="opt.value" :value="opt.value" :label="opt.label"></el-option>
</el-select>
<el-input v-else-if="child.type === 'input'" :placeholder="child.placeholder" v-model="child.value" @change="emitChange('child', { itemIndex: index, optionValue: option.value, childKey: key, value: $event })" style="width: 100px"></el-input>
<number-input v-else-if="child.type === 'input'" :placeholder="child.placeholder" v-model="child.value" @change="emitChange('child', { itemIndex: index, optionValue: option.value, childKey: key, value: $event })" style="width: 100px"></number-input>
</template>
</template>
</template>
@@ -22,7 +22,9 @@
</template>
<script setup>
import { ref, watch, onMounted, defineEmits, defineProps } from "vue";
import { ref, watch, onMounted, defineProps } from "vue";
import NumberInput from "@/components/NumberInput";
const props = defineProps({
data: {
@@ -3,7 +3,7 @@
</template>
<script setup>
import { ref, watch, defineEmits, defineProps } from "vue";
import { ref } from "vue";
import ProductCraft from "@/components/ProductCraft";
const defaultCraftData = ref([
@@ -156,6 +156,8 @@ const defaultCraftData = ref([
},
]);
const emits = defineEmits(["update:modelValue"]);
const handleCraftChange = (info) => {
const { optionValue, itemIndex, data } = info;
const currentItem = data[itemIndex];
@@ -164,7 +166,9 @@ const handleCraftChange = (info) => {
currentItem.options.forEach((opt) => {
if (opt.value === optionValue) {
} else {
opt.checked = false;
if (itemIndex != 5) {
opt.checked = false;
}
}
});
@@ -197,13 +201,50 @@ const handleCraftChange = (info) => {
// 3. 更新响应式数据
defaultCraftData.value = data;
handleDataInfo();
};
//处理工艺数据
const handleDataInfo = () => {
let datainfo = [];
defaultCraftData.value.forEach((craft) => {
const selectedOption = craft.options.filter((opt) => {
return opt.checked;
});
if (selectedOption && selectedOption.length > 0) {
selectedOption.forEach((opt) => {
let item = {};
if (opt.checked) {
item.type = opt.label;
item.value = opt.value;
if (opt.children) {
let childItem = {};
item.children = [];
opt.children.forEach((child) => {
if (child.id && child.value) {
childItem[child.id] = child.value;
} else {
childItem.value = child.value;
}
});
item.children.push(childItem);
}
}
datainfo.push(item);
});
}
});
emits("update:modelValue", datainfo);
};
const verifyCraftData = () => {
// 验证工艺数据的完整性和正确性
return { valid: true };
return { valid: false, message: "工艺数据验证失败" };
};
handleDataInfo();
defineExpose({
verifyCraftData,
});
+195 -80
View File
@@ -1,46 +1,51 @@
<template>
<view class="container">
<h1 style="font-weight: bold">不干胶</h1>
<el-form>
<el-form-item>
<el-radio-group v-model="data.types" @change="handleChange">
<el-radio label="常用种类" value="常用种类" size="large" border />
<el-radio label="专版打印" value="专版打印" size="large" border />
</el-radio-group>
</el-form-item>
<view class="form-title">品种</view>
<el-form-item>
<el-select v-model="data.material" placeholder="请选择" size="large" style="width: 300px">
<template v-for="item in materials" :key="item.name">
<el-option :label="item.name" :value="item.name"></el-option>
</template>
</el-select>
</el-form-item>
<view class="form-title">尺寸</view>
<el-form-item>
<el-input style="width: 150px" v-model="data.size[0]" type="number">
<template #append> <text>cm</text></template>
</el-input>
<text style="margin: 0 10px">X</text>
<el-input style="width: 150px" v-model="data.size[1]" type="number">
<template #append> <text>cm</text> </template>
</el-input>
</el-form-item>
<view class="form-title">个数</view>
<el-form-item>
<el-input style="width: 300px" v-model="data.count" type="number" placeholder="请输入数量" size="large"></el-input>
</el-form-item>
<view class="form-title">款数</view>
<el-form-item>
<el-input style="width: 300px" v-model="data.number" type="number" placeholder="请输入数量" size="large"></el-input>
</el-form-item>
<view class="form-title">客户旺旺</view>
<el-form-item>
<el-input style="width: 300px" v-model="data.customerWw" placeholder="请输入客户旺旺" size="large"></el-input>
</el-form-item>
<component v-if="currentCraftComponent" :is="currentCraftComponent" ref="componentRef" />
<el-button type="primary" @click="handlesave">保存</el-button>
</el-form>
<view class="left-info">
<h1 style="font-weight: bold">不干胶</h1>
<el-form>
<el-form-item>
<el-radio-group v-model="data.types" @change="handleChange">
<el-radio label="常用种类" value="常用种类" size="large" border />
<el-radio label="专版打印" value="专版打印" size="large" border />
</el-radio-group>
</el-form-item>
<view class="form-title">品种</view>
<el-form-item>
<el-select v-model="data.material" placeholder="请选择" size="large" style="width: 300px">
<template v-for="item in materials" :key="item.name">
<el-option :label="item.name" :value="item.name"></el-option>
</template>
</el-select>
</el-form-item>
<view class="form-title">尺寸</view>
<el-form-item>
<number-input style="width: 150px" v-model="data['length']">
<template #append> <text>cm</text></template>
</number-input>
<text style="margin: 0 10px">X</text>
<number-input style="width: 150px" v-model="data['width']">
<template #append> <text>cm</text> </template>
</number-input>
</el-form-item>
<view class="form-title">个数</view>
<el-form-item>
<number-input style="width: 300px" v-model="data.count" placeholder="请输入数量" size="large"></number-input>
</el-form-item>
<view class="form-title">款数</view>
<el-form-item>
<number-input style="width: 300px" v-model="data.number" placeholder="请输入数量" size="large"></number-input>
</el-form-item>
<view class="form-title">客户旺旺</view>
<el-form-item>
<el-input style="width: 300px" v-model="data.customerWw" placeholder="请输入客户旺旺" size="large"></el-input>
</el-form-item>
<component v-if="currentCraftComponent" :is="currentCraftComponent" ref="componentRef" v-model="data.crafts" />
<PriceResult :data="data" @verifyCraftData="handleVerifyCraftData" />
</el-form>
</view>
<view class="right-image">
<ImageRemark :images="images" :remark="remark" />
</view>
</view>
</template>
<script setup>
@@ -48,30 +53,100 @@ import { ref, watch, shallowRef } from "vue";
import copperplate from "./crafts/copperplate.vue";
import pvc from "./crafts/pvc.vue";
import transparent from "./crafts/transparent.vue";
import NumberInput from "@/components/NumberInput";
import ImageRemark from "@/components/ImageRemark";
import PriceResult from "@/components/PriceResult";
const materials = [
{ name: "铜板纸不干胶", images: "" },
{ name: "pvc不干胶", images: "" },
{ name: "透明不干胶", images: "" },
{ name: "牛皮纸", images: "" },
{ name: "哑金不干胶", images: "" },
{ name: "哑银不干胶", images: "" },
{ name: "书写纸不干胶", images: "" },
{ name: "银平光", images: "" },
{ name: "拉丝金", images: "" },
{ name: "拉丝银", images: "" },
{ name: "美纹纸", images: "" },
{ name: "PP合成纸", images: "" },
{ name: "易碎纸不干胶", images: "" },
{ name: "刚古水纹超白", images: "" },
{ name: "红底散金", images: "" },
{ name: "布纹纸超白", images: "" },
{ name: "珠光超白", images: "" },
{ name: "10C静电膜", images: "" },
{ name: "树纹纸", images: "" },
{ name: "草香纸/大地纸", images: "" },
{ name: "单防热敏纸(底纸白色)", images: "" },
{ name: "三防热敏纸(底纸蓝色)", images: "" },
{
name: "铜板纸不干胶",
images: ["https://ltcloudfile.oss-cn-hangzhou.aliyuncs.com/price_img/20240229/%E9%93%9C%E7%89%88%E7%BA%B8%E4%B8%8D%E5%B9%B2%E8%83%B6/%E4%BA%AE%E8%86%9C.jpg"],
remark: "广东:数量500-1000张(顺丰14点前当天发货 普通快递16点前当天发货) 中通 圆通 顺丰;\n江苏:(3-4天发货) 韵达 顺丰;",
},
{
name: "pvc不干胶",
images: ["https://ltcloudfile.oss-cn-hangzhou.aliyuncs.com/price_img/20240229/%E8%A6%86%E4%BA%AE%E8%86%9C.jpg"],
},
{
name: "透明不干胶",
images: ["https://ltcloudfile.oss-cn-hangzhou.aliyuncs.com/price_img/20240229/%E9%80%8F%E6%98%8E%E4%B8%8D%E5%B9%B2%E8%83%B6/%E4%BA%AE%E8%86%9C.jpg"],
},
{
name: "牛皮纸",
images: ["https://offer.lingtao8.com/upImg/upload/product/20210722/不干胶-牛皮纸不干胶.jpg"],
},
{
name: "哑金不干胶",
images: ["https://offer.lingtao8.com/upImg/upload/product/20210722/不干胶-哑金.jpg", "https://ltcloudfile.oss-cn-hangzhou.aliyuncs.com/price_img/20240229/%E5%93%91%E9%87%91%E4%B8%8D%E5%B9%B2%E8%83%B6/%E5%93%91%E9%87%91%E4%B8%8D%E5%B9%B2%E8%83%B6%E5%8D%B0%E5%88%B71%E8%89%B2.jpg", "https://ltcloudfile.oss-cn-hangzhou.aliyuncs.com/price_img/20240229/%E5%93%91%E9%87%91%E4%B8%8D%E5%B9%B2%E8%83%B6/%E5%93%91%E9%87%91%E4%B8%8D%E5%B9%B2%E8%83%B6%E5%8A%A0%E5%87%B9%E5%87%B8.jpg", "https://ltcloudfile.oss-cn-hangzhou.aliyuncs.com/price_img/20240229/%E5%93%91%E9%87%91%E4%B8%8D%E5%B9%B2%E8%83%B6/%E5%93%91%E9%87%91%E4%B8%8D%E5%B9%B2%E8%83%B6%E5%8D%B02%E8%89%B2.jpg"],
},
{
name: "哑银不干胶",
images: ["https://offer.lingtao8.com/upImg/upload/product/20210722/不干胶-哑银.jpg", "https://ltcloudfile.oss-cn-hangzhou.aliyuncs.com/price_img/20240229/%E5%93%91%E9%93%B6%E4%B8%8D%E5%B9%B2%E8%83%B6/%E5%93%91%E9%87%91%E4%B8%8D%E5%B9%B2%E8%83%B6%E5%8D%B01%E8%89%B2.jpg", "https://ltcloudfile.oss-cn-hangzhou.aliyuncs.com/price_img/20240229/%E5%93%91%E9%93%B6%E4%B8%8D%E5%B9%B2%E8%83%B6/%E5%93%91%E9%93%B6%E4%B8%8D%E5%B9%B2%E8%83%B6%E5%8A%A0%E5%87%B9%E5%87%B8.jpg"],
},
{
name: "书写纸不干胶",
images: ["https://ltcloudfile.oss-cn-hangzhou.aliyuncs.com/price_img/20240229/%E4%B9%A6%E5%86%99%E7%BA%B8%E4%B8%8D%E5%B9%B2%E8%83%B6.jpeg"],
},
{
name: "银平光",
images: ["https://offer.lingtao8.com/upImg/upload/product/20210722/不干胶-银平光.jpg"],
},
{
name: "拉丝金",
images: ["https://offer.lingtao8.com/upImg/upload/product/20210722/不干胶-拉丝金.jpg"],
},
{
name: "拉丝银",
images: ["https://offer.lingtao8.com/upImg/upload/product/20210722/不干胶-拉丝银.jpg", "https://offer.lingtao8.com/upImg/upload/product/20210722/不干胶-拉丝银 (2).jpg"],
},
{
name: "美纹纸",
images: ["https://offer.lingtao8.com/upImg/upload/product/20210722/不干胶-美纹纸.jpg"],
},
{
name: "PP合成纸",
images: ["https://ltcloudfile.oss-cn-hangzhou.aliyuncs.com/price_img/20240229/PP%E5%90%88%E6%88%90%E7%BA%B8.png"],
},
{
name: "易碎纸不干胶",
images: ["https://offer.lingtao8.com/upImg/upload/product/20210722/易碎贴.jpg", "https://ltcloudfile.oss-cn-hangzhou.aliyuncs.com/price_img/20240229/%E6%98%93%E7%A2%8E%E7%BA%B8%E4%B8%8D%E5%B9%B2%E8%83%B6.jpg"],
},
{
name: "刚古水纹超白",
images: ["https://offer.lingtao8.com/upImg/upload/product/20220323/刚古水纹超白.png"],
},
{
name: "红底散金",
images: ["https://offer.lingtao8.com/upImg/upload/product/20220323/红底散金.png"],
},
{
name: "布纹纸超白",
images: ["https://offer.lingtao8.com/upImg/upload/product/20220323/布纹纸超白.png"],
},
{
name: "珠光超白",
images: ["https://offer.lingtao8.com/upImg/upload/product/20220323/珠光超白.png"],
},
{
name: "10C静电膜",
images: ["https://ltcloudfile.oss-cn-hangzhou.aliyuncs.com/price_img/20240229/10C%E9%9D%99%E7%94%B5%E8%86%9C.png"],
},
{
name: "树纹纸",
images: ["https://ltcloudfile.oss-cn-hangzhou.aliyuncs.com/price_img/20240229/swz/%E6%BF%80%E5%87%B8.png"],
},
{
name: "草香纸/大地纸",
images: ["https://ltcloudfile.oss-cn-hangzhou.aliyuncs.com/price_img/20240229/%E5%A4%A7%E5%9C%B0%E7%BA%B8%E6%BF%80%E5%87%B8.png"],
},
{
name: "单防热敏纸(底纸白色)",
images: ["https://ltcloudfile.oss-cn-hangzhou.aliyuncs.com/price_img/20240229/%E5%8D%95%E9%98%B2%E7%83%AD%E6%95%8F%E7%BA%B8%EF%BC%88%E5%BA%95%E7%BA%B8%E7%99%BD%E8%89%B2%EF%BC%89.png"],
},
{
name: "三防热敏纸(底纸蓝色)",
images: ["https://ltcloudfile.oss-cn-hangzhou.aliyuncs.com/price_img/20240229/%E4%B8%89%E9%98%B2%E7%83%AD%E6%95%8F%E7%BA%B8%EF%BC%88%E5%BA%95%E7%BA%B8%E8%93%9D%E8%89%B2%EF%BC%89.png"],
},
];
const craftMap = {
@@ -81,32 +156,25 @@ const craftMap = {
};
const currentCraftComponent = shallowRef(null);
const componentRef = ref(null);
const handlesave = () => {
console.log(data.value);
if (typeof componentRef.value?.verifyCraftData === "function") {
let { valid, message } = componentRef.value.verifyCraftData();
if (!valid) {
console.error("工艺数据验证失败:", message);
return;
}
}
};
const images = ref([]);
const remark = ref("");
const data = ref({
types: "常用种类",
material: "",
size: [],
length: null,
width: null,
count: null,
number: 1,
customerWw: "",
craft: [],
crafts: [],
});
watch(
() => data.value.material,
(mat) => {
handleGetImages(mat);
currentCraftComponent.value = craftMap[mat] || null;
data.value.craft = [];
data.value.crafts = [];
},
);
@@ -114,14 +182,56 @@ const handleChange = (val) => {
const initData = {
types: val,
material: "",
size: [],
length: null,
width: null,
count: null,
number: 1,
customerWw: "",
craft: [],
crafts: [],
};
data.value = initData;
};
const handleGetImages = (name) => {
images.value = [];
if (name) {
let item = materials.find((item) => item.name === name) || {
images: [],
};
images.value = item.images;
} else {
materials.forEach((item) => {
images.value.push(...item.images);
});
}
remark.value = materials.find((item) => item.name === name)?.remark || "";
};
const handleVerifyCraftData = (callback) => {
if (data.value.material == "") {
callback({ valid: false, message: "请选择材质" });
return;
}
if (!data.value.width) {
callback({ valid: false, message: "请输入宽度" });
return;
}
if (!data.value.length) {
callback({ valid: false, message: "请输入长度" });
return;
}
if (!data.value.count) {
callback({ valid: false, message: "请输入数量" });
return;
}
if (typeof componentRef.value?.verifyCraftData === "function") {
let { valid, message } = componentRef.value.verifyCraftData();
callback({ valid, message });
return;
}
callback({ valid: true, message: "工艺数据验证通过" });
};
handleGetImages();
</script>
<style lang="scss" scoped>
.el-form-item--default {
@@ -130,7 +240,6 @@ const handleChange = (val) => {
.container {
margin: 0 20px;
display: flex;
flex-direction: column;
}
.form-title {
display: block;
@@ -138,4 +247,10 @@ const handleChange = (val) => {
font-size: 16px;
margin-bottom: 5px;
}
.left-info {
flex: 1;
}
.right-image {
flex: 1;
}
</style>