LittleMaterialRequestDialog.ets 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399
  1. import ProcessRequest from '../common/util/request/ProcessRequest'
  2. import MaterialInfo from '../viewmodel/MaterialInfo'
  3. import PageInfo from '../viewmodel/PageInfo'
  4. import RequestParamModel from '../viewmodel/RequestParamModel'
  5. @CustomDialog
  6. export struct LittleMaterialRequestDialog {
  7. private scrollerMaterial: Scroller = new Scroller()
  8. //物料配件列表
  9. @State materialTypesList: MaterialInfo[] = [];
  10. //监控选中的索引
  11. @State @Watch('onSelectedIndexesChange') selectedIndexes: number[] = [];
  12. //选中物料
  13. @State selectMaterials:MaterialInfo[]=[]
  14. //查询物料名字
  15. @State queryMaterialName: string = ''
  16. //物料map(名称,数量)
  17. @State materialNumMap: Record<string, number> = {};
  18. //实时更新选中物料
  19. onSelectedIndexesChange() {
  20. this.selectMaterials = this.selectedIndexes.map(index => this.materialTypesList[index]);
  21. }
  22. controller: CustomDialogController
  23. onConfirm: () => void = () => {}
  24. //加载物料配件类型
  25. loadMaterialTypes = async () => {
  26. let res = await ProcessRequest.post('/api/v1/base/material/page',
  27. {
  28. materialName: this.queryMaterialName
  29. } as RequestParamModel) as PageInfo;
  30. this.materialTypesList = res.records??[]
  31. //初始所有物料数量为0
  32. this.materialTypesList.forEach(item => {
  33. this.materialNumMap[item.materialName??''] = 0;
  34. });
  35. };
  36. private onDeleteMaterial(item: MaterialInfo) {
  37. // 找到物料在已选列表中的索引
  38. const selectedIndex = this.selectMaterials.findIndex(m => m.materialName === item.materialName);
  39. if (selectedIndex !== -1) {
  40. // 从已选列表中移除
  41. this.selectMaterials.splice(selectedIndex, 1);
  42. this.selectMaterials = [...this.selectMaterials]; // 触发状态更新
  43. // 找到物料在总列表中的索引
  44. const materialIndex = this.materialTypesList.findIndex(m => m.materialName === item.materialName);
  45. if (materialIndex !== -1) {
  46. // 从选中索引中移除
  47. this.selectedIndexes = this.selectedIndexes.filter(i => i !== materialIndex);
  48. }
  49. }
  50. }
  51. private onSelectMaterial(index: number) {
  52. if (this.selectedIndexes.includes(index)) {
  53. this.selectedIndexes = this.selectedIndexes.filter(i => i !== index);
  54. } else {
  55. this.selectedIndexes = [index, ...this.selectedIndexes];
  56. }
  57. }
  58. aboutToAppear(): void {
  59. this.loadMaterialTypes()
  60. }
  61. sendMaterialRequest=async()=>{
  62. let res = await ProcessRequest.post('/api/v1/process/vehicleOperation/sporadicCallItem',
  63. {
  64. // materialName: this.queryMaterialName
  65. } as RequestParamModel) as PageInfo;
  66. }
  67. build() {
  68. Column() {
  69. Column() {
  70. Text("零星叫料")
  71. .fontColor($r('app.color.FFFFFF'))
  72. .fontSize($r('app.float.fontSize_30'))
  73. }
  74. .height('8%')
  75. .width('100%')
  76. .justifyContent(FlexAlign.Center)
  77. Row(){
  78. Column() {
  79. Text("查询物料")
  80. .fontColor($r('app.color.FFFFFF'))
  81. .fontSize($r('app.float.fontSize_24'))
  82. Row() {
  83. TextInput({ text: this.queryMaterialName, placeholder: '输入物料名称' })
  84. .type(InputType.Normal)
  85. .placeholderFont({ size: $r('app.float.fontSize_16') })
  86. .placeholderColor($r('app.color.30FFFFFF'))
  87. .fontSize($r('app.float.fontSize_16'))
  88. .fontColor($r('app.color.FFFFFF'))
  89. .enableKeyboardOnFocus(false)
  90. .width('84%')
  91. .onChange((value: string) => {
  92. this.queryMaterialName = value
  93. this.loadMaterialTypes()
  94. })
  95. Row() {
  96. Image($r('app.media.process_search'))
  97. .width($r('app.float.virtualSize_48'))
  98. .height($r('app.float.virtualSize_48'))
  99. .fillColor($r('app.color.0A84FF'))
  100. .onClick(() => {
  101. this.loadMaterialTypes()
  102. })
  103. }
  104. .width('16%')
  105. .height('100%')
  106. .justifyContent(FlexAlign.Center)
  107. .borderRadius($r('app.float.virtualSize_16'))
  108. .backgroundColor($r('app.color.20FFFFFF'))
  109. }
  110. .height('8%')
  111. .width('60%')
  112. .margin({bottom:'2%',top:'2%'})
  113. .borderRadius($r('app.float.virtualSize_16'))
  114. .backgroundColor($r('app.color.000000'))
  115. List({ scroller: this.scrollerMaterial }) {
  116. ForEach(this.materialTypesList, (item: MaterialInfo, index) => {
  117. ListItem() {
  118. Row() {
  119. Column({space:5}){
  120. Text(`${item.materialName}`)
  121. .fontSize($r('app.float.fontSize_16'))
  122. .fontColor($r('app.color.FFFFFF'))
  123. Text(`${item.spec}`)
  124. .fontSize($r('app.float.fontSize_12'))
  125. .fontColor($r('app.color.FFFFFF'))
  126. .fontWeight(FontWeight.Lighter)
  127. }
  128. .width('90%')
  129. .height('100%')
  130. .justifyContent(FlexAlign.Center)
  131. .alignItems(HorizontalAlign.Start)
  132. Column(){
  133. Text(`${item.unitDictValue}`)
  134. .fontSize($r('app.float.fontSize_16'))
  135. .fontColor($r('app.color.FFFFFF'))
  136. .fontWeight(FontWeight.Lighter)
  137. }
  138. .width('10%')
  139. .height('100%')
  140. .justifyContent(FlexAlign.Center)
  141. }
  142. .height('90%')
  143. .width('95%')
  144. .margin({ left: '2%' })
  145. .justifyContent(FlexAlign.Center)
  146. }
  147. .height('10%')
  148. .width('100%')
  149. .margin({ bottom: 8})
  150. .borderRadius($r('app.float.virtualSize_16'))
  151. .backgroundColor(
  152. this.selectedIndexes.includes(index) ?
  153. $r('app.color.2030D158') :
  154. $r('app.color.20FFFFFF')
  155. )
  156. .border({
  157. width: this.selectedIndexes.includes(index) ? 2 : 0,
  158. color: this.selectedIndexes.includes(index) ?
  159. $r('app.color.2030D158') :
  160. $r('app.color.20FFFFFF')
  161. })
  162. .onClick(() => {
  163. this.onSelectMaterial(index)
  164. })
  165. })
  166. }
  167. .width('100%')
  168. .height('82%')
  169. }
  170. .width('50%')
  171. .alignItems(HorizontalAlign.Start)
  172. .justifyContent(FlexAlign.Start)
  173. .margin({left:'2%'})
  174. .height('100%')
  175. Image($r('app.media.arrow_right'))
  176. .width($r('app.float.virtualSize_48'))
  177. .height($r('app.float.virtualSize_48'))
  178. .fillColor($r('app.color.FFFFFF'))
  179. .margin({left:'2%',right:'2%'})
  180. Column() {
  181. Row(){
  182. Text("已选物料")
  183. .fontColor($r('app.color.FFFFFF'))
  184. .fontSize($r('app.float.fontSize_24'))
  185. }
  186. .width('100%')
  187. .height('6%')
  188. .justifyContent(FlexAlign.Start)
  189. List({ scroller: this.scrollerMaterial }) {
  190. ForEach(this.selectMaterials, (item: MaterialInfo) => {
  191. ListItem() {
  192. Column(){
  193. Row(){
  194. Column({space:5}){
  195. Text(`${item.materialName}`)
  196. .fontSize($r('app.float.fontSize_24'))
  197. .fontColor($r('app.color.FFFFFF'))
  198. Text(`${item.spec}`)
  199. .fontSize($r('app.float.fontSize_16'))
  200. .fontColor($r('app.color.FFFFFF'))
  201. .fontWeight(FontWeight.Lighter)
  202. }
  203. .width('86%')
  204. .alignItems(HorizontalAlign.Start)
  205. Column(){
  206. Image($r('app.media.process_delete_seq'))
  207. .width($r('app.float.virtualSize_48'))
  208. .height($r('app.float.virtualSize_48'))
  209. .fillColor($r('app.color.FF453A'))
  210. .onClick(()=>{
  211. this.onDeleteMaterial(item)
  212. })
  213. }
  214. .width('14%')
  215. .alignItems(HorizontalAlign.End)
  216. }
  217. .height('38%')
  218. Text(`数量(${item.unitDictValue})`)
  219. .fontSize($r('app.float.fontSize_16'))
  220. .fontColor($r('app.color.FFFFFF'))
  221. .margin({bottom:'1%'})
  222. .width('100%')
  223. .textAlign(TextAlign.Start)
  224. Column(){
  225. AddAndSubButton({
  226. materialNum:this.materialNumMap[item.materialName??''],
  227. onChange: (num: number) => {
  228. this.materialNumMap[item.materialName??''] = num
  229. }
  230. })
  231. }
  232. .height('52%')
  233. .width('100%')
  234. .margin({bottom:'2%'})
  235. }
  236. .height('100%')
  237. .width('100%')
  238. .alignItems(HorizontalAlign.Start)
  239. }
  240. .height('30%')
  241. .width('100%')
  242. .margin({ bottom: 8})
  243. })
  244. }
  245. .width('95%')
  246. .height('92%')
  247. .divider({
  248. strokeWidth:1,
  249. color:$r('app.color.15FFFFFF')
  250. })
  251. }
  252. .width('40%')
  253. .alignItems(HorizontalAlign.Start)
  254. .justifyContent(FlexAlign.Start)
  255. .height('100%')
  256. }
  257. .height('84%')
  258. .width('100%')
  259. Column() {
  260. Divider()
  261. .vertical(false)
  262. .strokeWidth(1)
  263. .color($r('app.color.15FFFFFF'))
  264. Row() {
  265. Row() {
  266. Text('取消')
  267. .fontColor($r('app.color.60FFFFFF'))
  268. .fontSize($r('app.float.fontSize_30'))
  269. }
  270. .justifyContent(FlexAlign.Center)
  271. .width('50%')
  272. .onClick(() => this.controller.close())
  273. Divider()
  274. .vertical(true)
  275. .strokeWidth(1)
  276. .color($r('app.color.15FFFFFF'))
  277. Row() {
  278. Text('发送叫料')
  279. .fontColor($r('app.color.007AFF'))
  280. .fontSize($r('app.float.fontSize_30'))
  281. }
  282. .justifyContent(FlexAlign.Center)
  283. .width('50%')
  284. .onClick(() => {
  285. this.controller.close();
  286. })
  287. }
  288. }
  289. .width('100%')
  290. .height('8%')
  291. }
  292. .height('71%')
  293. .width('62%')
  294. .backgroundColor($r('app.color.2A2A2A'))
  295. .justifyContent(FlexAlign.End)
  296. .alignItems(HorizontalAlign.Start)
  297. .borderColor($r('app.color.000000'))
  298. .borderWidth(1)
  299. .borderRadius($r('app.float.virtualSize_16'))
  300. }
  301. }
  302. @Component
  303. struct AddAndSubButton {
  304. @State addClick: number = 1
  305. @State subClick: number = 1
  306. @Prop materialNum: number
  307. onChange: (num: number) => void = () => {}
  308. handleValueChange(delta: number) {
  309. const newNum = this.materialNum + delta
  310. if (newNum >= 0) {
  311. this.onChange(newNum)
  312. }
  313. }
  314. build() {
  315. Row() {
  316. Row() {
  317. Button({ type: ButtonType.Normal }) {
  318. Image($r('app.media.process_material_subtraction'))
  319. .width('50%')
  320. .height('50%')
  321. .objectFit(ImageFit.Contain)
  322. .fillColor($r('app.color.FFFFFF'))
  323. }
  324. .width('100%')
  325. .height('100%')
  326. .backgroundColor($r('app.color.20FFFFFF'))
  327. .borderRadius($r('app.float.virtualSize_16'))
  328. .scale({ x: this.addClick, y: this.addClick })
  329. .animation({
  330. duration: 200,
  331. curve: Curve.Linear
  332. })
  333. .onClick(() => {
  334. this.addClick = 0.9;
  335. setTimeout(() => {
  336. this.addClick = 1;
  337. if(this.materialNum>0)
  338. {
  339. this.handleValueChange(-1)
  340. }
  341. }, 200);
  342. })
  343. }.width('22%')
  344. Row() {
  345. Text(String(this.materialNum))
  346. .fontColor($r('app.color.FFFFFF'))
  347. .fontSize($r('app.float.fontSize_38'))
  348. }
  349. .width('56%')
  350. .justifyContent(FlexAlign.Center)
  351. Row() {
  352. Button({ type: ButtonType.Normal }) {
  353. Image($r('app.media.process_material_add'))
  354. .width('50%')
  355. .height('50%')
  356. .objectFit(ImageFit.Contain)
  357. .fillColor($r('app.color.FFFFFF'))
  358. .borderRadius($r('app.float.virtualSize_16'))
  359. }
  360. .width('100%')
  361. .height('100%')
  362. .backgroundColor($r('app.color.20FFFFFF'))
  363. .borderRadius($r('app.float.virtualSize_16'))
  364. .scale({ x: this.subClick, y: this.subClick })
  365. .animation({
  366. duration: 200,
  367. curve: Curve.Linear
  368. })
  369. .onClick(() => {
  370. this.subClick = 0.9;
  371. setTimeout(() => {
  372. this.subClick = 1;
  373. this.handleValueChange(1)
  374. }, 200);
  375. })
  376. }.width('22%')
  377. }.width('100%')
  378. .height('100%')
  379. .backgroundColor($r('app.color.10FFFFFF'))
  380. .borderRadius($r('app.float.virtualSize_16'))
  381. }
  382. }