createOrder.vue 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566
  1. <template>
  2. <view class="container">
  3. <uni-nav-bar
  4. fixed="true"
  5. statusBar="true"
  6. left-icon="back"
  7. title="转生产订单"
  8. background-color="#157A2C"
  9. color="#fff"
  10. @clickLeft="back"
  11. ></uni-nav-bar>
  12. <scroll-view scroll-y class="content">
  13. <view class="form-section">
  14. <view class="section-title">基本信息</view>
  15. <view class="form-item">
  16. <text class="label">所属工厂</text>
  17. <input class="input" v-model="form.applyFactoriesName" disabled />
  18. </view>
  19. <view class="form-item">
  20. <text class="label">请托部门</text>
  21. <input class="input" v-model="form.applyDeptName" disabled />
  22. </view>
  23. <view class="form-item">
  24. <text class="label">请托人</text>
  25. <input class="input" v-model="form.createUserName" disabled />
  26. </view>
  27. <view class="form-item">
  28. <text class="label">受托工厂</text>
  29. <input
  30. class="input"
  31. v-model="form.beEntrustedFactoriesName"
  32. disabled
  33. />
  34. </view>
  35. <view class="form-item">
  36. <text class="label">受托部门</text>
  37. <input class="input" v-model="form.beEntrustedDeptName" disabled />
  38. </view>
  39. <view class="form-item">
  40. <text class="label">类型</text>
  41. <input class="input" :value="getTypeText(form.type)" disabled />
  42. </view>
  43. </view>
  44. <view class="form-section">
  45. <view class="section-title">产品信息</view>
  46. <view class="form-item">
  47. <text class="label">名称</text>
  48. <input class="input" v-model="form.productName" disabled />
  49. </view>
  50. <view class="form-item">
  51. <text class="label">编码</text>
  52. <input class="input" v-model="form.productCode" disabled />
  53. </view>
  54. <view class="form-item">
  55. <text class="label">牌号</text>
  56. <input class="input" v-model="form.brandNo" disabled />
  57. </view>
  58. <view class="form-item">
  59. <text class="label">型号</text>
  60. <input class="input" v-model="form.model" disabled />
  61. </view>
  62. <view class="form-item">
  63. <text class="label">规格</text>
  64. <input class="input" v-model="form.specification" disabled />
  65. </view>
  66. <view class="form-item">
  67. <text class="label">批次号</text>
  68. <input class="input" v-model="form.batchNo" disabled />
  69. </view>
  70. <view class="form-item">
  71. <text class="label">订单数量</text>
  72. <view class="input-group">
  73. <input class="input" v-model="form.contractNum" disabled />
  74. <text class="unit">{{ form.measuringUnit }}</text>
  75. </view>
  76. </view>
  77. <view class="form-item">
  78. <text class="label">完成日期</text>
  79. <input class="input" v-model="form.planDeliveryTime" disabled />
  80. </view>
  81. <view class="form-item">
  82. <text class="label">计划开始时间</text>
  83. <input class="input" v-model="form.planStartTime" disabled />
  84. </view>
  85. <view class="form-item">
  86. <text class="label">计划结束时间</text>
  87. <input class="input" v-model="form.planCompleteTime" disabled />
  88. </view>
  89. <view class="form-item required">
  90. <text class="label">工艺路线</text>
  91. <view class="input clickable" @click="chooseRoute">
  92. <text
  93. :class="
  94. form.produceRoutingName ? 'input-text' : 'placeholder-text'
  95. "
  96. >
  97. {{ form.produceRoutingName || "请选择工艺路线" }}
  98. </text>
  99. </view>
  100. </view>
  101. <view class="form-item">
  102. <text class="label">紧急程度</text>
  103. <input
  104. class="input"
  105. :value="getPriorityText(form.priority)"
  106. disabled
  107. />
  108. </view>
  109. <view class="form-item">
  110. <text class="label">需求描述</text>
  111. <textarea class="textarea" v-model="form.describes" disabled />
  112. </view>
  113. </view>
  114. </scroll-view>
  115. <view class="footer">
  116. <button class="btn-cancel" @click="cancel">取消</button>
  117. <button class="btn-confirm" @click="save">确定</button>
  118. </view>
  119. <view
  120. class="popup-mask"
  121. v-if="showRoutePicker"
  122. @click="showRoutePicker = false"
  123. >
  124. <view class="popup-content" @click.stop>
  125. <view class="popup-header">
  126. <text class="popup-title">选择工艺路线</text>
  127. <text class="popup-close" @click="showRoutePicker = false">✕</text>
  128. </view>
  129. <scroll-view scroll-y class="popup-list">
  130. <view
  131. class="popup-item"
  132. v-for="item in routeList"
  133. :key="item.id"
  134. :class="{ active: form.produceRoutingId === item.id }"
  135. @click="selectRoute(item)"
  136. >
  137. <text>{{ item.name }}</text>
  138. <text v-if="form.produceRoutingId === item.id" class="check-icon"
  139. >✓</text
  140. >
  141. </view>
  142. <view v-if="routeList.length === 0" class="popup-empty"
  143. >暂无工艺路线</view
  144. >
  145. </scroll-view>
  146. </view>
  147. </view>
  148. </view>
  149. </template>
  150. <script>
  151. import { beEntrustDetail, createProductionOrder } from "@/api/beEntrust/index";
  152. import { producerouting } from "@/api/pda/workOrder";
  153. export default {
  154. data() {
  155. return {
  156. id: "",
  157. showRoutePicker: false,
  158. routeList: [],
  159. form: {
  160. applyFactoriesName: "",
  161. applyDeptName: "",
  162. createUserName: "",
  163. beEntrustedFactoriesName: "",
  164. beEntrustedDeptName: "",
  165. type: "",
  166. productName: "",
  167. productCode: "",
  168. brandNo: "",
  169. model: "",
  170. specification: "",
  171. batchNo: "",
  172. contractNum: "",
  173. measuringUnit: "",
  174. planDeliveryTime: "",
  175. planStartTime: "",
  176. planCompleteTime: "",
  177. produceRoutingName: "",
  178. produceRoutingId: "",
  179. priority: "",
  180. describes: "",
  181. sourceId: "",
  182. sourceCode: "",
  183. },
  184. };
  185. },
  186. onLoad(options) {
  187. this.id = options.id;
  188. if (this.id) {
  189. this.loadData();
  190. }
  191. },
  192. methods: {
  193. back() {
  194. uni.navigateBack();
  195. },
  196. async loadData() {
  197. try {
  198. const res = await beEntrustDetail(this.id);
  199. const data = JSON.parse(JSON.stringify(res));
  200. data.productCode = data.categoryCode;
  201. data.productName = data.categoryName;
  202. data.model = data.modelType;
  203. data.brandNo = data.brandNum;
  204. data.contractNum = data.totalCount;
  205. data.sourceCode = data.code;
  206. data.sourceId = data.id;
  207. data.formingWeight = data.totalWeight;
  208. data.newWeightUnit = data.weightUnit;
  209. data.produceRoutingId = "";
  210. data.produceRoutingName = "";
  211. this.form = data;
  212. } catch (error) {
  213. uni.showToast({
  214. title: "加载失败",
  215. icon: "none",
  216. });
  217. }
  218. },
  219. getTypeText(type) {
  220. const map = { 1: "加工", 2: "装配" };
  221. return map[type] || "";
  222. },
  223. getPriorityText(priority) {
  224. const map = { 1: "一般", 2: "紧急" };
  225. return map[priority] || "";
  226. },
  227. async chooseRoute() {
  228. try {
  229. const res = await producerouting({
  230. pageNum: 1,
  231. size: -1,
  232. routeType: 2,
  233. });
  234. this.routeList = (res.list || res || []).map((item) => ({
  235. id: item.id,
  236. name: item.name,
  237. }));
  238. this.showRoutePicker = true;
  239. } catch (error) {
  240. uni.showToast({
  241. title: "获取工艺路线失败",
  242. icon: "none",
  243. });
  244. }
  245. },
  246. selectRoute(item) {
  247. this.form.produceRoutingId = item.id;
  248. this.form.produceRoutingName = item.name;
  249. this.showRoutePicker = false;
  250. },
  251. cancel() {
  252. uni.navigateBack();
  253. },
  254. save() {
  255. if (!this.form.produceRoutingName) {
  256. uni.showToast({
  257. title: "请选择工艺路线",
  258. icon: "none",
  259. });
  260. return;
  261. }
  262. uni.showModal({
  263. title: "提示",
  264. content: "确定转为生产订单吗?",
  265. success: (res) => {
  266. if (res.confirm) {
  267. this.doSave();
  268. }
  269. },
  270. });
  271. },
  272. async doSave() {
  273. uni.showLoading({ title: "提交中..." });
  274. try {
  275. let params = {
  276. ...this.form,
  277. sourceType: 3,
  278. };
  279. if (params.planDeliveryTime) {
  280. params.planDeliveryTime = params.planDeliveryTime.split(" ")[0];
  281. }
  282. await createProductionOrder(params);
  283. uni.hideLoading();
  284. uni.showToast({
  285. title: "转换成功",
  286. icon: "success",
  287. });
  288. setTimeout(() => {
  289. uni.navigateBack();
  290. }, 1500);
  291. } catch (error) {
  292. uni.hideLoading();
  293. uni.showToast({
  294. title: "转换失败",
  295. icon: "none",
  296. });
  297. }
  298. },
  299. },
  300. };
  301. </script>
  302. <style lang="scss" scoped>
  303. .container {
  304. display: flex;
  305. flex-direction: column;
  306. height: 100vh;
  307. background-color: #f5f5f5;
  308. }
  309. .content {
  310. flex: 1;
  311. padding: 20rpx;
  312. }
  313. .form-section {
  314. background-color: #fff;
  315. border-radius: 12rpx;
  316. padding: 24rpx;
  317. margin-bottom: 20rpx;
  318. .section-title {
  319. font-size: 32rpx;
  320. font-weight: bold;
  321. color: #333;
  322. margin-bottom: 24rpx;
  323. padding-bottom: 16rpx;
  324. border-bottom: 2rpx solid #f0f0f0;
  325. }
  326. }
  327. .form-item {
  328. display: flex;
  329. align-items: center;
  330. margin-bottom: 24rpx;
  331. &.required .label::before {
  332. content: "*";
  333. color: #f56c6c;
  334. margin-right: 4rpx;
  335. }
  336. .label {
  337. width: 200rpx;
  338. flex-shrink: 0;
  339. font-size: 28rpx;
  340. color: #666;
  341. }
  342. .input {
  343. flex: 1;
  344. height: 64rpx;
  345. line-height: 64rpx;
  346. padding: 0 16rpx;
  347. background-color: #f5f5f5;
  348. border: none;
  349. border-radius: 8rpx;
  350. font-size: 28rpx;
  351. color: #333;
  352. box-sizing: border-box;
  353. }
  354. /deep/ .uni-input-wrapper,
  355. /deep/ .uni-input-input {
  356. height: 64rpx !important;
  357. line-height: 64rpx !important;
  358. min-height: auto !important;
  359. border: none !important;
  360. outline: none !important;
  361. background: transparent !important;
  362. font-size: 28rpx !important;
  363. color: #333 !important;
  364. }
  365. .input-group {
  366. flex: 1;
  367. display: flex;
  368. align-items: center;
  369. gap: 8rpx;
  370. .input {
  371. flex: 1;
  372. }
  373. .unit {
  374. font-size: 28rpx;
  375. color: #999;
  376. flex-shrink: 0;
  377. }
  378. }
  379. .textarea {
  380. flex: 1;
  381. padding: 16rpx;
  382. background-color: #f5f5f5;
  383. border: none;
  384. border-radius: 8rpx;
  385. font-size: 28rpx;
  386. color: #333;
  387. min-height: 120rpx;
  388. box-sizing: border-box;
  389. }
  390. }
  391. .footer {
  392. display: flex;
  393. gap: 20rpx;
  394. padding: 20rpx;
  395. background-color: #fff;
  396. box-shadow: 0 -2rpx 8rpx rgba(0, 0, 0, 0.08);
  397. button {
  398. flex: 1;
  399. height: 80rpx;
  400. line-height: 80rpx;
  401. font-size: 30rpx;
  402. border-radius: 12rpx;
  403. }
  404. .btn-cancel {
  405. background-color: #fff;
  406. color: #666;
  407. border: 1rpx solid #e0e0e0;
  408. }
  409. .btn-confirm {
  410. background-color: #157a2c;
  411. color: #fff;
  412. }
  413. }
  414. .clickable {
  415. display: flex;
  416. align-items: center;
  417. justify-content: space-between;
  418. .input-text {
  419. font-size: 28rpx;
  420. color: #333;
  421. }
  422. .placeholder-text {
  423. font-size: 28rpx;
  424. color: #999;
  425. }
  426. .arrow {
  427. font-family: uniicons;
  428. font-size: 28rpx;
  429. color: #999;
  430. }
  431. }
  432. .popup-mask {
  433. position: fixed;
  434. top: 0;
  435. left: 0;
  436. right: 0;
  437. bottom: 0;
  438. background-color: rgba(0, 0, 0, 0.5);
  439. z-index: 999;
  440. display: flex;
  441. align-items: flex-end;
  442. }
  443. .popup-content {
  444. width: 100%;
  445. background-color: #fff;
  446. border-radius: 24rpx 24rpx 0 0;
  447. max-height: 70vh;
  448. display: flex;
  449. flex-direction: column;
  450. }
  451. .popup-header {
  452. display: flex;
  453. justify-content: space-between;
  454. align-items: center;
  455. padding: 28rpx 32rpx;
  456. border-bottom: 1rpx solid #f0f0f0;
  457. .popup-title {
  458. font-size: 32rpx;
  459. font-weight: bold;
  460. color: #333;
  461. }
  462. .popup-close {
  463. font-size: 36rpx;
  464. color: #999;
  465. padding: 8rpx;
  466. }
  467. }
  468. .popup-list {
  469. max-height: 60vh;
  470. padding: 0 32rpx;
  471. }
  472. .popup-item {
  473. display: flex;
  474. justify-content: space-between;
  475. align-items: center;
  476. padding: 28rpx 16rpx;
  477. border-bottom: 1rpx solid #f5f5f5;
  478. font-size: 28rpx;
  479. color: #333;
  480. &.active {
  481. color: #157a2c;
  482. font-weight: bold;
  483. }
  484. .check-icon {
  485. color: #157a2c;
  486. font-size: 32rpx;
  487. }
  488. }
  489. .popup-empty {
  490. text-align: center;
  491. padding: 60rpx 0;
  492. font-size: 28rpx;
  493. color: #999;
  494. }
  495. </style>