edit.vue 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558
  1. <template>
  2. <div>
  3. <Toptitle :title="setTip">
  4. <Button @click="back" type="primary" ghost style="margin-right:10px;"
  5. >返回</Button
  6. >
  7. <Button
  8. v-if="type != 3"
  9. type="primary"
  10. @click="handleSubmit('Info', 'item_detail')"
  11. >保存</Button
  12. >
  13. </Toptitle>
  14. <Form ref="Info" inline :model="info" :rules="rules">
  15. <FormItem label="ID">
  16. <Input
  17. v-model="info.id"
  18. disabled
  19. :placeholder="type == 1 || type == 2 ? '自动生成' : '12'"
  20. />
  21. </FormItem>
  22. <FormItem label="物料名称" prop="title">
  23. <Input
  24. :disabled="type == 3 ? true : false"
  25. v-model="info.title"
  26. placeholder="请输入物料名称"
  27. />
  28. </FormItem>
  29. <FormItem label="物料分类" prop="m_id">
  30. <Select
  31. filterable
  32. clearable
  33. style="width:186px;"
  34. v-model="info.m_id"
  35. :disabled="type == 3"
  36. placeholder="请选择材质"
  37. >
  38. <Option
  39. v-for="item of materialList"
  40. :key="item.id"
  41. :label="item.title"
  42. :value="item.id"
  43. ></Option>
  44. </Select>
  45. </FormItem>
  46. <FormItem label="厚" v-show="isShowInfoHigh" prop="high">
  47. <Input
  48. :disabled="type == 3 ? true : false"
  49. v-model="info.high"
  50. placeholder="请输入厚度"
  51. />
  52. </FormItem>
  53. <FormItem label="单位" prop="unit">
  54. <Input
  55. :disabled="type == 3 ? true : false"
  56. v-model="info.unit"
  57. placeholder="请输入单位"
  58. />
  59. </FormItem>
  60. <FormItem label="损耗(%)" v-show="info.detail.length == 0" prop="scale">
  61. <Input
  62. type="number"
  63. :disabled="type == 3 ? true : false"
  64. v-model="info.scale"
  65. placeholder="请输入百分比"
  66. />
  67. </FormItem>
  68. <FormItem label="描述">
  69. <Input
  70. :disabled="type == 3 ? true : false"
  71. v-model="info.remark"
  72. placeholder="请输入描述"
  73. />
  74. </FormItem>
  75. <FormItem label="上传附件:">
  76. <div class="product-img">
  77. <div class="product-add">
  78. <div class="img_items" v-if="this.info.img_url !== ''">
  79. <img
  80. @click="looks(info.img_url)"
  81. :src="$store.state.ip + this.info.img_url"
  82. alt=""
  83. />
  84. <Icon
  85. v-if="type != 3"
  86. size="20"
  87. @click="delItems( )"
  88. class="delete-img"
  89. type="ios-close-circle"
  90. />
  91. </div>
  92. <div class="add-items" v-if="type != 3&&!info.img_url">
  93. <div class="item">
  94. <Icon size="50" type="ios-add" />
  95. </div>
  96. <span>支持jpg/png格式</span>
  97. <input
  98. @change="changeIpt($event, info.img_url)"
  99. type="file"
  100. class="ipt"
  101. />
  102. </div>
  103. </div>
  104. </div>
  105. <!-- <Button type="primary"
  106. style="margin-right:10px;"
  107. ghost>上传附件</Button> -->
  108. <!-- <Upload style="display: inline"
  109. name="your_file"
  110. :show-upload-list="false"
  111. :headers="headers"
  112. multiple
  113. :data="uploadData"
  114. :on-error="uploadError"
  115. :on-progress="onProgress"
  116. :on-success="uploadSuccess"
  117. :action="$store.state.ip + '/api/deep_img_import'">
  118. <Button type="primary"
  119. style="margin-right: 10px">上传附件</Button>
  120. </Upload> -->
  121. </FormItem>
  122. <FormItem label="安全库存" v-show="isShowInfoMinStock" prop="stock">
  123. <Input
  124. type="number"
  125. :disabled="type == 3 ? true : false"
  126. v-model="info.warning_number"
  127. placeholder="请输入库存"
  128. />
  129. </FormItem>
  130. <FormItem label="最高库存" v-show="isShowInfoTopNumber" prop="stock">
  131. <Input
  132. type="number"
  133. :disabled="type == 3 ? true : false"
  134. v-model="info.top_number"
  135. placeholder="请输入库存"
  136. />
  137. </FormItem>
  138. <FormItem label="单价(元)" v-show="isShowInfoPrice" prop="price">
  139. <Input
  140. type="number"
  141. :disabled="type == 3 ? true : false"
  142. v-model="info.price"
  143. placeholder="请输入金额"
  144. />
  145. </FormItem>
  146. </Form>
  147. <div class="page-edit" v-show="isShowDetail" style="padding-bottom:100px;">
  148. <div class="items" v-for="(rows, key) in info.detail" :key="key">
  149. <!-- id 1 木板 2 木皮 3 实木 4 辅料 5 五金 6 油漆 -->
  150. <Form ref="item_detail" inline :model="rows" :rules="itemRules">
  151. <FormItem label="高" prop="long" v-show="isShowDetailLong">
  152. <Input
  153. :disabled="type == 3 ? true : false"
  154. v-model="rows.long"
  155. placeholder="请输入高度"
  156. />
  157. </FormItem>
  158. <FormItem label="宽" prop="width" v-show="isShowDetailWidth">
  159. <Input
  160. :disabled="type == 3 ? true : false"
  161. v-model="rows.width"
  162. placeholder="请输入宽度"
  163. />
  164. </FormItem>
  165. <FormItem label="损耗(%)">
  166. <Input
  167. type="number"
  168. :disabled="type == 3 ? true : false"
  169. v-model="rows.scale"
  170. placeholder="请输入百分比"
  171. />
  172. </FormItem>
  173. <FormItem label="价格计算方式" prop="todo" v-show="isShowDetailCalc">
  174. <Select
  175. filterable
  176. clearable
  177. style="width:186px;"
  178. v-model="rows.todo"
  179. placeholder="请选择"
  180. >
  181. <Option
  182. v-for="item of priceMathList"
  183. :key="item.value"
  184. :label="item.label"
  185. :value="item.value"
  186. ></Option>
  187. </Select>
  188. </FormItem>
  189. <FormItem label="安全库存">
  190. <Input
  191. type="number"
  192. :disabled="type == 3 ? true : false"
  193. v-model="rows.warning_number"
  194. placeholder="请输入库存"
  195. />
  196. </FormItem>
  197. <FormItem label="最高库存">
  198. <Input
  199. type="number"
  200. :disabled="type == 3 ? true : false"
  201. v-model="rows.top_number"
  202. placeholder="请输入库存"
  203. />
  204. </FormItem>
  205. <FormItem label="单价(元)" prop="price">
  206. <Input
  207. type="number"
  208. :disabled="type == 3 ? true : false"
  209. v-model="rows.price"
  210. placeholder="请输入金额"
  211. />
  212. </FormItem>
  213. <FormItem label="操作" v-if="isShowDetailBtn">
  214. <div
  215. style="width:100%;display:flex;height:100%;align-items:center;"
  216. >
  217. <Button
  218. type="success"
  219. ghost
  220. :disabled="type == 3 ? true : false"
  221. @click="addMaterrial(info.detail)"
  222. >添加</Button
  223. >
  224. <Button
  225. type="error"
  226. ghost
  227. v-if="info.detail.length != 1 && type != 3"
  228. style="margin-left:10px;"
  229. @click="removeChild(info.detail, key)"
  230. >删除</Button
  231. >
  232. </div>
  233. </FormItem>
  234. </Form>
  235. </div>
  236. </div>
  237. <Modal
  238. v-model="showKey"
  239. :width="1250"
  240. :mask-closable="false"
  241. :closable="false"
  242. >
  243. <div>
  244. <KeyBoard @cancel="successKey" @success="successKey" class="key-co" />
  245. </div>
  246. <div slot="footer"></div>
  247. </Modal>
  248. </div>
  249. </template>
  250. <script>
  251. import KeyBoard from "../../components/keyboard/index";
  252. export default {
  253. data() {
  254. return {
  255. type: 1,
  256. info: {
  257. m_id: "",
  258. img_url:'',
  259. detail: [
  260. {
  261. long: "",
  262. width: "",
  263. price: "",
  264. stock: "",
  265. warning_number: "",
  266. scale: "",
  267. },
  268. ],
  269. },
  270. id: null,
  271. materialList: [],
  272. priceMathList: [
  273. { label: "按米", value: 1 },
  274. { label: "按数量", value: 2 },
  275. ],
  276. showKey: false,
  277. itemRules: {
  278. price: [{ required: true, message: " " }],
  279. long: [{ required: true, message: " ", trigger: "blur" }],
  280. width: [{ required: true, message: " ", trigger: "blur" }],
  281. stock: [{ required: true, message: " " }],
  282. scale: [{ required: true, message: " " }],
  283. warning_number: [{ required: true, message: " " }],
  284. },
  285. rules: {
  286. title: [{ required: true, message: " ", trigger: "blur" }],
  287. m_id: [{ required: true, message: " " }],
  288. high: [{ required: true, message: " ", trigger: "blur" }],
  289. unit: [{ required: true, message: " ", trigger: "blur" }],
  290. },
  291. basic_type_id: "",
  292. isShowInfoMinStock: false,
  293. isShowInfoTopNumber: false,
  294. isShowInfoHigh: false,
  295. isShowInfoPrice: false,
  296. isShowDetail: false,
  297. isShowDetailLong: false,
  298. isShowDetailWidth: false,
  299. isShowDetailCalc: false,
  300. isShowDetailBtn: false,
  301. };
  302. },
  303. components: { KeyBoard },
  304. created() {},
  305. mounted() {
  306. this.type = this.$route.query.type;
  307. this.id = this.$route.query.id || "";
  308. this.type == 1
  309. ? (this.info.m_id = this.$route.query.back_id * 1)
  310. : this.info.m_id;
  311. this.axios("/api/basics_material_index").then((res) => {
  312. this.materialList = res.data.data;
  313. console.log(res)
  314. });
  315. if (this.id) {
  316. this.getData(this.id);
  317. }
  318. //根据基本类型展示不同字段
  319. setTimeout(() => {
  320. let id = this.$route.query.back_id;
  321. let tempArr = this.$store.state.navgationData[9].sub;
  322. this.$store.state.navgationData.forEach((element) => {
  323. if (element.title == "物料档案") {
  324. element.sub.forEach((elem) => {
  325. if (elem.id == id) {
  326. this.basic_type_id = elem.sub_type_id;
  327. }
  328. });
  329. }
  330. });
  331. // tempArr.forEach(el => {
  332. // console.log('el :>> ', el);
  333. // if (el.id == id) {
  334. // this.basic_type_id = el.sub_type_id
  335. // }
  336. // });
  337. switch (this.basic_type_id) {
  338. // 1木板 2木皮 3实木 4辅料 5五金 6油漆
  339. case 1:
  340. case 3:
  341. this.isShowInfoHigh = true;
  342. this.isShowDetailLong = true;
  343. this.isShowDetailWidth = true;
  344. this.isShowDetail = true;
  345. this.isShowDetailBtn = true;
  346. break;
  347. case 2:
  348. this.isShowInfoHigh = true;
  349. this.isShowInfoMinStock = true;
  350. this.isShowInfoTopNumber = true;
  351. this.isShowInfoPrice = true;
  352. break;
  353. case 4:
  354. case 5:
  355. case 6:
  356. this.isShowInfoMinStock = true;
  357. this.isShowInfoTopNumber = true;
  358. this.isShowInfoPrice = true;
  359. break;
  360. }
  361. }, 500);
  362. },
  363. computed: {
  364. setTip() {
  365. const { type } = this.$route.query;
  366. const inner =
  367. type == 1
  368. ? "新增物料"
  369. : type == 2
  370. ? "编辑物料"
  371. : type == 3
  372. ? "查看物料"
  373. : "拷贝物料";
  374. return inner;
  375. },
  376. },
  377. methods: {
  378. looks(img) {
  379. const array = [{ img_url: img }];
  380. this.$previewImg({
  381. list: array,
  382. baseUrl: this.$store.state.ip,
  383. baseImgField: "img_url",
  384. baseTitleField: "",
  385. });
  386. },
  387. delItems() {
  388. this.info.img_url = '';
  389. this.$forceUpdate();
  390. },
  391. changeIpt(e, row) {
  392. // if (this.info.img.length >= 3) {
  393. // return this.$Message.warning("图片最多上传3张");
  394. // }
  395. let file = e.target.files[0];
  396. this.postImg(file, row);
  397. e.target.value = null;
  398. },
  399. postImg(file, row) {
  400. let formData = new FormData();
  401. formData.append("file", file);
  402. this.axios.post("/api/upload_pic", formData).then((res) => {
  403. this.info.img_url = res.data.url;
  404. this.$forceUpdate();
  405. });
  406. },
  407. getData(id) {
  408. this.axios("/api/material", { params: { id: id } }).then((res) => {
  409. console.log(res)
  410. let data = res.data.shift();
  411. this.info = data;
  412. if (this.info.detail.length < 1) {
  413. this.info.detail = [
  414. {
  415. long: "",
  416. width: "",
  417. price: "",
  418. stock: "",
  419. warning_number: "",
  420. scale: "",
  421. },
  422. ];
  423. }
  424. });
  425. },
  426. postData() {
  427. const { type } = this.$route.query;
  428. this.info.op = type == 1 || type == 4 ? "add" : "edit";
  429. [2, 4, 5, 6].includes(this.basic_type_id) &&
  430. ((this.info.detail[0].top_number = this.info.top_number),
  431. (this.info.detail[0].warning_number = this.info.warning_number),
  432. (this.info.detail[0].price = this.info.price));
  433. type == 4 ? (this.info.id = "") : "";
  434. this.axios.post("/api/material", this.info).then((res) => {
  435. console.log(this.info)
  436. if (res.code == 200) {
  437. this.$Message.success(res.msg);
  438. this.back();
  439. }
  440. });
  441. },
  442. back() {
  443. this.$router.go(-1);
  444. },
  445. successKey(str) {
  446. this.info.formula = str;
  447. this.showKey = false;
  448. },
  449. popKeyBoard() {
  450. this.showKey = true;
  451. },
  452. async handleSubmit(name, itemName) {
  453. // const nameValue = await this.$refs[name].validate((valid)=>valid)
  454. // let result = []
  455. // for(let i = 0;i<this.$refs[itemName].length;i++){
  456. // this.$refs[itemName][i].validate(valid=>{
  457. // result.push(valid)
  458. // })
  459. // }
  460. // const itemVal = result.every(val=>val)
  461. // if(nameValue&&itemVal){
  462. this.postData();
  463. // }
  464. },
  465. addMaterrial(row) {
  466. row.push({
  467. long: "",
  468. width: "",
  469. price: "",
  470. stock: "",
  471. warning_number: "",
  472. scale: "",
  473. });
  474. },
  475. removeChild(row, n) {
  476. row.splice(n, 1);
  477. },
  478. },
  479. };
  480. </script>
  481. <style lang="scss" scoped>
  482. .items {
  483. padding: 10px;
  484. box-shadow: 0 2px 7px rgba(0, 0, 0, 0.15);
  485. border-color: transparent;
  486. position: relative;
  487. margin: 20px 0;
  488. }
  489. .product-img {
  490. padding-top: 10px;
  491. }
  492. .product-add {
  493. padding: 10px 0;
  494. // display: flex;
  495. flex-wrap: nowrap;
  496. .ipt {
  497. position: absolute;
  498. width: 100%;
  499. height: 100%;
  500. opacity: 0;
  501. cursor: pointer;
  502. outline: none;
  503. top: 0;
  504. left: 0;
  505. }
  506. .add-items {
  507. width: 120px;
  508. height: 120px;
  509. border: 1px dotted #e7e7e7;
  510. border-radius: 5px;
  511. display: flex;
  512. justify-content: center;
  513. align-items: center;
  514. overflow: hidden;
  515. position: relative;
  516. flex-direction: column;
  517. background: #f4f5f7;
  518. .item {
  519. width: 46px;
  520. height: 46px;
  521. background: #3764ff;
  522. opacity: 0.6;
  523. display: flex;
  524. justify-content: center;
  525. align-items: center;
  526. border-radius: 50%;
  527. color: #fff;
  528. }
  529. }
  530. .img_items {
  531. width: 120px;
  532. height: 120px;
  533. margin-bottom: 10px;
  534. display: flex;
  535. justify-content: center;
  536. align-items: center;
  537. background: #e7e7e7;
  538. margin-right: 10px;
  539. border-radius: 5px;
  540. position: relative;
  541. img {
  542. max-width: 108px;
  543. max-height: 108px;
  544. }
  545. }
  546. }
  547. .delete-img {
  548. position: absolute;
  549. right: 0px;
  550. top: 0px;
  551. color: red;
  552. }
  553. </style>