detail.vue 38 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876
  1. <template>
  2. <div>
  3. <el-card class="box-card">
  4. <div style="padding: 8px; text-align: center" v-if="formData.data.code || formData.data.wlnCode">
  5. <span style="font-size: 18px; font-weight: 700">{{ formData.data.code }} </span>
  6. <span style="font-size: 18px; font-weight: 700" v-if="formData.data.wlnCode"> ({{ formData.data.wlnCode }})</span>
  7. </div>
  8. <byForm :formConfig="formConfig" :formOption="formOption" v-model="formData.data" :rules="rules" ref="submit">
  9. <template #deliveryAddress>
  10. <div style="width: 100%">
  11. <el-row>
  12. <el-col :span="3">
  13. <el-form-item label-width="0" prop="province" style="width: 100%">
  14. <el-input v-model="formData.data.province" placeholder="请输入省" />
  15. </el-form-item>
  16. </el-col>
  17. <el-col :span="3">
  18. <el-form-item label-width="0" prop="city" style="width: 100%">
  19. <el-input v-model="formData.data.city" placeholder="请输入市" />
  20. </el-form-item>
  21. </el-col>
  22. <el-col :span="3">
  23. <el-form-item label-width="0" prop="county" style="width: 100%">
  24. <el-input v-model="formData.data.county" placeholder="请输入区/县" />
  25. </el-form-item>
  26. </el-col>
  27. <el-col :span="11">
  28. <el-form-item label-width="0" prop="detailedAddress" style="width: 100%">
  29. <el-input v-model="formData.data.detailedAddress" placeholder="请输入详细地址" />
  30. </el-form-item>
  31. </el-col>
  32. <el-col :span="4">
  33. <el-form-item label-width="0" prop="postcode" style="width: 100%">
  34. <el-input v-model="formData.data.postcode" placeholder="请输入邮编" />
  35. </el-form-item>
  36. </el-col>
  37. </el-row>
  38. </div>
  39. </template>
  40. <template #consignee>
  41. <div style="width: 100%">
  42. <el-row>
  43. <el-col :span="6">
  44. <el-form-item label-width="0" prop="consignee" style="width: 100%">
  45. <el-input v-model="formData.data.consignee" placeholder="请输入联系人" />
  46. </el-form-item>
  47. </el-col>
  48. <el-col :span="6">
  49. <el-form-item label-width="0" prop="consigneeNumber" style="width: 100%">
  50. <el-input v-model="formData.data.consigneeNumber" placeholder="请输入联系电话" />
  51. </el-form-item>
  52. </el-col>
  53. <el-col :span="6">
  54. <el-form-item label-width="0" prop="departmentId" style="width: 100%">
  55. <el-select v-model="formData.data.departmentId" placeholder="请选择事业部" clearable style="width: 100%">
  56. <el-option v-for="item in departmentList" :key="item.dictKey" :label="item.dictValue" :value="item.dictKey" />
  57. </el-select>
  58. </el-form-item>
  59. </el-col>
  60. </el-row>
  61. </div>
  62. </template>
  63. <template #orderSkuList>
  64. <div style="width: 100%; padding: 0 20px">
  65. <el-collapse v-model="activeNames">
  66. <div v-for="(item, index) in formData.data.orderSkuList" :key="index" style="margin-bottom: 20px">
  67. <div style="border: 1px solid #edf0f5">
  68. <el-table :data="[item]" :row-style="{ height: '35px' }" header-row-class-name="tableHeader">
  69. <el-table-column label="产品" width="300">
  70. <template #default="{ row }">
  71. <div style="width: 100%">
  72. <div style="line-height: 35px">
  73. <span style="color: black; font-weight: 700">商品名称: </span>
  74. <span>{{ item.wlnSkuName }}</span>
  75. </div>
  76. <div style="line-height: 35px">
  77. <span style="color: black; font-weight: 700">品号: </span>
  78. <span>{{ item.code }}</span>
  79. </div>
  80. <div style="line-height: 35px; word-break: break-all">
  81. <span style="color: black; font-weight: 700">品名: </span>
  82. <span>{{ item.name }}</span>
  83. </div>
  84. <div style="line-height: 35px; display: flex">
  85. <span style="width: 37px; color: black; font-weight: 700">数量: </span>
  86. <el-form-item
  87. :prop="'orderSkuList.' + index + '.quantity'"
  88. :rules="rules.quantity"
  89. :inline-message="true"
  90. style="width: calc(100% - 37px)">
  91. <el-input-number
  92. onmousewheel="return false;"
  93. v-model="row.quantity"
  94. placeholder="数量"
  95. style="width: 100%"
  96. :controls="false"
  97. :min="0"
  98. :precision="0"
  99. @change="changeQuantity(index)" />
  100. </el-form-item>
  101. </div>
  102. <div style="line-height: 35px">
  103. <span style="color: black; font-weight: 700">加工费: </span>
  104. <span>{{ item.customProcessingFee }}</span>
  105. <el-tooltip content="修改加工费" placement="top" effect="light">
  106. <el-icon
  107. style="margin-left: 10px; transform: translateY(2px); color: #409eff; cursor: pointer"
  108. @click="clickChangePrice(item, index, 'customProcessingFee', '加工费')"
  109. v-if="route.query && route.query.detailId">
  110. <EditPen />
  111. </el-icon>
  112. </el-tooltip>
  113. </div>
  114. <div style="line-height: 35px">
  115. <span style="color: black; font-weight: 700">代发费: </span>
  116. <span>{{ item.lssueFee }}</span>
  117. <el-tooltip content="修改代发费" placement="top" effect="light">
  118. <el-icon
  119. style="margin-left: 10px; transform: translateY(2px); color: #409eff; cursor: pointer"
  120. @click="clickChangePrice(item, index, 'lssueFee', '代发费')"
  121. v-if="route.query && route.query.detailId">
  122. <EditPen />
  123. </el-icon>
  124. </el-tooltip>
  125. </div>
  126. <div style="line-height: 35px">
  127. <span style="color: black; font-weight: 700">快递包材费: </span>
  128. <span>{{ item.deliveryMaterialsFee }}</span>
  129. <el-tooltip content="修改快递包材费" placement="top" effect="light">
  130. <el-icon
  131. style="margin-left: 10px; transform: translateY(2px); color: #409eff; cursor: pointer"
  132. @click="clickChangePrice(item, index, 'deliveryMaterialsFee', '快递包材费')"
  133. v-if="route.query && route.query.detailId">
  134. <EditPen />
  135. </el-icon>
  136. </el-tooltip>
  137. </div>
  138. <div style="line-height: 35px">
  139. <span style="color: black; font-weight: 700">包装人工费: </span>
  140. <span>{{ item.packingLabor }}</span>
  141. <el-tooltip content="修改包装人工费" placement="top" effect="light">
  142. <el-icon
  143. style="margin-left: 10px; transform: translateY(2px); color: #409eff; cursor: pointer"
  144. @click="clickChangePrice(item, index, 'packingLabor', '包装人工费')"
  145. v-if="route.query && route.query.detailId">
  146. <EditPen />
  147. </el-icon>
  148. </el-tooltip>
  149. </div>
  150. <div style="line-height: 35px">
  151. <span style="color: black; font-weight: 700">管理费: </span>
  152. <span>{{ item.managementFee }}</span>
  153. <el-tooltip content="修改管理费" placement="top" effect="light">
  154. <el-icon
  155. style="margin-left: 10px; transform: translateY(2px); color: #409eff; cursor: pointer"
  156. @click="clickChangePrice(item, index, 'managementFee', '管理费')"
  157. v-if="route.query && route.query.detailId">
  158. <EditPen />
  159. </el-icon>
  160. </el-tooltip>
  161. </div>
  162. <div style="line-height: 35px">
  163. <span style="color: black; font-weight: 700">单价: </span>
  164. <span>{{ item.unitPrice }}</span>
  165. <el-tooltip content="修改单价" placement="top" effect="light">
  166. <el-icon
  167. style="margin-left: 10px; transform: translateY(2px); color: #409eff; cursor: pointer"
  168. @click="clickChangePrice(item, index, 'unitPrice', '单价')"
  169. v-if="route.query && route.query.detailId">
  170. <EditPen />
  171. </el-icon>
  172. </el-tooltip>
  173. </div>
  174. <div style="line-height: 35px">
  175. <span style="color: black; font-weight: 700">小计: </span>
  176. <span>{{ item.subtotal }}</span>
  177. </div>
  178. <div style="line-height: 35px">
  179. <span style="width: 37px; color: black; font-weight: 700">打印: </span>
  180. <el-form-item
  181. :prop="'orderSkuList.' + index + '.printType'"
  182. :rules="rules.printType"
  183. :inline-message="true"
  184. style="width: calc(100% - 37px)">
  185. <el-radio-group v-model="item.printType">
  186. <el-radio v-for="(itemType, index) in printType" :key="index" :label="itemType.dictKey">{{ itemType.dictValue }}</el-radio>
  187. </el-radio-group>
  188. </el-form-item>
  189. </div>
  190. </div>
  191. </template>
  192. </el-table-column>
  193. <el-table-column label="产品图稿" width="400">
  194. <template #default="{ row }">
  195. <el-form-item :prop="'orderSkuList.' + index + '.blueprint'">
  196. <div style="display: flex; width: 100%">
  197. <div style="width: 65px">设计图:</div>
  198. <div style="width: calc(100% - 65px)">
  199. <el-image
  200. fit="scale-down"
  201. style="width: 148px; height: 148px; margin-right: 10px"
  202. v-if="row.blueprint"
  203. :src="row.blueprint"
  204. @click="openFile(row.blueprint)" />
  205. </div>
  206. </div>
  207. <div style="display: flex; margin-top: 20px; width: 100%">
  208. <div style="width: 65px">图稿文件:</div>
  209. <div style="width: calc(100% - 65px)">
  210. <a
  211. style="color: #409eff; cursor: pointer; word-break: break-all; margin-right: 10px"
  212. @click="openFile(row.productionDocument)"
  213. v-if="row.productionDocument">
  214. {{ row.productionDocument }}
  215. </a>
  216. <!-- <el-button type="primary" style="transform: translateY(-2px)" @click="clickDrawingFile(index)" text>选择文件</el-button> -->
  217. </div>
  218. </div>
  219. </el-form-item>
  220. </template>
  221. </el-table-column>
  222. <el-table-column label="包材配件/单品" min-width="400">
  223. <template #default="{ row }">
  224. <div style="width: 100%">
  225. <el-table :data="row.orderSkuBomList" :row-style="{ height: '35px' }" header-row-class-name="tableHeader">
  226. <el-table-column label="单价¥" width="120">
  227. <template #default="props">
  228. <div>
  229. <span>{{ moneyFormat(props.row.unitPrice, 2) }}</span>
  230. <el-tooltip content="修改单价¥" placement="top" effect="light">
  231. <el-icon
  232. style="margin-left: 10px; transform: translateY(2px); color: #409eff; cursor: pointer"
  233. @click="clickChangeBomPrice(index, props.row, props.$index, 'unitPrice', '单价¥')"
  234. v-if="route.query && route.query.detailId">
  235. <EditPen />
  236. </el-icon>
  237. </el-tooltip>
  238. </div>
  239. </template>
  240. </el-table-column>
  241. <el-table-column label="数量" width="100">
  242. <template #default="props">
  243. <el-form-item
  244. :prop="'orderSkuList.' + index + '.orderSkuBomList.' + props.$index + '.quantity'"
  245. :rules="rules.quantity"
  246. :inline-message="true"
  247. style="width: 100%">
  248. <el-input-number
  249. onmousewheel="return false;"
  250. v-model="props.row.quantity"
  251. placeholder="数量"
  252. style="width: 100%"
  253. :controls="false"
  254. :min="0"
  255. @change="changeBOMQuantity(index)" />
  256. </el-form-item>
  257. </template>
  258. </el-table-column>
  259. <el-table-column label="名称" prop="bomSpecName" min-width="150" />
  260. <el-table-column label="总量" prop="allQuantity" width="80" />
  261. <el-table-column label="小计¥" width="100">
  262. <template #default="props">
  263. {{ moneyFormat(props.row.allUnitPrice, 2) }}
  264. </template>
  265. </el-table-column>
  266. </el-table>
  267. </div>
  268. </template>
  269. </el-table-column>
  270. </el-table>
  271. <el-collapse-item :name="index">
  272. <template #title>
  273. <span>包装</span>
  274. </template>
  275. <div style="display: flex; padding: 8px 10px 0px">
  276. <div style="flex: 1; padding: 0px 10px">
  277. <div>包装要求:</div>
  278. <div v-html="getStyle(item.packageRemark)"></div>
  279. </div>
  280. </div>
  281. </el-collapse-item>
  282. </div>
  283. </div>
  284. </el-collapse>
  285. </div>
  286. </template>
  287. <template #deliveryTime>
  288. <div style="width: 100%">
  289. <el-date-picker
  290. v-model="formData.data.deliveryTime"
  291. type="datetime"
  292. placeholder="请选择交货日期"
  293. value-format="YYYY-MM-DD HH:mm:ss"
  294. style="width: 100%" />
  295. </div>
  296. </template>
  297. <template #totalMonet>
  298. <div style="width: 100%; margin-left: 30px">
  299. <div>
  300. <span style="font-weight: 700; color: #6c88f1">产品总金额: ¥{{ moneyFormat(formData.data.productTotalAmount, 2) }}</span>
  301. <span style="font-weight: 700; color: #6c88f1; margin-left: 40px">定制加工费: ¥{{ moneyFormat(formData.data.customProcessingFee, 2) }}</span>
  302. <span style="font-weight: 700; color: #6c88f1; margin-left: 40px">代发费: ¥{{ moneyFormat(formData.data.lssueFee, 2) }}</span>
  303. <span style="font-weight: 700; color: #6c88f1; margin-left: 40px">快递包材费: ¥{{ moneyFormat(formData.data.deliveryMaterialsFee, 2) }}</span>
  304. <span style="font-weight: 700; color: #6c88f1; margin-left: 40px">包装人工费: ¥{{ moneyFormat(formData.data.packingLabor, 2) }}</span>
  305. <span style="font-weight: 700; color: #6c88f1; margin-left: 40px">包材费: ¥{{ moneyFormat(formData.data.packagingMaterialCost, 2) }}</span>
  306. <span style="font-weight: 700; color: #6c88f1; margin-left: 40px">管理费: ¥{{ moneyFormat(formData.data.managementFee, 2) }}</span>
  307. </div>
  308. <div style="padding: 8px 0 0 0">
  309. <span style="font-weight: 700; color: red">订单总金额(含税): ¥{{ moneyFormat(formData.data.totalAmount, 2) }}</span>
  310. </div>
  311. </div>
  312. </template>
  313. <template #remark>
  314. <div style="width: 100%">
  315. <div v-html="getStyle(formData.data.remark)"></div>
  316. </div>
  317. </template>
  318. </byForm>
  319. <div style="text-align: center; margin: 10px">
  320. <el-button @click="clickCancel()" size="large">关 闭</el-button>
  321. </div>
  322. </el-card>
  323. <el-dialog :title="'修改' + textPrice" v-if="openChangePrice" v-model="openChangePrice" width="500">
  324. <el-form :model="changePrice.data" label-width="120px" ref="price">
  325. <el-form-item
  326. label="定制加工类型"
  327. prop="customProcessingType"
  328. :rules="[{ required: true, message: '请选择定制加工类型', trigger: 'change' }]"
  329. v-if="labelPrice === 'customProcessingFee'">
  330. <el-select
  331. v-model="changePrice.data.customProcessingType"
  332. placeholder="请选择定制加工类型"
  333. style="width: 100%"
  334. clearable
  335. @change="changeProcessingType">
  336. <el-option :label="'无'" :value="'-1'" />
  337. <el-option
  338. v-for="itemDict in useUserStore().allDict['processing_layout']"
  339. :key="itemDict.dictKey"
  340. :label="itemDict.dictValue"
  341. :value="itemDict.dictKey" />
  342. </el-select>
  343. </el-form-item>
  344. <el-form-item :label="textPrice" :prop="labelPrice" :rules="[{ required: true, message: '请输入' + textPrice, trigger: 'blur' }]">
  345. <el-input-number
  346. onmousewheel="return false;"
  347. v-model="changePrice.data[labelPrice]"
  348. :placeholder="textPrice"
  349. style="width: 100%"
  350. :controls="false"
  351. :min="0"
  352. :precision="2"
  353. :disabled="(!changePrice.data.customProcessingType || changePrice.data.customProcessingType === '-1') && labelPrice === 'customProcessingFee'" />
  354. </el-form-item>
  355. </el-form>
  356. <template #footer>
  357. <el-button @click="openChangePrice = false" size="large">取 消</el-button>
  358. <el-button type="primary" @click="submitChangePrice()" size="large" v-preReClick>确 定</el-button>
  359. </template>
  360. </el-dialog>
  361. </div>
  362. </template>
  363. <script setup>
  364. import byForm from "@/components/byForm/index";
  365. import { ElMessage } from "element-plus";
  366. import { useRouter, useRoute } from "vue-router";
  367. import useTagsViewStore from "@/store/modules/tagsView";
  368. const { proxy } = getCurrentInstance();
  369. const router = useRouter();
  370. const route = useRoute();
  371. const submit = ref(null);
  372. const departmentList = ref([]);
  373. const activeNames = ref([]);
  374. const formOption = reactive({
  375. inline: true,
  376. labelWidth: "120px",
  377. itemWidth: 100,
  378. rules: [],
  379. labelPosition: "right",
  380. });
  381. const formData = reactive({
  382. data: {
  383. remark: "",
  384. orderSkuList: [],
  385. },
  386. });
  387. const formConfig = computed(() => {
  388. return [
  389. {
  390. type: "title",
  391. title: "产品",
  392. label: "",
  393. },
  394. {
  395. type: "slot",
  396. prop: "orderSkuList",
  397. slotName: "orderSkuList",
  398. },
  399. route.query && route.query.detailId
  400. ? {}
  401. : {
  402. type: "title",
  403. title: "地址",
  404. label: "",
  405. },
  406. route.query && route.query.detailId
  407. ? {}
  408. : {
  409. type: "slot",
  410. slotName: "deliveryAddress",
  411. label: "收货地址",
  412. },
  413. route.query && route.query.detailId
  414. ? {}
  415. : {
  416. type: "slot",
  417. slotName: "consignee",
  418. label: "收货人",
  419. },
  420. {
  421. type: "title",
  422. title: "贸易",
  423. label: "",
  424. },
  425. {
  426. type: "slot",
  427. prop: "deliveryTime",
  428. slotName: "deliveryTime",
  429. label: "交货时间",
  430. itemWidth: 25,
  431. },
  432. {
  433. type: "select",
  434. label: "选择快递",
  435. prop: "expressDeliveryId",
  436. data: [],
  437. itemWidth: 25,
  438. clearable: true,
  439. },
  440. {
  441. type: "select",
  442. label: "店铺来源",
  443. prop: "sourcePlatform",
  444. data: proxy.useUserStore().allDict["source_platform"],
  445. itemWidth: 25,
  446. clearable: true,
  447. },
  448. {
  449. type: "select",
  450. label: "店铺名称",
  451. prop: "shopName",
  452. data: proxy.useUserStore().allDict["shop_name"],
  453. itemWidth: 25,
  454. clearable: true,
  455. },
  456. {
  457. type: "title",
  458. title: "总计",
  459. label: "",
  460. },
  461. {
  462. type: "slot",
  463. prop: "totalMonet",
  464. slotName: "totalMonet",
  465. },
  466. // {
  467. // type: "title",
  468. // title: "附件",
  469. // label: "",
  470. // },
  471. // {
  472. // type: "slot",
  473. // slotName: "attachments",
  474. // label: "附件",
  475. // },
  476. {
  477. type: "title",
  478. title: "订单备注",
  479. label: "",
  480. },
  481. {
  482. type: "slot",
  483. slotName: "remark",
  484. },
  485. ];
  486. });
  487. const rules = ref({
  488. province: [{ required: true, message: "请输入省", trigger: "blur" }],
  489. detailedAddress: [{ required: true, message: "请输入详细地址", trigger: "blur" }],
  490. consignee: [{ required: true, message: "请输入联系人", trigger: "blur" }],
  491. consigneeNumber: [{ required: true, message: "请输入联系电话", trigger: "blur" }],
  492. deliveryTime: [{ required: true, message: "请选择交货时间", trigger: "change" }],
  493. // expressDeliveryId: [{ required: true, message: "请选择快递", trigger: "change" }],
  494. commercePlatform: [{ required: true, message: "请选择电商平台", trigger: "change" }],
  495. quantity: [{ required: true, message: "请输入数量", trigger: "blur" }],
  496. });
  497. const getDemandData = () => {
  498. proxy.post("/department/page", { pageNum: 1, pageSize: 999 }).then((res) => {
  499. if (res.rows && res.rows.length > 0) {
  500. departmentList.value = res.rows.map((item) => {
  501. return {
  502. dictKey: item.id,
  503. dictValue: item.name,
  504. };
  505. });
  506. }
  507. });
  508. };
  509. getDemandData();
  510. const openFile = (path) => {
  511. window.open(path);
  512. };
  513. const clickCancel = () => {
  514. const useTagsStore = useTagsViewStore();
  515. useTagsStore.delVisitedView(router.currentRoute.value);
  516. if (route.query && route.query.orderInquiry) {
  517. router.replace({
  518. path: "/production/schedule/order-inquiry",
  519. });
  520. } else {
  521. router.replace({
  522. path: "/group/order/order-management",
  523. });
  524. }
  525. };
  526. onMounted(() => {
  527. if (route.query && (route.query.id || route.query.detailId)) {
  528. useTagsViewStore().visitedViews = useTagsViewStore().visitedViews.map((item) => {
  529. if (item.query && item.query.random === route.query.random) {
  530. return {
  531. ...item,
  532. name: route.query.text,
  533. title: route.query.text,
  534. };
  535. } else {
  536. return {
  537. ...item,
  538. };
  539. }
  540. });
  541. getOrderDetail({ id: route.query.id || route.query.detailId });
  542. }
  543. });
  544. const getOrderDetail = (parameter) => {
  545. proxy.post("/orderInfo/detail", parameter).then((res) => {
  546. formData.data = res;
  547. if (route.query.id) {
  548. proxy.$refs.editor.changeHtml(formData.data.remark);
  549. }
  550. if (route.query.detailId) {
  551. let allIndex = [];
  552. for (let i = 0; i < formData.data.orderSkuList.length; i++) {
  553. allIndex.push(i);
  554. }
  555. activeNames.value = allIndex;
  556. formOption.disabled = true;
  557. }
  558. if (formData.data.orderSkuList && formData.data.orderSkuList.length > 0) {
  559. for (let i = 0; i < formData.data.orderSkuList.length; i++) {
  560. let subtotal = 0;
  561. let packagingMaterialCost = 0;
  562. if (formData.data.orderSkuList[i].quantity) {
  563. subtotal = Number(
  564. Math.round(
  565. (formData.data.orderSkuList[i].customProcessingFee +
  566. formData.data.orderSkuList[i].deliveryMaterialsFee +
  567. formData.data.orderSkuList[i].lssueFee +
  568. formData.data.orderSkuList[i].packingLabor +
  569. formData.data.orderSkuList[i].managementFee +
  570. formData.data.orderSkuList[i].unitPrice) *
  571. formData.data.orderSkuList[i].quantity *
  572. 100
  573. ) / 100
  574. );
  575. if (formData.data.orderSkuList[i].orderSkuBomList && formData.data.orderSkuList[i].orderSkuBomList.length > 0) {
  576. for (let j = 0; j < formData.data.orderSkuList[i].orderSkuBomList.length; j++) {
  577. let allQuantity = 0;
  578. let allUnitPrice = 0;
  579. if (formData.data.orderSkuList[i].orderSkuBomList[j].quantity) {
  580. allQuantity = Number(
  581. Math.round(formData.data.orderSkuList[i].orderSkuBomList[j].quantity * formData.data.orderSkuList[i].quantity * 100) / 100
  582. );
  583. if (formData.data.orderSkuList[i].orderSkuBomList[j].unitPrice) {
  584. allUnitPrice = Number(
  585. Math.round(
  586. formData.data.orderSkuList[i].orderSkuBomList[j].quantity *
  587. formData.data.orderSkuList[i].orderSkuBomList[j].unitPrice *
  588. formData.data.orderSkuList[i].quantity *
  589. 100
  590. ) / 100
  591. );
  592. packagingMaterialCost = Number(
  593. Math.round(
  594. (packagingMaterialCost +
  595. formData.data.orderSkuList[i].orderSkuBomList[j].quantity * formData.data.orderSkuList[i].orderSkuBomList[j].unitPrice) *
  596. 100
  597. ) / 100
  598. );
  599. }
  600. }
  601. formData.data.orderSkuList[i].orderSkuBomList[j].allQuantity = allQuantity;
  602. formData.data.orderSkuList[i].orderSkuBomList[j].allUnitPrice = allUnitPrice;
  603. }
  604. }
  605. }
  606. formData.data.orderSkuList[i].subtotal = subtotal;
  607. formData.data.orderSkuList[i].packagingMaterialCost = packagingMaterialCost;
  608. }
  609. }
  610. let list = [res.id];
  611. if (res.orderSkuList && res.orderSkuList.length > 0) {
  612. list = list.concat(res.orderSkuList.map((item) => item.id));
  613. }
  614. });
  615. };
  616. const getStyle = (text) => {
  617. if (text) {
  618. return text.replace(/\n|\r\n/g, "<br>");
  619. } else {
  620. return "";
  621. }
  622. };
  623. const printType = ref([
  624. {
  625. dictKey: 1,
  626. dictValue: "单面",
  627. },
  628. {
  629. dictKey: 2,
  630. dictValue: "双面",
  631. },
  632. ]);
  633. const changeQuantity = (index) => {
  634. if (formData.data.orderSkuList[index].quantity) {
  635. proxy
  636. .post("/orderInfo/getSkuSpecPrice", { skuSpecId: formData.data.orderSkuList[index].skuSpecId, quantity: formData.data.orderSkuList[index].quantity })
  637. .then((res) => {
  638. formData.data.orderSkuList[index].customProcessingFee = res.customProcessingFee;
  639. formData.data.orderSkuList[index].customProcessingType = res.customProcessingType;
  640. formData.data.orderSkuList[index].deliveryMaterialsFee = res.deliveryMaterialsFee;
  641. formData.data.orderSkuList[index].lssueFee = res.lssueFee;
  642. formData.data.orderSkuList[index].packingLabor = res.packingLabor;
  643. formData.data.orderSkuList[index].managementFee = res.managementFee;
  644. formData.data.orderSkuList[index].unitPrice = res.unitPrice;
  645. formData.data.orderSkuList[index].subtotal = Number(
  646. Math.round(
  647. (res.customProcessingFee + res.deliveryMaterialsFee + res.lssueFee + res.packingLabor + res.managementFee + res.unitPrice) *
  648. formData.data.orderSkuList[index].quantity *
  649. 100
  650. ) / 100
  651. );
  652. changeBOMQuantity(index);
  653. });
  654. }
  655. };
  656. const changeBOMQuantity = (index) => {
  657. if (formData.data.orderSkuList[index].orderSkuBomList && formData.data.orderSkuList[index].orderSkuBomList.length > 0) {
  658. if (formData.data.orderSkuList[index].quantity) {
  659. formData.data.orderSkuList[index].orderSkuBomList = formData.data.orderSkuList[index].orderSkuBomList.map((item) => {
  660. let allQuantity = 0;
  661. let allUnitPrice = 0;
  662. if (item.quantity) {
  663. allQuantity = Number(Math.round(Number(item.quantity) * Number(formData.data.orderSkuList[index].quantity)));
  664. }
  665. if (item.unitPrice) {
  666. allUnitPrice = Number(Math.round(Number(item.unitPrice) * Number(allQuantity) * 100) / 100);
  667. }
  668. return {
  669. ...item,
  670. allQuantity: allQuantity,
  671. allUnitPrice: allUnitPrice,
  672. };
  673. });
  674. } else {
  675. formData.data.orderSkuList[index].orderSkuBomList = formData.data.orderSkuList[index].orderSkuBomList.map((item) => {
  676. return {
  677. ...item,
  678. allQuantity: 0,
  679. allUnitPrice: 0,
  680. };
  681. });
  682. }
  683. }
  684. calculatedAmount();
  685. };
  686. const calculatedAmount = () => {
  687. let productTotalAmount = 0;
  688. let customProcessingFee = 0;
  689. let lssueFee = 0;
  690. let deliveryMaterialsFee = 0;
  691. let packingLabor = 0;
  692. let managementFee = 0;
  693. let packagingMaterialCost = 0;
  694. let totalAmount = 0;
  695. if (formData.data.orderSkuList && formData.data.orderSkuList.length > 0) {
  696. for (let i = 0; i < formData.data.orderSkuList.length; i++) {
  697. if (formData.data.orderSkuList[i].quantity) {
  698. if (formData.data.orderSkuList[i].customProcessingFee) {
  699. customProcessingFee = Number(
  700. Math.round((customProcessingFee + formData.data.orderSkuList[i].customProcessingFee * formData.data.orderSkuList[i].quantity) * 100) / 100
  701. );
  702. }
  703. if (formData.data.orderSkuList[i].lssueFee) {
  704. lssueFee = Number(Math.round((lssueFee + formData.data.orderSkuList[i].lssueFee * formData.data.orderSkuList[i].quantity) * 100) / 100);
  705. }
  706. if (formData.data.orderSkuList[i].deliveryMaterialsFee) {
  707. deliveryMaterialsFee = Number(
  708. Math.round((deliveryMaterialsFee + formData.data.orderSkuList[i].deliveryMaterialsFee * formData.data.orderSkuList[i].quantity) * 100) / 100
  709. );
  710. }
  711. if (formData.data.orderSkuList[i].packingLabor) {
  712. packingLabor = Number(Math.round((packingLabor + formData.data.orderSkuList[i].packingLabor * formData.data.orderSkuList[i].quantity) * 100) / 100);
  713. }
  714. if (formData.data.orderSkuList[i].managementFee) {
  715. managementFee = Number(
  716. Math.round((managementFee + formData.data.orderSkuList[i].managementFee * formData.data.orderSkuList[i].quantity) * 100) / 100
  717. );
  718. }
  719. if (formData.data.orderSkuList[i].unitPrice) {
  720. productTotalAmount = Number(
  721. Math.round((productTotalAmount + formData.data.orderSkuList[i].unitPrice * formData.data.orderSkuList[i].quantity) * 100) / 100
  722. );
  723. }
  724. let money = 0;
  725. if (formData.data.orderSkuList[i].orderSkuBomList && formData.data.orderSkuList[i].orderSkuBomList.length > 0) {
  726. for (let j = 0; j < formData.data.orderSkuList[i].orderSkuBomList.length; j++) {
  727. if (formData.data.orderSkuList[i].orderSkuBomList[j].quantity && formData.data.orderSkuList[i].orderSkuBomList[j].unitPrice) {
  728. packagingMaterialCost = Number(
  729. Math.round(
  730. (packagingMaterialCost +
  731. formData.data.orderSkuList[i].orderSkuBomList[j].quantity *
  732. formData.data.orderSkuList[i].orderSkuBomList[j].unitPrice *
  733. formData.data.orderSkuList[i].quantity) *
  734. 100
  735. ) / 100
  736. );
  737. money = Number(
  738. Math.round(
  739. (money + formData.data.orderSkuList[i].orderSkuBomList[j].quantity * formData.data.orderSkuList[i].orderSkuBomList[j].unitPrice) * 100
  740. ) / 100
  741. );
  742. }
  743. }
  744. }
  745. formData.data.orderSkuList[i].packagingMaterialCost = money;
  746. }
  747. }
  748. }
  749. formData.data.productTotalAmount = productTotalAmount;
  750. formData.data.customProcessingFee = customProcessingFee;
  751. formData.data.lssueFee = lssueFee;
  752. formData.data.deliveryMaterialsFee = deliveryMaterialsFee;
  753. formData.data.packingLabor = packingLabor;
  754. formData.data.managementFee = managementFee;
  755. formData.data.packagingMaterialCost = packagingMaterialCost;
  756. totalAmount = Number(
  757. Math.round((productTotalAmount + customProcessingFee + lssueFee + deliveryMaterialsFee + packingLabor + managementFee + packagingMaterialCost) * 100) / 100
  758. );
  759. formData.data.totalAmount = totalAmount;
  760. };
  761. const changePrice = reactive({
  762. data: {},
  763. });
  764. const openChangePrice = ref(false);
  765. const productIndex = ref(0);
  766. const productIndexBOM = ref(0);
  767. const labelPrice = ref("");
  768. const textPrice = ref("");
  769. const clickChangePrice = (item, index, label, text) => {
  770. changePrice.data = {
  771. customProcessingFee: item.customProcessingFee,
  772. lssueFee: item.lssueFee,
  773. deliveryMaterialsFee: item.deliveryMaterialsFee,
  774. packingLabor: item.packingLabor,
  775. managementFee: item.managementFee,
  776. unitPrice: item.unitPrice,
  777. customProcessingType: item.customProcessingType,
  778. };
  779. productIndex.value = index;
  780. productIndexBOM.value = null;
  781. labelPrice.value = label;
  782. textPrice.value = text;
  783. openChangePrice.value = true;
  784. };
  785. const submitChangePrice = () => {
  786. proxy.$refs.price.validate((valid) => {
  787. if (valid) {
  788. if (productIndexBOM.value === null) {
  789. formData.data.orderSkuList[productIndex.value][labelPrice.value] = changePrice.data[labelPrice.value];
  790. if (labelPrice.value === "customProcessingFee") {
  791. formData.data.orderSkuList[productIndex.value].customProcessingType = changePrice.data.customProcessingType;
  792. }
  793. Promise.all([calculatedAmount()]).then(() => {
  794. proxy.post("/orderInfo/edit", formData.data).then(() => {
  795. ElMessage({ message: "修改完成", type: "success" });
  796. openChangePrice.value = false;
  797. getOrderDetail({ id: route.query.id || route.query.detailId });
  798. });
  799. });
  800. } else {
  801. formData.data.orderSkuList[productIndex.value].orderSkuBomList[productIndexBOM.value][labelPrice.value] = changePrice.data[labelPrice.value];
  802. Promise.all([changeBOMQuantity(productIndex.value)]).then(() => {
  803. proxy.post("/orderInfo/edit", formData.data).then(() => {
  804. ElMessage({ message: "修改完成", type: "success" });
  805. openChangePrice.value = false;
  806. getOrderDetail({ id: route.query.id || route.query.detailId });
  807. });
  808. });
  809. }
  810. }
  811. });
  812. };
  813. const clickChangeBomPrice = (index, item, indexBOM, label, text) => {
  814. changePrice.data = {
  815. unitPrice: item.unitPrice,
  816. };
  817. productIndex.value = index;
  818. productIndexBOM.value = indexBOM;
  819. labelPrice.value = label;
  820. textPrice.value = text;
  821. openChangePrice.value = true;
  822. };
  823. const changeProcessingType = () => {
  824. changePrice.data[labelPrice.value] = 0;
  825. };
  826. </script>
  827. <style lang="scss" scoped>
  828. ::v-deep(.el-input-number .el-input__inner) {
  829. text-align: left;
  830. }
  831. :deep(.el-dialog) {
  832. margin-top: 10px !important;
  833. margin-bottom: 10px !important;
  834. }
  835. :deep(.ql-editor) {
  836. height: auto;
  837. }
  838. :deep(.el-collapse-item__header) {
  839. justify-content: center;
  840. }
  841. :deep(.el-collapse-item__arrow) {
  842. margin: 0;
  843. }
  844. .avatar-uploader .avatar {
  845. width: 148px;
  846. height: 148px;
  847. display: block;
  848. background-color: black;
  849. }
  850. .avatar-uploader .el-upload {
  851. border: 1px dashed var(--el-border-color);
  852. border-radius: 6px;
  853. cursor: pointer;
  854. position: relative;
  855. overflow: hidden;
  856. transition: var(--el-transition-duration-fast);
  857. }
  858. .avatar-uploader .el-upload:hover {
  859. border-color: var(--el-color-primary);
  860. }
  861. .el-icon.avatar-uploader-icon {
  862. font-size: 28px;
  863. color: #8c939d;
  864. width: 148px;
  865. height: 148px;
  866. text-align: center;
  867. border: 1px dashed var(--el-border-color);
  868. }
  869. :deep(.el-table__cell) {
  870. vertical-align: top;
  871. }
  872. </style>