123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564 |
- <template>
- <div v-loading="loading">
- <byForm :formConfig="formConfig" :formOption="formOption" v-model="formData.data" :rules="rules" ref="formDom">
- <template #chart>
- <div style="width:100%;padding-left:25px">
- <div ref="chartDom" style="height:300px"></div>
- </div>
- </template>
- <template #buyer>
- <div style="width: 100%">
- <el-form-item label="客户信息" prop="buyCorporationId" class="wid100">
- <el-select v-model="formData.data.buyCorporationId" filterable remote reserve-keyword placeholder="请输入关键字" remote-show-suffix
- :remote-method="remoteMethod" :loading="loadingSearch" @input="remoteMethod" style="width: 100%" @change="changeCustomer">
- <el-option v-for="item in customerList" :key="item.value" :label="item.label" :value="item.value" />
- </el-select>
- </el-form-item>
- <el-row style="width: 100%">
- <el-col :span="12">
- <el-form-item label="地址" class="wid100 margin-b-0">
- <el-row style="padding-right:5px;width:100%">
- <el-col :span="6">
- <el-form-item label="" prop="buyCountryId" class="margin-b-0 wid100" label-width="0px">
- <el-select v-model="formData.data.buyCountryId" placeholder="国家" style="width:100%" filterable
- @change="(val) => getCityData(val, '20', true)">
- <el-option v-for="item in countryData" :label="item.name" :value="item.id">
- </el-option>
- </el-select>
- </el-form-item>
- </el-col>
- <el-col :span="6">
- <el-form-item label="" prop="provinceName" class="margin-b-0 wid100" label-width="0px">
- <selectCity placeholder="省/洲" @change="(val) => getCityData(val, '30', true)" addressId="buyProvinceId"
- addressName="provinceName" v-model="formData.data" :data="provinceData">
- </selectCity>
- </el-form-item>
- </el-col>
- <el-col :span="6">
- <el-form-item label="" prop="cityName" class="margin-b-0 wid100" label-width="0px">
- <selectCity placeholder="城市" addressId="buyCityId" addressName="cityName" v-model="formData.data" :data="cityData">
- </selectCity>
- </el-form-item>
- </el-col>
- <el-col :span="6">
- <el-form-item label="" prop="buyPostalCode" class="margin-b-0" label-width="0px">
- <el-input v-model="formData.data.buyPostalCode" placeholder="请输入邮编" />
- </el-form-item>
- </el-col>
- </el-row>
- </el-form-item>
- </el-col>
- <el-col :span="12" style="padding-left:5px">
- <el-form-item label="详细地址" prop="buyAddress" class="margin-b-0 wid100">
- <el-input v-model="formData.data.buyAddress" type="text" placeholder="请输入详细地址">
- </el-input>
- </el-form-item>
- </el-col>
- </el-row>
- </div>
- </template>
- <template #commodity>
- <div style="width: 100%;padding-left:25px">
- <el-table :data="formData.data.quotationProductList" style="width: 100%;" default-expand-all>
- <el-table-column type="expand" width="50" align="center">
- <template #default="scope">
- <div style="padding-left:50px">
- <div style="margin-bottom:10px;">
- <TitleInfo content='BOM单:'></TitleInfo>
- </div>
- <el-table :data="scope.row.quotationProductBomList" style="width: 100%;" border class="bom-table">
- <el-table-column label="图片" width="80">
- <template #default="{ row }">
- <div v-if="row.fileUrl">
- <img :src="row.fileUrl" class="pic" @click="onPicture(row.fileUrl)" />
- </div>
- <div v-else></div>
- </template>
- </el-table-column>
- <el-table-column prop="productCode" label="物料编码" width="190" />
- <el-table-column prop="productName" label="物料名称" min-width="200" />
- <el-table-column label="尺寸 (cm)" width="150">
- <template #default="{ row, $index }">
- <div style="width: 100%">
- {{row.productLength}} * {{row.productWidth}} * {{row.productHeight}}
- </div>
- </template>
- </el-table-column>
- <el-table-column prop="quantity" label="数量" width="110" />
- <!-- <template #default="{ row, $index }">
- <div style="width: 100%">
- <el-form-item :prop="'quotationProductList.' + scope.$index + '.quotationProductBomList.' + $index + '.quantity'"
- :rules="rules.quantity" :inline-message="true" class="margin-b-0 wid100">
- <el-input-number onmousewheel="return false;" v-model="row.quantity" placeholder="请输入" style="width: 100%" :precision="0"
- :controls="false" :min="1" :disabled="row.type==1" @change="changeQuantity()" />
- </el-form-item>
- </div>
- </template> -->
- <el-table-column prop="allQuantity" label="总量" width="80" />
- <el-table-column prop="price" label="单价" width="110">
- <template #default="{ row, $index }">
- <div style="width: 100%">
- ¥ {{row.price}}
- </div>
- </template>
- </el-table-column>
- <el-table-column prop="amount" label="小计" width="110">
- <template #default="{ row, $index }">
- <div style="width: 100%">
- ¥ {{row.amount}}
- </div>
- </template>
- </el-table-column>
- <el-table-column prop="remark" label="备注" width="180" />
- <!-- <template #default="{ row, $index }">
- <div style="width: 100%">
- <el-form-item :prop="'quotationProductList.' + scope.$index + '.quotationProductBomList.' + $index + '.remark'"
- :rules="rules.remark" :inline-message="true" class="margin-b-0 wid100">
- <el-input v-model="row.remark" placeholder="请输入" style="width: 100%" :min="0" />
- </el-form-item>
- </div>
- </template> -->
- </el-table>
- </div>
- </template>
- </el-table-column>
- <el-table-column label="图片" width="80">
- <template #default="{ row }">
- <div v-if="row.fileUrl">
- <img :src="row.fileUrl" class="pic" @click="onPicture(row.fileUrl)" />
- </div>
- <div v-else></div>
- </template>
- </el-table-column>
- <el-table-column prop="productCode" label="商品编码" width="190" />
- <el-table-column prop="productName" label="商品名称" min-width="200" />
- <el-table-column label="尺寸 (cm)" width="150">
- <template #default="{ row, $index }">
- <div style="width: 100%">
- {{row.productLength}} * {{row.productWidth}} * {{row.productHeight}}
- </div>
- </template>
- </el-table-column>
- <el-table-column prop="productColor" label="颜色" width="100" />
- <el-table-column prop="quantity" label="数量" width="110" />
- <!-- <template #default="{ row, $index }">
- <div style="width: 100%">
- <el-form-item :prop="'quotationProductList.' + $index + '.quantity'" :rules="rules.quantity" :inline-message="true"
- class="margin-b-0 wid100">
- <el-input-number onmousewheel="return false;" v-model="row.quantity" placeholder="请输入" style="width: 100%" :precision="0"
- :controls="false" :min="1" @change="changeQuantity()" />
- </el-form-item>
- </div>
- </template> -->
- <el-table-column prop="price" label="单价" width="110">
- <template #default="{ row, $index }">
- <div style="width: 100%">
- ¥ {{row.price}}
- </div>
- </template>
- </el-table-column>
- <el-table-column prop="amount" label="小计" width="110">
- <template #default="{ row, $index }">
- <div style="width: 100%">
- ¥ {{row.amount}}
- </div>
- </template>
- </el-table-column>
- </el-table>
- </div>
- </template>
- </byForm>
- </div>
- </template>
- <script setup>
- import byForm from "@/components/byForm/index";
- import selectCity from "@/components/selectCity/index.vue";
- import * as echarts from "echarts";
- const { proxy } = getCurrentInstance();
- const props = defineProps({
- rowData: Object,
- dataType: {
- type: String,
- default: "1",
- },
- });
- const typeData = ref([
- {
- label: "常规订单",
- value: 1,
- },
- {
- label: "出口退税订单",
- value: 2,
- },
- ]);
- const treeData = ref([]);
- const countryData = ref([]);
- const provinceData = ref([]);
- const cityData = ref([]);
- const formData = reactive({
- data: {
- type: 1,
- quotationProductList: [],
- },
- });
- const loading = ref(false);
- const formDom = ref(null);
- const formOption = reactive({
- inline: true,
- labelWidth: 100,
- itemWidth: 100,
- disabled: true,
- });
- let myChart = null;
- const chartDom = ref(null);
- const isShowChart = ref(false);
- const formConfig = computed(() => {
- return [
- // {
- // type: "title1",
- // title: "报价趋势",
- // isShow: isShowChart.value,
- // },
- // {
- // type: "slot",
- // slotName: "chart",
- // isShow: isShowChart.value,
- // },
- {
- type: "title1",
- title: "报价类型",
- },
- {
- type: "input",
- prop: "code",
- label: "报价单号",
- isShow: formData.data.code ? true : false,
- },
- {
- type: "select",
- prop: "type",
- label: "报价类型",
- data: typeData.value,
- itemWidth: 50,
- },
- {
- type: "treeSelect",
- prop: "companyId",
- label: "报价公司",
- data: treeData.value,
- propsTreeLabel: "deptName",
- propsTreeValue: "deptId",
- itemWidth: 50,
- fn: (val) => {
- companyId.value = val;
- },
- },
- {
- type: "title1",
- title: "贸易信息",
- },
- {
- type: "slot",
- slotName: "buyer",
- label: "",
- itemWidth: 100,
- },
- {
- type: "input",
- itemType: "text",
- label: "联系人",
- prop: "buyContactName",
- itemWidth: 50,
- },
- {
- type: "input",
- itemType: "text",
- label: "联系人电话",
- prop: "buyContactNumber",
- itemWidth: 50,
- },
- {
- type: "title1",
- title: "商品信息",
- },
- {
- type: "slot",
- slotName: "commodity",
- label: "",
- },
- {
- type: "title1",
- title: "报价总金额",
- },
- {
- type: "input",
- prop: "amount",
- label: "报价总金额",
- itemWidth: 25,
- disabled: true,
- },
- ];
- });
- const getCityData = (id, type, isChange = false) => {
- proxy.post("/customizeArea/list", { parentId: id }).then((res) => {
- if (type === "20") {
- provinceData.value = res;
- if (isChange) {
- formData.data.buyProvinceId = "";
- formData.data.provinceName = "";
- formData.data.buyCityId = "";
- formData.data.cityName = "";
- }
- } else if (type === "30") {
- cityData.value = res;
- if (isChange) {
- formData.data.buyCityId = "";
- formData.data.cityName = "";
- }
- } else {
- countryData.value = res;
- }
- });
- };
- getCityData("0");
- const getDict = () => {
- proxy
- .get("/tenantDept/list", {
- pageNum: 1,
- pageSize: 9999,
- keyword: "",
- tenantId: proxy.useUserStore().user.tenantId,
- type: 0,
- })
- .then((res) => {
- treeData.value = proxy.handleTree(res.data, "deptId");
- });
- };
- getDict();
- const getFileData = () => {
- let ids = [];
- formData.data.quotationProductList.map((x) => {
- // ids.push(x.productId);
- x.quotationProductBomList.map((y) => {
- ids.push(y.materialId);
- });
- });
- ids = Array.from(new Set(ids));
- proxy
- .post("/fileInfo/getList", {
- businessIdList: ids,
- })
- .then((fileObj) => {
- formData.data.quotationProductList.map((x) => {
- // x.fileList = fileObj[x.productId] || [];
- // if (x.fileList && x.fileList.length > 0) {
- // x.fileUrl = x.fileList[0].fileUrl;
- // }
- x.quotationProductBomList.map((y) => {
- y.fileList = fileObj[y.materialId] || [];
- if (y.fileList && y.fileList.length > 0) {
- y.fileUrl = y.fileList[0].fileUrl;
- }
- });
- });
- });
- };
- const changeQuantity = () => {
- let money = 0;
- if (
- formData.data.quotationProductList &&
- formData.data.quotationProductList.length > 0
- ) {
- // 单个产品的价格
- for (let i = 0; i < formData.data.quotationProductList.length; i++) {
- let iele = formData.data.quotationProductList[i];
- let productPrice = 0;
- for (let j = 0; j < iele.quotationProductBomList.length; j++) {
- const jele = iele.quotationProductBomList[j];
- productPrice += Number(
- parseFloat(Number(jele.quantity) * Number(jele.price)).toFixed(2)
- );
- }
- iele.price = parseFloat(productPrice).toFixed(2);
- }
- // 计算数量以及小计
- for (let i = 0; i < formData.data.quotationProductList.length; i++) {
- let iele = formData.data.quotationProductList[i];
- if (iele.quantity) {
- if (iele.price) {
- iele.amount = parseFloat(
- Number(iele.quantity) * Number(iele.price)
- ).toFixed(2);
- money += Number(iele.amount);
- }
- for (let j = 0; j < iele.quotationProductBomList.length; j++) {
- const jele = iele.quotationProductBomList[j];
- jele.allQuantity = iele.quantity * jele.quantity;
- if (jele.price) {
- jele.amount = parseFloat(
- Number(jele.allQuantity) * Number(jele.price)
- ).toFixed(2);
- }
- }
- }
- }
- formData.data.amount = parseFloat(money).toFixed(2);
- }
- };
- const chartData = ref([]);
- const chartOption = reactive({
- data: {
- tooltip: {
- trigger: "axis",
- },
- // legend: {
- // data: ["价格"],
- // },
- grid: {
- left: "3%",
- right: "6%",
- top: "10%",
- bottom: "3%",
- containLabel: true,
- },
- tooltip: {
- show: true,
- trigger: "axis",
- // 格式化函数
- // valueFormatter: (val) => {
- // return val + "aaa";
- // },
- formatter: (params, ticket, callback) => {
- return `
- ${params[0].seriesName}:${params[0].value}
- <br/>
- 报价单号:${chartData.value[params[0].dataIndex].code}
- `;
- },
- textStyle: {
- fontSize: 12,
- },
- },
- // toolbox: {
- // feature: {
- // saveAsImage: {},
- // },
- // },
- xAxis: {
- type: "category",
- boundaryGap: false,
- data: [],
- },
- yAxis: {
- type: "value",
- },
- series: [
- {
- name: "报价金额",
- type: "line",
- data: [],
- },
- ],
- },
- });
- const customerList = ref([]);
- const getData = (query) => {
- let url =
- props.dataType == "1" ? "/saleQuotation/detail" : "/extQuotation/detail";
- loading.value = true;
- proxy.post(url, query).then((res) => {
- formData.data = res;
- proxy
- .post("/customer/selPage", { keyword: formData.data.buyCorporationName })
- .then((res) => {
- customerList.value = res.rows.map((x) => ({
- ...x,
- label: x.name,
- value: x.id,
- }));
- });
- // 城市数据回显
- if (formData.data.buyCountryId) {
- getCityData(formData.data.buyCountryId, "20");
- }
- if (formData.data.buyProvinceId) {
- getCityData(formData.data.buyProvinceId, "30");
- }
- getFileData();
- let productIds = formData.data.quotationProductList.map((x) => x.productId);
- proxy.getFileData({
- businessIdList: productIds,
- data: formData.data.quotationProductList,
- att: "productId",
- businessType: "0",
- fileAtt: "productFile",
- filePathAtt: "fileUrl",
- });
- changeQuantity();
- loading.value = false;
- // if (res.quotationTrendList && res.quotationTrendList.length >= 2) {
- // isShowChart.value = true;
- // nextTick(() => {
- // myChart = echarts.init(chartDom.value);
- // window.addEventListener("resize", () => {
- // myChart.resize();
- // });
- // chartData.value = res.quotationTrendList;
- // chartOption.data.xAxis.data = chartData.value.map((item) => {
- // return item.createTime.slice(0, 10);
- // });
- // chartOption.data.series[0].data = chartData.value.map((item, index) => {
- // if (item.code == props.rowData.code) {
- // return {
- // value: item.amount || 0,
- // itemStyle: { color: "red" },
- // };
- // } else {
- // return item.amount || 0;
- // }
- // });
- // myChart.setOption(chartOption.data);
- // myChart.resize();
- // });
- // } else {
- // isShowChart.value = false;
- // }
- });
- };
- watch(
- () => props.rowData,
- (val) => {
- if (props.rowData.id) {
- getData({ id: props.rowData.id });
- }
- },
- {
- immediate: true,
- deep: true,
- }
- );
- </script>
- <style lang="scss" scoped>
- .pic {
- object-fit: contain;
- width: 50px;
- height: 50px;
- cursor: pointer;
- vertical-align: middle;
- }
- :deep(.bom-table .el-table__body-wrapper .el-table__body .el-table__row) {
- background: #f4f4f5 !important;
- }
- </style>
|