edit.vue 16 KB

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