SalesOutBound.vue 8.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270
  1. <template>
  2. <div style="width: 100%; padding: 0px 15px">
  3. <byForm :formConfig="formConfig" :formOption="formOption" v-model="formData.data" :rules="rules" ref="formDom">
  4. <template #commodity>
  5. <div style="width: 100%">
  6. <el-table :data="formData.data.outboundRecordList" style="width: 100%; ">
  7. <el-table-column label="商品图片" width="80">
  8. <template #default="{ row }">
  9. <div v-if="row.fileUrl">
  10. <img :src="row.fileUrl" class="pic" @click="openImg(row.fileUrl)" />
  11. </div>
  12. <div v-else></div>
  13. </template>
  14. </el-table-column>
  15. <el-table-column prop="productName" label="商品名称" min-width="150" />
  16. <el-table-column prop="productCode" label="商品编码" width="200" />
  17. <el-table-column label="规格尺寸 (cm)" width="130">
  18. <template #default="{ row, $index }">
  19. <div style="width: 100%">
  20. {{row.productLength}} * {{row.productWidth}} * {{row.productHeight}}
  21. </div>
  22. </template>
  23. </el-table-column>
  24. <el-table-column prop="productColor" label="颜色" width="150" />
  25. <el-table-column prop="productFrontalTexture" label="纹路" width="130"
  26. :formatter="(row) => dictKeyValue(row.productFrontalTexture, frontLinesData)" />
  27. <el-table-column prop="productNetWeight" label="净重" width="100" />
  28. <el-table-column prop="productUnit" label="单位" width="100" />
  29. <el-table-column label="订单数量" width="100" prop="orderQuantity" />
  30. <el-table-column label="单价" width="100" prop="price" />
  31. <el-table-column label="已出库数量" width="100" prop="saleOutboundQuantity" fixed="right" />
  32. <el-table-column prop="quantity" label="出库数量" width="140" fixed="right">
  33. <template #default="{ row, $index }">
  34. <el-form-item :prop="'outboundRecordList.' + $index + '.quantity'" :rules="rules.quantity" :inline-message="true" class="margin-b-0">
  35. <el-input-number onmousewheel="return false;" v-model="row.quantity" placeholder="请输入" style="width: 100%" :precision="0"
  36. :controls="false" :min="0" @change="totalAmount()" />
  37. </el-form-item>
  38. </template>
  39. </el-table-column>
  40. <el-table-column label="小计" width="100" prop="amount" fixed="right" />
  41. <el-table-column label="备注" min-width="200" prop="remark" />
  42. </el-table>
  43. </div>
  44. </template>
  45. </byForm>
  46. </div>
  47. </template>
  48. <script setup>
  49. import byForm from "@/components/byForm/index";
  50. const route = useRoute();
  51. // 接收父组件的传值
  52. const props = defineProps({
  53. queryData: Object,
  54. });
  55. const { proxy } = getCurrentInstance();
  56. const frontLinesData = computed(
  57. () => proxy.useUserStore().allDict["front_lines"]
  58. );
  59. const formData = reactive({
  60. data: {},
  61. });
  62. const formDom = ref(null);
  63. const judgeStatus = () => {
  64. if (route.query.processType == 20 || route.query.processType == 10) {
  65. return true;
  66. }
  67. if (props.queryData.recordList && props.queryData.recordList.length > 0) {
  68. let data = props.queryData.recordList.filter(
  69. (item) => item.status === 2 && item.nodeType !== 1
  70. );
  71. if (data && data.length > 0) {
  72. return true;
  73. }
  74. }
  75. return false;
  76. };
  77. const formOption = reactive({
  78. inline: true,
  79. labelWidth: 100,
  80. itemWidth: 100,
  81. disabled: false,
  82. });
  83. const formConfig = computed(() => {
  84. return [
  85. {
  86. type: "title1",
  87. title: "商品信息",
  88. haveLine: true,
  89. },
  90. {
  91. type: "slot",
  92. slotName: "commodity",
  93. label: "",
  94. },
  95. {
  96. type: "title1",
  97. title: "出库总金额",
  98. haveLine: true,
  99. },
  100. {
  101. type: "input",
  102. label: "出库总金额",
  103. prop: "amount",
  104. itemWidth: 25,
  105. disabled: true,
  106. },
  107. ];
  108. });
  109. const rules = ref({
  110. quantity: [{ required: true, message: "请输入数量", trigger: "blur" }],
  111. });
  112. const totalAmount = () => {
  113. let money = 0;
  114. if (
  115. formData.data.outboundRecordList &&
  116. formData.data.outboundRecordList.length > 0
  117. ) {
  118. for (let i = 0; i < formData.data.outboundRecordList.length; i++) {
  119. formData.data.outboundRecordList[i].amount = parseFloat(
  120. Number(formData.data.outboundRecordList[i].quantity) *
  121. Number(formData.data.outboundRecordList[i].price)
  122. ).toFixed(2);
  123. money = parseFloat(
  124. Number(money) + Number(formData.data.outboundRecordList[i].amount)
  125. ).toFixed(2);
  126. }
  127. }
  128. formData.data.amount = money;
  129. };
  130. const handleSubmit = async () => {
  131. let flag = await formDom.value.handleSubmit(() => {});
  132. if (flag) {
  133. if (
  134. formData.data.outboundRecordList &&
  135. formData.data.outboundRecordList.length > 0
  136. ) {
  137. let total = 0;
  138. for (let i = 0; i < formData.data.outboundRecordList.length; i++) {
  139. const ele = formData.data.outboundRecordList[i];
  140. total += Number(ele.quantity);
  141. if (
  142. Number(ele.quantity) + Number(ele.saleOutboundQuantity) >
  143. Number(ele.orderQuantity)
  144. ) {
  145. proxy.msgTip("出库数量加已出库数量不能大于订单数量", 2);
  146. return false;
  147. }
  148. }
  149. if (!(total > 0)) {
  150. proxy.msgTip("出库数量不能为0", 2);
  151. return false;
  152. }
  153. }
  154. return true;
  155. } else {
  156. setTimeout(() => {
  157. const errorDiv = document.getElementsByClassName("is-error");
  158. errorDiv[0].scrollIntoView();
  159. }, 0);
  160. }
  161. return flag;
  162. };
  163. const getFormData = () => {
  164. return proxy.deepClone(formData.data);
  165. };
  166. // 向父组件暴露
  167. defineExpose({
  168. getFormData,
  169. handleSubmit,
  170. });
  171. const getAllData = (businessId) => {
  172. let obj = {};
  173. if (route.query && route.query.obj) {
  174. obj = JSON.parse(route.query.obj);
  175. }
  176. proxy.post("/contract/detail", { id: businessId }).then((res) => {
  177. formData.data = {
  178. contractId: businessId,
  179. outboundRecordList: res.contractProductList.map((x) => ({
  180. ...x,
  181. contractProductId: x.id,
  182. orderQuantity: x.quantity,
  183. quantity: obj[x.id] || null,
  184. amount: "",
  185. })),
  186. amount: "",
  187. };
  188. totalAmount();
  189. if (
  190. formData.data.outboundRecordList &&
  191. formData.data.outboundRecordList.length > 0
  192. ) {
  193. let productIds = formData.data.outboundRecordList.map((x) => x.productId);
  194. proxy.getFileData({
  195. businessIdList: productIds,
  196. data: formData.data.outboundRecordList,
  197. att: "productId",
  198. businessType: "0",
  199. fileAtt: "fileList",
  200. filePathAtt: "fileUrl",
  201. });
  202. }
  203. });
  204. };
  205. onMounted(() => {
  206. formOption.disabled = judgeStatus();
  207. if (route.query && route.query.businessId && !route.query.processType) {
  208. let businessId = route.query.businessId;
  209. getAllData(businessId);
  210. } else if (route.query && route.query.businessId && route.query.processType) {
  211. proxy
  212. .post("/contractOutboundInfo/detail", { id: route.query.businessId })
  213. .then((res) => {
  214. formData.data = res;
  215. totalAmount();
  216. if (
  217. formData.data.outboundRecordList &&
  218. formData.data.outboundRecordList.length > 0
  219. ) {
  220. let productIds = formData.data.outboundRecordList.map(
  221. (x) => x.productId
  222. );
  223. proxy.getFileData({
  224. businessIdList: productIds,
  225. data: formData.data.outboundRecordList,
  226. att: "productId",
  227. businessType: "0",
  228. fileAtt: "fileList",
  229. filePathAtt: "fileUrl",
  230. });
  231. }
  232. });
  233. }
  234. });
  235. </script>
  236. <style lang="scss" scoped>
  237. .table {
  238. border-collapse: collapse;
  239. border-spacing: 0;
  240. td {
  241. text-align: center;
  242. padding: 2px 4px;
  243. // padding: 5px 10px;
  244. }
  245. }
  246. .small-title {
  247. padding-left: 15px;
  248. margin-bottom: 10px;
  249. color: #3366ff;
  250. font-size: 14px;
  251. }
  252. :deep(.el-checkbox) {
  253. margin-right: 0px;
  254. }
  255. // :deep(.el-collapse-item) {
  256. // margin-bottom: 10px;
  257. // }
  258. :deep(.el-collapse-item__header) {
  259. background-color: #eee;
  260. }
  261. </style>