GoodsSpecificationScreen.js 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564
  1. /* eslint-disable no-else-return */
  2. /* eslint-disable prefer-const */
  3. /* eslint-disable react/jsx-one-expression-per-line */
  4. /* eslint-disable no-underscore-dangle */
  5. /* eslint-disable no-shadow */
  6. import * as WebBrowser from "expo-web-browser";
  7. import * as React from "react";
  8. import { StyleSheet, View } from "react-native";
  9. import { useModel } from "flooks";
  10. import {
  11. Layout,
  12. Text,
  13. useTheme,
  14. Button,
  15. Input,
  16. Toggle,
  17. } from "@ui-kitten/components";
  18. import { useFocusEffect, useRoute } from "@react-navigation/native";
  19. import { useEventEmitter } from "@umijs/hooks";
  20. import ActionButton from "react-native-action-button";
  21. import ListComponent from "../../components/ListComponent";
  22. import NavHeaderBar from "../../components/NavHeaderBar";
  23. const styles = StyleSheet.create({
  24. lay: {
  25. backgroundColor: "#fff",
  26. flex: 1,
  27. },
  28. padBot: {
  29. paddingBottom: 100,
  30. },
  31. list: {
  32. paddingVertical: 10,
  33. paddingHorizontal: 15,
  34. backgroundColor: "transparent",
  35. flex: 0,
  36. },
  37. item: {
  38. flexDirection: "row",
  39. alignItems: "center",
  40. paddingVertical: 10,
  41. },
  42. input: {
  43. marginHorizontal: 5,
  44. minWidth: 49,
  45. // width: 49,
  46. },
  47. text: {
  48. flex: 1,
  49. },
  50. flexRow: {
  51. flexDirection: "row",
  52. alignItems: "center",
  53. },
  54. buttonlast: {
  55. marginLeft: 10,
  56. },
  57. button: {
  58. alignSelf: "flex-start",
  59. },
  60. money: {
  61. marginLeft: 10,
  62. },
  63. addNew2: {
  64. width: 80,
  65. alignSelf: "center",
  66. },
  67. separatorStyle: {
  68. height: 0,
  69. },
  70. });
  71. export default function GoodsSpecificationScreen() {
  72. const theme = useTheme();
  73. const { changeBackground } = useModel("barModel", true);
  74. // const { mid } = useModel("userModel");
  75. const { httpGet, httpPost } = useModel("httpModel", true);
  76. const { success, warnning } = useModel("loadingModel", true);
  77. const { showDialog } = useModel("dialogModel");
  78. const [allEditInfo, setEdit] = React.useState([]);
  79. const [goodsId, setGoodsId] = React.useState(0);
  80. const [startState, changeState] = React.useState(true);
  81. const [editList, setEditList] = React.useState([]);
  82. const [addNew, changeNew] = React.useState([]);
  83. const list$ = useEventEmitter();
  84. const {
  85. delText,
  86. editText,
  87. confirm,
  88. cancel,
  89. successText,
  90. removeTips,
  91. YMZEFF,
  92. MUKYDG,
  93. TMMNWL,
  94. IQYCDU,
  95. GVDYKL,
  96. BCXVJS,
  97. CUYTPO,
  98. MLPRPD,
  99. } = useModel("wordsModel");
  100. const { addClassGoods } = useModel("goodsModel");
  101. useFocusEffect(
  102. React.useCallback(() => {
  103. changeBackground(theme["color-primary-500"]);
  104. }, [])
  105. );
  106. const route = useRoute();
  107. function getList() {
  108. const { params } = route;
  109. const { goodsId } = params || {};
  110. setGoodsId(goodsId);
  111. return httpGet(
  112. "/goodsSpecification/byGoodsId",
  113. {
  114. goodsId: goodsId || 0,
  115. },
  116. true
  117. ).then(res => {
  118. changeState(false);
  119. let isNew = false;
  120. if (res.length === 0) {
  121. isNew = true;
  122. changeNew([]);
  123. } else {
  124. isNew = false;
  125. }
  126. let content = [];
  127. if (res.length > 0) {
  128. let parents = res.filter(item => {
  129. return !item.parent;
  130. });
  131. parents.forEach(item => {
  132. content.push(item);
  133. let _children = res.filter(_f => {
  134. return _f.parent === item.id;
  135. });
  136. content = content.concat(_children);
  137. });
  138. }
  139. if (isNew) {
  140. content.push({ name: "", multiple: false, addIndex: 0 });
  141. changeNew([{ name: "", multiple: false, addIndex: 0 }]);
  142. } else {
  143. addNew.forEach((item, index) => {
  144. if (item.addType === "1") {
  145. content.push({ name: "", multiple: false, addIndex: index });
  146. } else {
  147. let _index = content.findIndex(_i => {
  148. return _i.id === item.parent;
  149. });
  150. content.splice(_index + 1, 0, {
  151. name: "",
  152. amount: "",
  153. parent: item.parent,
  154. addIndex: index,
  155. });
  156. }
  157. });
  158. }
  159. content = content.map(item => {
  160. const _info = {
  161. ...item,
  162. amount: item.amount != null ? item.amount.toString() : "",
  163. };
  164. if (!_info.id || editList.indexOf(_info.id) !== -1) {
  165. _info.edit = true;
  166. } else {
  167. _info.edit = false;
  168. }
  169. return _info;
  170. });
  171. setEdit(content);
  172. return Promise.resolve({
  173. content,
  174. last: true,
  175. });
  176. });
  177. }
  178. const listByOrder = (list1, list2, type, extra) => {
  179. let list = [...list1];
  180. if (type === "add") {
  181. list2.forEach((item, index) => {
  182. if (item.addType === "1") {
  183. list.push({ name: "", multiple: false, addIndex: index });
  184. } else {
  185. let _index = list.findIndex(_i => {
  186. return _i.id === item.parent;
  187. });
  188. list.splice(_index + 1, 0, {
  189. name: "",
  190. amount: "",
  191. parent: item.parent,
  192. addIndex: index,
  193. });
  194. }
  195. });
  196. } else if (type === "save") {
  197. list = list.map(item => {
  198. if (
  199. (item.addIndex === extra && extra != null) ||
  200. item.id === list2[0].id
  201. ) {
  202. item = { ...list2[0] };
  203. }
  204. return item;
  205. });
  206. } else if (type === "edit") {
  207. list = list.map(item => {
  208. if (item.id === extra) {
  209. item = {
  210. ...item,
  211. edit: true,
  212. };
  213. }
  214. return item;
  215. });
  216. } else if (type === "cancel" && extra.id) {
  217. list = list.map(item => {
  218. if (item.id === extra.id) {
  219. item.edit = false;
  220. }
  221. return item;
  222. });
  223. } else if (type === "del" || (!extra.id && type === "cancel")) {
  224. list = list.filter(item => {
  225. return (
  226. (extra.id && item.id !== extra.id) ||
  227. (!extra.id && item.addIndex !== extra.addIndex)
  228. );
  229. });
  230. }
  231. setEdit(list);
  232. return list;
  233. };
  234. const editInfo = id => {
  235. const _editList = [...editList];
  236. _editList.push(id);
  237. setEditList(_editList);
  238. list$.emit({
  239. type: "edit",
  240. list: [],
  241. changeEvent: listByOrder,
  242. extra: id,
  243. });
  244. };
  245. const delInfo = info => {
  246. showDialog({
  247. bodyText: removeTips,
  248. status: "danger",
  249. cancelable: true,
  250. confirmCallback: () => {
  251. if (!info.parent) {
  252. let _allEditInfo = [...allEditInfo];
  253. let _children = _allEditInfo.filter(item => {
  254. return item.parent === info.id;
  255. });
  256. if (_children.length > 0) {
  257. showDialog({
  258. bodyText: YMZEFF,
  259. status: "danger",
  260. });
  261. return;
  262. }
  263. }
  264. httpPost(`/goodsSpecification/del/${info.id}`)
  265. .then(() => {
  266. success(successText);
  267. // changeState(true);
  268. list$.emit({
  269. type: "del",
  270. list: [],
  271. changeEvent: listByOrder,
  272. extra: info,
  273. });
  274. })
  275. .catch(e => {
  276. warnning(e.error);
  277. });
  278. },
  279. });
  280. };
  281. // 取消
  282. const cancelInfo = info => {
  283. if (info.id) {
  284. let _editList = [...editList];
  285. _editList = _editList.filter(item => {
  286. return item !== info.id;
  287. });
  288. setEditList(_editList);
  289. list$.emit({
  290. type: "cancel",
  291. list: [],
  292. changeEvent: listByOrder,
  293. extra: info,
  294. });
  295. } else {
  296. let _addNew = [...addNew];
  297. _addNew.splice(info.addIndex, 1);
  298. changeNew(_addNew);
  299. list$.emit({
  300. type: "cancel",
  301. list: [],
  302. changeEvent: listByOrder,
  303. extra: info,
  304. });
  305. }
  306. // changeState(true);
  307. };
  308. // 保存
  309. const saveInfo = info => {
  310. // const _editInfo = { ...allEditInfo };
  311. // let name = "";
  312. // let amount = "";
  313. // if (_editInfo[info.id || "new"]) {
  314. // name = _editInfo[info.id || "new"].name;
  315. // amount = _editInfo[info.id || "new"].amount;
  316. // }
  317. const data = {
  318. ...info,
  319. goodsId,
  320. };
  321. delete data.addIndex;
  322. addClassGoods(data).then(res => {
  323. if (info.id) {
  324. let _editList = [...editList];
  325. _editList = _editList.filter(item => {
  326. return item !== info.id;
  327. });
  328. setEditList(_editList);
  329. list$.emit({
  330. type: "save",
  331. list: [res],
  332. changeEvent: listByOrder,
  333. });
  334. } else {
  335. let _addNew = [...addNew];
  336. _addNew.splice(info.addIndex, 1);
  337. changeNew(_addNew);
  338. list$.emit({
  339. type: "save",
  340. list: [res],
  341. extra: info.addIndex,
  342. changeEvent: listByOrder,
  343. });
  344. }
  345. });
  346. };
  347. //
  348. const addFullReduction = info => {
  349. let list = [...addNew];
  350. let hasType1 = list.find(item => {
  351. return item.addType === "1";
  352. });
  353. if (info && info.parent) {
  354. let hasParent = list.find(item => {
  355. return item.parent === info.parent;
  356. });
  357. if (!hasParent) {
  358. list.push(info);
  359. changeNew(list);
  360. list$.emit({
  361. type: "add",
  362. list: [
  363. {
  364. ...info,
  365. },
  366. ],
  367. changeEvent: listByOrder,
  368. });
  369. }
  370. } else if (!info && !hasType1) {
  371. list.push({
  372. addType: "1",
  373. });
  374. changeNew(list);
  375. list$.emit({
  376. type: "add",
  377. list: [
  378. {
  379. addType: "1",
  380. },
  381. ],
  382. changeEvent: listByOrder,
  383. });
  384. }
  385. };
  386. const saveItem = (info, index) => {
  387. let editNowInfo = { ...info };
  388. return (
  389. <View Key={index}>
  390. <Layout style={styles.item}>
  391. <Layout style={[styles.text, styles.flexRow]}>
  392. {editNowInfo.parent ? (
  393. <Text category="c1">
  394. {MUKYDG}
  395. {editNowInfo.name}
  396. </Text>
  397. ) : (
  398. <Text category="s1">
  399. {TMMNWL}
  400. {editNowInfo.name}
  401. </Text>
  402. )}
  403. {!!editNowInfo.parent && (
  404. <Layout style={styles.money}>
  405. <Text category="c1">¥{editNowInfo.amount}</Text>
  406. </Layout>
  407. )}
  408. {!editNowInfo.parent && (
  409. <Layout style={styles.money}>
  410. <Text category="s1">
  411. {editNowInfo.multiple ? { IQYCDU } : { GVDYKL }}
  412. </Text>
  413. </Layout>
  414. )}
  415. </Layout>
  416. <Button
  417. size="small"
  418. appearance="outline"
  419. onPress={() => editInfo(editNowInfo.id)}
  420. >
  421. {editText}
  422. </Button>
  423. <Button
  424. size="small"
  425. status="danger"
  426. style={styles.buttonlast}
  427. onPress={() => delInfo(editNowInfo, index)}
  428. >
  429. {delText}
  430. </Button>
  431. </Layout>
  432. {!editNowInfo.parent && (
  433. <Button
  434. style={styles.addNew2}
  435. onPress={() =>
  436. addFullReduction({ addType: "2", parent: editNowInfo.id })
  437. }
  438. >
  439. {MUKYDG}
  440. </Button>
  441. )}
  442. </View>
  443. );
  444. };
  445. const editItem = (info, index) => {
  446. let _allEditInfo = [...allEditInfo];
  447. let editNowInfo = { ..._allEditInfo[index] };
  448. return (
  449. <Layout style={styles.item}>
  450. <Layout style={[styles.text, styles.flexRow]}>
  451. <Text>{editNowInfo.parent ? { BCXVJS } : { TMMNWL }}</Text>
  452. <Input
  453. size="small"
  454. defaultValue={editNowInfo.name}
  455. style={styles.input}
  456. key={`${index}_0`}
  457. onChangeText={text => {
  458. editNowInfo.name = text;
  459. _allEditInfo.splice(index, 1, editNowInfo);
  460. setEdit(_allEditInfo);
  461. }}
  462. />
  463. {!!editNowInfo.parent && (
  464. <>
  465. <Text>价钱</Text>
  466. <Input
  467. size="small"
  468. defaultValue={info.amount}
  469. style={styles.input}
  470. key={`${index}_2`}
  471. keyboardType="numeric"
  472. onChangeText={text => {
  473. editNowInfo.amount = text;
  474. _allEditInfo.splice(index, 1, editNowInfo);
  475. setEdit(_allEditInfo);
  476. }}
  477. />
  478. </>
  479. )}
  480. {!editNowInfo.parent && (
  481. <>
  482. <Text>{MLPRPD}</Text>
  483. <Toggle
  484. key="Toggle"
  485. checked={editNowInfo.multiple}
  486. onChange={checked => {
  487. editNowInfo.multiple = checked;
  488. _allEditInfo.splice(index, 1, editNowInfo);
  489. setEdit(_allEditInfo);
  490. }}
  491. />
  492. </>
  493. )}
  494. </Layout>
  495. <Button
  496. disabled={
  497. !editNowInfo.name ||
  498. (!!editNowInfo.parent && editNowInfo.amount === "")
  499. }
  500. size="small"
  501. onPress={() => saveInfo(editNowInfo)}
  502. >
  503. {confirm}
  504. </Button>
  505. <Button
  506. size="small"
  507. appearance="outline"
  508. style={styles.buttonlast}
  509. onPress={() => cancelInfo(editNowInfo)}
  510. >
  511. {cancel}
  512. </Button>
  513. </Layout>
  514. );
  515. };
  516. const renderItem = ({ item, index }) => {
  517. if (!item.id || item.edit) {
  518. return editItem(item, index);
  519. }
  520. return saveItem(item);
  521. };
  522. return (
  523. <>
  524. <NavHeaderBar title={CUYTPO} />
  525. <Layout style={[styles.lay]}>
  526. <ListComponent
  527. getInfo={getList}
  528. renderItem={renderItem}
  529. style={styles.list}
  530. separatorStyle={styles.separatorStyle}
  531. showEmpty
  532. extraData={{ allEditInfo }}
  533. startState={startState}
  534. list$={list$}
  535. />
  536. <ActionButton
  537. buttonColor={theme["color-primary-500"]}
  538. onPress={addFullReduction}
  539. position="left"
  540. />
  541. </Layout>
  542. </>
  543. );
  544. }